diff --git a/.clang-format b/.clang-format index d80514908..6f7a70547 100644 --- a/.clang-format +++ b/.clang-format @@ -1,4 +1,7 @@ --- +Language: Json +BasedOnStyle: llvm +--- Language: Cpp # BasedOnStyle: LLVM AccessModifierOffset: -4 @@ -87,4 +90,3 @@ Standard: Cpp11 TabWidth: 4 UseTab: Always ... - diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 000000000..50a901b76 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,17 @@ +FROM mcr.microsoft.com/devcontainers/base:bookworm +# utils packages +RUN apt-get update && \ + export DEBIAN_FRONTEND=noninteractive && \ + apt-get -y install --no-install-recommends \ + apt-utils dialog clang-format clang pbuilder + +# bookworm packaging +RUN mkdir -p /usr/local/src/pkg +COPY bookworm /usr/local/src/pkg/debian + +# get build dependences +RUN cd /usr/local/src/pkg/ && \ + /usr/lib/pbuilder/pbuilder-satisfydepends-experimental + +# clean +RUN apt-get clean && rm -rf /var/lib/apt/lists/* diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..9a3e3a474 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,38 @@ +{ + /* For format details, see https://aka.ms/devcontainer.json. For config options, see the + * README at: https://github.com/devcontainers/templates/tree/main/src/debian + */ + "name": "Debian", + "build": { + "cacheFrom": "ghcr.io/kamailio/kamailio-5.8-devcontainer", + "context": "../pkg/kamailio/deb", + "dockerfile": "Dockerfile" + }, + + // Features to add to the dev container. More info: https://containers.dev/features. + "features": { + "ghcr.io/wxw-matt/devcontainer-features/command_runner:0": {}, + "ghcr.io/devcontainers/features/github-cli:1": {} + }, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 5060 + ], + + // Configure tool-specific properties. + "customizations": { + "vscode": { + "settings": {}, + "extensions": [ + "ms-vscode.cpptools-extension-pack", + "GitHub.vscode-github-actions", + "eamodio.gitlens", + "xaver.clang-format" + ] + } + }, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + "remoteUser": "root" +} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..7e8b8a886 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,14 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: check-yaml + - id: check-xml + - id: end-of-file-fixer + - id: trailing-whitespace + - id: check-merge-conflict + - id: mixed-line-ending + - repo: https://github.com/pre-commit/mirrors-clang-format + rev: v15.0.7 + hooks: + - id: clang-format diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 000000000..7234200e5 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,2 @@ +# workflows changes need admin approval +.github/workflows/ @kamailio/admin diff --git a/ChangeLog b/ChangeLog index bc3378458..e7e94033b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,14787 +1,12381 @@ -===================== 2024-01-18 Version 5.7.4 Released ===================== +===================== 2024-04-03 Version 5.8.1 Released ===================== -===================== Changes Since Version 5.7.3 =========================== +===================== Changes Since Version 5.8.0 =========================== +commit e8aa98718d91d0e5af7d757176a180e0f2940417 +Author: Daniel-Constantin Mierla +Date: Wed Apr 3 12:23:42 2024 +0200 + + Makefile.defs: version set to 5.8.1 -commit 116ce498cba50a071ee878e803dbcf63530688cc +commit 69f667fe9b95d09a642cb7edd7f16ce09bbac3f1 Author: Daniel-Constantin Mierla -Date: Thu Jan 18 10:49:23 2024 +0100 +Date: Wed Apr 3 12:18:47 2024 +0200 - Makefile.defs: version set to 5.7.4 + core: msg translator - duplicate reply via xavp params and handle errors + + (cherry picked from commit 5f83d4f9c447f5a7e3de8336dc0e076b10e43833) -commit 743cfae479bed2e5f09ed8e1cd4f3a959299e3ab +commit 1caec71aeddb7f65afb93bf05cb9e0aae2a2c0cd Author: Daniel-Constantin Mierla -Date: Thu Jan 18 10:30:20 2024 +0100 +Date: Wed Apr 3 12:16:18 2024 +0200 - pkg: deb specs updated for v5.7.4 + core: xavp - added missing closing parenthesis in log messages + + (cherry picked from commit 3b09fd343575c56d9658a61efebd4851662de338) -commit d5cf7148375feb7d4202a07023caaeaeda3396c7 +commit 4708758f1c428cc94d1abdf9bb706c7c509efebe Author: Daniel-Constantin Mierla -Date: Thu Jan 18 09:30:27 2024 +0100 +Date: Wed Apr 3 08:22:44 2024 +0200 - pkg: version set to 5.7.4 for rpms and alpine specs + pkg: deb specs updated for v5.8.1 -commit 3b79c1ef3cc6c1019fe7cb99ff77e0c51d8e789a -Author: S-P Chan -Date: Thu Jan 18 06:21:55 2024 +0800 +commit 3b00630c8a20cc0f2b2f458742d885ea7e28e05f +Author: Daniel-Constantin Mierla +Date: Wed Apr 3 08:20:49 2024 +0200 - tls_wolfssl: clean-up—using wolfSSL native naming for functions / structs - - (cherry-pick from 5bbb224fdad1770150dd2fc37c69393aeda96d40) + pkg/kamailio: version set 5.8.1 for rpms and alpine -commit 784bb3b397cc1922d06054c611c443dd19216504 -Author: Elena-Ramona Modroiu -Date: Tue Jan 16 16:07:43 2024 +0100 +commit 4e4e935c45ccf32dab9bf5af693a0f52f54684ae +Author: Kamailio Dev +Date: Mon Apr 1 08:31:34 2024 +0200 - tls: set parameter name for tls_h_mod_randctx() - - - without it fails to compile on Unbuntu 22.04 with low latency kernel - - (cherry picked from commit 03456e5e5983e2236b8e182cf3317d14ebf34e18) + modules: readme files regenerated - modules ... [skip ci] -commit a539ca32ec3a898e354aab90d899b99564064392 +commit e394a05152b29d4009c9cb963bced72526c7651b Author: Daniel-Constantin Mierla -Date: Thu Jan 11 08:21:00 2024 +0100 +Date: Thu Mar 28 08:30:17 2024 +0100 - core: keep listen socket even if advertise address does not resolve + blst: reformat exported structures - - the core advertise_address parameter works in the same fashion - - previously it was starting by skipping the listen, which resulted in - unexpected runtime list of sockets + (cherry picked from commit e39557c96d2f419184c826d779f1a3309acc4269) + +commit c0c8ee05ab25256b9154d2056ee04b07f3f2290a +Author: Daniel-Constantin Mierla +Date: Wed Mar 27 08:19:03 2024 +0100 + + smsops: short reference section about variables - (cherry picked from commit b50036200c5bc09fd2d412a18585b42d63763b27) + (cherry picked from commit 9a94930ae1168d5df79e3dc1414841cdf23a2eba) -commit 2dff6f52d1393cf8eabe714262ec8e56aad0d212 -Author: Federico Cabiddu -Date: Wed Jan 10 08:52:03 2024 +0100 +commit b21a7aaa467f2b76a52308557657c65274e34087 +Author: Daniel-Constantin Mierla +Date: Tue Mar 26 19:17:23 2024 +0100 - http_async_client: exit mod_init if tm is not loaded + smsops: reformat module exports structures - (cherry picked from commit 5a40d1ef1b484c4fc437a3f0183a101241e80313) + (cherry picked from commit 9848d43cb367d6901a0b8c727759feb8a8fad930) -commit dc59286c26e9799f86e698a9698c9da846a2a41a +commit 3f3c1940788a4713705169f8d96ae9a13ee2bad1 Author: Daniel-Constantin Mierla -Date: Tue Jan 9 14:06:21 2024 +0100 +Date: Mon Mar 25 23:25:19 2024 +0100 - htable: read rpc number value as long + db_mysql: right position for define KSR_MYSQL_OPT_RECONNECT - - remove autoconvert for number, it is only for string values - - GH #3674 + - follow up of previous commit - (cherry picked from commit 577fb11010ff61af3c4b567581c0bbc5404654c8) + (cherry picked from commit 14dc277e29a170b9ac51e7dda07fa25cbd9be048) -commit 37a07037b6e3485f3ddd1b27b1998af6e4283bcb -Author: Dennis Yurasov -Date: Wed Dec 20 16:11:56 2023 +0300 +commit 557d7e83c01c930df608b9d96791553d8f2bf724 +Author: Daniel-Constantin Mierla +Date: Mon Mar 25 23:07:55 2024 +0100 - dialog: fixed saving dialogs on shutdown that are already loaded at startup when using db_mode 3 + db_mysql: MYSQL_OPT_RECONNECT is deprecated by MySQL 8.0.34 - - The dialogs that loaded at startup are not saved in DB on shutdown, and so not loaded at restart, - fixes issue #3669 + - https://dev.mysql.com/doc/c-api/8.0/en/c-api-auto-reconnect.html + - MariaDB seems to still have it - (cherry picked from commit 2d00ce546bb0852dc1784d5bc2e794d06f919577) + (cherry picked from commit da3d6e9a74b63fdb7b1c4063d6be017f1ce42bea) -commit be5b4b160ecff8dc398735fbd28ceb71845f1bef -Author: Nikolay Ivanuschak -Date: Mon Dec 18 22:20:50 2023 +0300 +commit c9edb30ffa0c9544a10d0e72aabe84a1b3b2a103 +Author: Daniel-Constantin Mierla +Date: Sat Mar 23 21:38:00 2024 +0100 - core: fixed haproxy protocol parser + keepalive: reformat module exports structures - fixes GH #3683 + (cherry picked from commit dd221a6e5162838b979fd38ffdfb750663aef869) + +commit 3f44cabcfc0abc83ae1971ac74fbb0bd36829ce4 +Author: Elena-Ramona Modroiu +Date: Sat Mar 23 09:58:46 2024 +0100 + + corex: fix conditions for dns_cache modparam srv attributes - (cherry picked from commit c5237830f3e7fbeec403a0190471a066081c1117) + (cherry picked from commit 8114b2016d032484edafe4edd04fb02d52cfd058) -commit fc0bd88b55121e3588f5793480f0594e44bf2b17 -Author: Daniel-Constantin Mierla -Date: Tue Dec 26 17:51:48 2023 +0100 +commit dbf9208f3a402844c9981fb7ed09493a1338dfdd +Author: Elena-Ramona Modroiu +Date: Sat Mar 23 09:51:47 2024 +0100 - statsd: use bool type for local variable to match return of function + core: resolve/create_srv_pref_list() - insert at correct position in list - (cherry picked from commit 0186246fce8f0e4bb46b30c05174983cd957a3ba) + (cherry picked from commit f35cf8904119dcf582ea2451648de5fef095466b) -commit 6cd8f2acc0601fbd040999d776f15b828d6e4946 +commit 0e00ae1db0242fc01e6f8c332e3920fd9465b3f9 Author: Daniel-Constantin Mierla -Date: Sun Dec 24 12:20:57 2023 +0100 +Date: Fri Mar 22 10:25:48 2024 +0100 - tmx: rework cleaning up on init failure + core: socket info - parse advertise ip part to get address family - (cherry picked from commit 5192e5d275761ccd1af49d4bf9dd12e1438947b7) + (cherry picked from commit 5f901c3557f9f875545d82a7ab00f6d0c5c1fe52) -commit 916d02d883dc938247576bdf8f5c5b23a588cb9c +commit c48fbea981c7b0bd281cd1fc2abedcda41d92c13 Author: Daniel-Constantin Mierla -Date: Fri Dec 22 14:50:59 2023 +0100 +Date: Wed Mar 20 13:40:28 2024 +0100 - tm: make lookup event_route[tm:local-response] only once - - - related to issue #3064 and PR #3687 + gcrypt: docs - module name used for section ids - (cherry picked from commit 1f5444fd2e25d227ffd70f1087d057a3b8002558) + (cherry picked from commit 68c69966c38b56775a3966d07c33ff94c2a8ba95) -commit 5a26d9e9fba36a49a93bb3b886836615f62ed3d1 -Author: Daniel-Constantin Mierla -Date: Mon Dec 18 12:31:34 2023 +0100 +commit 613e2cdfc3ae9242d259bf8b67b6ed715c0c0ad8 +Author: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com> +Date: Wed Mar 27 15:48:50 2024 +0000 - pv: removed unnecessary condition + file_out: FIx ‘for’ loop initial declarations error - (cherry picked from commit 2f43510be37c157f800389dfb432b6c52d7435a7) + (cherry picked from commit ae04ccac92225a1e7b573a28ded555789e8604cd) -commit 2d385c1983a921a95fb392e8aea0332fdc10a387 -Author: Daniel-Constantin Mierla -Date: Mon Dec 18 12:22:25 2023 +0100 +commit f4d44a9201a79acf0620a005008f2594ff8d26ee +Author: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com> +Date: Wed Mar 27 15:48:25 2024 +0000 - pv: typo in transformation log message + tls: Fix ‘for’ loop initial declarations error - (cherry picked from commit ca2a9479adf720e67bf50c9d2795cc8937e223dc) + (cherry picked from commit 9f2abc69e27c4b3246628138ec81fced81d7bc7a) -commit 0ca30e87655798e3841c005abb63ca66bb2ca0aa -Author: Daniel-Constantin Mierla -Date: Sat Dec 16 20:04:08 2023 +0100 +commit 3fac5afc42a606391d6a7c0337ef5e4e136d6b80 +Author: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com> +Date: Fri Mar 22 10:24:05 2024 +0000 - core: srjson - init vars and check scanned values + file_out: Cast to correct type of str - (cherry picked from commit 678b1a68de86d9539adeaf0262d9735b8d435077) + (cherry picked from commit 4ada818099b5b7cb7deff1b1ce93b5aacaa1b84e) -commit 4371adffc07bb555e2a52dedd6cd5afa2631287a +commit 028ba8f9d6bc40dcd47e6a0e5b40e5b3e2ea7b17 Author: Daniel-Constantin Mierla -Date: Wed Dec 13 12:23:23 2023 +0100 +Date: Fri Mar 1 11:42:45 2024 +0100 - app_python3: check allocated pointer + file_out: additional checks for silenting warnings - (cherry picked from commit 49b3b90cd229b7c4da06b61cdfd782450d383cc9) + (cherry picked from commit 19894425684504e2a19622ae5a9cdfc565f16fd3) -commit 62b76c076ff0f36b847a13c180b7d5090e98d94e -Author: Daniel-Constantin Mierla -Date: Wed Dec 13 12:15:28 2023 +0100 +commit 814f5bdc9ee5d4594ffb0fd72843bca7b5fa79ea +Author: Victor Seva +Date: Sat Mar 23 00:00:44 2024 +0100 - core: check if conversion could not be done + dmq: fix inter-lock on error - (cherry picked from commit 077651fa3bfd50e0f654c907f3783b1421497bd5) + triggered by intermittent DNS resolution error. dmq workers + were getting locked at dmq_notification_callback_f() due to + this missing lock_release() + + (cherry picked from commit 0d240e4e0dc3184ef37d338ba6872d295d6b16f2) + +commit 7bcef8ef487a713f5b6c6fadb7a3166ed41fb136 +Author: Kamailio Dev +Date: Wed Mar 20 13:31:25 2024 +0100 + + modules: readme files regenerated - modules ... [skip ci] -commit 0712576dc4d57ba41e45012486dd206d955c35e6 +commit 60fd6c2622c9c5edbe82908c0e461d646225c8a6 Author: Daniel-Constantin Mierla -Date: Wed Dec 13 12:08:56 2023 +0100 +Date: Tue Mar 19 17:39:19 2024 +0100 - registrar: check returned branch pointer + ndb_redis: break on finding a server via sentinel inside redisc_reconnect_server() - (cherry picked from commit 5d641f56fc1bc342d9be008ecd96959e114fef66) + (cherry picked from commit 951ab118bb7d9955f8e69b66bec1f0c107d474a2) -commit 1189bb2962dd80c21a1d497125f3199ccc018270 +commit 86df978bc9842687035d6673ee1b71e542dcbd71 Author: Daniel-Constantin Mierla -Date: Wed Dec 13 12:02:01 2023 +0100 +Date: Tue Mar 19 14:29:11 2024 +0100 - tm: check get_t() result for consistency + ndb_redis: fix index on parsing sentinel address inside redisc_reconnect_server() - (cherry picked from commit 1191ab4e5e03b35714ec1ad9d9bf2dd9665c71fd) + (cherry picked from commit c8f3b496a05ae5bf29341dc7e2630f951d4effc5) -commit 37621005e38a0191a93fbaf4f39b8b88c7486c9d +commit a0dfa0ac81ed4aec33863fc20cf5cb3ee077a90c Author: Daniel-Constantin Mierla -Date: Sat Dec 9 20:07:37 2023 +0100 +Date: Tue Mar 19 14:26:27 2024 +0100 - dialog: check first the size + ndb_redis: clang-format for WITH_SSL code - (cherry picked from commit 9db18bc48bff0d230e66973a45c8e72e1b7744e8) + (cherry picked from commit e54051d698b059aa168229493dc2d6bf3cdd757c) -commit 81dce4e5003f3c00301671144ac67877f5824b72 +commit a7d4ce95b383dc26c547ef9ee07b05d51abc50f9 Author: Daniel-Constantin Mierla -Date: Fri Dec 8 16:23:03 2023 +0100 +Date: Tue Mar 19 10:21:51 2024 +0100 - core: xavp - info long when skipping serializing a field + keepalive: small formatting updates and comments to the ka dest structure - (cherry picked from commit 5d97afefd2a8f53072a36b6eb8927c180fb984c9) + (cherry picked from commit cee82c92b06a026b88fea654944f6146eb5cb4d8) -commit 3046d01bed4bdd0fe763fd770ffc8f7aeeae3418 -Author: Péter Barabás -Date: Wed Dec 6 21:16:46 2023 +0100 +commit 0b3aa00775a5c0b4b1dc4990f4c26bc637fc6de5 +Author: Daniel-Constantin Mierla +Date: Tue Mar 19 09:51:28 2024 +0100 - uac: fix socket length settings + keepalive: proper storing of last up/down timestamps - - set _uac_req.s_sock.len value to 0 in pv_set_uac_req() method in case of "all" case - - change setting of _uac_req.s_apasswd.len to _uac_req.s_sock.len in pv_set_uac_req() method in case of "sock" case + - GH #3790 - (cherry picked from commit 10519d199f6cac116399f4473bd82f2b08de72ba) + (cherry picked from commit 9e2a0ee545646bd4491ecdbe58d7fea770764b54) -commit 065203150aaf2f99bd6fe40ce5ffb960bd430c16 +commit 91b0962679092f28abb5022d1505372356460f7d Author: Daniel-Constantin Mierla -Date: Tue Dec 5 10:27:32 2023 +0100 +Date: Mon Mar 18 11:02:07 2024 +0100 - dialog: prevent duplicate of leg1 attributes in json for dmq + acc: more log messages of failure arsing extra acc string - - reported by #3656 + (cherry picked from commit 04a73ace6572dd5c95a8f50b39b2ce712f7ebe84) + +commit 5daadecd248322e5f8eaf15555e46692f3d1c267 +Author: Axel Sommerfeldt +Date: Fri Mar 8 12:32:07 2024 +0100 + + ims_ipsec_pcscf: TLS support in ipsec_forward() improved + + This patch was initially done by Herle Supreeth in his fork but isn't present upstream yet: + https://github.com/kamailio/kamailio/commit/8b9a2977e111d9adb8595d98ab59f8c8eb033120 + + See also: https://github.com/kamailio/kamailio/issues/3772 - (cherry picked from commit ca7e1e49aecd3e0f12cc783e3b97868980f1d3d2) + (cherry picked from commit 3154a0aba5543cab75153429bc8ec617c3484f71) -commit 18fead63dca0982df500b35b7c4e2d06550d9b40 -Author: Daniel-Constantin Mierla -Date: Mon Nov 20 10:07:50 2023 +0100 +commit 7df7508d7d2b7b9495dafab8b515a5721bd669ee +Author: Dennis Yurasov +Date: Mon Mar 11 14:22:37 2024 +0300 - core: set proto on fixing forward actions + dispatcher: refine documentation + - more clear documentation for the new ds_is_from_list flags - (cherry picked from commit e51ccd11fe51f2d53dd7719b8fdec561a6ba7494) + (cherry picked from commit 761e963c0f7d9bf1b66c1ef18a409756b919ae2c) -commit d411c6ea4358e6d9dd367349e877ed5f5bf4bb2f -Author: Federico Cabiddu -Date: Tue Jan 16 09:42:27 2024 +0100 +commit 90f8117f9669069b4dab7e9d747dfa06245ec8a0 +Author: Daniel-Constantin Mierla +Date: Fri Mar 15 21:24:42 2024 +0100 - dialog: don't send the BYE if dialog is in deleted state (#3714) + ctl: handle int input for double storage - (cherry picked from commit 695f155f3a127f0bbe220a6b44a0fc3887e1e4be) + (cherry picked from commit 1380a4a0d18159c7130b70c0216134a253ad83f7) -commit b6796b110adbe4dec7ac1acb1d7d70bdc58bf1c2 -Author: S-P Chan -Date: Tue Jan 16 16:36:25 2024 +0800 +commit 0af55b0eac8c3457db859a9c37fea211ece91b8a +Author: Stefan-Cristian Mititelu +Date: Tue Mar 5 16:30:01 2024 +0200 - tls_wolfssl: mask outer make DESTDIR=XX if building internal submodule + pdb server: Return negative carrierid for failures. Clang format + + (cherry-picked from commit 88b698e0f62c39ed60af9f0a4fb3ca2dc6867d8f) -commit d5ebc2716992c2480c604555511511ce043bead7 -Author: S-P Chan -Date: Tue Jan 16 16:13:55 2024 +0800 +commit 6410f375cd6d1e357afeb9e100bd3a3c51321280 +Author: Stefan-Cristian Mititelu +Date: Tue Mar 5 16:14:11 2024 +0200 - tls_wolfssl: update to v5.6.6-stable + pdb: Return negative carrierid for failures + + (cherry-picked from commit bf78b619ae28924361fb2c757a4d09eb1a39f5cd) -commit 449155221586294d716e760fbabbd4e101ad1be2 -Author: S-P Chan -Date: Mon Jan 15 21:32:53 2024 +0800 +commit d6cd0859158a8013e998ec779e956a550b493934 +Author: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com> +Date: Thu Mar 14 16:47:28 2024 +0000 - outbound: update to OpenSSL 3 API + file_out: Fix var position and initialize - (cherry-pick from fe5c7125c66e37d2db032a63328ad713738a4b0c) + (cherry picked from commit e36b2232e9b097794845659f71543bc57ef58a35) -commit bbbcb27040c632642c50209455efbb8225888723 -Author: S-P Chan -Date: Sun Jan 14 14:08:03 2024 +0800 +commit f9b1cca33a45560f06b2708975c624da9728b6f5 +Author: Oded Arbel +Date: Sun Mar 10 19:55:20 2024 +0200 - tls: remove thread-enablement on EVP_RAND_CTX + pkg/kamailio/obs: Allow builders to disable wolfssl module [skip ci] - - with late initialisation it is not necessary to enable thread locking - on EVP_RAND_CTX - - the function remains but is not used in case requirements change - with OpenSSL >= 3.2 + Building the WolfSSL module should be optional, even if it is on by default, builders should be able to choose to not need to install 4th party repositories. + + fixes #3781 - (cherry-pick from 8dffc45ee91aeed839efb38d17040359dcac953a) + (cherry picked from commit 5392dbf8070abf36734d9c857924df91186bc2dd) -commit c5ed0e65b2530443b1367986dac2b3da111c0701 -Author: S-P Chan -Date: Thu Jan 11 08:03:07 2024 +0800 +commit 45ee72fcf0ae8aeb135196ef8729fe0cea14048e +Author: Daniel-Constantin Mierla +Date: Sat Mar 9 20:11:07 2024 +0100 - tls: historical code comment on repeating SSL_CTX per worker + topos: properly handle cases of no user in contact for mode 1 - (cherry-pick from 29007ada5bc9e07ede3cdbce285f04d1298c0612) + - contact mode 1 accepted cases with no-user in contact uri but not in + r-uri, however, requests within dialog can have one's contact in r-uri + and then processing failed + + (cherry picked from commit 24e410f9a20d004f55bcc79cd10fb35cb26e4570) -commit 1eb1d50e676fe8f81521c209f37ffe907fa9cf94 -Author: S-P Chan -Date: Fri Jan 5 20:56:39 2024 +0800 +commit 772b464552cff0b9ebb769e57fae718c0357ba11 +Author: Daniel-Constantin Mierla +Date: Fri Mar 8 19:43:49 2024 +0100 - outbound: build, fix missing argument name + topos: small rearangement by removing else after return in the true block + + - reduce level of indentation + - a few wraps in curly braces for clearer view of the if block - (cherry-pick from 4708f537d7f5d28123b48cd89474a4931dd698ad) + (cherry picked from commit b6fccea258e56b7d3195659245713a6d44acb013) -commit fe0968687d5ee7918f6a18591623fcb1b5fe2004 -Author: S-P Chan -Date: Thu Jan 4 21:47:23 2024 +0800 +commit 2122afae2a6604c0bc44a43ab37ee274a15a700a +Author: Juha Heinanen +Date: Tue Mar 12 22:16:23 2024 +0200 - outbound: OpenSSL 1.1.1 thread-local, init libssl in thread - - (cherry-pick from 689de2736f5c92f11860e5854ccd95c84239f032) + Avoid 'qm_strnstr' defined but not used warning -commit 31e42aade0a42aac8a128a4af3f37edb23bb3ab8 -Author: S-P Chan -Date: Thu Jan 4 20:11:21 2024 +0800 +commit 1928af8f90ebf02f610c0904bc3d24a00aaedb81 +Author: Juha Heinanen +Date: Tue Mar 12 07:54:50 2024 +0200 - outbound: OpenSSL 3.x thread-local, init libssl in thread - - (cherry-pick from 4742c8131aba878c4fc954e42b656b9d4bafdd24) + core: set null-terminated char for modparam (backport from master) -commit 7060ad2b0ebf90288be9d8d7e9d789ccbb3aebdc -Author: S-P Chan -Date: Fri Jan 5 07:38:56 2024 +0800 +commit c229e11ba39da40cadaecd1b6aa3ae153e014bb1 +Author: Sergey Safarov +Date: Thu Mar 7 13:32:22 2024 +0200 - tls: OpenSSL 3.x/1.1.1 thread-local, clean-up dead code and preprocessor blocks + pkg/kamailio/obs: packaged README.file_out - (cherry-pick from 798cc26908395d2ba21015684ad6f0ac4f012b2e) + (cherry picked from commit 20edb64247a20a5d6b4b8bfb264b6e31d283b039) -commit e73b07e9835ba5f0b89065616d8cd6390898d700 -Author: S-P Chan -Date: Fri Jan 5 08:09:34 2024 +0800 - tls: thread-local, revert 1a9b0b6361 as double-layer locking is redundant - - - the 2nd lock was put in place as defensive programming for shm contention - - GH #3695: the underlying issue is early init of thread-locals - - (cherry-pick from 1c70775530b1a3a905e8a983610cb0d092b0d240) -commit c011f518b083fc2f7da3a08a2c1a306c6122b04c -Author: S-P Chan -Date: Thu Jan 4 21:56:00 2024 +0800 +===================== 2024-03-07 Version 5.8.0 Released ===================== - tls: OpenSSL 1.1.1 thread-local, init libssl in thread - - - no need for RAND workaround; default is OpenSSL 1.1.1 RAND - - linux/pthreads will handle forking - - (cherry-pick from 7b531cfe038fae5e3414ac74c4e076c10e32b86c) +===================== Changes Since Version 5.7.0 =========================== -commit 90ea4120c04cb70f858f417309ee4fab71a070e7 -Author: S-P Chan -Date: Thu Jan 4 21:51:15 2024 +0800 +commit 1fa3ba8ee48b6a68f2133544da56e0d68eae8609 +Author: Daniel-Constantin Mierla +Date: Thu Mar 7 12:29:02 2024 +0100 - tls: fix compilation with OpenSSL <= 1.1.1 - - (cherry-pick from 7111687e1107261bcdd7a9f8cc90959754c93272) + Makefile.defs: version set to 5.8.0 -commit ed2d70359723458089dd8a62fe1e37a60dd83869 -Author: S-P Chan -Date: Thu Jan 4 20:00:09 2024 +0800 + - first in the new 5.8.x series - tls: OpenSSL 3.x thread-local, init libssl in thread or PROC_SIPINIT - - - avoid initialising ERR_STATE in rank 0(thread#1) - - (cherry-pick from e49a60e1052c6c1dcebe7f78f2ac970338eabe2e) +commit e6b67b13a75a49d9269c53443de7233888c0df00 +Author: Daniel-Constantin Mierla +Date: Thu Mar 7 12:23:09 2024 +0100 -commit bfc63986ae7239a64803b8f20f634522bc584948 + pkg/kamailio: version set 5.8.0 for rpms and alpine + +commit 50a0f82eab0a1f9dc5738f022231eba349a46a3a Author: Victor Seva -Date: Tue Dec 12 15:38:33 2023 +0100 +Date: Thu Mar 7 11:41:19 2024 +0100 - pkg/kamailio/deb: override lintian error on stretch [skip ci] - - (cherry picked from commit aaeb54c8b630b4aac50df75ff430ad5baea6746c) + pkg/kamailio/deb: version set 5.8.0 [skip ci] -commit 75aecd3f2e10509d5ed71cc5e89ae6f5c3bd0fea -Author: Daniel-Constantin Mierla -Date: Tue Dec 12 13:08:18 2023 +0100 +commit ed99a5e2648c39e29fbbc7842c86425147c607c6 +Author: Kamailio Dev +Date: Thu Mar 7 10:17:15 2024 +0100 - pv: remove extra len increment for some uri transformations + modules: readme files regenerated - modules ... [skip ci] + +commit 22f274513a98cc081d44a6694e35c3e96844dae3 +Author: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com> +Date: Tue Mar 5 14:34:19 2024 +0000 + + tls/docs: Update certificate generation docs - (cherry picked from commit 3fe9a279abecf6f367ce9fd2d4b085c41c87ad77) + (cherry picked from commit 67785fea8f906236e4a30bc09bb11b3292c46572) -commit 8674b333300d5829bff9cb4993886bcf7bea249b -Author: Daniel-Constantin Mierla -Date: Fri Dec 8 22:10:36 2023 +0100 +commit 6533c42fc0bba6408376a8f8b41b02b97b04ca1b +Author: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com> +Date: Tue Mar 5 12:52:51 2024 +0000 - core: parse privacy recompute lenght of rest to parse + tls/docs: Update tls.reload docs - (cherry picked from commit 804ee651b45498727196886c97cb55d20b254c4a) + (cherry picked from commit 4c9cfa7a6a770a693ecb3b840ad042fb201db675) -commit b634dc7f4d8f1653502328488f0dded134547b54 +commit a814df7e828db7be0b34738c2eb78b133c22ddef Author: Daniel-Constantin Mierla -Date: Fri Dec 8 12:34:56 2023 +0100 +Date: Tue Mar 5 20:53:47 2024 +0100 - tls: init early the local lock for memory - - - needed to done before mod param init_mode is set - - runtime uses the modparam to do lock/unlock - - #3668 + presence: docs - remove extra section end tag - (cherry picked from commit 1a9b0b63617afebcee2aecb3b2240d7684ecabc2) + (cherry picked from commit ed32512f4594cc0ddc3437e274bcba5acfc16410) -commit 63e8749132257ef1f8c8d86ec78f6db2c699f1c8 +commit 500e5fabf9da31b5fa2949cac90956da99751223 Author: Daniel-Constantin Mierla -Date: Thu Dec 7 13:00:50 2023 +0100 +Date: Mon Mar 4 15:31:18 2024 +0100 - tls: rework init mode 1 to set PTHREAD_PROCESS_SHARED + core: main - init local variables used for cli param parsing - - pthread mutex set in shm - - GH #3635 - - (cherry picked from commit 4b068f49b618dca5fa85a1687bd9054c1d98ae6a) + (cherry picked from commit 8a2894cd6180f904dd37acb4985db4e4935aa434) -commit b29d5808505aa072fd23b59adf7943fb13ea98a2 -Author: Victor Seva -Date: Wed Nov 29 17:21:59 2023 +0100 +commit d45c78eeeaea6a9fc9dcb927436f834392d9d7c9 +Author: Daniel-Constantin Mierla +Date: Mon Mar 4 13:58:35 2024 +0100 - Makefile.groups: fix ktls when KTLS_INCLUDE_TLSA is not set + ctl: reset log prefix on reading ctl traffic - fix #3660 + - it may be previously set in process by some event route - (cherry picked from commit aef29af56cabaf626e2ae552ae69c3cd2f692a27) + (cherry picked from commit 5b8b2717ee2f57da932132683b27eb33cea3fd59) -commit 0d028d9a4900411856a64ab31f81f57e3fc68099 -Author: Victor Seva -Date: Fri Nov 24 14:21:27 2023 +0100 +commit 42282a2c78fc24ff2b3856983a6dbb188a2912e3 +Author: Daniel-Constantin Mierla +Date: Mon Mar 4 09:07:22 2024 +0100 - pkg/kamailio/deb: include tlsa in tls package [skip ci] + acc: cdr - do not free static empty string in case of error - * skip xenial since build fails + (cherry picked from commit 0fc0cdd791ce5157232dd2139238708403cdde1d) -commit 7f07a6ef9ae90baee4281394d0dcf505b30c8fcb +commit 4626cb7f0e0b273153ce0004900a92553783a893 Author: Daniel-Constantin Mierla -Date: Fri Nov 24 10:38:49 2023 +0100 +Date: Sun Mar 3 20:57:45 2024 +0100 - Makefile.groups: tlsa in packaging group ktls if KTLS_INCLUDE_TLSA=yes - - - if not, then it is in separate group module_group_ktlsa + core: parser rr - check for rr value before serializing - (cherry picked from commit a49c8d8d968e31a539e47db6c06a0756e4be55e3) + (cherry picked from commit 6ee26a3ae3293aaeb4507d5d0b16ad31173cc39a) -commit 1de0032363ffb0fb6e257497a173f70deac58525 +commit 089bf63178039b13cde0beccfacab1536af76179 Author: Daniel-Constantin Mierla -Date: Thu Nov 23 12:35:48 2023 +0100 +Date: Fri Mar 1 12:46:17 2024 +0100 - websocket: use literal module name for stats group - - - prevent conflicts with global exports + core: select - handle ws and wss inside select_ip_port() - (cherry picked from commit 93609b53d70df84788741800fc2b80c5502a3358) + (cherry picked from commit d8e0942c9e83c8cad7c182bf41c156ba35bf24d2) -commit 292c8764b22d3cdb78a85f101b0359424d138d5d +commit 4c78a564c5ad8662014cf686428a37238a6d8476 Author: Daniel-Constantin Mierla -Date: Thu Nov 23 12:35:47 2023 +0100 +Date: Fri Mar 1 12:41:13 2024 +0100 - usrloc: use literal module name for stats group - - - prevent conflicts with global exports + core: ppcfg - jump to end when defexp eval does not get a str val - (cherry picked from commit 186ae3eef7f3e1b5ad6222c98a2f35a487deb316) + (cherry picked from commit daac0bdb88f6f732bda7c683af45b90f87fdb7c9) -commit bf665fc6d398009a0643cb60f9dad95f66cdb17c +commit 219c21fe62638e7191dd1b5ad32ba098273e2009 Author: Daniel-Constantin Mierla -Date: Thu Nov 23 12:35:47 2023 +0100 +Date: Fri Mar 1 09:55:16 2024 +0100 - tsilo: use literal module name for stats group - - - prevent conflicts with global exports + influxdbc: copy with buffer size limit - (cherry picked from commit a9d29645ab417c9b0f7afc6745e6dd54bdac07b4) + (cherry picked from commit 73c66150c604326c07d454002c12cb221289936a) -commit d5829f56bfc36133ba6db124bf738a6b9a90c904 +commit 0747c18d5c4db2e7e8408ad2c7efa120ec76523e Author: Daniel-Constantin Mierla -Date: Thu Nov 23 12:35:47 2023 +0100 +Date: Fri Mar 1 09:37:59 2024 +0100 - tmx: use literal module name for stats group - - - prevent conflicts with global exports + core: rthreads - init return variable - (cherry picked from commit d4c0e1bbcb0e423a545650aad4fbb4b2da8bb488) + (cherry picked from commit 181c602616e13323786335e8e28f182871aa5e9b) -commit 21abe7ab16d450f1b085a97a4c0f416d45ac2daf -Author: Daniel-Constantin Mierla -Date: Thu Nov 23 12:35:47 2023 +0100 +commit c06ea12d0fff50569803ea0fef9486726ab428ce +Author: herlesupreeth +Date: Tue Feb 27 21:01:44 2024 +0100 - sst: use literal module name for stats group + ims_registrar_pcscf: update registered state to pending registration if contact exists - - prevent conflicts with global exports + (cherry picked from commit 4fb8accc6747ad56fec3dc84d70cb2b8bbd7316e) + +commit ab981daa54c1afc1017af16afbb67ef55567e6fa +Author: herlesupreeth +Date: Sun Feb 25 16:16:14 2024 +0100 + + ims_usrloc: make matching of username in contact conditional - (cherry picked from commit 96bdd69945af9f08e6c89fb725248b8b268ee71a) + (cherry picked from commit 17bdbd34b1038de936f14c1a41ce55f571e6402a) -commit 9a768e006eb0b6ab508ebc5385690eb87711e14f +commit 8835f04334981b81df7eed6c03e581fcc4070da8 Author: Daniel-Constantin Mierla -Date: Thu Nov 23 12:35:47 2023 +0100 +Date: Tue Feb 27 09:50:05 2024 +0100 - siptrace: use literal module name for stats group - - - prevent conflicts with global exports + tcpops: if connection not found, return attributes from sip msg rcv - (cherry picked from commit 92cdcb4bd280850743b3a952f1b6003be69daaf2) + (cherry picked from commit c3d753885b3cd1bc0cb9f46986e5798dfb5f6552) -commit 9a658e0533e592641f86db037eb398ae34f65848 +commit c2ac3ffc907ded71bcde59c3c5c0d6b69e997696 Author: Daniel-Constantin Mierla -Date: Thu Nov 23 12:35:47 2023 +0100 +Date: Tue Feb 27 07:57:22 2024 +0100 - sipcapture: use literal module name for stats group - - - prevent conflicts with global exports + tcpops: variables to get active connection attributes - (cherry picked from commit 01abed3ef17f6a5f0f215675a2980f0b9a4267fd) + (cherry picked from commit 59230a07b8c6a79c4a574890bae775c3d166c471) -commit 1467f7517b6256a712eeb93288561934477f36a4 +commit 50c759030f024dd080c08a3d94127f1d1af544e2 Author: Daniel-Constantin Mierla -Date: Thu Nov 23 12:35:47 2023 +0100 +Date: Mon Feb 26 14:06:38 2024 +0100 - registrar: use literal module name for stats group + ndb_redis: init enabled for tcp-main and postchildinit callbacks - - prevent conflicts with global exports + - GH #3768 - (cherry picked from commit 0516fb802628ddb659a130aa2959df5b0b8e0c96) + (cherry picked from commit 19e5bf3d4cfc2b7d47623e307fff7e60e73e8a18) -commit 59c32aef1e40edcfb081a18728b4e6029d2d2be8 +commit 2d2006701f491f732ea07b36a48016f7fbe436bf Author: Daniel-Constantin Mierla -Date: Thu Nov 23 12:35:47 2023 +0100 +Date: Mon Feb 26 13:09:27 2024 +0100 - p_usrloc: use literal module name for stats group - - - prevent conflicts with global exports + microhttpd: docs - note about variables available in the event route - (cherry picked from commit a951cb44ecbcd0f9cba937176ea5117c6a1d15b6) + (cherry picked from commit 993583015b127b0a83603acd352925c8d6e6db70) -commit 21f4e3c9ce4a6d7ae87ad746742b283dde621a50 +commit 3415be29303bbacaf25b646d6c86027e93cf7c7e Author: Daniel-Constantin Mierla -Date: Thu Nov 23 12:35:47 2023 +0100 +Date: Sun Feb 25 19:29:24 2024 +0100 - nat_traversal: use literal module name for stats group - - - prevent conflicts with global exports + evrexec: reformat exported structures - (cherry picked from commit f35f327a528670dcca0d7a767643a222f1aebd89) + (cherry picked from commit 65eef5c5446c1f6870eecf8bbc84d68d12271bc7) -commit 51937a32b205288ebeddfac7c4310b1f3ce698e7 +commit 15ffdf7c0721fb5d05772d96e133ac74412c0068 Author: Daniel-Constantin Mierla -Date: Thu Nov 23 12:35:47 2023 +0100 +Date: Sun Feb 25 01:15:28 2024 +0100 - msilo: use literal module name for stats group - - - prevent conflicts with global exports + ndb_redis: reformat exported structures - (cherry picked from commit 609960812c572d2d19ba774b064fdf7e2ac45765) + (cherry picked from commit fb21f89dc544551b1bb65805303131fa990d2f44) -commit 876fa1d0667acb2c46e5b8643cdb994546e45b21 -Author: Daniel-Constantin Mierla -Date: Thu Nov 23 12:35:47 2023 +0100 +commit dae15377dac1b019f2278baca208162154d5a7ad +Author: S-P Chan +Date: Tue Mar 5 09:59:41 2024 +0800 - ims_usrloc_pcscf: use literal module name for stats group + tls: NULL safety check - - prevent conflicts with global exports - - (cherry picked from commit d29b3d6515f74d4cd7417dc9030d8ca53d57054e) + (cherry picked from commit f6f9d90ada963b53b6552e1a172b8f2fd021c33b) -commit e96ecec877f2f9bc13000c7bd752ed8f1ec41935 -Author: Daniel-Constantin Mierla -Date: Thu Nov 23 12:35:47 2023 +0100 +commit 56aeb0723562409aa97098e51c602bcddc8b6789 +Author: S-P Chan +Date: Tue Mar 5 06:47:24 2024 +0800 - ims_registrar_scscf: use literal module name for stats group - - - prevent conflicts with global exports + etc/kamailio.cfg: document tls_threads_mode = 2 to use atfork handler - (cherry picked from commit 641d29820f8536247c49d5fb4caa882764dbd9af) + (cherry picked from commit 5b4926b04ba0fcd8f65f5709789abd83181a381a) -commit b5a2b0c782a18cd807d6d4851baa9be2bd299a0c -Author: Daniel-Constantin Mierla -Date: Thu Nov 23 12:35:47 2023 +0100 +commit 0ba1ff1d430e5e51c7745d7eb1242dcae2557db9 +Author: S-P Chan +Date: Mon Mar 4 22:00:14 2024 +0800 - ims_icscf: use literal module name for stats group + tls: new option tls_threads_mode = 2 - - prevent conflicts with global exports + - use pthread_atfork to force all thread-locals + to 0x0 after fork() - (cherry picked from commit 39514660001b37eabfe3af6818949586fae9a4bf) + (cherry picked from commit 464299c202f3ba963aed821b777075397e843856) -commit 6f3f297ea64a8fed4c77fdaf2abc90e468f6443c -Author: Daniel-Constantin Mierla -Date: Thu Nov 23 12:35:47 2023 +0100 +commit 0a565d34b98b7ec4de0524a3e216e8d907661181 +Author: S-P Chan +Date: Mon Mar 4 21:49:10 2024 +0800 - ims_auth: use literal module name for stats group + core/rthreads.h: add new option tls_threads_mode = 2 - - prevent conflicts with global exports + - add global handling of thread-locals with + tls_threads_mode = 2 + - this will run a pthread_atfork handler to reset + all thread-locals to 0x0 + - alternative solution to running functions + in thread executors + - requires tls.so to be loaded to be effective - (cherry picked from commit 524eeca084e0a0e61ad80f349ea79f8b1c3031f6) + (cherry picked from commit e7f040f219b46592081a6053b4ed1ae0d0552b1a) -commit c8a09510204e7d0ed9e486f4dc871353f1820866 -Author: Daniel-Constantin Mierla -Date: Thu Nov 23 12:35:47 2023 +0100 +commit 3d80bc811c75eb0cbcf0f4aee8929a5082b4de6a +Author: S-P Chan +Date: Sat Mar 2 20:46:16 2024 +0800 - imc: use literal module name for stats group + tls: basic OpenSSL 3 support of provider keys (replaces ENGINE) - - prevent conflicts with global exports + - initial support for v3 provider keys (replaces ENGINE from v1.1.1) + - can be disabled behind build flag -DOPENSSL_NO_PROVIDER + - provider keys start with /uri: e.g + private_key = /uri:pkcs11:token=NSS%20Certificate%20DB;type=private;object=Fork-Test-c67cc0e0 + - global config: + provider_quirks: 0 | 1 + - 0 - default + - 1 - create a new OSS_LIB_CTX* in the child - (cherry picked from commit 407168804cc1806b857c2ce78399e02a81692d1e) - -commit 583a403d58c3e0e0b64a354d2e5fe4a28192403f -Author: Daniel-Constantin Mierla -Date: Thu Nov 23 12:35:47 2023 +0100 - - http_async_client: use literal module name for stats group + This integration does not load any providers itself and depends on + the usual - - prevent conflicts with global exports + export OPENSSL_CONF=my-openssl.cnf + + to configure providers. - (cherry picked from commit 40dd9f4e0fbe54046b7786e3572b491103af03d1) + (cherry picked from commit 69883dd381368ca219cc52140e71d571775f95d5) -commit d343b6d99cdb9a23ec5bfa332a34245cdce4c3af -Author: Daniel-Constantin Mierla -Date: Thu Nov 23 12:35:47 2023 +0100 +commit 6ee443731a23032fce9a32ce9609ae5b7c6bd171 +Author: S-P Chan +Date: Sat Mar 2 21:41:11 2024 +0800 - dialog: use literal module name for stats group - - - prevent conflicts with global exports + tls: remove unused ENGINE define - (cherry picked from commit d434270933f06b4de43cdf6d4b464bd264a3cb92) + (cherry-picked from commit 73e7123c2dd19b82db167ceee93444e43f70f446) -commit 84b1543cf7b77bfffba0c3e6369b4cb06bf149b5 +commit 8e81774d5a71c06906df84fb4809bcfb73bd532e Author: Daniel-Constantin Mierla -Date: Wed Nov 22 14:52:59 2023 +0100 +Date: Sat Mar 2 08:13:40 2024 +0100 - dialog: do not print module name in log messages + tlsa: removed the map files used in the past for tls engine - - it is added automatically + - sync with code of tls module - (cherry picked from commit e45c97d112c7c396ae0a11b7a431582a71361e5b) + (cherry picked from commit d443a1e37d85e0eec6f6c9875bb8e821b34c8d6b) -commit 48fd5246c186524413d452032320378d9c87afc4 -Author: Daniel-Constantin Mierla -Date: Wed Nov 22 14:52:18 2023 +0100 +commit 9d42e4aacab4a7bf18192701cd66cba95c2c98dd +Author: S-P Chan +Date: Sat Mar 2 08:29:31 2024 +0800 - avp: do not print module name in log messages + tls: clean-up of ENGINE - - it is added automatically + - remove tls_map.* - not needed anymore + - install an ENGINE in each worker SSL_CTX + no need to replicate to all processes - (cherry picked from commit 463d5b34390e330a2b733deb673c1c77e5be9fcb) + Cherry-pick from 5933893b91 -commit c97e6b96821f0ffaf449643ed2229086b7bf0001 -Author: Daniel-Constantin Mierla -Date: Wed Nov 22 14:26:23 2023 +0100 +commit 0ddbd961e91abf3e967285d80cc1c6f8d2aa5cf9 +Author: S-P Chan +Date: Fri Mar 1 08:06:13 2024 +0800 - avpops: do not print module name in log messages + tls: make explicit ENGINE deprecation in OpenSSL 3 - - it is added automatically - - (cherry picked from commit 89a95ce1abefd772c0f09054473b07bbfc5426bc) + Cherry-pick from 0c68a5511e -commit 3ab5e87f2e162704a261c3a45eeb5c000b6ddb99 -Author: Daniel-Constantin Mierla -Date: Wed Nov 22 14:20:13 2023 +0100 +commit f53c6b49e158203ba0783ec6a6fbadd76c5fdde9 +Author: S-P Chan +Date: Thu Feb 29 19:01:14 2024 +0800 - textops: do not print module name in log messages - - - it is added automatically + tls: fix OpenSSL 1.1.1 engine keys - (cherry picked from commit ba1c0424732f1f2ab01bfd078ee272221a6b3e10) + Cherry-pick from e535cc5eb2 -commit 069876708076154387a599bf039edd83f5067974 -Author: Daniel-Constantin Mierla -Date: Wed Nov 22 14:02:59 2023 +0100 +commit 59ab58551e5895b710893985d0072c8c510c672c +Author: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com> +Date: Tue Feb 27 11:50:54 2024 +0000 - app_ruby: use module name prefix for exports structure + file_out: Fix leaks - (cherry picked from commit 65322a8ea66ed18fb2d089ade54702341e064944) + (cherry picked from commit 8af509ae280b2ef155f1946acac5a7d977bb5c14) -commit 8c5a7a8db1309515a1d2f167754a4ee046684569 -Author: Daniel-Constantin Mierla -Date: Wed Nov 22 13:59:14 2023 +0100 +commit 6721fb7aae373d42c4059a630fc79815d2f709b7 +Author: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com> +Date: Mon Feb 26 11:17:19 2024 +0000 - app_jsdt: use module name prefix for exports structure + file_out: Add header guards - (cherry picked from commit a81e3c45dad338378fc8cf417bb0e9da1172a854) + (cherry picked from commit 967fb30b14fb63bcb396956f9e9ed0ca92028682) -commit 2442079e05b410cc9393fd15daf1f94169f80139 -Author: Daniel-Constantin Mierla -Date: Tue Nov 21 15:43:11 2023 +0100 +commit bc4c206999094ed74e77c73f5537e857111d0a30 +Author: S-P Chan +Date: Tue Feb 27 12:38:09 2024 +0800 - app_lua: use module name prefix for exports structure + http_async_client: libssl refactor thread executors for curl - (cherry picked from commit 35e191e1bea5463e766cb6f8f2ffb4862bd812a8) + Cherry-pick from 6a0c86bba8 -commit ef9c5e79b6923401a686c31a15af390e376e63e3 -Author: Daniel-Constantin Mierla -Date: Tue Nov 21 15:39:21 2023 +0100 +commit 533989406d0fa1e57ff007fd8d7f702f5831dacd +Author: S-P Chan +Date: Tue Feb 27 05:01:45 2024 +0800 - app_lua: reformat exports structures + xcap_client: libssl thread executor for curl_global_init() - (cherry picked from commit c6feb52c97bbd3fc33dc837d2b23e56c75f09583) + Cherry-pick from f5164b39c8 -commit d38cc3c15698b554c177e77e05f7393ae6a1baa7 -Author: Daniel-Constantin Mierla -Date: Tue Nov 21 15:35:04 2023 +0100 +commit 49c3290fc6eb50de0b08661c50ff42663ff3de6b +Author: S-P Chan +Date: Tue Feb 27 05:01:31 2024 +0800 - app_python3s: use module name prefix for exports structure + http_client: libssl thread executor for curl_global_init() - (cherry picked from commit ebe77a2068c5073b436a1f8fefdfd689c9010816) + Cherry-pick from f58225950c -commit 340efb9e3951fb4d15ae32e834ac58470b2c06f1 -Author: Daniel-Constantin Mierla -Date: Tue Nov 21 15:32:57 2023 +0100 +commit 5d4fae5c24eb4f13d585e1af4cb1753ea5a784c5 +Author: S-P Chan +Date: Tue Feb 27 05:01:14 2024 +0800 - app_python3s: reformat exports structures + http_async_client: libssl thread executor for curl_global_init() - (cherry picked from commit 9fb9cbddee8974a1733b999807cc1943248753f7) + Cherry-pick from 514635dc3e -commit 986cadb088805f5126c61d55fc0b72cec6fd3d18 -Author: Daniel-Constantin Mierla -Date: Tue Nov 21 15:29:49 2023 +0100 +commit ce17fee304e9ffa5046194a0827f771742113640 +Author: S-P Chan +Date: Tue Feb 27 05:00:35 2024 +0800 - app_python3: use module name prefix for exports structure + core/rthreads.h: add thread executor for curl_global_init() - (cherry picked from commit 114d6fe510d7c1876782054ed89e4017d39d5f69) + Cherry-pick from db05449932 -commit 4d04bafdba440b82a7da8424682b06db23721c8f -Author: Daniel-Constantin Mierla -Date: Tue Nov 21 15:26:23 2023 +0100 +commit b1a308801430a5561c4c13c1d4602fe5d5542cf8 +Author: S-P Chan +Date: Tue Feb 27 05:03:10 2024 +0800 - app_python3: reformat exports structures - - (cherry picked from commit 042bb9d10e12a256f9e4461031347e09b89fbe98) + Revert ac4f1be039 - split into per module commits -commit d2f5603aff1bad106340b024d4a33f2be7791980 -Author: Daniel-Constantin Mierla -Date: Tue Nov 21 15:14:39 2023 +0100 +commit ac4f1be039809d68483fe39e94b0803da1661a48 +Author: S-P Chan +Date: Mon Feb 26 10:25:19 2024 +0800 - core: resolve - variables initialisation + OpenSSL integration: manage curl_global_init(...) used by modules - (cherry picked from commit 1623f9ed1728455b72abf0a74f06bfd24365cefb) + - http_client, http_async_client, xcap_client use libcurl + - call curl_global_init in a thread executor as it invokes + OpenSSL functions on Debian 12 + - clang-format -commit 55584b4de5ac60a1385edf245fc7f5bb516c271e -Author: Daniel-Constantin Mierla -Date: Tue Nov 21 13:57:52 2023 +0100 +commit b98718c28f72b1372a62b17174b43c403fa6b729 +Author: S-P Chan +Date: Sun Feb 25 20:42:14 2024 +0800 - core/mem: tlsf - cast to char* for pointer operations - - (cherry picked from commit d0a353342b559191aafc732174773e132554694a) + tls: fix OpenSSL 1.1.1 compatibility -commit 8779039f655e6cdc27c35a0145985de00ecef81e -Author: Daniel-Constantin Mierla -Date: Tue Nov 21 13:30:26 2023 +0100 +commit aa8fcf9ec76e7c4543db22de6de5ef62374c80be +Author: S-P Chan +Date: Sun Feb 25 12:56:19 2024 +0800 - core: resolve - cast after pointer operations for RES_AR - - (cherry picked from commit 30c42aab767d777e3beb1493165458489957e92d) + tls: fix restore early init -commit 9b72b6dd4ffcf67f47f9d51c862e7a101c110c3f -Author: Victor Seva -Date: Thu Nov 23 13:29:15 2023 +0100 +commit 49a9d8a4fb2f8a03d478aed2a405f812d2c2c5e8 +Author: S-P Chan +Date: Sun Feb 25 08:03:17 2024 +0800 - github: refresh alpine workflow [skip ci] + tls: restore early init for other modules that use TLS + + Client modules (e.g. dispatcher) that require outbound TLS + may race if tls init is too late. + + Restore tls init to PROC_INIT with a thread executor. + + Addresses GH #3765 + + Cherry-pick from 706d7b7ff3 -commit 7ea47e5fc72d08384223fb479f6bcc098e236990 +commit 5af33b2e0ddc1098919008d44ab91959bc7dfb80 Author: Victor Seva -Date: Thu Nov 23 13:27:51 2023 +0100 - - pkg/docker: set branch 5.7 and refresh [skip ci] +Date: Fri Feb 23 21:24:19 2024 +0100 -===================== 2023-11-17 Version 5.7.3 Released ===================== + pkg/docker: set branch 5.8 and refresh [skip ci] -===================== Changes Since Version 5.7.2 =========================== +commit fbdca3da6293aba548989e3ab9d600be338199b2 +Author: Victor Seva +Date: Fri Feb 23 20:43:33 2024 +0100 + github: set branch to 5.8 [skip ci] -commit 1ec5093657959b4af1c9d4e0ea48879ed1105f4d -Author: Daniel-Constantin Mierla -Date: Fri Nov 17 09:56:00 2023 +0100 +commit 3566edd00ea729bb187b160a80b54fe92e2bbe4d +Author: Victor Seva +Date: Fri Feb 23 20:05:34 2024 +0100 - Makefile.defs: version set to 5.7.3 + pkg/kamailio/deb: version set 5.8.0~rc0 -commit 2fa620918979548af5182114f8d44df67776b76f +commit faddcecbf04a0221aa4a2531141571246d043060 Author: Daniel-Constantin Mierla -Date: Fri Nov 17 09:52:09 2023 +0100 +Date: Fri Feb 23 19:35:27 2024 +0100 - pkg: deb specs updated for v5.7.3 + Makefile.defs: version set to 5.8.0-rc0 + + - entering the phase to prepare releasing next major version series + 5.8.x -commit ec6c7ac6c7758cf2ff2a554985204315bd72859a +commit 716319089c3e7bbc4caf9a2454235d77c3a9f88b Author: Daniel-Constantin Mierla -Date: Fri Nov 17 09:47:30 2023 +0100 +Date: Fri Feb 23 19:24:55 2024 +0100 - pkg: version set to 5.7.3 for rpms and alpine specs + Makefile.defs: version set to 5.8.0-pre1 + + - marking end of first phase of testing -commit 5879b5d10d41f8a8a7b458873a4afaf7777fe27d +commit 7e22636bb2797f6ed9cac677678a7a1bfc4f2537 Author: Daniel-Constantin Mierla -Date: Thu Nov 16 19:50:13 2023 +0100 +Date: Fri Feb 23 12:53:39 2024 +0100 - core: copy the value between quotes for #!defexps - - - GH #3631 + dispatcher: rename interal define to reflect better is a mix of matching - (cherry picked from commit c26e9877419ac53fb109a24aefb3fcd711fae1d7) + - rather than a full address matching -commit 3e9791570645dee833737077b3326ca6acde6aef -Author: Ovidiu Sas -Date: Thu Nov 16 11:27:21 2023 -0500 +commit 17536b1064b40c305f28c4c19392504afc0b9701 +Author: Dennis Yurasov +Date: Thu Jan 4 18:28:56 2024 +0300 - core: fix indentation on tcp_main.c + dispatcher: added two new flags to mode parameter of ds_is_from_list function for more strictly matching - (cherry picked from commit 243951bc487c5c67c81062445d4f4d7ee725684f) + - Two new flgs added: + DS_MATCH_SOCKET (8) to take in account socket/sockname attribute of gw + DS_MATCH_TRY_FULLADDRSOCK (16) try to find the most complete "address/protocol/port/local socket" combination for all dispatcher targets -commit 308506c3dacf9c22c63059166f5b674d0199eb44 -Author: Ovidiu Sas -Date: Thu Nov 16 09:29:00 2023 -0500 +commit 6948a3cc1f81cd468eae92518215d0fe9178b1e7 +Author: Daniel-Constantin Mierla +Date: Fri Feb 23 12:18:07 2024 +0100 - core: fix compilation for older kernels - - (cherry picked from commit 34054fbd144102d414318249de217cedf8e5bd39) + microhttpd: added the header return option for pv -commit c30e0a3a6dbe9b80b591ecb9caa53574ebc2988f -Author: Ovidiu Sas -Date: Wed Nov 15 22:45:34 2023 -0500 +commit 998a790563fcba9d6263c18f83f59e9080c78af0 +Author: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com> +Date: Thu Feb 22 17:46:00 2024 +0000 - pua_dialoginfo: safety check for request pointer - - (cherry picked from commit 4e614ba6b7a5663bd88f353a3ce7a0976d8e878f) + file_out: Refactor -commit 889f3f6a77e6404940a724b3289dac765c724117 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:39 2023 +0100 +commit 06d0596ef34f1c213cc28442594bb6f1ebae46b4 +Author: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com> +Date: Thu Feb 22 13:11:54 2024 +0000 - xprint: docs - removed trailing spaces + file_out: Prefix can use PVs -commit 5bb0993df8fa8ef6c0f833c0e0f9648df4b3efaf -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:39 2023 +0100 +commit ff8229b58d6f91bae527bc2f5912c7d291c55268 +Author: falshunov <37283637+falshunov@users.noreply.github.com> +Date: Thu Feb 22 08:56:00 2024 +0000 - xmpp: docs - removed trailing spaces + microhttpd: fixed typo in the documentation [skip ci] -commit 4aafb51b61b8256ab40592d13e8ef93d7b64d8cc -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:39 2023 +0100 +commit e54152e06e4a097ac17522e282f26b277ecae4da +Author: Torrey Searle +Date: Wed Feb 21 08:05:10 2024 +0100 - xmlops: docs - removed trailing spaces + tools/kemi: fix bug in mock + + remove stray debug print statement that results in generated code + being invalid -commit 242be71548787ef0a6f309b3ec09565eb3bda12e +commit e3e6fd75bdd688acebf0ec8a1b7efa6fcada1de6 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:39 2023 +0100 +Date: Mon Feb 19 22:24:21 2024 +0100 - xlog: docs - removed trailing spaces + core: tcp - skip checking when tcp_accept_iplimit is 0 -commit 31d35cc7b89cbfef0873df1d3ff253dd651d0a45 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:39 2023 +0100 +commit dad7f3ff3af02d086c1cb3f915f1502bca127d58 +Author: Henning Westerholt +Date: Mon Feb 19 20:30:45 2024 +0000 - xhttp_rpc: docs - removed trailing spaces + file_out: small extensions to the module docs -commit 15b8bc58f45a93de95bfd4b6014ec91edab94779 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:39 2023 +0100 +commit a722d4cba1ab18f481bfe8353cebc0c6fa1a7ebb +Author: Xenofon Karamanos +Date: Mon Feb 19 14:04:58 2024 +0000 - xhttp_prom: docs - removed trailing spaces + file_out: Add a prefix paramater -commit 4c81fba9194f47404c39cae7e141286ecd172f4e -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:39 2023 +0100 +commit 22581f95690415681ea233c97923137e46fb55ae +Author: Xenofon Karamanos +Date: Mon Feb 19 13:56:34 2024 +0000 - xhttp_pi: docs - removed trailing spaces + file_out: Free allocated memory -commit 945baa34210b1f1dac50d5fd928dc3e0da527f2e -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:39 2023 +0100 +commit d2459f4a9978e6b42ba99212b77dd856005df0d7 +Author: Xenofon Karamanos +Date: Fri Feb 16 09:38:24 2024 +0000 - xhttp: docs - removed trailing spaces + file_out: Fix fixup functions to handle all string. -commit 1cf19e69e961e0b262a725aaffaa87732d03a40d -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:39 2023 +0100 +commit d3fbee58cb5505130ea73cfa0143adfd470d2c27 +Author: Xenofon Karamanos +Date: Fri Feb 16 09:27:33 2024 +0000 - xcap_server: docs - removed trailing spaces + file_out: Improve logging -commit d0d1a53486c4999b94f9f0c28e290ea8e7b53312 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:39 2023 +0100 +commit 6ac4148d3d7e6ea772438b7c5b42807175e5888a +Author: Xenofon Karamanos +Date: Fri Feb 16 09:26:02 2024 +0000 - xcap_client: docs - removed trailing spaces + file_out: Free message when done -commit 89f7c87630565dbb1205b4614f2a52060ac0660c -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:39 2023 +0100 +commit e4163d287e1c8c617ef9f21452a88f09c040bd47 +Author: Xenofon Karamanos +Date: Fri Feb 16 09:25:32 2024 +0000 - websocket: docs - removed trailing spaces + file_out: Switch to str type for string handling -commit 38f9665864f394c9c072e24fc8de357a18b7d659 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:39 2023 +0100 +commit e15a15cf8ce0c09aa6b26200dd2bce0e3933b6cd +Author: Xenofon Karamanos +Date: Fri Feb 16 09:12:19 2024 +0000 - uuid: docs - removed trailing spaces + file_out: Add initial Readme and improve docs -commit 3e1e46956a7638a4ab4ca60ef7b86d8a0619b707 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:39 2023 +0100 +commit 107d8c9ae4cb1191d9e0132a42acad8af4cc66c9 +Author: Xenofon Karamanos +Date: Fri Feb 16 09:27:59 2024 +0000 - utils: docs - removed trailing spaces + file_out: Change default base folder format -commit 3ee11f7b166bdcf587335a99c64827a3b9f6e273 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:39 2023 +0100 +commit 1e4236445167d837a89d54ce6bee5ef14aef568e +Author: S-P Chan +Date: Wed Feb 14 19:49:10 2024 +0800 - usrloc: docs - removed trailing spaces + db_mysql: libssl thread guard for db_mysql_query (and libmysqlclient) + + This function is observed to call SSL_read() when compiled with + libmysqlclient.so.21 (but not libmariadb.so.3). + + Apply a thread executor just in case. -commit 726a1fc8745f48698fb755b6502f54aed610989b -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:39 2023 +0100 +commit 87ef83d23f68a43fc5265a81330cbeed6205f922 +Author: Kamailio Dev +Date: Wed Feb 14 08:31:13 2024 +0100 - userblocklist: docs - removed trailing spaces + modules: readme files regenerated - db_mysql ... [skip ci] -commit 5e59c9a7f6f6323bff14877ddb43dc69e7eaa15e -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +commit c89fe41b1583af74cdf7e20d2357d7c90990839f +Author: S-P Chan +Date: Wed Feb 14 15:17:26 2024 +0800 - uri_db: docs - removed trailing spaces + db_mysql: fix typos + + The option opt_ssl_ca is a string not integer. + + The comment for ea81e6cb should show the code fix as + mysql_options(ptr->con, MYSQL_OPT_SSL_CA, (void *)db_mysql_opt_ssl_ca) -commit 8a27cfaf0f0f7cf8c1e2b85f679e25572b9fe36a -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +commit a61bfe9fb8357cedf5cb22e2698ec5d817fcfe5a +Author: Kamailio Dev +Date: Wed Feb 14 08:16:19 2024 +0100 - uid_uri_db: docs - removed trailing spaces + modules: readme files regenerated - db_mysql ... [skip ci] -commit b202f06b513c0f82843b7a0ff5a4473427b5266d -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +commit eafd93f0576504ea03fe6b5e3898506072218cef +Author: S-P Chan +Date: Wed Feb 14 14:59:52 2024 +0800 - uid_gflags: docs - removed trailing spaces + db_mysql: update docs for opt_ssl_ca -commit a7b8ccf85e87229f7ff61224f5e62352fc9d6082 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +commit ea81e6cb8b2b2d896de7a07ce191876f9f182673 +Author: S-P Chan +Date: Wed Feb 14 14:15:10 2024 +0800 - uid_domain: docs - removed trailing spaces + db_mysql: new module param opt_ssl_ca to configure CA certs + + ERROR: db_mysql [km_my_con.c:200]: db_mysql_new_connection(): + driver error: SSL connection error: CA certificate is required + if ssl-mode is VERIFY_CA or VERIFY_IDENTITY + + When opt_ssl_mode = 4 | 5 libmysqclient + requires that the trusted CAs be configured. + Fixed with: + mysql_options(ptr->con, MYSQL_OPT_SSL_CA, (void *)db_mysql_opt_ssl_mode) + + Note: libmariadb3 doesn't require this setting + and uses the system trust store. -commit 07bfc5fb59248123bb337b510308281a5a815e62 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +commit c4e4b266ad6852bacdb4513e9cc79166ac661f23 +Author: Kamailio Dev +Date: Mon Feb 12 10:17:15 2024 +0100 - uid_avp_db: docs - removed trailing spaces + modules: readme files regenerated - influxdbc ... [skip ci] -commit 274687596804b2d4240e1a9c04078657bf955393 +commit 7e1f521f2086b50b3ad73bc19ea98deb18686e82 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +Date: Sun Feb 11 16:17:47 2024 +0100 - uid_auth_db: docs - removed trailing spaces + influxdbc: docs for a couple of existing functions -commit 54204321dabf2efb8e06a28ea82116cff1081406 +commit f2772bd0248a1e75a82f4cad55280fa2b4f98578 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +Date: Sat Feb 10 22:27:30 2024 +0100 - uac_redirect: docs - removed trailing spaces + influxdbc: function to add double value as divison of int numbers -commit 1671f4cb9895573dc62d2522749575275aa2a7d1 +commit ce437384ce13bb78b01d3d18f9ddfdd6b8e37fa5 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +Date: Fri Feb 9 08:02:26 2024 +0100 - uac: docs - removed trailing spaces + core: helper fixup functions for (str, str, int) parameters -commit 90ae37bbcbd2ee45cde223ddf037140e72cf169b -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +commit 44fcca3596438841c0752d39dedfbe7de07a30c5 +Author: Xenofon Karamanos +Date: Thu Feb 8 15:10:22 2024 +0000 - tsilo: docs - removed trailing spaces + file_out: Update docs -commit 2763482be980b88f914e6d2aca68e28b2dabc7fb -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +commit 62e3069f484ea28745bce93dd5e1e7634c336f6b +Author: Xenofon Karamanos +Date: Thu Feb 8 14:31:13 2024 +0000 - topos: docs - removed trailing spaces + file_out: Add support for multiple files, extensions and interval -commit 2dbc0974ace0943ee3d75c9ab1b3987079d8b8d3 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +commit 3e1a7bb5f6143383b1f486b8c67c3bf97cb32a3f +Author: tsearle +Date: Fri Feb 9 10:17:58 2024 +0100 - tmx: docs - removed trailing spaces + tools/kemi: update kemi_mock for python (#3751) + + fixes code generation when python keywords are uses + fixes formating issues of generated code + fixes crash from pv.setl reporting parameters as null instead of 'none' -commit ac69b36d285b1fec67487bca4d81444e4d9e479a -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +commit 6918c9e34b826f8d8c7fb1746851055fa35f8ece +Author: Kamailio Dev +Date: Fri Feb 9 10:01:34 2024 +0100 - tmrec: docs - removed trailing spaces + modules: readme files regenerated - ldap ... [skip ci] -commit 4582bc9bc158a5bdcaee9c4cb105840582374e22 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +commit e7397acb86db5cf0a214fe7f2812e21130e7b2f6 +Author: Xenofon Karamanos +Date: Wed Feb 7 12:23:30 2024 +0000 - tm: docs - removed trailing spaces + ldap/docs: Add connect_mode docs -commit 4b5906ff2f7341a27d9202b06f8cd135b18e67f4 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +commit 3120d1dfcfa393b90272526e6fe2efb3aa32a19d +Author: Xenofon Karamanos +Date: Tue Feb 6 14:39:15 2024 +0000 - tls: docs - removed trailing spaces + ldap: option to start even when connecting to server fails -commit de47f18226fee624a5d97a96604dd90a7c373dad -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +commit 7043a581c4cfe05d6f9a0161368a61f7c67e326c +Author: S-P Chan +Date: Thu Feb 8 12:50:03 2024 +0800 - textopsx: docs - removed trailing spaces + db_mysql: libssl thread guard for db_mysql_close -commit 550c061230e11c6c7166b498941845a817486b32 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +commit c393d5d5d167bdbf9a2f465effdc761195ed1279 +Author: S-P Chan +Date: Thu Feb 8 07:41:45 2024 +0800 - textops: docs - removed trailing spaces + db_unixodbc: libssl thread guards for db_unixodbc_(close|free_result|query) -commit 860393ea0c6a97b436ab6a1977b06d580c9ded10 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +commit e33911f5edbac36f54b6371f9b952b57488bcced +Author: S-P Chan +Date: Thu Feb 8 07:18:16 2024 +0800 - tcpops: docs - removed trailing spaces + db_postgres: libssl thread guard for db_postgres_close -commit 8c680916944bf103cafd9fe6e206ea595b7775a0 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +commit 4baa76cd3e0d4052baf037c663a898fd11c54514 +Author: S-P Chan +Date: Thu Feb 8 07:30:48 2024 +0800 - stun: docs - removed trailing spaces + core/rthreads.h: thread wrapper for db_XXXX_query -commit 8386cfa7516aa50109efd33ae2256e800e498cf8 +commit 5844207ce42ef830fe560e408c6e807184c8d31e Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +Date: Thu Feb 8 16:31:19 2024 +0100 - stirshaken: docs - removed trailing spaces + influxdbc: functions for kemi framework -commit e06231bddfb9eaebcecb6b951964712c8cd45497 +commit c8306ceb46c201172f84f72e5566922c22578fc2 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +Date: Wed Feb 7 20:10:34 2024 +0100 - statsd: docs - removed trailing spaces + influxdb: added missing for sub start and end -commit e981047a8699cafc25a4bee003bf6d5c4135f095 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +commit fb7c4ec9a33d8147094aa664ce3c96b6c3cb7d35 +Author: S-P Chan +Date: Wed Feb 7 14:08:01 2024 +0800 - statistics: docs - removed trailing spaces + core/rthreads.h: fix missing returns -commit f7e0a307eec9f31a116ba8c4ac0aae5b71a1d82b -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +commit 1a2993ca370da35c34abae1cb44086492faa0ade +Author: S-P Chan +Date: Wed Feb 7 05:54:35 2024 +0800 - sst: docs - removed trailing spaces + core/rthreads.h: fix missing return -commit af5c00e3b26b633b939d4281b7daa6b14cc31781 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +commit e52bc4ba41417362c79da1cd3d41b283aabc4eb8 +Author: S-P Chan +Date: Wed Feb 7 05:49:14 2024 +0800 - sqlops: docs - removed trailing spaces + Sample etc/kamailio.cfg: add tls_threads_mode to config -commit 1e76578632cdfcda3c78cbd65bc4ccaa29f95bef -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +commit aa15489f0a8de4a27197602d771fe02cf5745287 +Author: S-P Chan +Date: Tue Feb 6 21:43:22 2024 +0800 - snmpstats: docs - removed trailing spaces + core/rthreads.h: use global ksr_tls_threads_mode to constrain thread + wrapping + + - 0: run wrapped function directly + - 1: run wrapped function in thread for process#0 else run directly + - 2: always run wrapped function in thread -commit ae4c7efba2772825f28edb8c164670e86d4d3c3c +commit 4d6e37fa048a1aaa2d2fc6655985b4bcb9754258 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:38 2023 +0100 +Date: Tue Feb 6 14:24:08 2024 +0100 - smsops: docs - removed trailing spaces + core: added tls_threads_mode global parameter + + - control how to execute functions that may be using libssl3 behind -commit b62dd7d9300623b2804aa0a250d70079da16f845 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +commit 475b4da798fce232eba6834c3cb05e3c97e12d03 +Author: S-P Chan +Date: Tue Feb 6 11:09:04 2024 +0800 - sms: docs - removed trailing spaces + Sample etc/kamailio.cfg: tls should be loaded first if used -commit f41908997292f689b964a76afff9ce2afc65316c -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +commit d638c774ed816eec800e72ba2546004215cfe097 +Author: S-P Chan +Date: Tue Feb 6 00:29:55 2024 +0800 - sl: docs - removed trailing spaces + db_postgres: handle SSL and submit query -commit 917c51a4a065a419cc7013d5a33bc21af41c980d -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +commit 51d9f92eca3ef1044052581c9438af6e643652a1 +Author: S-P Chan +Date: Tue Feb 6 00:29:41 2024 +0800 - siputils: docs - removed trailing spaces + db_mysql: handle SSL and submit query -commit d99ffdec924c8187ec24d6af65063ae8841f9afd -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +commit 7d917e6649be7188bb9ab152ada75bc7199b2980 +Author: S-P Chan +Date: Tue Feb 6 00:23:16 2024 +0800 - siptrace: docs - removed trailing spaces + db_unixodbc: handle SSL and submit query -commit 83c738ded192aa4df574c245343e00f47d610199 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +commit ba921b2112e87625fba5789d1b049161bb611073 +Author: S-P Chan +Date: Tue Feb 6 00:22:52 2024 +0800 - sipt: docs - removed trailing spaces + core/rthread.h: add prototype for db queries -commit a3d918751ded0e4484e583ab8280a96408fb8b39 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +commit 2ab212ccf0b4ecd7a0671235641e2a80feb251ff +Author: Kamailio Dev +Date: Mon Feb 5 16:32:00 2024 +0100 - sipcapture: docs - removed trailing spaces + modules: readme files regenerated - influxdbc ... [skip ci] -commit 8bf3d8e293349389cfc3dc8b69e8d0cf0dc62f09 +commit 10b86323cc47f29b41c21fd601d5b309cca050e6 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +Date: Mon Feb 5 16:18:47 2024 +0100 - secfilter: docs - removed trailing spaces + influxdbc: convert string value to double -commit 047cdc8aa57e78e2d5be6db86a57736083656dc2 +commit ba2d0e171b0171ba98bc7219a420dcda7677d366 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +Date: Sun Feb 4 08:30:50 2024 +0100 - seas: docs - removed trailing spaces + influxdbc: docs for several parameters and functions -commit dad67d95180cd2087bf4e9ee4f1c09c6e7a24d5e +commit faaad7e0e654359e744d0c18253cc0dc84cd906e Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +Date: Sat Feb 3 16:06:06 2024 +0100 - sdpops: docs - removed trailing spaces + rtpengine: docs for ping_mode parameter -commit 4f2a73691197fd25cd6f7e12a5db9ef221dc8992 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +commit 81605f9289364a273a7b904d12972a6d01dc6207 +Author: Sergey Safarov +Date: Sun Feb 4 17:53:48 2024 +0200 - sctp: docs - removed trailing spaces + pkg/kamailio: RPM packaged new modules -commit 9ac5f13982c6aa94b65d4fc70c106f398fba80b0 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +commit 8bdd9ca4b3c3d4f9f2f201b0a9e0ad9a61eee41d +Author: Victor Seva +Date: Sat Feb 3 10:53:33 2024 +0100 - sanity: docs - removed trailing spaces + outbound: fix build on xenial + + > outbound_mod.c: In function 'mod_init': + > outbound_mod.c:122:2: error: too many arguments to function 'mod_init_openssl' + > mod_init_openssl(NULL); + > ^ + > outbound_mod.c:82:13: note: declared here + > static void mod_init_openssl(void) + ^ -commit 2317e16ef7b3559ec31bb2f54944a7a4d70bb595 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +commit b8c0a3757eb282ddb9e4878deb7120c4efd7f571 +Author: Victor Seva +Date: Sat Feb 3 10:41:43 2024 +0100 - rtpproxy: docs - removed trailing spaces + db_mysql: fix build for stretch + + * mysql_optionsv is not there. We still use the deprecated flavour + * MYSQL_OPT_SSL_ENFORCE is not there -commit 5d50c2ee15f263b77c7baa767e5d3f8c80459052 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +commit 2cb2e5c99c3e565762820ef702404ae5ec59a6c9 +Author: Victor Seva +Date: Sat Feb 3 09:47:46 2024 +0100 - rtpengine: docs - removed trailing spaces + Revert "db_mysql: fix build for older releases" + + it doesn't fix anything + + This reverts commit f0e73eabee3be198dbad2e50752d9889e4aa8e5f. -commit fb4833a148ee20e5e5f30f1ad957809dd028438a -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +commit 80214d2f878b3f2d7547060c9d4bd578a9e1a837 +Author: Victor Seva +Date: Fri Feb 2 15:21:14 2024 +0100 - rtp_media_server: docs - removed trailing spaces + pkg/kamailio/deb: version set 5.8.0~pre0 -commit f3b8e68b4867c50f51822f504d4140d55afe8124 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +commit 976670db1313e96a859009288abbf1ea97583357 +Author: Victor Seva +Date: Fri Feb 2 14:44:13 2024 +0100 - rtjson: docs - removed trailing spaces + pkg/kamailio/deb: remove mono from wheezy -commit 1aecd6ccba1d562f9d5385835de43849bcace45a -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +commit 015da378ab8b4ce5ced8b05f9c51e809ec11e53e +Author: Victor Seva +Date: Fri Feb 2 14:19:30 2024 +0100 - rtimer: docs - removed trailing spaces + pkg/kamailio/deb: no libpcre2-dev on older releases -commit f678d2404c9b7238a8ba439e1a7067ca28b63424 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +commit f0e73eabee3be198dbad2e50752d9889e4aa8e5f +Author: Victor Seva +Date: Fri Feb 2 08:33:14 2024 +0100 - rr: docs - removed trailing spaces + db_mysql: fix build for older releases + + > km_my_con.c: In function 'db_mysql_new_connection': + > km_my_con.c:132:4: warning: implicit declaration of function 'mysql_optionsv' [-Wimplicit-function-declaration] + > mysql_optionsv(ptr->con, MYSQL_OPT_SSL_ENFORCE, (void *)&(int){1}); + > ^~~~~~~~~~~~~~ + > km_my_con.c:132:29: error: 'MYSQL_OPT_SSL_ENFORCE' undeclared (first use in this function) + > mysql_optionsv(ptr->con, MYSQL_OPT_SSL_ENFORCE, (void *)&(int){1}); + > ^~~~~~~~~~~~~~~~~~~~~ + > km_my_con.c:132:29: note: each undeclared identifier is reported only once for each function it appears in + > ../../Makefile.rules:100: recipe for target 'km_my_con.o' failed -commit 515b128c26e7fc7905a2d8ace7aa7f0e0f95c42e -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +commit 1fcf99817580379d3e7550d1d874050a3e0315bc +Author: Xenofon Karamanos +Date: Fri Feb 2 13:16:08 2024 +0000 - rls: docs - removed trailing spaces + file_out: make worker sleep period configurable, to allow to adapt performance parameters -commit ec581e1d454fc4c8021dc623f9c490c7d308e773 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +commit 82593a09f8ef6d53e7e88238c057bbcdd9ab287b +Author: Xenofon Karamanos +Date: Fri Feb 2 10:56:41 2024 +0100 - registrar: docs - removed trailing spaces + core: properly handle drop() action for kemi engines + + - GH #3718 -commit 6186a9aab78f5d6f1ee186b4c938ab871570635e +commit a226823910735c315fc31df0e46132710db38def Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +Date: Fri Feb 2 09:27:10 2024 +0100 - regex: docs - removed trailing spaces + influxdbc: fix compile warnings -commit daa75cffbcb3e2d39b534601f27aaf964c55d323 +commit b85471a7c28324fcb890961a1ad67810bfbb8ac4 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +Date: Fri Feb 2 08:56:52 2024 +0100 - ratelimit: docs - removed trailing spaces + Makefile.defs: version set to 5.8.0-pre0 + + - mark start of testing for v5.8.x series -commit a47333b3df586f10543b35a14a5308ad7a36d7e2 +commit 8c5e97589fc0fed121ee6e8ca4adbf9ec63ad2eb Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +Date: Fri Feb 2 08:55:38 2024 +0100 - rabbitmq: docs - removed trailing spaces + Makefile.defs: version set to 5.8.0-dev3 + + - mark end of development for v5.8.x series -commit f3d9663bb305362a87d2c5d4f8f20aa9f6e007c1 +commit 03e60c809a0ac26b402bdf1154d6ec7b0476f26a Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +Date: Fri Feb 2 07:35:48 2024 +0100 - qos: docs - removed trailing spaces + Makefile.groups: added file_out to extra group -commit 2af082e8a0d155c6619e1337ccc4783ebc0e3e9c +commit 49bc5b266dad33e418e8895e9ed7ead46e254016 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +Date: Thu Feb 1 21:32:18 2024 +0100 - pv_headers: docs - removed trailing spaces + rtpengine: new modparam to disable pinging rtpengines at startup -commit 97615d742c1b6ac1db4ac3ca209d306bb7852dac +commit 40b735216c610cae2da5b0758af31b1d3ade4731 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +Date: Thu Feb 1 21:19:11 2024 +0100 - pv: docs - removed trailing spaces + rtpengine: optional ping parameter for rpc reload command + + - specify if ping should be done to rtpengines at reload time -commit 9bf317ed20343a7df93535d3ddda221063c06bf3 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:37 2023 +0100 +commit df3d1e5cb80b7a6ac6ce93b582352aaa8e6fd369 +Author: Xenofon Karamanos +Date: Thu Feb 1 19:41:22 2024 +0000 - pua_xmpp: docs - removed trailing spaces + file_out: use name instead of index for file_out function parameter -commit 8cb714ee285ae625e8f42d4dc4d5f933257e3f1c -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +commit 6478ac00e9bf1180092010b0df4656630d4550c2 +Author: Henning Westerholt +Date: Thu Feb 1 19:33:38 2024 +0000 - pua_usrloc: docs - removed trailing spaces + file_out: adjust syntax of examples to standard -commit e2dcc7585786421e6ea10b9bdc03e57ee5c5bee5 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +commit a6892009361ceff1475b568a2317b5d8a7c889cc +Author: Henning Westerholt +Date: Thu Feb 1 19:25:12 2024 +0000 - pua_reginfo: docs - removed trailing spaces + file_out: fix error in XML include for README -commit 2137a2389d7f5347b62cc178059f30b42e789a75 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +commit 4c144ac1ad40008b5bd9396aa18d7630145b4c4c +Author: Henning Westerholt +Date: Thu Feb 1 19:22:53 2024 +0000 - pua_json: docs - removed trailing spaces + file_out: small doc adaptions -commit e7169ec345d5421c032ed68c09e9521c1d22bbd8 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +commit dd5c9a5204eb946e731550a0ee7f3046c7065515 +Author: Xenofon Karamanos +Date: Thu Feb 1 19:15:17 2024 +0200 - pua_dialoginfo: docs - removed trailing spaces + file_out: Module to log custom strings to files (GH #3741) + + * add new module to log custom strings to files (GH #3741) + * support for multiple files and also file balancing + * smaller refactorings will be done afterwards (use string in function for names with internal matching, make worker sleep also configurable + * a round of tests has been done, but it will be certainly tested more in the next days -commit 8bacf4eb20aee42b39b8ea0998329ccbb8d4510b +commit f0ef9d29e8736e7eb7e7e2c62485704d3506fbdd Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +Date: Thu Feb 1 13:48:41 2024 +0100 - pua_bla: docs - removed trailing spaces + Makefile.groups: added influxdbc module to extra group -commit b54cb3efed256dbc67741a4f2529b06754949021 +commit ff94b5a691c525ed5687ad76bbf5436a8d877768 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +Date: Thu Feb 1 13:47:28 2024 +0100 - pua: docs - removed trailing spaces + influxdbc: added functions to push string and double values -commit a8303346d26f48e468fcb9a8da5ab63e09d7afc0 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +commit 4efd1fc33ceb5dc33b01020968b0d7281e902d1f +Author: Stefan-Cristian Mititelu +Date: Thu Feb 1 14:00:14 2024 +0200 - print_lib: docs - removed trailing spaces + p_usrloc: Add new modparam 'preload' + + Useful when using kemi with p_usrloc, in order to preload + location table. -commit e71e38b5c6fcac4d8009a0c5e0d42c8d3dbd5314 +commit 46e04c65dfa07ada122ad2132e9a7a841bc1e8ea Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +Date: Thu Feb 1 08:08:23 2024 +0100 - print: docs - removed trailing spaces + influxdbc: initial doc files -commit dfb6f586d9db2119f180abc5d9614f2efd65d3aa +commit dc6930581ab21df13c086fdb6f69130adf0e00f2 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +Date: Wed Jan 31 17:57:19 2024 +0100 - presence_xml: docs - removed trailing spaces + influxdbc: new module - client connector for influxdb -commit 57c97b77492ee7d6336161805cbb8cf3342061c1 +commit 0833a72d4b70d224ab02c90b7b94648db7f52c73 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +Date: Wed Jan 31 10:13:48 2024 +0100 - presence_reginfo: docs - removed trailing spaces + db_mysql: proper macro to check mysql version id -commit c25f46716765fd7549977c4ffb3664a12a320f9e -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +commit 94f6df509bf77c19c745749716a9e075ec17f3c7 +Author: S-P Chan +Date: Tue Jan 30 14:07:11 2024 +0800 - presence_profile: docs - removed trailing spaces + outbound: use core/rthreads.h -commit 2a6734a65ecf409ffa5dda99c798c49792c72403 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +commit 8a1c383f6af5bc0547e32430a4469333160b93e6 +Author: S-P Chan +Date: Tue Jan 30 07:42:34 2024 +0800 - presence_mwi: docs - removed trailing spaces + db_postgres: use core/rthreads.h -commit 537e83019bc317a3ac5c511592856d5ac590d34b -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +commit 733a268114261d49ed11aec83fe39ea8c34a0b69 +Author: S-P Chan +Date: Tue Jan 30 07:42:05 2024 +0800 - presence_dialoginfo: docs - removed trailing spaces + db_mysql: use core/rthreads.h -commit 90c2fea8452bea09496b7ebe28ad108c4a493638 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +commit b71ce6e5733ab08b84ff09481ada91e5fca43a33 +Author: S-P Chan +Date: Tue Jan 30 07:41:37 2024 +0800 - presence_conference: docs - removed trailing spaces + db_unixodbc: use core/rthreads.h -commit c021d38bf3ca96a3af19822239d09fcd0ccfe1df -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +commit f8909163c47c8776d23373fad688586f02d31e67 +Author: S-P Chan +Date: Tue Jan 30 07:40:54 2024 +0800 - presence: docs - removed trailing spaces + core: add infrastructure to run functions in threads -commit 93a38d0b6ea5ad91cfdd737b90c988a1171fd3be -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +commit 1e87f96ad3a85b35935f14db36626036469cb6b0 +Author: S-P Chan +Date: Tue Jan 30 22:12:18 2024 +0800 - prefix_route: docs - removed trailing spaces + tls_wolfssl: un-break jammy using libwolfssl32 -commit a4016235b94ae9389fba44ce192566b67f487605 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +commit dad7c857eaab613deed27ab687ddd0b1fdf8001b +Author: Kamailio Dev +Date: Tue Jan 30 14:32:10 2024 +0100 - pipelimit: docs - removed trailing spaces + modules: readme files regenerated - db_mysql ... [skip ci] -commit 80438595eeda0d3d762343598f09802d76217696 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +commit 2bcc32a14e63d895077071715b0321fbdcdb8a33 +Author: S-P Chan +Date: Tue Jan 30 21:12:50 2024 +0800 - pike: docs - removed trailing spaces + db_mysql: update docs for MariaDB Connector/C builds -commit 9cbef5531a25db83aa1059c8e2607bff7aeb62b1 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +commit d772b4c24a3a4995b93287ccf8eac9b80d1a5bac +Author: S-P Chan +Date: Tue Jan 30 16:49:32 2024 +0800 - permissions: docs - removed trailing spaces + db_mysql: enable TLS when building with mariadb-connector-c + + - mariadb-connector-c requires at least one non-NULL configuration + value to use TLS + - emulate MySQL SSL_MODE_XXXX options -commit 9efc9559f56044a21673d37ce7e10bc1243e5c4e -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +commit e470f67c9aaaeb2dc39f49a1b5abb3352b45ad13 +Author: Victor Seva +Date: Tue Jan 30 10:43:33 2024 +0100 - peering: docs - removed trailing spaces + github: [skip ci] enable dependabot for devcontainers -commit 03583a07d4ab34c9f4a79ac1b1afd5efb58a98cb -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +commit 8e2a1a36f14a18834d1a98e8483b4595a533abff +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jan 29 21:22:54 2024 +0000 - pdt: docs - removed trailing spaces + github: [skip ci]: bump wolletd/clang-format-checker from 1.10 to 1.11 + + Bumps [wolletd/clang-format-checker](https://github.com/wolletd/clang-format-checker) from 1.10 to 1.11. + - [Release notes](https://github.com/wolletd/clang-format-checker/releases) + - [Commits](https://github.com/wolletd/clang-format-checker/compare/v1.10...v1.11) + + --- + updated-dependencies: + - dependency-name: wolletd/clang-format-checker + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] -commit 133db4ca657eb4082618b079de15c62cfc9f13c7 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +commit 520b9dce03d695cd1d95432e6bf52ed47d046cd4 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jan 29 21:22:56 2024 +0000 - pdb: docs - removed trailing spaces + github: [skip ci]: bump ammaraskar/gcc-problem-matcher + + Bumps [ammaraskar/gcc-problem-matcher](https://github.com/ammaraskar/gcc-problem-matcher) from 0.2.0 to 0.3.0. + - [Release notes](https://github.com/ammaraskar/gcc-problem-matcher/releases) + - [Commits](https://github.com/ammaraskar/gcc-problem-matcher/compare/0.2.0...0.3.0) + + --- + updated-dependencies: + - dependency-name: ammaraskar/gcc-problem-matcher + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] -commit 6d0983fcc57bd3b1199ec5a34160d40dcd6caba0 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +commit 3426b153d02d9d8d3e909eff9d18cb14108072ca +Author: S-P Chan +Date: Mon Jan 29 12:06:56 2024 +0800 - path: docs - removed trailing spaces + db_postgres: init libssl in a thread -commit d76d9090665cc10ee166ab38bb8fddb7e8ccbc82 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +commit 5dffb934a2f7f986fdc09e433833991c54612646 +Author: S-P Chan +Date: Sun Jan 28 08:19:44 2024 +0800 - p_usrloc: docs - removed trailing spaces + db_mysql: init libssl in a thread -commit d8f97b6d72e457eb4fe324dba7b78e5eb76ed678 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +commit 2611a4670c65dd32fc1daf6b67e37852936ba69c +Author: S-P Chan +Date: Sun Jan 28 07:38:16 2024 +0800 - outbound: docs - removed trailing spaces + db_unixodbc: init libssl in a thread -commit 2a33799dbb66c3821c20f7c0b977989e3b83dcd0 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:36 2023 +0100 +commit 9560e973807bc454dab84bdfd5ac0e300c847864 +Author: S-P Chan +Date: Mon Jan 29 20:02:42 2024 +0800 - osp: docs - removed trailing spaces + tls_wolfssl: fix possible uninitialised variable -commit f3b8fa2455d0ff81e540e81c9f541f0df066fb02 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +commit c2f14e0dccbabdd74dbddcbd569c32d0b429617e +Author: Kamailio Dev +Date: Mon Jan 29 10:02:14 2024 +0100 - nsq: docs - removed trailing spaces + modules: readme files regenerated - sdpops ... [skip ci] -commit 8653df168c227371320bdb801acec7a6a5be46d7 +commit 68331254149a2ef3f2986bb92549cb63bb355989 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +Date: Sun Jan 28 17:17:40 2024 +0100 - nosip: docs - removed trailing spaces + textopsx: proper define id for body line interator name size -commit efcbe8dc84a511a78db4db4ab52e1cfc5198cc2c +commit 03d93a43a38f2af44640f42e3fd0f8f2a073b108 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +Date: Sat Jan 27 10:45:12 2024 +0100 - ndb_redis: docs - removed trailing spaces + sdpops: docs for sdp line interator functions and variable -commit 6f061299f483fe0ec1ed76a79940ef40f272f33f +commit ff54f183cdedded4ef9d24d055c755b770b07651 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +Date: Sat Jan 27 09:57:24 2024 +0100 - ndb_mongodb: docs - removed trailing spaces + sdpops: added sdp line interator functions and variables + + - walk sdb lines in the message body (also for multipart body) + - append/insert/remove line of the current iterator + - variable to get the value of the curent iterator -commit d6ff28c2b9ef129ed9bc629f1d22fe1cc274b05b +commit 7b676473d2193b34ba59600eb3ce9c5acd19da1b Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +Date: Sat Jan 27 09:16:39 2024 +0100 - ndb_cassandra: docs - removed trailing spaces + textopsx: reformat module exported structures -commit f5c68f220b5ddbf0603971a63a2f58a1c380e446 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +commit 0f963a7a1e2aca28611c2238f4c29180a0acd320 +Author: S-P Chan +Date: Mon Jan 29 11:26:35 2024 +0800 - nathelper: docs - removed trailing spaces + tls_wolfssl: clang-format -commit 450be5a6b89b8c18880bb1765d097400347dc44a -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +commit 04ca08d0da622519578c479664a85563ec6db483 +Author: S-P Chan +Date: Sat Jan 27 07:09:19 2024 +0800 - nat_traversal: docs - removed trailing spaces + tls_wolfssl: fix ring buffer write -commit 03e7a4646c72d792d3143e325779d558996badbc -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +commit c286bacad82b84165753187a326952573fe5fc7a +Author: Kamailio Dev +Date: Fri Jan 26 11:16:15 2024 +0100 - mtree: docs - removed trailing spaces + modules: readme files regenerated - sdpops ... [skip ci] -commit 0dd9a4fc9626dce42a94d37b817145496dd03cf2 +commit 46e3727368f7e801b3731272d219cefdceebadde Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +Date: Fri Jan 26 11:02:27 2024 +0100 - msrp: docs - removed trailing spaces + sdpops: docs - listed $sdp(c:ip) variable -commit 8f879a5c352c2fc55a95e379e4552d8d5821b2f6 +commit faaefbb02563b8ba0827b23422a363a71259ad1e Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +Date: Fri Jan 26 10:55:43 2024 +0100 - msilo: docs - removed trailing spaces + sdpops: added $sdp(c:ip) variable to return connection ip -commit c8ae635628224f280df591243bd428da3c3a0a3f +commit fe9b8f04cacd2ca92bf3fac1dc2fac323b8cf62d Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +Date: Fri Jan 26 08:27:36 2024 +0100 - mqueue: docs - removed trailing spaces + sl: format module exports structures -commit c129e9321466061d076fe7e5b25d3668a0664d3d +commit cab001e9677670585facf5cf2b7fd0c9889ac069 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +Date: Fri Jan 26 08:23:21 2024 +0100 - mqtt: docs - removed trailing spaces + sdpops: format module exports structures -commit 4f00043caae60a5084e5413838352bdceffbefdd -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +commit 247e6164cbacdcc5d260e98c1085c84ad93957ee +Author: Victor Seva +Date: Fri Jan 26 09:03:37 2024 +0100 - misctest: docs - removed trailing spaces + pkg/kamailio/deb: restore tls_wolfssl for bookworm and jammy + + fixed build error at 43ec11a7e0a37dfdaead873d555b26cb65589bd1 -commit f986d6bbfe0f92246d4485f443564358eba39485 +commit 4db5d7eb3fb34ad1282c9ded9b2d05b3f81fd476 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +Date: Thu Jan 25 20:11:19 2024 +0100 - misc_radius: docs - removed trailing spaces + core: mem - relocated unfinished memory allocators to archive repository + + - many years without development activity -commit cf0595e557583db983e81dbb3d4a5345e213f3e6 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +commit 43ec11a7e0a37dfdaead873d555b26cb65589bd1 +Author: S-P Chan +Date: Thu Jan 25 21:44:07 2024 +0800 - memcached: docs - removed trailing spaces + tls_wolfssl: allow building with debian libwolfssl35 + + - internal submodule is v5.6.6-stable + - libwolfssl35 is at v5.5.4-stable -commit 65ac04c8e55d02f301298ec5ad573b500827fea0 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +commit aaa3b102c62af9ac0abe1aaac12876abaa7ad351 +Author: Victor Seva +Date: Thu Jan 25 12:23:47 2024 +0100 - maxfwd: docs - removed trailing spaces + pkg/kamailio/deb: remove support for tls_wolfssl on bookworm/jammy + + > module expects wolfssl ~ v5.6.6-stable which is equivalent to libwolfssl42(5.6.6-1.2) libwolfssl-dev_5.6.6 -commit cfd9ddc7689fbebb8fd07b02197b9506429593b9 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +commit 5d3c11c5e0854ce74424a10a88b0cca4453cee75 +Author: S-P Chan +Date: Wed Jan 24 16:30:48 2024 +0800 - matrix: docs - removed trailing spaces + tls_wolfssl: clean-up; continue to remove OpenSSL-isms -commit 5a71325860cdac11bd314d3871fd818f1d27fc03 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +commit 099eceecab7af118bfa0bdfca68a8c0b30cec6f0 +Author: Kamailio Dev +Date: Wed Jan 24 21:31:18 2024 +0100 - mangler: docs - removed trailing spaces + modules: readme files regenerated - ims_charging ... [skip ci] -commit 92254b1f74d3691221673a3ae6b58077cd8f8147 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +commit 76cd7979aae176b3fde3b3d73975629b06cd509c +Author: Morten Tryfoss +Date: Wed Jan 24 21:16:08 2024 +0100 - lrkproxy: docs - removed trailing spaces + ims_charging: Add option to get and use P-Access-Network-Info for terminating scenario (#3726) + + Add option to configure node functionality for Ro requests -commit 03db8597482da2d646e0aefd15daec9d744dca14 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +commit ba36c65dfb2a6608dd7d51422a7ed021206bcae3 +Author: Kamailio Dev +Date: Wed Jan 24 17:32:06 2024 +0100 - lost: docs - removed trailing spaces + modules: readme files regenerated - tm ... [skip ci] -commit 7b50ffcc5ec129e8560ad427cd6bfca05b3b1a43 +commit d26b0bef2e76be55c5cb099520f221487d362b48 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +Date: Wed Jan 24 17:17:23 2024 +0100 - log_systemd: docs - removed trailing spaces + tm: docs - update to use send_reply_error() when t_relay() fails + + - the transaction might be already created and needs a stateful reply -commit fda00b8c1c754e3b73ad8cda7ca3e8d9f6b136a2 +commit 76b7beef6d089272b749aa53f29e100711aa4c50 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +Date: Wed Jan 24 10:31:07 2024 +0100 - log_custom: docs - removed trailing spaces + sl: do not send error reply if message marked with delayed-reply flag -commit da034fe3d65d38633bb6b45cb4833cb8ea61b80a +commit 09c75716530f7d8be2671e5823dca5b640cad45a Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +Date: Wed Jan 24 10:26:45 2024 +0100 - ldap: docs - removed trailing spaces + tm: mark request with delayed reply flag -commit 6ffbb166238a329a06ab935831e88598cb770089 +commit 5c8cfdd803e81a592bf9fdeb208b13404e96da25 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +Date: Wed Jan 24 10:23:01 2024 +0100 - lcr: docs - removed trailing spaces + core: parser - internal flag to mark delayed local replies -commit 9d63b3778f35962539821351c704ecc425d825e5 +commit 236c56f5f4c11fb867e545f830182b386f0a0c66 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +Date: Wed Jan 24 08:21:19 2024 +0100 - kex: docs - removed trailing spaces + tm: prefixed global kill reason variable -commit 2ed4817474c7dee216d79273079bc08e7d9c49ea -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:35 2023 +0100 +commit 3d0e7521c6de4023b6595685fc306129ef57b8ac +Author: S-P Chan +Date: Tue Jan 23 23:13:08 2024 +0800 - keepalive: docs - removed trailing spaces + tls_wolfssl: clean-up; remove OpenSSL-isms -commit 49e06be4e9aacdd770f519944bdf28d916371f7a +commit 33b2e513aefe00bf166cdcae360e305615b223da Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +Date: Tue Jan 23 21:05:41 2024 +0100 - kazoo: docs - removed trailing spaces + tm: release transaction on kill if a final response was sent + + - do not send another final response for error cases -commit 67d2ee655a8653af4bdfac4daffe649cd1babe50 +commit 0f8f4d6926e53ca5e526a11729f6ee6277b185b9 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +Date: Tue Jan 23 14:23:27 2024 +0100 - kafka: docs - removed trailing spaces + auth: reformat exported structures -commit 77cb0a486c1ad77708cb0ff9a4e0a553c9bf0e8c +commit aa167c410860732918061106c4a84a7c6b030d69 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +Date: Tue Jan 23 14:18:19 2024 +0100 - jsonrpcc: docs - removed trailing spaces + auth: removed commented code and prefixed short global variable -commit d5d5ec74b55cdabb3c673663742cd7f6185330de -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +commit 32089e134413200bf5d1a97f207378b7d10e65a2 +Author: S-P Chan +Date: Sun Jan 21 18:17:37 2024 +0800 - json: docs - removed trailing spaces + tls_wolfssl: refactor custom BIO + + - remove use of custom BIO at the expense of some memory copies -commit 6dd9324fc660da907e9de1b612413bdb56ca341f -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +commit 88f27e2b89142652ea1b8f133df1ff403f9f61b2 +Author: S-P Chan +Date: Fri Jan 19 12:16:01 2024 +0800 - janssonrpcc: docs - removed trailing spaces + tls_wolfssl: use shared WOLFSSL_CTX -commit 1e8232df5ed6719105cc1f540fdf5f96e7ad30b1 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +commit 255e563e94e9536f0e541c3baeec45cbc68fac5b +Author: S-P Chan +Date: Thu Jan 18 12:38:09 2024 +0800 - jansson: docs - removed trailing spaces + tls_wolfssl: clean-up OpenSSL compatibility + + - remove unneeded OpenSSL-isms -commit b17fa4f25669a73ebdc6b60c51bb9427b5f868ab -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +commit 100d96bf3819082ac38f8a4fae1f3c64c8d0c5e1 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jan 22 21:58:56 2024 +0000 - ipops: docs - removed trailing spaces + github: [skip ci]: bump tj-actions/changed-files from 41 to 42 + + Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 41 to 42. + - [Release notes](https://github.com/tj-actions/changed-files/releases) + - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) + - [Commits](https://github.com/tj-actions/changed-files/compare/v41...v42) + + --- + updated-dependencies: + - dependency-name: tj-actions/changed-files + dependency-type: direct:production + update-type: version-update:semver-major + ... + + Signed-off-by: dependabot[bot] -commit dd8472303e5eda82e92e20ec84921436f60a2bdd +commit 569b536404afd855742a42320d7c858a8bb4952b Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +Date: Mon Jan 22 14:11:29 2024 +0100 - ims_usrloc_scscf: docs - removed trailing spaces + tm: mark request with final reply flag + + - send error function checks flag and returns if set to avoid sending + more than one final reply in case of failure -commit 7b3a7cbf663c50a6abe53af8465963cffe664e5b +commit 1a2477ba348928e6bdff15be765cb907e32cffc4 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +Date: Mon Jan 22 14:02:47 2024 +0100 - ims_usrloc_pcscf: docs - removed trailing spaces + sl: mark request with final reply flag + + - send error function checks flag and returns if set to avoid sending + more than one final reply in case of failures -commit 14e29adfea7e30d015ddebe0de199f195a4516f5 +commit c3b47e0c5cf4ed405b02aa2d0d4cb31073bab0aa Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +Date: Mon Jan 22 13:50:08 2024 +0100 - ims_registrar_scscf: docs - removed trailing spaces + core: parser - flag to mark request when a local final reply is sent -commit 016163471649c9fe87b8046c9e16981ac9c5a3e8 +commit 15aafe49a6a022809f278f596812c97dc5404982 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +Date: Mon Jan 22 13:25:04 2024 +0100 - ims_registrar_pcscf: docs - removed trailing spaces + presence: prefix short global variables -commit 976df7b5c5ce31900fe5f305f66c02d3511632bb +commit 7da07508bc74a6a0c87e1dc7993d0061b65e2faa Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +Date: Mon Jan 22 13:18:15 2024 +0100 - ims_qos: docs - removed trailing spaces + presence: removed unused external variable -commit 51c6db1fec2f4d49914ba21572f0a5ac6e3effb1 +commit 050760411bac006c1e6351f179fab7ea6333b3e5 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +Date: Sun Jan 21 21:29:28 2024 +0100 - ims_ocs: docs - removed trailing spaces + lib: presence - remove old commented code and adjust comments -commit cd451aba7f2f62c2cc51912a7ca350dd6c0f619b +commit 0a11489d4b699a62596b2c4626171e8d92e966fd Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +Date: Sun Jan 21 10:20:39 2024 +0100 - ims_isc: docs - removed trailing spaces + lib/srdb2: review and adapt old comments -commit 00c3b0f5f9eb8cc1cd9dfc7c0c73614448a1b854 +commit 67f71d1b7c44a7d3ef1ba2917272e2ba36608cd7 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +Date: Sat Jan 20 12:37:12 2024 +0100 - ims_icscf: docs - removed trailing spaces + lib/xcap: reviewed and removed old comments and disabled code -commit 7edce07d04df8b07637f48380dd18cb1f525d951 +commit e8ee31f6bce32050f8caaa8d053ddaea8d99cc1d Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +Date: Sat Jan 20 12:16:13 2024 +0100 - ims_diameter_server: docs - removed trailing spaces + lib/cds: reviewed and removed old comments -commit a2ad493749fcecb354dcb29a8f580d1c09015e6c -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +commit 2f7b7a5750815814bedb4b2a6b3716ea72e4d904 +Author: Victor Seva +Date: Fri Jan 19 15:40:06 2024 +0100 - ims_charging: docs - removed trailing spaces + github: remove cleanup workflow [skip ci] + + it's removing untagged images that are layers of the tagged ones -commit 9d2ebcd15d1acab1b0ca5734b78676342b3078ab -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +commit f59dacf7993da83553cd67de516fc31f493d2a7d +Author: Stefan-Cristian Mititelu +Date: Fri Jan 19 15:54:15 2024 +0200 - ims_auth: docs - removed trailing spaces + p_usrloc: Add missing api function get_udomain() + + When registrar kemi save()/save_uri() function is called, + then usrloc api function get_udomain() is called. + + This usrloc api function is missing in p_usrloc module + and results in a segfault. -commit 0dbcdbbc1fad7cd8e60f3eaa9c15a568d0a4c2df -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +commit e506b60c1045cfbd4485434165305fbc2fb57aa9 +Author: Stefan-Cristian Mititelu +Date: Wed Jan 10 17:20:27 2024 +0200 - imc: docs - removed trailing spaces + xlog: add kemi xlog_facility function -commit 165e11c43e1e4df9be4696941024fef794b981ae +commit 4a2665a8c5ff31d50468bd998ef0853c3ff510cc Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +Date: Fri Jan 19 10:18:33 2024 +0100 - http_async_client: docs - removed trailing spaces + pv: increase the number of slots for transformations + + - safer handling of chained transformations -commit db128b173cb6fa1b432eccd39c8078c366621477 +commit 59104fe7d57bc8c75c835bbb75d5a1b7d01f6bda Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +Date: Fri Jan 19 10:09:46 2024 +0100 - htable: docs - removed trailing spaces + core: increase default pv buffer size to accomodate safer webrtc traffic -commit 286cc1d1b31f5a0889fe61e143569ef6d4168b6d +commit cc26d25eefac40ec1c7e209e25312eed978cf348 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +Date: Fri Jan 19 09:49:55 2024 +0100 - h350: docs - removed trailing spaces + pv: convert pv value to long for ftime transformation -commit 78e60150ae5afe67e48f8a3a4b72382678e84ef2 +commit a2bff77c3f7bfee8dae90c3ef20522d480f2e14d Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +Date: Fri Jan 19 09:44:33 2024 +0100 - gzcompress: docs - removed trailing spaces + jansson: declare variables at the beginning of blocks -commit 859ddc705665ecf7bf3033af0e4a1f3f44f58355 +commit 8a1613096ad86db125398e50d2ecced5d3ff1978 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +Date: Thu Jan 18 18:48:22 2024 +0100 - group: docs - removed trailing spaces + core: parser - check diversion pointer before accessing it -commit 25556085883ec46e11bec9950c78917d5fc9a35c +commit a972c3bd5287177f8fa73dfb0ed5b2da8e3f4f57 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:34 2023 +0100 +Date: Thu Jan 18 18:37:41 2024 +0100 - geoip2: docs - removed trailing spaces + gcrypt: init allocated buffer -commit baaae4ac31c00976d679d50d55fba3312e780c06 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +commit 304b8a41464f1bed83d733a3002088b759c7e679 +Author: Kamailio Dev +Date: Thu Jan 18 16:01:19 2024 +0100 - geoip: docs - removed trailing spaces + modules: readme files regenerated - kex ... [skip ci] -commit b60be507732d43d4292e631cc01f5c429f14d794 +commit 2ebf19b16987b815b2fc2902bff5ccbea6e90e13 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +Date: Thu Jan 18 11:44:32 2024 +0100 - exec: docs - removed trailing spaces + kex: reformat exported structures -commit 23c8ab91e15599efc3995cb4eea36bb1237a353b +commit ee191ccd01ec6391c715e22efed2dc6581fe9d72 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +Date: Wed Jan 17 19:40:23 2024 +0100 - evapi: docs - removed trailing spaces + kex: docs for is_myhost() -commit 9eeed047839ffd66ffbd4791bb8db270996a1205 +commit aaec01e0556bf6148ec50795f896af71f9680a70 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +Date: Wed Jan 17 17:49:33 2024 +0100 - erlang: docs - removed trailing spaces + kex: added is_myhost(uri) - check if host part only is local + + - similar to is_myself() but ignores the port and protocol -commit 7d146f8d9c0fb6c842addbd6c46997ef1089d6fb -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +commit 79697b4d565665b696ee39021e27d82e716bc176 +Author: S-P Chan +Date: Thu Jan 18 06:47:14 2024 +0800 - enum: docs - removed trailing spaces + pkg: RPM spec missing %description for sqlang -commit 64dad2edb541fcd8322a8a75e9a1aa0a0e1e359f -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +commit d0e7aa5405a293401ad19347cc062d1585d06956 +Author: S-P Chan +Date: Thu Jan 18 06:38:29 2024 +0800 - domainpolicy: docs - removed trailing spaces + pkg: RPM spec use automatic dependency for wolfssl + + - wolfssl doesn't follow semantic versioning + - let RPM figure out the correct runtime library name + depending on the -devel package used for building + i.e. based on the package used for pkgconfig(wolfssl) + + e.g. if wolfssl35-devel - then libwolfssl.so.35 + if wolfssl42-devel - then libwolfssl.so.42 -commit e3416fbc3b8ec0b000bcca8fde4ddfd1925b5741 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +commit 5bbb224fdad1770150dd2fc37c69393aeda96d40 +Author: S-P Chan +Date: Thu Jan 18 06:21:55 2024 +0800 - domain: docs - removed trailing spaces + tls_wolfssl: clean-up—using wolfSSL native naming for functions / structs -commit 2e1b1b2ef01c73af1632633378edab3d3d7e1bae -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +commit 03456e5e5983e2236b8e182cf3317d14ebf34e18 +Author: Elena-Ramona Modroiu +Date: Tue Jan 16 16:07:43 2024 +0100 - dnssec: docs - removed trailing spaces + tls: set parameter name for tls_h_mod_randctx() + + - without it fails to compile on Unbuntu 22.04 with low latency kernel -commit a289bfb0b37d28ca477f80920b35744e0bda4563 +commit 14828091b06dca86c91659d705a4f58a6fead4d3 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +Date: Tue Jan 16 13:10:34 2024 +0100 - dmq_usrloc: docs - removed trailing spaces + rtp_media_server: use local user for building contact + + - GH #3380 -commit db5ea1d538011b1ae6518fbe4628b94c96a51b4a +commit 167d8af9ff1c55804a66cc948670ab1d3069e063 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +Date: Tue Jan 16 11:02:20 2024 +0100 - dmq: docs - removed trailing spaces + core: snexpr - rename some inner blocks variables -commit 456fb769aa914d3cc91b404600362afa25dac35a +commit 6ebe3b612d60e02854c7b88cd241615b50666b00 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +Date: Tue Jan 16 09:22:29 2024 +0100 - diversion: docs - removed trailing spaces + ss7ops: rename local variable that hides the function parameter -commit 42b6346d31d1415dc80e8dfcfe0123db7b30d49a -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +commit 695f155f3a127f0bbe220a6b44a0fc3887e1e4be +Author: Federico Cabiddu +Date: Tue Jan 16 09:42:27 2024 +0100 - dispatcher: docs - removed trailing spaces + dialog: don't send the BYE if dialog is in deleted state (#3714) -commit 081362a01b63b81e7f0eaff1024761d59ca9634b -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +commit 7e5843e28dc4e331f434381defeb4cef43c5298f +Author: S-P Chan +Date: Tue Jan 16 16:36:25 2024 +0800 - dialplan: docs - removed trailing spaces + tls_wolfssl: mask outer make DESTDIR=XX if building internal submodule -commit da4f07203b9c891c1e2c7a02c86dc9da23d7c526 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +commit 4df939428555f8c4fde67f7b8638809aca56c9f2 +Author: Victor Seva +Date: Tue Jan 16 09:33:20 2024 +0100 - dialog: docs - removed trailing spaces + github: add default registry credentials [skip ci] + + > https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idcontainercredentials -commit ecae4beaeb5ceb6ecefb23fea8d8b1a7fbc776c8 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +commit a752fde2fd2eb3615d16eb8940364ceea2f7d79c +Author: S-P Chan +Date: Tue Jan 16 16:06:45 2024 +0800 - debugger: docs - removed trailing spaces + tls_wolfssl: update to v5.6.6-stable -commit ec99b316295cf0c619fcd1cd3fbc58469974f00e -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +commit 404b47791678c4eaccd4cfc7a83e0bb97a29b5d3 +Author: Xenofon Karamanos +Date: Mon Jan 15 17:22:06 2024 +0000 - db_unixodbc: docs - removed trailing spaces + usrloc: synchronize attributes from DMQ (GH #3679) + + - make ucontact_xavp_store static and add some comments + - change order of xavp operations in ucontact_xavp_store to not overwrite DMQ xavp + - add logic to receive xavp information from DMQ and save it in the contact -commit a70122bf9c4b4e8380eeb5942f5b7485baf7ea71 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +commit d2eb6a9f324a2077d0f4422621aa4d125c72c880 +Author: Xenofon Karamanos +Date: Mon Jan 15 17:21:39 2024 +0000 - db_text: docs - removed trailing spaces + dmq_usrloc: DMQ also copies and sends attributes related to contacts (GH #3679) -commit e88720df7af1a0698bd46e9a3e5a62271d890b58 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +commit aa67092e6ea7d8581e11970993607511771c1be6 +Author: Victor Seva +Date: Mon Jan 15 15:23:55 2024 +0100 - db_postgres: docs - removed trailing spaces + github: fix cleanup matrix definition [skip ci] -commit 903dcca9fd7d8ddaa72f3bb4b8c3ea41a92d74bb -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +commit f3b4f2fe2b88a06cdc49ba473e4b3fc3fbbfd8bf +Author: Victor Seva +Date: Mon Jan 15 15:21:06 2024 +0100 - db_perlvdb: docs - removed trailing spaces + github: add all packages images to cleanup -commit b8f3cc55ed31f98aa374196eb1754dbe83f71944 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +commit cb520baa9349f86fc104e2c1eed633ea59157b1b +Author: Victor Seva +Date: Mon Jan 15 15:03:15 2024 +0100 - db_oracle: docs - removed trailing spaces + github: use CLEAN_PACKAGES secret at cleanup workflow + + kamailio-sync PAT with delete:packages permissions as described + > https://github.com/camargo/delete-untagged-action -commit 21326bdb882efff9c5eb211bae49c3d9d37412c0 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +commit fe5c7125c66e37d2db032a63328ad713738a4b0c +Author: S-P Chan +Date: Mon Jan 15 21:32:53 2024 +0800 - db_mysql: docs - removed trailing spaces + outbound: update to OpenSSL 3 API -commit b0819734f1d929259e73610a9e8b09c6333f31d1 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +commit 47303fc34d4795edc7b58569fb97e7b0532b0367 +Author: Henning Westerholt +Date: Mon Jan 15 12:07:16 2024 +0000 - db_mongodb: docs - removed trailing spaces + Makefile.defs: remove unused define WITH_XAVP, its not used anymore from the code -commit 866ba37b622df10672b9938f899956a311275019 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +commit 555530c70f8f7034046e0b81f4a8469ed76bb405 +Author: Henning Westerholt +Date: Mon Jan 15 12:06:54 2024 +0000 - db_flatstore: docs - removed trailing spaces + doc/tutorial: remove unused define WITH_XAVP, its not used anymore from the code -commit 77f77d852b173373b2dfef1d84c97e32593698bd -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +commit 6f9620704c661151415ad723e5f0b31f34b70c1d +Author: Henning Westerholt +Date: Mon Jan 15 12:06:25 2024 +0000 - db_cluster: docs - removed trailing spaces + docs/scripts: remove unused define WITH_XAVP, its not used anymore from the code -commit 630fe40dfef237316c5d0d0c0b3b7a7a18ad1620 +commit 2ffeaf6f480cbe1581395519b252c2bf35291ef7 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +Date: Mon Jan 15 12:15:58 2024 +0100 - db_cassandra: docs - removed trailing spaces + usrloc: fix condition for keepalive interval -commit c32f87d137921c7df6f420248b37f2f9ef1535de +commit 4d8e888c805ddecdb7227350c1c01e52c235ffb5 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:33 2023 +0100 +Date: Mon Jan 15 10:37:42 2024 +0100 - db_berkeley: docs - removed trailing spaces + usrloc: add ka_randomize to ka_interval when checking for keepalive -commit d2ec4962ee1f1abe365a524605d075e063410cc9 +commit b3e19d8c97c099823ad439167b07ccbb30d05a25 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +Date: Sun Jan 14 16:15:49 2024 +0100 - db2_ops: docs - removed trailing spaces + lcr: prefix global variable with short name -commit 7a31f56bb1b266f7e158437aa1473c69060f9990 +commit e6836cf2dc772fd7e5b4322d4243ca3c2177de1f Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +Date: Sun Jan 14 09:11:19 2024 +0100 - db2_ldap: docs - removed trailing spaces + registrar: prefix global variables with short name -commit ce7b1be8c6e2e20746f4049cc72f7baddc0eba20 +commit 82ae289d8f549b142aa0631b6225838bbbc1f446 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +Date: Sat Jan 13 21:00:32 2024 +0100 - ctl: docs - removed trailing spaces + sanity: prefix global variables with short name -commit 76236ada3622fd74a00954b9cf11419241f6c81e +commit 7867a29d3f49d6bc149b9f556ae28ce089e841f4 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +Date: Sat Jan 13 19:54:46 2024 +0100 - crypto: docs - removed trailing spaces + siptrace: prefix global variables with short name -commit 4a9d850aa6704f6742a3cae43dc8aae384ab2f5f -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +commit 8dffc45ee91aeed839efb38d17040359dcac953a +Author: S-P Chan +Date: Sun Jan 14 14:08:03 2024 +0800 - cplc: docs - removed trailing spaces + tls: remove thread-enablement on EVP_RAND_CTX + + - with late initialisation it is not necessary to enable thread locking + on EVP_RAND_CTX + - the function remains but is not used in case requirements change + with OpenSSL >= 3.2 -commit 015b4b5ed32e65600ed18301be8ab006064b72cf -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +commit 42b9fe9781e6805436227e0e7b88db73767a94b1 +Author: Дилян Палаузов +Date: Sat Jan 13 16:26:20 2024 +0100 - counters: docs - removed trailing spaces + src/Makefile.defs: recognize GCC 14 as recent ⇔ not too old compiler + + similar to 87ed3d9c3ae3ecfabe6 -commit 7ca0cd30c74b6a85c7416df4c4ea7bafc422b338 +commit 1c13e99efb119f75ddbd6a0aa4798cd27accbff5 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +Date: Fri Jan 12 20:02:14 2024 +0100 - corex: docs - removed trailing spaces + topoh: prefix global variable -commit 391e8173a3422eef677fab850f05858dad67ecb8 +commit cb92b6a23d622b06bcb18195b5c0525fcd273e7a Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +Date: Fri Jan 12 19:53:57 2024 +0100 - cnxcc: docs - removed trailing spaces + topos: prefix global variable -commit dba983323474a7940572e1914d0c584777662a89 +commit 987e21a914edcebc9eafe21af19c8a476bf73b06 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +Date: Fri Jan 12 19:50:28 2024 +0100 - cfgutils: docs - removed trailing spaces + xhttp: prefix for global variable -commit 47f8b348a24b37bdb8c384f03b91bf990ddd1444 +commit 0479c40fe6fd6765de92eea8f9e0bf04dea8cbd0 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +Date: Fri Jan 12 14:37:02 2024 +0100 - cfgt: docs - removed trailing spaces + mohqueue: rename local variables to prevent shadowing the global -commit ca6c8bf6767d04f1725172044e8b699a2f04f8aa +commit 0ea603413de9505b5312e5930168102e816dced3 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +Date: Fri Jan 12 13:10:33 2024 +0100 - cfg_db: docs - removed trailing spaces + avp: rename local variable to prevent shadowing the global structure -commit c3a9147bdaa05618f7f90cca2bb9abe01e9074ad -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +commit 1671c96462f76d902b4c331c2f51e99cd2e33af1 +Author: Kamailio Dev +Date: Thu Jan 11 17:17:12 2024 +0100 - cdp_avp: docs - removed trailing spaces + modules: readme files regenerated - rtpengine ... [skip ci] -commit b0b40122f22db100411a85379fd73061bd0a7f14 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +commit 1aec0c1397e4230e52f2b9427fdb32b10f649ecb +Author: Xenofon Karamanos +Date: Thu Jan 11 14:38:02 2024 +0000 - cdp: docs - removed trailing spaces + rtpengine/docs: Add codec-consume docs -commit 3a2de012e1a45bde2c3c6873ae09402f83241f9b -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +commit a40d5b7d65394606f2200a5932284b874e196063 +Author: Xenofon Karamanos +Date: Thu Jan 11 13:49:40 2024 +0000 - carrierroute: docs - removed trailing spaces + rtpengine: Add support for codec-accept and codec-consume -commit 3d864d6bce8a312f19338946685314c60a16c662 +commit b678e66a974f3f88f5ed05e57e5d898e4715fe0a Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +Date: Thu Jan 11 15:34:33 2024 +0100 - call_obj: docs - removed trailing spaces + p_usrloc: rename short global variable -commit b90ad7cd9a51ef3644ce8d85a56225b1aacb263b +commit 302231bf2262ef73a6aad4a2f476df7c9a3c05f0 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +Date: Thu Jan 11 15:23:55 2024 +0100 - call_control: docs - removed trailing spaces + ratelimit: rename variables to prevent global structure shadowing -commit 4a892d7df5c0bb698c7726d8dcc7973e42c8c8fc -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +commit 72595fe42d28d3e4a12341b405af63d41f827dc4 +Author: Henning Westerholt +Date: Thu Jan 11 10:30:40 2024 +0000 - blst: docs - removed trailing spaces + http_async_client: use error log level (GH #3706) -commit b4c1d5108a9509a45a78681309c608e611efcd1a +commit b50036200c5bc09fd2d412a18585b42d63763b27 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +Date: Thu Jan 11 08:21:00 2024 +0100 - benchmark: docs - removed trailing spaces + core: keep listen socket even if advertise address does not resolve + + - the core advertise_address parameter works in the same fashion + - previously it was starting by skipping the listen, which resulted in + unexpected runtime list of sockets -commit 2636e742077b9dbd6fc20900e3742d80993f6535 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +commit 29007ada5bc9e07ede3cdbce285f04d1298c0612 +Author: S-P Chan +Date: Thu Jan 11 08:03:07 2024 +0800 - avpops: docs - removed trailing spaces + tls: historical code comment on repeating SSL_CTX per worker -commit 6acc4e2bd4019699c129422030bc5721869210ac +commit 42bae2a634249fe7d8ba174eaffff0ee547f6d2b Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +Date: Wed Jan 10 13:41:33 2024 +0100 - avp: docs - removed trailing spaces + registrar: cumpute randmized-range expire value as float and then cast -commit 4876b743a30475619c777ac2cd11e5248f985796 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +commit 403ed48995e5eec5a795edd1748f9fe8a9ee520d +Author: Kamailio Dev +Date: Wed Jan 10 13:32:13 2024 +0100 - auth_xkeys: docs - removed trailing spaces + modules: readme files regenerated - usrloc ... [skip ci] -commit df22d87a09b9ca793b0a9f999e48a6f3d1ccbfe1 +commit bbb81e5f6ef5744cc9b74302e8ecee6687199872 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +Date: Wed Jan 10 13:16:14 2024 +0100 - auth_radius: docs - removed trailing spaces + usrloc: docs for ka_randomize parameter -commit 5045d153af73f928a743fcd5e8dce28cbcc56aaf +commit 5bf1a7ab30f14d989ab185585427c868429224fa Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +Date: Wed Jan 10 13:07:14 2024 +0100 - auth_identity: docs - removed trailing spaces + usrloc: option to randomize when keepalive is sent + + - default adds a range from 0 to 20 seconds to ka_interval -commit 8c0cc460416a87632173f017d361f46cbafa8108 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +commit 03f939e3d1a0dbf56791943f90942984984f2d72 +Author: Kamailio Dev +Date: Wed Jan 10 12:47:06 2024 +0100 - auth_diameter: docs - removed trailing spaces + modules: readme files regenerated - usrloc ... [skip ci] -commit 85288f9dd4f0a452ffff9d58fbb36817954aa45a +commit 36608af81b3ed64b3800be1625647ed0a9e5031d Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:32 2023 +0100 +Date: Wed Jan 10 12:40:56 2024 +0100 - auth: docs - removed trailing spaces + usrloc: docs for ka_interval parameter -commit df20976307dd501826c1409879dcdee82665ea2a +commit 53ace443020075f7ecd12c72f154193c6cfa6af3 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:31 2023 +0100 +Date: Wed Jan 10 12:24:39 2024 +0100 - app_python3: docs - removed trailing spaces + usrloc: added keepalive interval to set the step for sending + + - the keepalive is not going to be sent before the interval elapsed + - the keepalive is no longer sent on every timer callback + - default 40 seconds -commit 174f5babf470709523b078cbade62d2d7e96ad61 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:31 2023 +0100 +commit 5a40d1ef1b484c4fc437a3f0183a101241e80313 +Author: Federico Cabiddu +Date: Wed Jan 10 08:52:03 2024 +0100 - app_python: docs - removed trailing spaces + http_async_client: exit mod_init if tm is not loaded -commit a86448f7c99f159c383d4fa59b0bc6aab70df16e +commit f485a0c9f138ccfbeb548fa22ea9053afb449875 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:31 2023 +0100 +Date: Tue Jan 9 15:32:14 2024 +0100 - app_perl: docs - removed trailing spaces + pkg: rpm obs spec - removed app_sqlang module from packaging -commit 03b359a3960ed637a8a4c866251fbfe88acd6bf6 +commit 577fb11010ff61af3c4b567581c0bbc5404654c8 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:31 2023 +0100 +Date: Tue Jan 9 14:06:21 2024 +0100 - app_mono: docs - removed trailing spaces + htable: read rpc number value as long + + - remove autoconvert for number, it is only for string values + - GH #3674 -commit 192c9f339800a4c5a46d6147e4fbe78b4dae55bb +commit 3f4844b4ad1190a38eff8b377c89a9554be80e59 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:31 2023 +0100 +Date: Tue Jan 9 12:39:11 2024 +0100 - app_lua_sr: docs - removed trailing spaces + siputils: reformat module exported structures -commit ac993f3eb9fca4204111c17e1f8b4ea2d04a77e9 +commit 0fcc950dc54990a51fe74616ec2d2972a4e1c094 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:31 2023 +0100 +Date: Tue Jan 9 12:32:36 2024 +0100 - app_lua: docs - removed trailing spaces + siputils: added module prefix to global variables -commit 6f14426233533bdd96bf941c235a67a86d615eab -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:31 2023 +0100 +commit 587c3e337c3cbabed1373b9308065d59392a370d +Author: Kamailio Dev +Date: Tue Jan 9 12:17:06 2024 +0100 - app_java: docs - removed trailing spaces + modules: readme files regenerated - gcrypt ... [skip ci] -commit dfbb87ce8eba3dd02516d40c39a083dc70cb0478 +commit 33a0eeb40cb6be28c7921ccb61dcede1ebce4bad Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:31 2023 +0100 +Date: Tue Jan 9 12:00:41 2024 +0100 - alias_db: docs - removed trailing spaces + gcrypt: docs for aes_mode parameters -commit 124731a1b1aca63d86996412078e01944ad7a3d4 +commit 2024253fac4c4fda48f2b0c5b9a1f9717294aa22 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:31 2023 +0100 +Date: Tue Jan 9 11:56:50 2024 +0100 - acc_json: docs - removed trailing spaces + gcrypt: added aes_mode parameter + + - specify AES encryption mode: + - 0: ECB (GCRY_CIPHER_MODE_ECB) - default + - 1: CBC (GCRY_CIPHER_MODE_CBC) -commit f61e9f9a372011a1ad5a897b363ffee09b67fdfb -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:36:31 2023 +0100 +commit 977e4f3e4d2a002f8aed55035c4ab6c3ee9ea1b8 +Author: Kamailio Dev +Date: Tue Jan 9 11:02:08 2024 +0100 - acc: docs - removed trailing spaces + modules: readme files regenerated - gcrypt ... [skip ci] -commit d63514d7919b90435aa6973012cf5abe2415af4e +commit 4d96966272761816d16b40dc68adf3b24e79fbaf Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:33:44 2023 +0100 +Date: Tue Jan 9 10:52:24 2024 +0100 - test/mod_httpapitest: removed trailing spaces + gcrypt: docs for register_callid parameter -commit b0948b515da27b6900eb1cadf336662d7921a160 +commit fae3632a224cde753c2a6e3d1d2a72b6e9aa9ceb Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:31:07 2023 +0100 +Date: Tue Jan 9 10:49:48 2024 +0100 - test/misc/code: removed trailing spaces + gcrypt: added functions to generate random call-id in uuid format + + - alternative to the option offered by crypto module -commit 67f20986481de20c038c3a857b11687db70b8ec5 +commit db8dd08b5506ac40314b70386b9ea83b509e17b1 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:30:31 2023 +0100 +Date: Mon Jan 8 20:20:36 2024 +0100 - pdbt: removed trailing spaces + Makefile.groups: added group for gcrypt module -commit f9c78be0e014ae5c5416c06883f4d33cabee2d4f +commit 52e82aa79febcdc7aa422756e250d402b61dfe14 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:30:31 2023 +0100 +Date: Mon Jan 8 20:00:26 2024 +0100 - db_berkeley: removed trailing spaces + gcrypt: new module for crypto functions + + - uses the GNU libgcrypt library + - implemented AES256 ECB encrypt/decrypt functions -commit 6ab8de8f49cdd93c9fa4e7c60e2b9cee1bd5fe91 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:25:59 2023 +0100 +commit 4df92312166d8aad700007ef0898d0a7c6ba40b7 +Author: Xenofon Karamanos +Date: Thu Jan 4 11:43:21 2024 +0000 - xcap: removed trailing spaces + parser/contact: Change addition order to the end of list + + - Contacts are now added at the end of the list. + - hfl(Contact)[index] is now returning in the correct order. -commit c30d57ac5b7213bcf09e11ee12518243469dd802 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:25:59 2023 +0100 +commit b3ed254a85bd9528342d07c87791ee00f5d70622 +Author: Kamailio Dev +Date: Mon Jan 8 12:31:30 2024 +0100 - srdb2: removed trailing spaces + modules: readme files regenerated - siputils ... [skip ci] -commit e710b67b0a146ca1128efcc3ce1a6c6b57cbe9c0 +commit 257cfe9be9327054fb381a48df9605444ea8e6fd Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:25:59 2023 +0100 +Date: Mon Jan 8 12:25:32 2024 +0100 - srdb1: removed trailing spaces + siputils: docs for contact_param_check() function -commit 74b6d96c50b9355f6234d34f72c39d04458e52c5 +commit eef07574be8499b517e4c333a36d618c608253ef Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:25:59 2023 +0100 +Date: Mon Jan 8 12:13:14 2024 +0100 - print: removed trailing spaces + siputils: new function to check existence of a contact uri param -commit ccba05208609946d2de8736d16f0939df81d77db +commit 9d8037bfd71996cfae756a030cdc3dd139162863 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:25:59 2023 +0100 +Date: Mon Jan 8 09:17:22 2024 +0100 - presence: removed trailing spaces + lcr: rename function parameters to avoid shadowing the global variable -commit e3a8d1bd6f36a94a52626705c4c58c9d00dcbdca +commit ecca625fd265d0484165d7a56e958a634103b09a Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:25:59 2023 +0100 +Date: Sun Jan 7 21:06:33 2024 +0100 - ims: removed trailing spaces + rtpengine: renamed function parameters to avoid shadowing the global variable -commit 8e08fa2c9d6a6d46b219f9320c245d6a17fda76e +commit c53a3a0fdee77d6d638f2f50f405ee038288301d Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:25:59 2023 +0100 +Date: Sun Jan 7 10:58:51 2024 +0100 - cds: removed trailing spaces + siptrace: rename parameters to avoid overlapping with global structure -commit e8989c3102b068f53c85a26e6b9ceae278a51aca +commit 000404acbf84b0425d8d8e03ece29d525dc56efc Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:25:59 2023 +0100 +Date: Sat Jan 6 18:50:02 2024 +0100 - binrpc: removed trailing spaces + smsops: prefix some global variables with module name -commit 82ae416bd8a870698d9ff6b1d9cb32ba38e2ca01 +commit 69fab0d4005e09b6fd0b905e7c660a8fe62d3659 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:23:29 2023 +0100 +Date: Sat Jan 6 16:35:50 2024 +0100 - core: removed trailing spaces + pdb: pass structure by pointer to debug function + + - avoid copying large parameter value -commit bf90793c358b08c0a6e154c72f49a373847436a2 +commit 95d8d9374a0e4385fd549078fcf56ecadef424a0 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:24 2023 +0100 +Date: Fri Jan 5 21:35:52 2024 +0100 - xmpp: removed trailing spaces + msilo: make static and add prefix to global variables with short name -commit a1f35e58c117d56aa7ac667d887f4b2784500663 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:24 2023 +0100 +commit 4708f537d7f5d28123b48cd89474a4931dd698ad +Author: S-P Chan +Date: Fri Jan 5 20:56:39 2024 +0800 - xlog: removed trailing spaces + outbound: build, fix missing argument name -commit bff73792918dd8bd46ec974b36cf396d4456962e +commit ef45b7b804a3ba79880afd218f6b3f3962c85ed7 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:24 2023 +0100 +Date: Fri Jan 5 11:55:03 2024 +0100 - xhttp_pi: removed trailing spaces + tm: free new uac dlg in case of errors -commit 5d9801f165e3028d7853c8249a3f9ff255df03df -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:24 2023 +0100 +commit 8038fba2dd056193b37a5c2571f2d4d910c47e73 +Author: Xenofon Karamanos +Date: Thu Jan 4 09:53:29 2024 +0000 - xcap_server: removed trailing spaces + pv_core: Fix negative index bug for hfl() + + Before: -1 yielded null and -2 the last element of a header -commit f74093941b37aa272e792433d88ef6c2eec5fab9 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:24 2023 +0100 +commit 1c70775530b1a3a905e8a983610cb0d092b0d240 +Author: S-P Chan +Date: Fri Jan 5 08:09:34 2024 +0800 - xcap_client: removed trailing spaces + tls: thread-local, revert 1a9b0b6361 as double-layer locking is redundant + + - the 2nd lock was put in place as defensive programming for shm contention + - GH #3695: the underlying issue is early init of thread-locals -commit 248f459f95866035cb7a84be5c85c4f88da9858c -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:24 2023 +0100 +commit 798cc26908395d2ba21015684ad6f0ac4f012b2e +Author: S-P Chan +Date: Fri Jan 5 07:38:56 2024 +0800 - utils: removed trailing spaces + tls: OpenSSL 3.x/1.1.1 thread-local, clean-up dead code and preprocessor + blocks -commit 3e4e843d3e488c7f3894a0f1f29ff68d61935ab6 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:24 2023 +0100 +commit 7b531cfe038fae5e3414ac74c4e076c10e32b86c +Author: S-P Chan +Date: Thu Jan 4 21:56:00 2024 +0800 - usrloc: removed trailing spaces + tls: OpenSSL 1.1.1 thread-local, init libssl in thread + + - no need for RAND workaround; default is OpenSSL 1.1.1 RAND + - linux/pthreads will handle forking -commit 658a426bff5f7f5f88c0c1c47abdc90ed0790cb6 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:24 2023 +0100 +commit 7111687e1107261bcdd7a9f8cc90959754c93272 +Author: S-P Chan +Date: Thu Jan 4 21:51:15 2024 +0800 - userblocklist: removed trailing spaces + tls: fix compilation with OpenSSL <= 1.1.1 -commit 480882d9d26df0519e2aab539323d7e8a76ef873 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:24 2023 +0100 +commit 689de2736f5c92f11860e5854ccd95c84239f032 +Author: S-P Chan +Date: Thu Jan 4 21:47:23 2024 +0800 - uri_db: removed trailing spaces + outbound: OpenSSL 1.1.1 thread-local, init libssl in thread -commit 822dd527b2d5aa28f42aa262374fc2b3a19e9059 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:24 2023 +0100 +commit 4742c8131aba878c4fc954e42b656b9d4bafdd24 +Author: S-P Chan +Date: Thu Jan 4 20:11:21 2024 +0800 - uid_avp_db: removed trailing spaces + outbound: OpenSSL 3.x thread-local, init libssl in thread -commit 90698a42a4f75791b09dba213473d411236917f7 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:24 2023 +0100 +commit e49a60e1052c6c1dcebe7f78f2ac970338eabe2e +Author: S-P Chan +Date: Thu Jan 4 20:00:09 2024 +0800 - uac_redirect: removed trailing spaces + tls: OpenSSL 3.x thread-local, init libssl in thread or PROC_SIPINIT + + - avoid initialising ERR_STATE in rank 0(thread#1) -commit be9f359c3ec90a8cd38ae6efba8fb54520b3c147 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +commit aef9cec329893f58b0c7df5aec2050b6c3cecc60 +Author: Morten Tryfoss +Date: Thu Jan 4 13:26:26 2024 +0100 - uac: removed trailing spaces + core: avoid C99 error -commit badbe8f584a5ab49f3fe74791b76d04ddc858ef2 +commit f67bfe4a183b2b629d3ac741ecb95bcc4b669b37 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +Date: Thu Jan 4 12:52:50 2024 +0100 - tm: removed trailing spaces + rtpengine: clang-format file and skip-wrap of exported structures -commit 1bca2bb9893e8ad9bb86b82eb0e1b553d02c6a42 +commit aab734e7a31a9df2dc731e849005ce6bb00d534e Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +Date: Thu Jan 4 12:46:23 2024 +0100 - textops: removed trailing spaces + rtpengine: unsigned error field of 1-bit to prevent signness warnings -commit 895b667f0eefdf036e6ed4abe954df077e535091 +commit ad1365935e2f021095e6e14aca03da54d3862d5b Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +Date: Thu Jan 4 12:20:56 2024 +0100 - stun: removed trailing spaces + kamctl: dbtextdb/dbtextdb_test - do not store unused result of query -commit 1390f3a5e341f99e547bbae23435d28d75b3381f +commit 42b22b6e2d91d907cbf80b499b9e4380def2e652 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +Date: Wed Jan 3 22:18:58 2024 +0100 - statistics: removed trailing spaces + lcr: added module prefix to db_url global variable + + - safety for symbols overlapping -commit 234fc6152198870daa80e6f6fa759441bc0a4ef8 +commit f0fbf4d74b8090614469b2a6a16f187275c4f067 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +Date: Wed Jan 3 22:14:32 2024 +0100 - snmpstats: removed trailing spaces + dmq: rename global variables with short name + + - safety for symbols overlapping -commit 823fc718274052e4fc5f44fe2e36f23f05297000 +commit ae90cb489cd07aac42994fbaa124966a34cd4514 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +Date: Tue Jan 2 16:20:59 2024 +0100 - sms: removed trailing spaces + xhttp_rpc: rename global variable with short name -commit 6c2fdb5a92dd4ac3866ebcb6eb3735e590e8e8e0 +commit b48c566218b15cac62cd1cc9dc838d241de73efd Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +Date: Tue Jan 2 10:41:17 2024 +0100 - sl: removed trailing spaces + p_usrloc: rename global variable with short name -commit e96c95c29d0bf910fb381553402dc6473ad029e0 +commit 4af2452fa9362f4df913003370b0a5279070f372 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +Date: Tue Jan 2 10:24:50 2024 +0100 - sipt: removed trailing spaces + sms: renamed short global variables with common names -commit 19d5dcce0a488a9a3ca14d66578566a19c6f250f +commit 05bcd7a893d2f607943eaa5ab65293e7e273de8d Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +Date: Mon Jan 1 22:23:07 2024 +0100 - sipjson: removed trailing spaces + uac: global variable made static + + - renamed to avoid symbol conflicts -commit 50910357ebd4db4a7748e8ff332616e783c86263 +commit 619c7fe6db9c090ef9645ec8a39d43d00ba215bf Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +Date: Sun Dec 31 14:06:40 2023 +0100 - sipcapture: removed trailing spaces + domainpolicy: removed constant condition -commit eca932f474b90e581eb249870e705cef66227182 +commit 5bbff26ce6e95b841e69f2dffc2214318a748c36 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +Date: Sun Dec 31 09:35:08 2023 +0100 - secfilter: removed trailing spaces + sca: removed if on rc before being set + + - reorder some conditions on range -commit 5b6810bf005eccd45bcb5a5681a63a8a875a9171 +commit 6c129bdc87352d0d883cc46fce0b78444e619084 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +Date: Sun Dec 31 09:22:28 2023 +0100 - seas: removed trailing spaces + ratelimit: removed unnecessary condition -commit 81680ccd9772dc2cb35e9a7b6cd1a404d01a3436 +commit a268f073bc9716fefc35248687d793bdcc6d66b9 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +Date: Sat Dec 30 10:15:04 2023 +0100 - sctp: removed trailing spaces + core: main - typos in log messages -commit 4372616afb2d94b6621252e91291af93759b9f77 +commit 9410ce3848c1ab7fa8b7ded47d090342fd4cf1c0 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +Date: Sat Dec 30 10:05:29 2023 +0100 - sca: removed trailing spaces + core: cfg.y - check limit for shm size -commit 6eca9bfe242bb3fbf93f43e7be2d305d431b6327 +commit b59607bbcf6ca872e190dfcd9abf8fc5c0f64359 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +Date: Sat Dec 30 09:01:21 2023 +0100 - rtpengine: removed trailing spaces + debugger: explicit cast for pointer arithmetic operation -commit 2774836e5324c5163ee4c08ee9f967efe1376599 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +commit 3d2bae3532e496648a902dac853edf013434672f +Author: Kamailio Dev +Date: Fri Dec 29 10:01:51 2023 +0100 - rtp_media_server: removed trailing spaces + modules: readme files regenerated - siputils ... [skip ci] -commit 77028084945bc0a8f74b8d91eb4425e215695f52 +commit 3d6fecc6bc6d52f56d0fdd4e075a15032da91421 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +Date: Fri Dec 29 09:55:33 2023 +0100 - rr: removed trailing spaces + siputils: docs for tel2sip2() function -commit e4991331611f903213cd4151a4528de999c7b8be +commit 366e28627dc7047d4dce2aefe67b5e97b5ae6682 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +Date: Fri Dec 29 09:43:10 2023 +0100 - rls: removed trailing spaces + siputils: added tel2sip2() function + + - based on proposal presented at: + https://github.com/kamailio/kamailio/issues/1173#issuecomment-315198949 + - alternative to tel2sip() which has a simpler approach, but it does not + follow all the RFC requirements. This is still kept as it proved to be + useful over the years + + Co-authored-by: Donald Carr + Co-authored-by: Supreeth Herle -commit 91923f80924fb0787b3fa6bc764f22c6b5167116 +commit 453a8f1e2ae10d765790ddafe92bcaaf7f5b9c32 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +Date: Thu Dec 28 16:44:20 2023 +0100 - ratelimit: removed trailing spaces + pike: renamed short common name global variable -commit bde570b3519766a3f4051301042d3b2f20fbb9f3 +commit a12895208595d966cc3d4ab06358c511d0222031 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +Date: Thu Dec 28 14:25:51 2023 +0100 - qos: removed trailing spaces + pike: use buffer size parameter in pike_top_print_addr() -commit 1d07491dc82154ff9d29a544868f96b55a297f25 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +commit 159282d6bd05b73961037b753e0a9df5ac9cdbe3 +Author: herlesupreeth +Date: Mon Dec 25 12:08:34 2023 +0100 - pv: removed trailing spaces + cdp: add destination realm avp only if not present -commit 205023f9f12b2e5f8fb9ac3ba915040f5352ac95 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +commit 7b9e90e06f95b4192fb40ed2c4854a8554fac45b +Author: herlesupreeth +Date: Sun Dec 24 21:33:52 2023 +0100 - pua_xmpp: removed trailing spaces + cdp: fix disabled parts for openssl version newer than 1.1.0 -commit 3c4853e70f52973934b111921c9d17752974e5a2 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +commit 61d91d7a684df73a328c3062653522a7439d4d61 +Author: herlesupreeth +Date: Mon Dec 25 11:11:56 2023 +0100 - pua: removed trailing spaces + smsops: fix utf8 to ucs2 conversion -commit 9d0a2efb4aa588ffea385a9fd8b0309a75d93d1e -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:23 2023 +0100 +commit 75de09f369abad7192c853e74c99741feadec619 +Author: herlesupreeth +Date: Sun Dec 24 13:46:07 2023 +0100 - presence: removed trailing spaces + ims_ipsec_pcscf: reset destination URI after value is used to decide destination protocol to use -commit 486502bef65a768204f07f00c9a5b7887e167a61 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 +commit 2d00ce546bb0852dc1784d5bc2e794d06f919577 +Author: Dennis Yurasov +Date: Wed Dec 20 16:11:56 2023 +0300 - pipelimit: removed trailing spaces + dialog: fixed saving dialogs on shutdown that are already loaded at startup when using db_mode 3 + + - The dialogs that loaded at startup are not saved in DB on shutdown, and so not loaded at restart, + fixes issue #3669 -commit 2cff99ee3e97e4574a03703c073d8cc8933bc18c -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 +commit c5237830f3e7fbeec403a0190471a066081c1117 +Author: Nikolay Ivanuschak +Date: Mon Dec 18 22:20:50 2023 +0300 - peering: removed trailing spaces + core: fixed haproxy protocol parser + + fixes GH #3683 -commit d99c35042da398f6bfab5de1195fcef686626244 +commit 23a1d06737fa6d2509b6f88574ad171aa32cf275 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 +Date: Wed Dec 27 20:20:59 2023 +0100 - pdt: removed trailing spaces + dialog: rename function parameter to avoid shadowing of global variable -commit cb56620c455a5437bc6c8ceaa64b8660abb7dda7 +commit 4b862326cce4b16154353d393d60c8f12762da86 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 +Date: Wed Dec 27 12:09:26 2023 +0100 - pdb: removed trailing spaces + timer: rename local variable to avoid shadowing global -commit e863e819d78803621781e40e9b95166b8ca0c5c3 +commit 9c72487cc5a54d7599e2904251133fc8cc29ed84 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 +Date: Tue Dec 26 18:02:40 2023 +0100 - p_usrloc: removed trailing spaces + sipcature: rename global variable to avoid shadowing by function parameter -commit 9496877a55529640d5cfff7dd6acd0bd59ac0c5c +commit 0186246fce8f0e4bb46b30c05174983cd957a3ba Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 +Date: Tue Dec 26 17:51:48 2023 +0100 - osp: removed trailing spaces + statsd: use bool type for local variable to match return of function -commit 60b53e5507a07e7f53f594c2fcedea3bd06f9041 +commit 934a5dd1347c7b54a2d5e4437e1d3ab581f90596 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 +Date: Tue Dec 26 17:42:48 2023 +0100 - ndb_mongodb: removed trailing spaces + xhttp_prom: renamed global ctx variable + + - avoid short name code scanner warning and shadowing with function + parameter -commit fd86836d96fdb60c8caca140e485a8b6a0fd578e +commit dde74dc1d3413bc677813502aa71d727cbe1e981 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 +Date: Tue Dec 26 17:11:34 2023 +0100 - msilo: removed trailing spaces + tm: remove redundant check in if condition + + - else branch is already for >= 200 -commit 9c258d49ef0e18df62e19b24df3c590653089c74 +commit 09318b6d0f224cace31d7db925f792b66cefd469 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 +Date: Tue Dec 26 14:35:05 2023 +0100 - mqtt: removed trailing spaces + seas: if expression on else not needed + + - evaluation of it is true on else branch -commit edec677972f56ceb72e779c70cb480692f0819fb +commit 440a9955b4ce21b8c3dae9d6159d24a92ec28e7c Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 +Date: Mon Dec 25 22:12:24 2023 +0100 - misc_radius: removed trailing spaces + ss7ops: adapt if expression for uint + + - equal 0 or less than 1 is same in this case -commit 2545b464970565c79d97e9ceb43c24b2d2e2192c -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 +commit 439d451ab3172c1a22f88fd4ba0756ede2318191 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Dec 25 21:41:49 2023 +0000 - mediaproxy: removed trailing spaces + github: [skip ci]: bump tj-actions/changed-files from 40 to 41 + + Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 40 to 41. + - [Release notes](https://github.com/tj-actions/changed-files/releases) + - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) + - [Commits](https://github.com/tj-actions/changed-files/compare/v40...v41) + + --- + updated-dependencies: + - dependency-name: tj-actions/changed-files + dependency-type: direct:production + update-type: version-update:semver-major + ... + + Signed-off-by: dependabot[bot] -commit 5f4c83d373664f11dc6d22fc0a7b8feb946f537e +commit 973803b0a3944b9de7ebdc4366b23e933e66ffbe Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 +Date: Sun Dec 24 19:59:52 2023 +0100 - mangler: removed trailing spaces + pkg/obs: removed auth_identity modules -commit 424f4ef87b096b407dbd8341734eca41b8380bad +commit 8a07c21b45d8afd0a0b84c09bbac6361a0f979d3 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 +Date: Sun Dec 24 17:23:55 2023 +0100 - lost: removed trailing spaces + pkg/alpine: removed auth_identity module -commit 4a49c517bf704c9f352440b6c02aac0f015c97a1 +commit 3bdc56654874b7e94e7052823714440b6457a100 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 +Date: Sun Dec 24 17:21:57 2023 +0100 - ldap: removed trailing spaces + Makefile.groups: removed auth_identity module + + - relocated to kamailio-archive repository -commit 136e9714c66e7c2f9824b768f05f6afeeba9cd9c +commit 5192e5d275761ccd1af49d4bf9dd12e1438947b7 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 +Date: Sun Dec 24 12:20:57 2023 +0100 - lcr: removed trailing spaces + tmx: rework cleaning up on init failure -commit 9ecc0a5a91934d21c5d8ef1db654198bed386f2c +commit 1b959ead18fc8d7d55b1abe6f03fa3f849b57385 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 +Date: Sat Dec 23 17:20:40 2023 +0100 - kazoo: removed trailing spaces + auth_identity: module relocated to kamailio-archive repository + + - module is considered obsolete, not maintained + - based on precursor specs of stir/shaken, not actually deployed in + production by carriers + - located now at: + https://github.com/kamailio/kamailio-archive/tree/main/src/modules/auth_identity -commit cd77d7063e19f64da38fa7904abb1bb7b3f81e3e +commit 904a718d15e4a83d752b6d2f0fa692fb10cda4b4 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 +Date: Fri Dec 22 15:10:51 2023 +0100 - kafka: removed trailing spaces + sms: define size and check lenght for sender and ascii fields -commit 8b8c00e9102ad4c58ee7f27040a953ff7ba2396a +commit 1f5444fd2e25d227ffd70f1087d057a3b8002558 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 - - ipops: removed trailing spaces +Date: Fri Dec 22 14:50:59 2023 +0100 -commit dd459bcb71f67c1703c559d04d7e4c6991635a77 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 + tm: make lookup event_route[tm:local-response] only once + + - related to issue #3064 and PR #3687 - ims_usrloc_scscf: removed trailing spaces +commit 61efad28eeb84d8b8f80fe7fd38d7bbb634717f4 +Author: Victor Seva +Date: Fri Dec 22 10:02:45 2023 +0100 -commit 07e0fddceafd33aefc58b679dbde68c62fdfd934 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 + seas: fix build warning + + > CC (gcc) [M seas.so] encode_contact.o + > encode_allow.c:40: warning: "_GNU_SOURCE" redefined + > 40 | #define _GNU_SOURCE + > | + > : note: this is the location of the previous definition - ims_usrloc_pcscf: removed trailing spaces +commit 90df744978ee2a83700d36ef88161f00b2220acb +Author: Victor Seva +Date: Fri Dec 22 10:00:32 2023 +0100 -commit 6fb92096e933b5683ab06a12836a93aa88d9ab42 -Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 + pv: fix build warning + + > CC (gcc) [M pv.so] pv_xavp.o + > pv_core.c: In function 'pv_get_cnt': + > pv_core.c:2841:61: warning: 'ravp' may be used uninitialized [-Wmaybe-uninitialized] + > 2841 | if(ravp && ravp->val.type == SR_XTYPE_XAVP) { + > | ~~~~~~~~~^~~~~ + > pv_core.c:2776:36: note: 'ravp' was declared here + > 2776 | sr_xavp_t *ravp, *sub_avp; + > | ^~~~ + +commit 86c57ef77848513e3224c73a6d2889e8a2bd6fc3 +Author: Victor Seva +Date: Fri Dec 22 09:58:39 2023 +0100 + + db_text: fix build warning + + > CC (gcc) [M db_text.so] dbt_raw_query.o + > dbt_raw_query.c:23: warning: "_GNU_SOURCE" redefined + > 23 | #define _GNU_SOURCE + > | + > : note: this is the location of the previous definition + +commit 8bfd6580533b6d6005cd257632a5c0e575f75e39 +Author: Victor Seva +Date: Fri Dec 22 09:57:25 2023 +0100 + + cfgt: fix build warning + + > CC (gcc) [M cfgt.so] cfgt_mod.o + > cfgt_int.c:22: warning: "_GNU_SOURCE" redefined + > 22 | #define _GNU_SOURCE + > | + > : note: this is the location of the previous definition + +commit 7562aed2b1c33942b508c6cae9aa7db5ab75196e +Author: Victor Seva +Date: Fri Dec 22 09:56:08 2023 +0100 + + benchmark: fix build warning + + > CC (gcc) [M benchmark.so] benchmark.o + > benchmark.c:41: warning: "_GNU_SOURCE" redefined + > 41 | #define _GNU_SOURCE + > | + > : note: this is the location of the previous definition + +commit c413392a3bae1efdc40671b11da83bec173caff5 +Author: Victor Seva +Date: Fri Dec 22 09:53:16 2023 +0100 + + jansson: fix build warning + + > CC (gcc) [M jansson.so] jansson_utils.o + > jansson_utils.c:23: warning: "_GNU_SOURCE" redefined + > 23 | #define _GNU_SOURCE + > | + > : note: this is the location of the previous definition + +commit 9d4d9c0afce10d00f65eccb3c9bfd3c508bac336 +Author: Victor Seva +Date: Fri Dec 22 09:51:28 2023 +0100 + + auth_identity: fix build warning + + > CC (gcc) [M auth_identity.so] auth_dynstr.o + > auth_crypt.c:29: warning: "_GNU_SOURCE" redefined + > 29 | #define _GNU_SOURCE + > | + > : note: this is the location of the previous definition + +commit 84f6ca9b453b33dba321c11e12a0ebc0b9b8dab4 +Author: Victor Seva +Date: Fri Dec 22 09:49:43 2023 +0100 + + main: fix build warning + + > CC (gcc) [kamailio] core/atomic_ops.o + > main.c:34: warning: "_GNU_SOURCE" redefined + > 34 | #define _GNU_SOURCE + > | + > : note: this is the location of the previous definition + +commit 5ebe1758fb3ff03e3a035e7121f40e2539eb2c9c +Author: Victor Seva +Date: Fri Dec 22 09:32:10 2023 +0100 + + ims_qos: fix build warning + + > CC (gcc) [M ims_qos.so] rx_avp.o + > [...] + > /usr/include/fortify/stdio.h:122:16: warning: 'int_port_rctp_a' may be used uninitialized [-Wmaybe-uninitialized] + > [...] + > /usr/include/fortify/stdio.h:122:16: warning: 'int_port_rctp_b' may be used uninitialized [-Wmaybe-uninitialized] + +commit 59dc9b1ba93d4e6a06f87deabf136787a3ab1cf1 +Author: Victor Seva +Date: Fri Dec 22 09:19:50 2023 +0100 + + core: fix build warning + + > core/parser/parse_diversion.c: In function 'parse_diversion_body': core/parser/parse_diversion.c:60:18: warning: the comparison will always evaluate as 'false' for the address of 'uri_b' will never be NULL [-Waddress] + > 60 | if(uri_b == NULL) { + > | ^~ + > core/parser/parse_diversion.c:51:26: note: 'uri_b' declared here + > 51 | static to_body_t uri_b[NUM_DIVERSION_BODIES]; /* + > Temporary storage */ + > | + +commit ed0f2e77b80a2719957b1ac43a96dfc57b88f98e +Author: Victor Seva +Date: Fri Dec 22 09:13:28 2023 +0100 + + pkg/kamailio/alpine: remove app_sqlang module [skip ci] + + module was moved to kamailio-archive repository + +commit 268147a7a7bcf68689a913a94faecc87128187fb +Author: Victor Seva +Date: Fri Dec 22 09:00:08 2023 +0100 + + core: fix build warning + + > CC (gcc) [M jansson.so] jansson_utils.o + > jansson_utils.c:23: warning: "_GNU_SOURCE" redefined + > 23 | #define _GNU_SOURCE + > | + > : note: this is the location of the previous definition + +commit ca4509013a123f02d6d9c09d016fce3fea3e3dbe +Author: Victor Seva +Date: Fri Dec 22 08:51:39 2023 +0100 + + ndb_redis: replace use of grep -P + + PCRE option is been removed in BusyBox #3686 - ims_registrar_scscf: removed trailing spaces +commit 163028549df3abd3173a7c0ac8a9dc666c0e4879 +Author: Victor Seva +Date: Fri Dec 22 08:48:21 2023 +0100 + + db_redis: replace use of grep -P + + PCRE option is been removed in BusyBox #3686 + +commit 4c93985437122706bc68143b2f96a9d7f35be16d +Author: Henning Westerholt +Date: Thu Dec 21 16:08:32 2023 +0000 + + pua: fix possible copy/paste error, we should use reginfo_increase_version for reginfo events (GH #3234) -commit 8b3c6d12e514fdac2c9d6219e9ab2a8ca3e47af8 +commit ac4fa1129f5fbd1a48aad1b7dc21a2c130ecd164 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 +Date: Thu Dec 21 16:05:04 2023 +0100 - ims_registrar_pcscf: removed trailing spaces + tmx: use unsigned for bitwise operations -commit fa88db98cca078a4587bcba101343331bff4d590 +commit 4399fe3966f6774b18e02ea6e54a5ba132c7c4ab Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 +Date: Thu Dec 21 13:56:28 2023 +0100 + + sms: define buffer size for name field + + - check size before copy and trucate large messages + +commit b2045d559ed720789df80f543fc00923a07ada83 +Author: Henning Westerholt +Date: Thu Dec 21 11:54:52 2023 +0000 + + pv: remove another redunant variable definition related commit 8ed4165fd3b0a33 + +commit 0547a4becbc6a48fdc473cfd26cdeedfa2a9317d +Author: Henning Westerholt +Date: Thu Dec 21 11:34:14 2023 +0000 + + pv: remove another redunant variable definition (warning: unused variable ‘innerIndex’) + +commit 8ed4165fd3b0a331a4580894e2e7f83456b474fa +Author: Henning Westerholt +Date: Thu Dec 21 11:23:51 2023 +0000 - ims_qos: removed trailing spaces + pv: remove redunant variable definition (warning: unused variable ‘innerIndex’) -commit 714582b6771656534de9337615e1ff7a73a5ab9a +commit 64e4288217d4a9dd2441687b56f5dbd02b8549f4 +Author: Federico Cabiddu +Date: Wed Dec 20 10:44:40 2023 +0100 + + Makefile.groups: add dlgs and sworker to extra modules + +commit 9bb1976b4b7d52542a4de37144194bfc24649222 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:22 2023 +0100 +Date: Wed Dec 20 10:06:59 2023 +0100 - ims_ocs: removed trailing spaces + Makefile.groups: removed app_sqlang from modules list -commit 26afc34239fa7c2009f94f251118d47a6290f378 +commit bab926d0b3eb69b5f15e9a49fdc52c937e164612 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Wed Dec 20 10:04:24 2023 +0100 - ims_isc: removed trailing spaces + app_sqlang: module relocated to kamailio-archive repository + + - module is considered obsolete, not maintained + - app_jsdt should be considered a better alternative, or app_lua, + app_python3/s + - located now at: + https://github.com/kamailio/kamailio-archive/tree/main/src/modules/app_sqlang -commit 2047a0ce41205770c3baee61dc03fb57bd3f4862 +commit 943ff442d85a041ba0285cc494ce0697f4dbae59 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Wed Dec 20 09:36:57 2023 +0100 - ims_icscf: removed trailing spaces + pipelimit: reformat exported structures -commit 9e30f63831515215c3e77ab3987cdc1166d6b73a +commit 5e1f8e6c93dae914665b2e97b38e8a3a0673d1f2 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Wed Dec 20 09:33:17 2023 +0100 - ims_diameter_server: removed trailing spaces + pipelimit: renamed global variable with module prefix + + - avoid overlapping global symbols -commit 2d013875ca515220864878453a62baafe307e582 +commit 17e9e3f447867e34b8f320b8b93189f01fbc3f77 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Wed Dec 20 09:30:01 2023 +0100 - ims_dialog: removed trailing spaces + sipcapture: removed unused global variable + + - renamed local function variable that was conflicting -commit 190bc9a3e9a80eb3834d84ef1e0920b04c0f6710 +commit 1068bbbf9a7f2bf96d9ee2cefa1b81fbabac9805 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Tue Dec 19 21:18:03 2023 +0100 - ims_charging: removed trailing spaces + README.md: remove irc reference -commit e065656d73a206bc95476831bfc5d50ab63df0d4 +commit f036333b756c1021545e70871024561089954a56 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Tue Dec 19 10:50:56 2023 +0100 - ims_auth: removed trailing spaces + ims_dialog: refactored kemi get/set profile functions + + - expect final string values in the parameters, not with + kamailio-specific variables, they can conflict in the external + scripting languages and also leak pkg memory -commit 1a064f2291acbc10b64c5a225e90223b0b81ecdc +commit 19152caf44360eae533508ecd6f3f9e33af14fb7 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Tue Dec 19 09:53:34 2023 +0100 - imc: removed trailing spaces + ims_dialog: reformat exported structures -commit abfc3308cb7439f433cd78fd8dedbedf560a9605 +commit 19572a828ffeb08b190dab5ae4aee93f03d9a7f2 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Tue Dec 19 08:21:10 2023 +0100 + + tm: clearer reply code handling for uac dlg - http_client: removed trailing spaces +commit 68f653bfc66d8f4ff2e11f5fc9348f4d2632fe8b +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Dec 18 21:31:57 2023 +0000 + + github: [skip ci]: bump actions/upload-artifact from 3 to 4 + + Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3 to 4. + - [Release notes](https://github.com/actions/upload-artifact/releases) + - [Commits](https://github.com/actions/upload-artifact/compare/v3...v4) + + --- + updated-dependencies: + - dependency-name: actions/upload-artifact + dependency-type: direct:production + update-type: version-update:semver-major + ... + + Signed-off-by: dependabot[bot] + +commit b2f1cd6ed2cd5da84fe8ff48db688fc41f129ccb +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Dec 18 21:31:53 2023 +0000 + + github: [skip ci]: bump github/codeql-action from 2 to 3 + + Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2 to 3. + - [Release notes](https://github.com/github/codeql-action/releases) + - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) + - [Commits](https://github.com/github/codeql-action/compare/v2...v3) + + --- + updated-dependencies: + - dependency-name: github/codeql-action + dependency-type: direct:production + update-type: version-update:semver-major + ... + + Signed-off-by: dependabot[bot] -commit 48224395fb5f8d62b79fa93af25b740a43b7f71d +commit 0e5b8178de281db5ddfe30af28244a1ebaf12382 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Mon Dec 18 14:06:49 2023 +0100 - htable: removed trailing spaces + msilo: remove redundant condition -commit 24192fe8e437172b5a8c93ace02a0179c140cb93 +commit 2f43510be37c157f800389dfb432b6c52d7435a7 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Mon Dec 18 12:31:34 2023 +0100 - h350: removed trailing spaces + pv: removed unnecessary condition -commit 1e78e0fc7d8caa0ba421e54ac109b7d982606d98 +commit ca2a9479adf720e67bf50c9d2795cc8937e223dc Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Mon Dec 18 12:22:25 2023 +0100 - group: removed trailing spaces + pv: typo in transformation log message -commit 3c3d3170c0b486e7f27ea393b3c66738aea6c9f9 +commit f128db2b85a525ff82c28faffbeec3203f9560c3 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Sun Dec 17 22:16:05 2023 +0100 - enum: removed trailing spaces + tm: use coherent type int for tm route blocks indexes -commit fc52b07712a24fa5e7ff63b7db44546fc90db51d +commit 678b1a68de86d9539adeaf0262d9735b8d435077 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Sat Dec 16 20:04:08 2023 +0100 - drouting: removed trailing spaces + core: srjson - init vars and check scanned values -commit a4a735896cbeeef266bd995537d987e70dcd6830 +commit 586ddc6ed3a2b757ad55fb9eb859945b279c415c Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Fri Dec 15 21:18:19 2023 +0100 - domainpolicy: removed trailing spaces + presence_xml: check for number of read values -commit 4be77ba816e21820a21b2b643bb995dc234bd54a +commit 68940cc09c999621b1f9a765e190b3207728106e Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Fri Dec 15 12:19:25 2023 +0100 - domain: removed trailing spaces + seas: use same type iterator to avoid risk of overflow -commit e3fd4ab1e166fb7918292f7cf2d4ce254c13486f +commit 2bebff2b27acd8ffa9f9d22409c197b0f0bc168e Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Thu Dec 14 21:17:08 2023 +0100 - dmq: removed trailing spaces + sms: rework truncating long messages -commit d525729cf510d6a76507961ebc2eadbfe095c9f0 +commit 431b80a1b8313d7457d4bf5fa1770f9465820d39 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Thu Dec 14 19:52:23 2023 +0100 - diversion: removed trailing spaces + sms: define size for buffers and check the length on copy -commit 28efbbca7b8f5f0add544a44fd1f01e91ae2e032 +commit a78aeebd66ec63810987555d5bb492fec1979fc8 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Wed Dec 13 12:52:40 2023 +0100 - dispatcher: removed trailing spaces + smsops: check returned value -commit b731d163623775dbbcb2138cac8bb7e0a3bdfbb7 +commit 49b3b90cd229b7c4da06b61cdfd782450d383cc9 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Wed Dec 13 12:23:23 2023 +0100 - dialplan: removed trailing spaces + app_python3: check allocated pointer -commit 8ddc04df5644cf1d7796908792ecf4bf787c8167 +commit 077651fa3bfd50e0f654c907f3783b1421497bd5 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Wed Dec 13 12:15:28 2023 +0100 - dialog: removed trailing spaces + core: check if conversion could not be done -commit 147467ec18b1136838fe816d610a6c75cfd6b425 +commit 5d641f56fc1bc342d9be008ecd96959e114fef66 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Wed Dec 13 12:08:56 2023 +0100 - db_unixodbc: removed trailing spaces + registrar: check returned branch pointer -commit 140a047913a011eb5cf234537834cbc0ac16b89e +commit 1191ab4e5e03b35714ec1ad9d9bf2dd9665c71fd Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Wed Dec 13 12:02:01 2023 +0100 - db_text: removed trailing spaces + tm: check get_t() result for consistency -commit 0e99a0032335423b065cb5134e6f49f7730d0203 +commit 4e2edcb0acdac56a9c5946525e427cdd44d0289e Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Wed Dec 13 11:38:48 2023 +0100 - db_postgres: removed trailing spaces + sipcapture: signed iterator to cover negative condition -commit 9f93367efc1ef4e9383f63f849fd06f86c7e0741 +commit cae0f9a1302a79d748155401117e934a5a8e272f Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:21 2023 +0100 +Date: Wed Dec 13 11:24:24 2023 +0100 + + ratelimit: reorder for safer storage size - db_perlvdb: removed trailing spaces +commit aaeb54c8b630b4aac50df75ff430ad5baea6746c +Author: Victor Seva +Date: Tue Dec 12 15:38:33 2023 +0100 + + pkg/kamailio/deb: override lintian error on stretch [skip ci] -commit 34b41718a30d2d067a85ec2170598bfaacd719c0 +commit 3fe9a279abecf6f367ce9fd2d4b085c41c87ad77 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:20 2023 +0100 +Date: Tue Dec 12 13:08:18 2023 +0100 + + pv: remove extra len increment for some uri transformations + +commit 185e7f64668cf4e8de3fa83d482e02e90b4fd3e5 +Author: Sergey Safarov +Date: Sun May 21 07:02:17 2023 +0000 + + kazoo: fixed rabbitmq-c deprecation warning + +commit 1b589c2070973ace082205dc0985363570c5b7f6 +Author: Sergey Safarov +Date: Sun May 21 07:06:54 2023 +0000 - db_mongodb: removed trailing spaces + rabbitmq: fixed rabbitmq-c deprecation warning -commit debc999572386df0350c2fe50a19068d02454894 +commit 071f3f8fd1ffd85d872f6048db4750bbf6441cf3 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:20 2023 +0100 +Date: Tue Dec 12 12:33:10 2023 +0100 - db_flatstore: removed trailing spaces + ratelimit: init variables and check return of fscanf() -commit 8f0270245c38cc7ca91b7d3fe1cc3dc29efbb773 +commit ecf5ce88a2de9a2f28b87e1f9a0303e59870c1f7 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:20 2023 +0100 +Date: Tue Dec 12 11:40:23 2023 +0100 - db_cassandra: removed trailing spaces + nat_traversal: init variables read from string -commit e7cedacbb35a4684347bf6ff33672994c6738d7c +commit 9cd07110ed59058de27c077574e4a740df068485 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:20 2023 +0100 +Date: Tue Dec 12 11:24:44 2023 +0100 + + presence_dialoginfo: check return for sscanf() + +commit 8d3d53f5f698da1357c3475ae136677099b2f702 +Author: Sean Bright +Date: Mon Dec 11 10:21:20 2023 -0500 + + utils: Prefer `printf` over `echo -e`. + + On Ubuntu, `/bin/sh` defaults to `dash` whose built-in `echo` command + does not support the `-e` flag. `printf`, on the other hand, supports + backslash escapes by default so we use that instead. + + In passing, also clean up some messy ANSI escape codes. + +commit 14e763fd15a846d4377214521cac06113ba6888d +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Dec 11 21:04:57 2023 +0000 + + github: [skip ci]: bump actions/stale from 8 to 9 + + Bumps [actions/stale](https://github.com/actions/stale) from 8 to 9. + - [Release notes](https://github.com/actions/stale/releases) + - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) + - [Commits](https://github.com/actions/stale/compare/v8...v9) + + --- + updated-dependencies: + - dependency-name: actions/stale + dependency-type: direct:production + update-type: version-update:semver-major + ... + + Signed-off-by: dependabot[bot] + +commit ee2ad77aa71326d355e299625ebbd31f67f8ed20 +Author: Kamailio Dev +Date: Mon Dec 11 17:17:05 2023 +0100 - db_berkeley: removed trailing spaces + modules: readme files regenerated - jsonrpcs ... [skip ci] -commit 10d1e054e3f5da6f9f23258ce6215bcd27a817a9 +commit af49deacad22b9f2d6502649002d51ad2423f005 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:20 2023 +0100 +Date: Mon Dec 11 17:08:08 2023 +0100 - db2_ops: removed trailing spaces + jsonrpcs: doc - fix example for tcp_socket parameter -commit 692fd5baad162a583755b74110a905f32b6dbf17 +commit 7eb96925c4bb4664cce589050dff3e1c8b98b6f0 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:20 2023 +0100 +Date: Mon Dec 11 15:51:01 2023 +0100 - db2_ldap: removed trailing spaces + siptrace: check sscan() return value -commit 7210a362cab0fe8408b65911c6a64f67f5a560ac +commit 1b7ea63df655246b5b6ca123d9ed25d1764d9402 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:20 2023 +0100 +Date: Mon Dec 11 15:37:26 2023 +0100 - ctl: removed trailing spaces + core: main - check limit for values of -m and -M -commit febac66bd7ca5f129a1fb8b79b1f55e9eea9863f +commit 75a7d0d8b1340d292aba9b589263619f5a6e11c1 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:20 2023 +0100 +Date: Mon Dec 11 14:19:04 2023 +0100 - cplc: removed trailing spaces + core: route struct - use helper macro to get action address -commit 088fcb6043ed6ddd6ee761ab5a42476817dc89a4 +commit 9c336764f567c873e25792efd813be1806d215d3 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:20 2023 +0100 +Date: Mon Dec 11 13:01:18 2023 +0100 - counters: removed trailing spaces + core: cast to variable type action_u_t* -commit 79fe5addf240de08253f9ed4b53171f7ea559c4f +commit 6aa967eb82fa9092f0a32101e44798e4d66fc708 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:20 2023 +0100 +Date: Mon Dec 11 12:54:25 2023 +0100 - cdp_avp: removed trailing spaces + debugger: updated dbg_fixup_get_action() to use helper macro for structure address -commit 56aef00fb90433b5a9782ba93e41f54683d3faa1 +commit 1b81cbc9f79354aae604e33ac978dece95c0326c Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:20 2023 +0100 +Date: Sun Dec 10 20:25:54 2023 +0100 - carrierroute: removed trailing spaces + tm: use helper macro to get structure address from member -commit c957415a1f603dcbb11018c24515bbf0a7c040c1 +commit ad2e976d9200bd68c88e4a78edc0d250ba4045ba Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:20 2023 +0100 +Date: Sun Dec 10 19:31:54 2023 +0100 - benchmark: removed trailing spaces + core: helper macro to get enclosing struture from a member address -commit 8e05ac373a7b6fc39cbf206b57475516ff0f9c7e +commit 9db18bc48bff0d230e66973a45c8e72e1b7744e8 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:20 2023 +0100 +Date: Sat Dec 9 20:07:37 2023 +0100 - auth_radius: removed trailing spaces + dialog: check first the size -commit ab68b024b0bd20b5917df070198358a999f39079 +commit e614575d53f5e3b7d3a4796a445728f862e60916 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:20 2023 +0100 +Date: Sat Dec 9 19:53:46 2023 +0100 - auth_ephemeral: removed trailing spaces + sca: check return for snprintf() -commit b825adb9884b37fdcf5cd7d87470bff42af36be8 +commit 804ee651b45498727196886c97cb55d20b254c4a Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:20 2023 +0100 +Date: Fri Dec 8 22:10:36 2023 +0100 - auth_diameter: removed trailing spaces + core: parse privacy recompute lenght of rest to parse -commit 7387e5c32006c13137a35706b72e52d0c8fe38c7 +commit 5d97afefd2a8f53072a36b6eb8927c180fb984c9 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:20 2023 +0100 +Date: Fri Dec 8 16:23:03 2023 +0100 - auth_db: removed trailing spaces + core: xavp - info long when skipping serializing a field -commit 6ed407b87e6b7f712b4e1d95d660b4ee67a6139d +commit 1a9b0b63617afebcee2aecb3b2240d7684ecabc2 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:20 2023 +0100 +Date: Fri Dec 8 12:34:56 2023 +0100 - app_python3: removed trailing spaces + tls: init early the local lock for memory + + - needed to done before mod param init_mode is set + - runtime uses the modparam to do lock/unlock + - #3668 -commit a9a84fdfb466639a855b124529eba37648aa1d2c +commit 73536c5fe93f6f4e41eb92de29d054a0ac38536b Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:20 2023 +0100 +Date: Fri Dec 8 12:21:40 2023 +0100 - app_python: removed trailing spaces + core: msg translator - consider af from advertise structure -commit 45d6fb83aa5cf1835bd4add729b4ef1595c46b22 +commit 59592e0499fbb61ec701a1d7901c357ff5ebc4a4 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:20 2023 +0100 +Date: Fri Dec 8 11:53:45 2023 +0100 - app_perl: removed trailing spaces + core: consider af from advertise structure to build recv socket uri -commit 4b24af914dd5385addf4b4f4a14846eb641c803c +commit faf24134a00c1b15933f22e8e7702ec8e0dba35d Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:20 2023 +0100 +Date: Fri Dec 8 11:43:02 2023 +0100 - app_jsdt: removed trailing spaces + core: keep address family indication in advertised structure -commit 768ec252de7f4e6e82e9982ead690264ae20b5e1 +commit 975bbde5aa0fd4c2ef4063d906e125911d162ed6 Author: Daniel-Constantin Mierla -Date: Mon Nov 13 16:22:20 2023 +0100 +Date: Fri Dec 8 11:36:32 2023 +0100 - app_java: removed trailing spaces + core: use advertise proto when building get_rcv_socket_uri() -commit 60abd912f0fc2e237fb833d63250c184e7401ae5 -Author: Kamailio Dev -Date: Mon Nov 13 13:32:50 2023 +0100 +commit b02a38e66d3bd198e75103727130906b2ff9786c +Author: Xenofon Karamanos +Date: Fri Dec 8 11:04:27 2023 +0100 - modules: readme files regenerated - modules ... [skip ci] + pv: support for Diversion header in $hfl() and $hflc() -commit 94a6bc8fe6fb4dc5599584de1128dbb83d3dc128 -Author: Henning Westerholt -Date: Fri Nov 10 14:01:47 2023 +0000 +commit ced8d46eddb2bda614eaace98437b7dab2d123e3 +Author: Xenofon Karamanos +Date: Fri Dec 8 11:01:39 2023 +0100 - kamailio.cfg: use xalert instead of old format for xlog, similar as done in other cfg places + core: parser extended to handle diversion with multiple bodies - (cherry picked from commit 2b9666445a9fd31f75bf86b9924658daffb7ac85) + - similar to PAI and PPI -commit 40f5343d4ca2b4c1cf76eaf168a9b1ae4a722a6a +commit 6d14b4e439aec3d046addfa776a4be5f471a33f0 Author: Daniel-Constantin Mierla -Date: Fri Nov 10 07:31:38 2023 +0100 +Date: Fri Dec 8 10:20:14 2023 +0100 - app_python3: enable error log mode for some of missing callback functions - - - tm-specific callbacks should trigger error log messages if not found + lib/srdb1: rework store of long long values as number if value fits - (cherry picked from commit 695dc54dc1547fdee18b00cfa8e4d15f047834a5) + - GH #2106 -commit 64f28c7f1fd83719270d914e5368bffbfab09f78 -Author: Daniel-Constantin Mierla -Date: Thu Nov 9 15:32:39 2023 +0100 +commit c79f28b11f2683d11aafa72427efb15c95196b8b +Author: Xenofon Karamanos +Date: Wed Nov 22 15:01:23 2023 +0000 - dialog: use memcpy to fill profile uid + pv: Add PPI and PAI support to hfl and hflc + +commit 10519d199f6cac116399f4473bd82f2b08de72ba +Author: Péter Barabás +Date: Wed Dec 6 21:16:46 2023 +0100 + + uac: fix socket length settings - (cherry picked from commit 7bdd7fb4aa666b5f56ae3e554770126ad5b68c2e) + - set _uac_req.s_sock.len value to 0 in pv_set_uac_req() method in case of "all" case + - change setting of _uac_req.s_apasswd.len to _uac_req.s_sock.len in pv_set_uac_req() method in case of "sock" case -commit 9f417ee284fd1829c849061aae6b4d0231a0acca +commit 4b068f49b618dca5fa85a1687bd9054c1d98ae6a Author: Daniel-Constantin Mierla -Date: Thu Nov 9 14:54:13 2023 +0100 +Date: Thu Dec 7 13:00:50 2023 +0100 - imc: coverted some static global str variables to macros + tls: rework init mode 1 to set PTHREAD_PROCESS_SHARED - (cherry picked from commit 36806bea261f7a29dc1d2a8aedac837a06043968) + - pthread mutex set in shm + - GH #3635 -commit 42aae6920883e9633ba36b41b235ce26ffa13664 +commit 964c21e16ab4da96d989c230ea18d95872257394 Author: Victor Seva -Date: Wed Nov 8 20:53:53 2023 +0100 +Date: Thu Dec 7 11:41:44 2023 +0100 - dialplan: reformat exported structures more human friendly - - revert to the format it had before 01d0d1de2c8 + pv_headers: rearrange module parameters - (cherry picked from commit 6aa940f7acbc565545ae9199b288d16a50bafcab) + * pvh_ prefix for global variables -commit 88ad50d71fe7da01ae4619cdb14d5119b9e286eb -Author: Victor Seva -Date: Wed Nov 8 20:03:49 2023 +0100 +commit 890dc5f017084481cd2b0f0d759939393fa115bc +Author: Daniel-Constantin Mierla +Date: Thu Dec 7 08:21:22 2023 +0100 - debugger: reformat exported structures more human friendly - - revert to the format it had before 656e147c470 - - (cherry picked from commit 4642a12c109939f71f91ba7807ded1491e241e26) + ims_charging: free local structure in case of errors -commit c7290d0ef8f030ae851581ba436a10177d874858 +commit 8794e509b951658e055cc06374c0e2561debdde3 Author: Daniel-Constantin Mierla -Date: Wed Nov 8 18:44:58 2023 +0100 +Date: Wed Dec 6 10:45:10 2023 +0100 - core: utils/srjson - use snprintf() for silenting analyzers - - (cherry picked from commit a62d7118a2f86a82fd080ed4a89a0833e8c4d1a2) + core: tcp - set type for literals usef for time difference -commit 7f1ec26fbf59edc6c771da6104344d61cb6d031c +commit 8ca5d90a44166bf1a501680b2e01dfbbab5f5b94 Author: Victor Seva -Date: Wed Nov 8 19:44:38 2023 +0100 +Date: Wed Dec 6 12:54:50 2023 +0100 - dialog: reformat exported structures more human friendly - - revert to the format it had before 783a416f1a5 + cfgt: rearrange mod parameters - (cherry picked from commit f0cf082effe6a0fd8893299e49a519d90bfc6151) + * use _cfgt_ prefix for init_flag -commit 20d8546e0055c43709e77bd8e61377f834011149 +commit b7b3f94f949feed3cf9e2e3adf3b4596e6e20eac Author: Daniel-Constantin Mierla -Date: Wed Nov 8 11:06:17 2023 +0100 +Date: Wed Dec 6 08:42:41 2023 +0100 - topos: update headers for stateless cancel and non-2xx ack + core: xavp - serialize long long values - (cherry picked from commit 8f84f6681570d5eb1018e6fe45f280173451bf62) + - they are printed as unsigned values, same as for long values -commit 6fca96d1fe87a8216098304f2b64622f69d3e6aa -Author: Christian Marangi -Date: Mon Nov 6 16:13:55 2023 +0100 +commit e0909ab1c890b11204dd38b26283cba5fad289c7 +Author: Daniel-Constantin Mierla +Date: Tue Dec 5 22:00:43 2023 +0100 - kamcmd: Makefile - use CUSTOM_NAME for specifying custom binary name - - - previous use of NAME can clash with environment variable NAME that - could be set by OS or by Kamailio modules installation - - GH #3628 - - (cherry picked from commit b141f267ce1fe1068de1541d8bd5b5dc53c1d6d9) + topoh: init vars inside th_build_socket_strings() -commit 6df7569d6cb54b5057b708120c66db80f8c2828b -Author: Morten Tryfoss -Date: Mon Nov 6 11:14:36 2023 +0100 +commit a096684c69bd121ba5e60f682e236f621f0e343b +Author: Victor Seva +Date: Wed Dec 6 01:55:11 2023 +0100 - tm: T_ASYNC_SUSPENDED flag not removed when cancelling a suspension - - (cherry picked from commit 70ecd99e3d8069d0f89444a5b893f61dd1edd1b3) + github: devcontainer support force build parameter [skip ci] -commit d015ee9c06a8cb6644101d08e4b54f80b96accf6 +commit 6dd5598fc043fe3d2582e643d7d4ef675c9e6480 Author: Daniel-Constantin Mierla -Date: Fri Nov 3 11:00:34 2023 +0100 +Date: Tue Dec 5 19:30:21 2023 +0100 - db_redis: init allocated redis table structure + phonenum: Makefile - option to set C standard version - (cherry picked from commit e24df12d10d8b88582907481d161c6a2db5cf8f1) + - can be set via option CSTDVER + - defaults now to c++17 + - GH #3659 -commit 6aec4f79d0cd4af1639df981cfe0877124542292 -Author: Benjamin <92934023+tietzsg@users.noreply.github.com> -Date: Thu Nov 2 13:09:57 2023 +0100 +commit a9e02966384cbcdf04aa16feb034b87e524352c9 +Author: Daniel-Constantin Mierla +Date: Tue Dec 5 15:08:50 2023 +0100 - http_client: add information about parameter loading (#3619) - - * http_client: add information about parameter loading - - - Inform that the order of the parameters is important when httpcon is loaded first - - * http_client: docs - typos from previous commit - - --------- + core: remove unnecessary condition on msg - Co-authored-by: Daniel-Constantin Mierla - (cherry picked from commit 02dd4e2c883585601f4dbcea0b63b858b4dd24d6) + - the structure is already used before -commit 3dee1d598957cb092608e987b1d4f8a726258a5a +commit 3a02bf42bc182e0eb809e63d8fe828e3ece5f1da Author: Daniel-Constantin Mierla -Date: Wed Nov 1 08:55:29 2023 +0100 +Date: Tue Dec 5 12:26:22 2023 +0100 - tm: update return code for EoH check failure - - (cherry picked from commit c76444da502325c90eb7ac0cbcc24e7bf16dd5d1) + ims_charging: log message on db updated error -commit 98e2b05e29716d60789aadac59b372c8534fc8d8 +commit 4f6a2686c01a65fe3a23e4d2057c7940eedcf12a Author: Daniel-Constantin Mierla -Date: Wed Nov 1 08:21:46 2023 +0100 +Date: Tue Dec 5 12:18:33 2023 +0100 - core: new code for internal processing error + topoh: reorder conditions for safety of cleaning on error - (cherry picked from commit e34d41557e3a88cfb76571fb3f2793d85d264710) + - in the part related to the new th_build_socket_strings() internal function -commit dd034befebc2bed440979bce51c04d8054d075c6 -Author: Daniel-Constantin Mierla -Date: Tue Oct 31 20:04:34 2023 +0100 +commit 0d78a1add4292ff1e10347c0199f0d70d31678ea +Author: Victor Seva +Date: Tue Dec 5 12:04:36 2023 +0100 - tls: note about db_mysql module parameter opt_ssl_mode - - (cherry picked from commit d157aed3fc69d3584cb9e6ca0112e47ab917e88e) + pkg/kamailio/deb: version set 5.8.0~dev2 [skip ci] -commit 1bd0c64845e5eb90492cfa107bb4afd9c4a3bb42 +commit 6305adef50079891386a048b986fd27e9b6e7ca1 Author: Daniel-Constantin Mierla -Date: Tue Oct 31 18:35:06 2023 +0100 +Date: Tue Dec 5 12:00:00 2023 +0100 - core: error - better message for E_OUT_OF_MEM - - (cherry picked from commit 1e4bf66d37afcded52fcaa2a0dd61a87bb1f2c67) + Makefile.defs: version set to 5.8.0-dev2 -commit 6d0d39311fdf09007aaae6ac0e4e0342048211c5 +commit ca7e1e49aecd3e0f12cc783e3b97868980f1d3d2 Author: Daniel-Constantin Mierla -Date: Tue Oct 31 14:54:54 2023 +0100 +Date: Tue Dec 5 10:27:32 2023 +0100 - secsipid_proc: Makefile - look for secsipid include and libs in localbase - - - done when pkg-config cannot find libsecsipid install details + dialog: prevent duplicate of leg1 attributes in json for dmq - (cherry picked from commit a2468e66f530822094569cf847796d91b17d4be9) + - reported by #3656 -commit ab7cf4e57ee800c60ec171f801a76f16df318d51 +commit 2f98aaca9e4b71b8086abce4c2b41c215fb2a26f Author: Daniel-Constantin Mierla -Date: Wed Oct 25 18:30:54 2023 +0200 +Date: Mon Dec 4 20:33:40 2023 +0100 - usrloc: reformat exported structures to be more readable - - (cherry picked from commit 9a50e380216b7557b53a2e8a0e4068f81ecf635e) + ims_ipsec_pcscf: declare vars at beginning of the block -commit ba19a8f30d6c9f7757ef0c8d55e2139a8279d375 -Author: Daniel-Constantin Mierla -Date: Wed Oct 25 18:06:36 2023 +0200 +commit 812df26470b50d626ce9ee03b9272373b231ce2a +Author: Supreeth Herle +Date: Mon Dec 4 20:29:40 2023 +0100 - dmq_usrloc: avoid needless second local socket search - - - remove overwriting local socket string value with received item - - (cherry picked from commit f97149aec9da71085df9dcf4541abba7b756939c) + ims_ipsec_pcscf: handle IPSec registration case where first SIP REGISTER does not have VIA port as 5060 -commit 5ddfa0b2f29dbbe30e1933edf0110f8cfb353f76 -Author: Konstantin Tumalevich -Date: Tue Oct 24 15:23:26 2023 +0600 - - app_ruby: Fix rpc documentation typo - - (cherry picked from commit 111d9f70cf55eca08b78e21213f3452fa8622d21) - -commit d93d8b882b584ef41721f7c6d9fb221890ef365f -Author: Daniel-Constantin Mierla -Date: Sat Oct 21 09:05:44 2023 +0200 - - topos: remove check of th_param_mask_callid() for api callid masking - - - functions are not for topoh internal usage, but for intermodule API - - reported as part of GH #3606 - - (cherry picked from commit e5ecb666abd24433b0de030980f79e2521439524) - -commit c9c0b12efc7031ee894a62c6a148fec7f3df03f8 -Author: Daniel-Constantin Mierla -Date: Fri Oct 20 10:34:21 2023 +0200 - - tls: include file to fix warning about tls_openssl_clear_errors() - - (cherry picked from commit fe8eafd31327c14e7b081cd8f4a6532953e0a1c6) - -commit 84a6b3f59165372400340a7f049653176d071830 -Author: Victor Seva -Date: Tue Oct 17 14:12:57 2023 +0200 - - presence: active_watcher cleanup timer - - related #3074 - - (cherry picked from commit f27eda6fe3d99d1352d4df86d79e4646b0a4c17a) - -commit 97a37f7b9ad89a409e3a03bb63f07846bfcad0af -Author: Xenofon Karamanos -Date: Thu Oct 19 12:18:38 2023 +0000 - - tls: Add and apply tls_openssl_clear_errors function - - (cherry picked from commit 110ebbafadcc225f4e88749287f06ae29a6cfa2e) - -commit 2481ccd984ac0b9896def8b36458a34acc2cddeb -Author: Juha Heinanen -Date: Thu Oct 19 13:36:32 2023 +0200 - - core: change tcp_check_timer initialization - - - make tcp_check_timer default to depend on tcp_msg_data_timeout and - ksr_tcp_msg_read_timeout values, set to half of the minimum of the - two, it is not explicitely set - - GH #3608 - - (cherry picked from commit 5077127b0fe1a2d803e42abe19cfcd93339f0519) - -commit acd47ad9a175684548dd3fb9c45d18ca81ba6fdb -Author: VoIPNuggets.com -Date: Tue Oct 17 19:19:48 2023 +0530 - - tools: route_graph - added README file and updated reference URL [skip ci] - - (cherry picked from commit 976da8c72e9a056b724f584a803a4a8114f70d30) - -commit 6fbabb1fc2d93bd1983ad40d0d122ed0373236c6 -Author: Daniel-Constantin Mierla -Date: Mon Oct 16 09:09:08 2023 +0200 - - core: added tcp_accept_iplimit parameter - - - set limit for accepted connections from the same ip address - - default 1024 - - (cherry picked from commit 241127c5f0820614a3e2ac1467e9f8cb8a0eeb23) - -commit a86a46474bf53103155ee4e4dac200c67c971f12 -Author: Daniel-Constantin Mierla -Date: Mon Oct 16 08:57:32 2023 +0200 - - core: added tcp_msg_data_timeout parameter - - - duration in seconds for how long to wait till data is received on a - new tcp connection - - default 20 - - (cherry picked from commit 213e19108699ed4ea5c962caf673b0a60ce41480) - -commit 5bedf8c17a6309f3c17c69cfc6dacd9cccbe4ac1 -Author: Daniel-Constantin Mierla -Date: Mon Oct 16 08:35:09 2023 +0200 - - core: added tcp_check_timer parameter - - - set the check interval (in seconds) for tcp connections - - default 10 - - (cherry picked from commit 1acede64041307b783ed90736ca114917bafbc14) - -commit 0d890ed6fd7afd351ba84933da1f90a7433a5bfe -Author: Daniel-Constantin Mierla -Date: Sun Oct 15 19:20:13 2023 +0200 - - core: added tcp_msg_read_timeout parameter - - - specify read timeout for tcp messages - - (cherry picked from commit 92feec4fa026a153d1f9ed79e5893bf1086db909) - -commit 07c61363a9c1065cf5754672b6ef78c1d79cf641 -Author: Daniel-Constantin Mierla -Date: Sat Oct 14 16:49:20 2023 +0200 - - core: added msg_recv_max_size global parameter - - - set limit for max size of received tcp or upd messages - - (cherry picked from commit b56037fab181037d48bfc90802f25b85ae8bee04) - -commit 25d50b8977290d53da60a0f5800f762a735ac35b -Author: Daniel-Constantin Mierla -Date: Fri Oct 13 17:33:07 2023 +0200 - - core: tcp - limit number of accepted connections per src ip - - - default 1024 - - (cherry picked from commit a902e4a032a85a7755de32eeadac800a1312e64f) - -commit e21c8180cb8a676e48cea84427247c42bfd9243f -Author: Daniel-Constantin Mierla -Date: Fri Oct 13 16:36:39 2023 +0200 - - core: tcp - exclude crlf ping from data exchage state - - (cherry picked from commit ddfe15f860555048f1ad6884727d4eb52f11910f) - -commit 68f5f43963511dec19eaed2300d8ba1e291832b0 -Author: Daniel-Constantin Mierla -Date: Fri Oct 13 16:31:10 2023 +0200 - - core: tcp - close connection without data traffic at all - - - default timeout: 20sec - - cleanup is done on timer, it can take another 10sec - - (cherry picked from commit ef86402d2397ff7b0416bc17ab0a2ba906402215) - -commit e18ed857576ed682ee620184c8c1053e8222a952 -Author: Nikolay Ivanuschak -Date: Mon Jul 24 14:09:31 2023 +0300 - - core: fixed wrong network interface selection. - - fixed incorrect source IP address selection for the SIP - messages sending procedure when TCP transport is used or - for UDP with the 'mhomed' setting set as 'mhomed=1'. - - (cherry picked from commit d4e16520a06344ce2bfd07eda4447d68a2c3fce8) - -commit 1be68f52c4b2065c7a7da0c917e9c065a2c4cd00 -Author: Daniel-Constantin Mierla -Date: Fri Oct 13 16:02:12 2023 +0200 - - core: tcp - set limit for reading a message - - - default 10sec - if message is not read, close connection - - cleanup is done on timer, it can take an additional 10sec to clean up - connection - - (cherry picked from commit f5b46efc3a97aa45d090f46990a40bcc9dd91390) - -commit b503b95a2a62a2e51a5cff20caaa30212d078e84 -Author: Daniel-Constantin Mierla -Date: Fri Oct 6 12:32:53 2023 +0200 - - kamdbctl: check if kamctlrc is readable - - (cherry picked from commit f16ec35fa448d03613e6bbbff4c354012f56073e) - -commit 259812f03ec26d49776050ca5eb657f2771ce8d5 -Author: Daniel-Constantin Mierla -Date: Fri Oct 6 08:19:18 2023 +0200 - - kamctl: check if kamctlrc is readable - - - related to GH #3594 - - (cherry picked from commit a3fd3b12ca9b1c3688255e9d645085947052bc6d) - -commit 9081a586b32095b1d98ac9fef2328169939b482f -Author: Daniel-Constantin Mierla -Date: Thu Sep 28 09:03:50 2023 +0200 - - core: dns cache - warnings on put for unlinked items - - (cherry picked from commit 1bb1ba60992ffa35e8d36ed1dab98fdc36a2ea30) - -commit e86b362c2f875986bf5c70340089c039bc2bbada -Author: Victor Seva -Date: Sat Nov 11 00:33:34 2023 +0100 - - utils: clang-format for coherent indentation and coding style - -commit c2a1a22a2356267195dd86118bb4c2eba6d0d0c2 -Author: Victor Seva -Date: Sat Nov 11 00:33:13 2023 +0100 - - test: clang-format for coherent indentation and coding style - -commit e9397ab8f45ac24a4f8c44b112f8b5448bffb768 -Author: Victor Seva -Date: Sat Nov 11 00:32:57 2023 +0100 - - misc: clang-format for coherent indentation and coding style - -commit bde436f3ab8adb497ef71c3abb7fbf01e45fe671 -Author: Victor Seva -Date: Sat Nov 11 00:30:07 2023 +0100 - - xprint: clang-format for coherent indentation and coding style - -commit c6c79dfcf8161dd4fe327ffdf5cb95e5999f4cf1 -Author: Victor Seva -Date: Sat Nov 11 00:30:06 2023 +0100 - - xmpp: clang-format for coherent indentation and coding style - -commit f785215cde676129c39bfa4e9b70413426a40674 -Author: Victor Seva -Date: Sat Nov 11 00:30:06 2023 +0100 - - xmlrpc: clang-format for coherent indentation and coding style - -commit f28ba7113c7b041c53a24a084e97b6898637d3b8 -Author: Victor Seva -Date: Sat Nov 11 00:30:06 2023 +0100 - - xmlops: clang-format for coherent indentation and coding style - -commit 61a2b76ca2b15b0f32c966407a2bed3c53794a5a -Author: Victor Seva -Date: Sat Nov 11 00:30:06 2023 +0100 - - xlog: clang-format for coherent indentation and coding style - -commit ecc7b45aa2de626b0f050e19fcd5fa35b6ed3fea -Author: Victor Seva -Date: Sat Nov 11 00:30:06 2023 +0100 - - xhttp_rpc: clang-format for coherent indentation and coding style - -commit f37d20d0e2ca35e96466e20f5343fecf3dd3e40e -Author: Victor Seva -Date: Sat Nov 11 00:30:06 2023 +0100 - - xhttp_prom: clang-format for coherent indentation and coding style - -commit cdd79007ceb923ca25e0e4dfa034de49dc94e74c -Author: Victor Seva -Date: Sat Nov 11 00:30:05 2023 +0100 - - xhttp_pi: clang-format for coherent indentation and coding style - -commit 1b5ed5423c814387c06db3d040bca3309a00db7b -Author: Victor Seva -Date: Sat Nov 11 00:30:05 2023 +0100 - - xhttp: clang-format for coherent indentation and coding style - -commit 9cab5a37a6ef34b7f2a8dfff8123661987b52570 -Author: Victor Seva -Date: Sat Nov 11 00:30:05 2023 +0100 - - xcap_server: clang-format for coherent indentation and coding style - -commit 42f35537daf954a30308d9310658f9b083daa2b7 -Author: Victor Seva -Date: Sat Nov 11 00:30:05 2023 +0100 - - xcap_client: clang-format for coherent indentation and coding style - -commit 44a73f342084f03ee78e546592128dd570677672 -Author: Victor Seva -Date: Sat Nov 11 00:30:05 2023 +0100 - - websocket: clang-format for coherent indentation and coding style - -commit f32bcccb99f301b85dd85cab751ce35d85816daa -Author: Victor Seva -Date: Sat Nov 11 00:30:05 2023 +0100 - - uuid: clang-format for coherent indentation and coding style - -commit 708f270808233f8bd814e6be2bb39d910b4c7c0e -Author: Victor Seva -Date: Sat Nov 11 00:30:05 2023 +0100 - - utils: clang-format for coherent indentation and coding style - -commit b0fcfbff5b51f86a6dfe7ce48352c4a24363adb2 -Author: Victor Seva -Date: Sat Nov 11 00:30:04 2023 +0100 - - usrloc: clang-format for coherent indentation and coding style - -commit 85c68fd99069ccb6f61be264611ec43a5846d57b -Author: Victor Seva -Date: Sat Nov 11 00:30:04 2023 +0100 - - userblocklist: clang-format for coherent indentation and coding style - -commit 8c24f944b3c59d08e754e5d97b56b19abb65f61b -Author: Victor Seva -Date: Sat Nov 11 00:30:04 2023 +0100 - - uri_db: clang-format for coherent indentation and coding style - -commit cb11c30d6bb361fcc039b4f0fd1464d4ef7c62c1 -Author: Victor Seva -Date: Sat Nov 11 00:30:04 2023 +0100 - - uid_uri_db: clang-format for coherent indentation and coding style - -commit 6379786fe8a7ed83e6d9cccaeaa9b3ead9541109 -Author: Victor Seva -Date: Sat Nov 11 00:30:04 2023 +0100 - - uid_gflags: clang-format for coherent indentation and coding style - -commit 23031bb0026aaea32d1cfff7816f10bb29703f37 -Author: Victor Seva -Date: Sat Nov 11 00:30:04 2023 +0100 - - uid_domain: clang-format for coherent indentation and coding style - -commit eb25b4926d71ecded0ae24ed0ee622587dc2dcf9 -Author: Victor Seva -Date: Sat Nov 11 00:30:03 2023 +0100 - - uid_avp_db: clang-format for coherent indentation and coding style - -commit 4e64e52948c9ec74cc18b47286fd60c2f508afe8 -Author: Victor Seva -Date: Sat Nov 11 00:30:03 2023 +0100 - - uid_auth_db: clang-format for coherent indentation and coding style - -commit 61f8ee35429bda6f8b941e924a070eaf1abe6757 -Author: Victor Seva -Date: Sat Nov 11 00:30:03 2023 +0100 - - uac_redirect: clang-format for coherent indentation and coding style - -commit 38d693046f149c9151c54606fef1fe56628be4b1 -Author: Victor Seva -Date: Sat Nov 11 00:30:03 2023 +0100 - - uac: clang-format for coherent indentation and coding style - -commit fbf2d7e7a13b44f1686dd2c05e149bd62d9c2917 -Author: Victor Seva -Date: Sat Nov 11 00:30:03 2023 +0100 - - tsilo: clang-format for coherent indentation and coding style - -commit fcb5dccdd2457c61dcf8fe6e493e61e2a45cc031 -Author: Victor Seva -Date: Sat Nov 11 00:30:03 2023 +0100 - - topos_redis: clang-format for coherent indentation and coding style - -commit 8b0cff0cb6c6c3dde67de8624c9925b66914a64b -Author: Victor Seva -Date: Sat Nov 11 00:30:02 2023 +0100 - - topos: clang-format for coherent indentation and coding style - -commit b2868a6390cb30fb095ecb5252416de5465cf28b -Author: Victor Seva -Date: Sat Nov 11 00:30:02 2023 +0100 - - topoh: clang-format for coherent indentation and coding style - -commit dcb0cc220fec594e3347830741b76140e22cae36 -Author: Victor Seva -Date: Sat Nov 11 00:30:02 2023 +0100 - - tmx: clang-format for coherent indentation and coding style - -commit 27675989ab2f64fd396c5bcc1b4b91d9b39f7631 -Author: Victor Seva -Date: Sat Nov 11 00:30:02 2023 +0100 - - tmrec: clang-format for coherent indentation and coding style - -commit 78b6ad95d3e90a9355d2b789ad83c391622df7b5 -Author: Victor Seva -Date: Sat Nov 11 00:30:02 2023 +0100 - - tm: clang-format for coherent indentation and coding style - -commit 65163db47f81a9d2b3946c396f7e3657e8a0d687 -Author: Victor Seva -Date: Sat Nov 11 00:30:02 2023 +0100 - - tlsa: clang-format for coherent indentation and coding style - -commit b7af86eece493465f77de1a231d63a57d80236d9 -Author: Victor Seva -Date: Sat Nov 11 00:30:01 2023 +0100 - - tls_wolfssl: clang-format for coherent indentation and coding style - -commit 81a166bfbba96dcf4f65dc3639485a6b1d6c72d9 -Author: Victor Seva -Date: Sat Nov 11 00:29:59 2023 +0100 - - tls: clang-format for coherent indentation and coding style - -commit 3b4a5fb7058098b3b9317807131d275e8df82652 -Author: Victor Seva -Date: Sat Nov 11 00:29:59 2023 +0100 - - timer: clang-format for coherent indentation and coding style - -commit 2bfc3aa52be27238896b64a937dd7c321c349da6 -Author: Victor Seva -Date: Sat Nov 11 00:29:59 2023 +0100 - - textopsx: clang-format for coherent indentation and coding style - -commit 62ea726599f649583f3841c66b179ff8733dc514 -Author: Victor Seva -Date: Sat Nov 11 00:29:59 2023 +0100 - - textops: clang-format for coherent indentation and coding style - -commit 80758ae8e3c4f8e42cd39d1e5119e0177725d36a -Author: Victor Seva -Date: Sat Nov 11 00:29:59 2023 +0100 - - tcpops: clang-format for coherent indentation and coding style - -commit a9d25d79e13eef11e660dbfa2b92b7feef78558f -Author: Victor Seva -Date: Sat Nov 11 00:29:58 2023 +0100 - - systemdops: clang-format for coherent indentation and coding style - -commit c945acb71d1f951d398f664ab9a0f433ac523efb -Author: Victor Seva -Date: Sat Nov 11 00:29:58 2023 +0100 - - sworker: clang-format for coherent indentation and coding style - -commit acb202e3834b5625916555936d65bb944efdeef9 -Author: Victor Seva -Date: Sat Nov 11 00:29:58 2023 +0100 - - stun: clang-format for coherent indentation and coding style - -commit b12bdf74b45f629304a283550989e92d3f0258ae -Author: Victor Seva -Date: Sat Nov 11 00:29:58 2023 +0100 - - stirshaken: clang-format for coherent indentation and coding style - -commit 8278a782c31d5082985cb51f2ccc665e361c0d0c -Author: Victor Seva -Date: Sat Nov 11 00:29:58 2023 +0100 - - statsc: clang-format for coherent indentation and coding style - -commit b812d59a21c92fa9a07f5d48283a43b2acfe19bb -Author: Victor Seva -Date: Sat Nov 11 00:29:58 2023 +0100 - - statistics: clang-format for coherent indentation and coding style - -commit 605754e18f66ba02f8b033959705f68ed12f89fb -Author: Victor Seva -Date: Sat Nov 11 00:29:57 2023 +0100 - - sst: clang-format for coherent indentation and coding style - -commit 3315529c8439edfe042dcef025c5912f623e0bdb -Author: Victor Seva -Date: Sat Nov 11 00:29:57 2023 +0100 - - ss7ops: clang-format for coherent indentation and coding style - -commit 41b8142ff10ff66564c8c5cb65672bef9ac5c5da -Author: Victor Seva -Date: Sat Nov 11 00:29:57 2023 +0100 - - sqlops: clang-format for coherent indentation and coding style - -commit 852356b7aed5a485dd5863017605efac9583c7da -Author: Victor Seva -Date: Sat Nov 11 00:29:57 2023 +0100 - - speeddial: clang-format for coherent indentation and coding style - -commit 7278b3e081613ae917432bfb0b2bd4808ec6a6e1 -Author: Victor Seva -Date: Sat Nov 11 00:29:57 2023 +0100 - - snmpstats: clang-format for coherent indentation and coding style - -commit fc887c6ed5cd1df63d4b68ec6302fd20e341e719 -Author: Victor Seva -Date: Sat Nov 11 00:29:56 2023 +0100 - - smsops: clang-format for coherent indentation and coding style - -commit 6f1aeffbc41e54508f57a753d8945d5caa48c295 -Author: Victor Seva -Date: Sat Nov 11 00:29:56 2023 +0100 - - sms: clang-format for coherent indentation and coding style - -commit fe93fdb14bdbad7ff313ecfa929555811bb14076 -Author: Victor Seva -Date: Sat Nov 11 00:29:56 2023 +0100 - - slack: clang-format for coherent indentation and coding style - -commit 3ac3385b67ae442bcbd612a70e69600944ca63d8 -Author: Victor Seva -Date: Sat Nov 11 00:29:56 2023 +0100 - - sl: clang-format for coherent indentation and coding style - -commit 4714d8ea52a7f48e68ec760c61404fa46a45ee50 -Author: Victor Seva -Date: Sat Nov 11 00:29:56 2023 +0100 - - siputils: clang-format for coherent indentation and coding style - -commit 17e9fef12b198b3047c032ee4a036c7e96be4bad -Author: Victor Seva -Date: Sat Nov 11 00:29:56 2023 +0100 - - siptrace: clang-format for coherent indentation and coding style - -commit 683d6d79e075165abd6ba4b4b17a6200eef46a76 -Author: Victor Seva -Date: Sat Nov 11 00:29:55 2023 +0100 - - sipt: clang-format for coherent indentation and coding style - -commit cfd25ffdfd6be31951884c46c121564a502e4da4 -Author: Victor Seva -Date: Sat Nov 11 00:29:55 2023 +0100 - - siprepo: clang-format for coherent indentation and coding style - -commit 60065a779d9657258333fe9889db8eedc44e1fed -Author: Victor Seva -Date: Sat Nov 11 00:29:55 2023 +0100 - - sipjson: clang-format for coherent indentation and coding style - -commit d1ec5f160ce744d33c717c58984701879b763992 -Author: Victor Seva -Date: Sat Nov 11 00:29:55 2023 +0100 - - sipdump: clang-format for coherent indentation and coding style - -commit cf83ce271815d39419ec12cb6a535cc3ddea1a39 -Author: Victor Seva -Date: Sat Nov 11 00:29:55 2023 +0100 - - sipcapture: clang-format for coherent indentation and coding style - -commit 2cca87bc653621434c684c013536319bb23dd898 -Author: Victor Seva -Date: Sat Nov 11 00:29:54 2023 +0100 - - secsipid_proc: clang-format for coherent indentation and coding style - -commit bde3c9489a9232949afdab197db36bb26a4d1f12 -Author: Victor Seva -Date: Sat Nov 11 00:29:54 2023 +0100 - - secsipid: clang-format for coherent indentation and coding style - -commit ed67051e8bec9a8422a2e37fcf10b0efb4006339 -Author: Victor Seva -Date: Sat Nov 11 00:29:54 2023 +0100 - - secfilter: clang-format for coherent indentation and coding style - -commit e36cfac455c65cd9fe7f090a1e0743c726e6ca70 -Author: Victor Seva -Date: Sat Nov 11 00:29:54 2023 +0100 - - seas: clang-format for coherent indentation and coding style - -commit 4fbfa6a1f8d40d50e8e58f17f43db58a5b30de0a -Author: Victor Seva -Date: Sat Nov 11 00:29:54 2023 +0100 - - sdpops: clang-format for coherent indentation and coding style - -commit 54d31cff8ee3787bf97f69e6b4a4b47da3c6b7a8 -Author: Victor Seva -Date: Sat Nov 11 00:29:54 2023 +0100 - - sctp: clang-format for coherent indentation and coding style - -commit 93a18a05ef8221f67df1604d8a177f3d4b631769 -Author: Victor Seva -Date: Sat Nov 11 00:29:53 2023 +0100 - - sanity: clang-format for coherent indentation and coding style - -commit 818b7b303d9cb82956591dbf2ec69e305c0d6bc1 -Author: Victor Seva -Date: Sat Nov 11 00:29:53 2023 +0100 - - ruxc: clang-format for coherent indentation and coding style - -commit 5124fb45f0565c9b50dc5881d22ab5e32e5b1c1e -Author: Victor Seva -Date: Sat Nov 11 00:29:53 2023 +0100 - - rtpproxy: clang-format for coherent indentation and coding style - -commit 37d7f892c0887ce8050c839e6fd69558c2286e48 -Author: Victor Seva -Date: Sat Nov 11 00:29:53 2023 +0100 - - rtpengine: clang-format for coherent indentation and coding style - -commit 6462ad794665b094ce626bfb3e87ce312aa6bf38 -Author: Victor Seva -Date: Sat Nov 11 00:29:53 2023 +0100 - - rtp_media_server: clang-format for coherent indentation and coding style - -commit af817079ec17618786a3968d01c98dfbd0a7c305 -Author: Victor Seva -Date: Sat Nov 11 00:29:52 2023 +0100 - - rtjson: clang-format for coherent indentation and coding style - -commit 0d693bbb78292a97e4dab8c732880a5648ee7f22 -Author: Victor Seva -Date: Sat Nov 11 00:29:52 2023 +0100 - - rtimer: clang-format for coherent indentation and coding style - -commit a5085b6604971b9427eb7267ceb7b5cef63b14ec -Author: Victor Seva -Date: Sat Nov 11 00:29:52 2023 +0100 - - rr: clang-format for coherent indentation and coding style - -commit 27c7a57b0a271d89a263b578ec2d649280016b3c -Author: Victor Seva -Date: Sat Nov 11 00:29:52 2023 +0100 - - rls: clang-format for coherent indentation and coding style - -commit 5d34e998f67b77bebb7433ac18246ac87f2ed9e8 -Author: Victor Seva -Date: Sat Nov 11 00:29:52 2023 +0100 - - registrar: clang-format for coherent indentation and coding style - -commit e485dd55d24675c0f0ed229b90d284eb76c4d748 -Author: Victor Seva -Date: Sat Nov 11 00:29:51 2023 +0100 - - regex: clang-format for coherent indentation and coding style - -commit 31ffd3b1e48532ca6d4ab9d7144f6c66170c48b9 -Author: Victor Seva -Date: Sat Nov 11 00:29:51 2023 +0100 - - ratelimit: clang-format for coherent indentation and coding style - -commit 3c243106eae41f475ca154839049b5c013c74f12 -Author: Victor Seva -Date: Sat Nov 11 00:29:51 2023 +0100 - - rabbitmq: clang-format for coherent indentation and coding style - -commit f5cefe855e091cc88ef4d5c3b5031f64f3f310aa -Author: Victor Seva -Date: Sat Nov 11 00:29:51 2023 +0100 - - qos: clang-format for coherent indentation and coding style - -commit 090a0a5229b4961728bbf391600590a1c15d39c4 -Author: Victor Seva -Date: Sat Nov 11 00:29:51 2023 +0100 - - pv_headers: clang-format for coherent indentation and coding style - -commit 77d1867e04722e4e54a7f0119afc53384e2c6031 -Author: Victor Seva -Date: Sat Nov 11 00:29:50 2023 +0100 - - pv: clang-format for coherent indentation and coding style - -commit 3b9a5f5b355aa5ed78f8d414486c6102fa5a3988 -Author: Victor Seva -Date: Sat Nov 11 00:29:50 2023 +0100 - - pua_xmpp: clang-format for coherent indentation and coding style - -commit 6152b421b3b434243fa2d5b0204a6fc7f18f750a -Author: Victor Seva -Date: Sat Nov 11 00:29:50 2023 +0100 - - pua_usrloc: clang-format for coherent indentation and coding style - -commit dd9ef62304bdb1f466b1a50dedb1336169b25873 -Author: Victor Seva -Date: Sat Nov 11 00:29:50 2023 +0100 - - pua_rpc: clang-format for coherent indentation and coding style - -commit f6e645b4bd19355c81c5fbefc9b14895dd443e44 -Author: Victor Seva -Date: Sat Nov 11 00:29:50 2023 +0100 - - pua_reginfo: clang-format for coherent indentation and coding style - -commit 58b340a7b8ff42c0372f9ebb13f84099acd3f05c -Author: Victor Seva -Date: Sat Nov 11 00:29:49 2023 +0100 - - pua_json: clang-format for coherent indentation and coding style - -commit ca8720ab8c64e55018c3cb2d9f69886c2b03af2f -Author: Victor Seva -Date: Sat Nov 11 00:29:49 2023 +0100 - - pua_dialoginfo: clang-format for coherent indentation and coding style - -commit beeac1c186ec19e4c32faaad76f3640a129aa2f6 -Author: Victor Seva -Date: Sat Nov 11 00:29:49 2023 +0100 - - pua: clang-format for coherent indentation and coding style - -commit 33bc3c462bc8e031a2c1cc6c6abad04e83a97773 -Author: Victor Seva -Date: Sat Nov 11 00:29:49 2023 +0100 - - print_lib: clang-format for coherent indentation and coding style - -commit cacea1147eb1156369fd4a3d2d2cb8f14cf93950 -Author: Victor Seva -Date: Sat Nov 11 00:29:49 2023 +0100 - - print: clang-format for coherent indentation and coding style - -commit 1b3989c0b7206cf340f6081f35d760d9de905642 -Author: Victor Seva -Date: Sat Nov 11 00:29:48 2023 +0100 - - presence_xml: clang-format for coherent indentation and coding style - -commit 2a5651e1b13999cfd18ed1d746ba0eaf4d1afc37 -Author: Victor Seva -Date: Sat Nov 11 00:29:48 2023 +0100 - - presence_reginfo: clang-format for coherent indentation and coding style - -commit 4fd23e90765328551fdae40e252b7a8bd8de30c6 -Author: Victor Seva -Date: Sat Nov 11 00:29:48 2023 +0100 - - presence_profile: clang-format for coherent indentation and coding style - -commit 9392e0576c9f574693c4aa6df6ab79643c1bed1c -Author: Victor Seva -Date: Sat Nov 11 00:29:48 2023 +0100 - - presence_mwi: clang-format for coherent indentation and coding style - -commit 26429896dbb7e3258ef38f96f3b581a4d226f19a -Author: Victor Seva -Date: Sat Nov 11 00:29:47 2023 +0100 - - presence_dialoginfo: clang-format for coherent indentation and coding style - -commit 660bb67bfb8a9c6d2bb21e56c6fbe75958f47f1b -Author: Victor Seva -Date: Sat Nov 11 00:29:47 2023 +0100 - - presence_conference: clang-format for coherent indentation and coding style - -commit e6009d8765e64232b143d5e55fe4a1020944899d -Author: Victor Seva -Date: Sat Nov 11 00:29:47 2023 +0100 - - presence: clang-format for coherent indentation and coding style - -commit 0ec2d4c773916217ad3e1df3f9517f18af79517d -Author: Victor Seva -Date: Sat Nov 11 00:29:47 2023 +0100 - - prefix_route: clang-format for coherent indentation and coding style - -commit b1754ca2f7a25764f5505b4fbd8eeac2188bf80e -Author: Victor Seva -Date: Sat Nov 11 00:29:47 2023 +0100 - - posops: clang-format for coherent indentation and coding style - -commit 92387942814a8debc652c1ac63052a10c4b9f37b -Author: Victor Seva -Date: Sat Nov 11 00:29:46 2023 +0100 - - pipelimit: clang-format for coherent indentation and coding style - -commit 7856f6b1f32e8b70caac63874d71e9afd57e065f -Author: Victor Seva -Date: Sat Nov 11 00:29:46 2023 +0100 - - pike: clang-format for coherent indentation and coding style - -commit da5f082847b15137bb37813c6688e31ab80801b5 -Author: Victor Seva -Date: Sat Nov 11 00:29:46 2023 +0100 - - phonenum: clang-format for coherent indentation and coding style - -commit 2ac32e211a817351b2f1e6fced5cdd77f825c0e1 -Author: Victor Seva -Date: Sat Nov 11 00:29:46 2023 +0100 - - permissions: clang-format for coherent indentation and coding style - -commit 87dc7bbba357324aa83b80fb450dfada1906931a -Author: Victor Seva -Date: Sat Nov 11 00:29:46 2023 +0100 - - peering: clang-format for coherent indentation and coding style - -commit 187ff10d21eeea60bacd7fc387061594352de73f -Author: Victor Seva -Date: Sat Nov 11 00:29:45 2023 +0100 - - pdt: clang-format for coherent indentation and coding style - -commit ccb0471fad59dc08d996c08de72c94d0cbd8eddf -Author: Victor Seva -Date: Sat Nov 11 00:29:45 2023 +0100 - - pdb: clang-format for coherent indentation and coding style - -commit 6dec7489513660c62fe5ea6067bf9d66265b431d -Author: Victor Seva -Date: Sat Nov 11 00:29:45 2023 +0100 - - path: clang-format for coherent indentation and coding style - -commit a7f7e838443c2253176536096fba60873bda8636 -Author: Victor Seva -Date: Sat Nov 11 00:29:45 2023 +0100 - - p_usrloc: clang-format for coherent indentation and coding style - -commit bbf515018debf4112b135394ab01a458a2f2fa63 -Author: Victor Seva -Date: Sat Nov 11 00:29:45 2023 +0100 - - outbound: clang-format for coherent indentation and coding style - -commit 5e05a7eeac09be9649d48293a1252bfd107b677f -Author: Victor Seva -Date: Sat Nov 11 00:29:44 2023 +0100 - - osp: clang-format for coherent indentation and coding style - -commit b39268ecce5158067b008095723fd6037d1b1674 -Author: Victor Seva -Date: Sat Nov 11 00:29:44 2023 +0100 - - nsq: clang-format for coherent indentation and coding style - -commit 3ace37468c1a1bb938bc3cdcd2bdcd09ceee2bbc -Author: Victor Seva -Date: Sat Nov 11 00:29:44 2023 +0100 - - nosip: clang-format for coherent indentation and coding style - -commit f4038ba81e117011436a978c47f5a57cb531b6f6 -Author: Victor Seva -Date: Sat Nov 11 00:29:44 2023 +0100 - - ndb_redis: clang-format for coherent indentation and coding style - -commit 0d48647f43c2da0c09135e0998f1a1ea1eedd1c0 -Author: Victor Seva -Date: Sat Nov 11 00:29:43 2023 +0100 - - ndb_mongodb: clang-format for coherent indentation and coding style - -commit 7655ade6e131522bdbcda2b5a55c0a5e7207c33c -Author: Victor Seva -Date: Sat Nov 11 00:29:40 2023 +0100 - - ndb_cassandra: clang-format for coherent indentation and coding style - -commit 1284e2a68b860a133cb33bdbaed23304815a51ba -Author: Victor Seva -Date: Sat Nov 11 00:29:39 2023 +0100 - - nats: clang-format for coherent indentation and coding style - -commit fa528f44025a957b75be64ded06c33a386c26094 -Author: Victor Seva -Date: Sat Nov 11 00:29:39 2023 +0100 - - nathelper: clang-format for coherent indentation and coding style - -commit 61349ccda2368d4d252ea3add6417a32697d61a3 -Author: Victor Seva -Date: Sat Nov 11 00:29:39 2023 +0100 - - nat_traversal: clang-format for coherent indentation and coding style - -commit a0c054627bf8ad4a05dcc3b8c6e7e3b48dec5a3d -Author: Victor Seva -Date: Sat Nov 11 00:29:39 2023 +0100 - - mtree: clang-format for coherent indentation and coding style - -commit 5470166381b5c2f0c8eaa36f24789a710fbc5e06 -Author: Victor Seva -Date: Sat Nov 11 00:29:38 2023 +0100 - - msrp: clang-format for coherent indentation and coding style - -commit 407e65ea99e8cbcdce424f69d4b1026c1984d45b -Author: Victor Seva -Date: Sat Nov 11 00:29:38 2023 +0100 - - msilo: clang-format for coherent indentation and coding style - -commit 2476a8805c63d74267b978b94b96a2c210f6d0e1 -Author: Victor Seva -Date: Sat Nov 11 00:29:38 2023 +0100 - - mqueue: clang-format for coherent indentation and coding style - -commit 4da9fbeae73bd8b1393d4ae3f38f4c475f40ac58 -Author: Victor Seva -Date: Sat Nov 11 00:29:38 2023 +0100 - - mqtt: clang-format for coherent indentation and coding style - -commit 4b14ce51fbf80fcfc57fb141f0076011edeeeb86 -Author: Victor Seva -Date: Sat Nov 11 00:29:38 2023 +0100 - - mohqueue: clang-format for coherent indentation and coding style - -commit 0c3c40c52a02ed8286da3bcdbe73af571e147c24 -Author: Victor Seva -Date: Sat Nov 11 00:29:37 2023 +0100 - - misctest: clang-format for coherent indentation and coding style - -commit 5a3a9bb35479d670a5f474f005dc315066a1d5f3 -Author: Victor Seva -Date: Sat Nov 11 00:29:37 2023 +0100 - - misc_radius: clang-format for coherent indentation and coding style - -commit 3cbdddbcfbb3fe6a306e90e2eaf3e731a28de0cc -Author: Victor Seva -Date: Sat Nov 11 00:29:37 2023 +0100 - - memcached: clang-format for coherent indentation and coding style - -commit 3810f75fbd8c60ed51d8956cc92b0d1b1b06d1ed -Author: Victor Seva -Date: Sat Nov 11 00:29:37 2023 +0100 - - mediaproxy: clang-format for coherent indentation and coding style - -commit 3c7b3b29b331bf54e1e40f83fbd4a73b03b69268 -Author: Victor Seva -Date: Sat Nov 11 00:29:36 2023 +0100 - - matrix: clang-format for coherent indentation and coding style - -commit 3090bb4198ba89ddd3ffb79b970ebccec2dd9b02 -Author: Victor Seva -Date: Sat Nov 11 00:29:36 2023 +0100 - - math: clang-format for coherent indentation and coding style - -commit c4f37b16516b2c83a5ff93712c8de45424f5bfcf -Author: Victor Seva -Date: Sat Nov 11 00:29:36 2023 +0100 - - mangler: clang-format for coherent indentation and coding style - -commit 0b267aef7cdba04e589a6262a78a35ed37fa71dc -Author: Victor Seva -Date: Sat Nov 11 00:29:36 2023 +0100 - - lwsc: clang-format for coherent indentation and coding style - -commit 4af6f2b52620b6c39fa40075d394b57e77d381cc -Author: Victor Seva -Date: Sat Nov 11 00:29:36 2023 +0100 - - lrkproxy: clang-format for coherent indentation and coding style - -commit e02039fcac50f7e85704bd85912e7acb394dea02 -Author: Victor Seva -Date: Sat Nov 11 00:29:35 2023 +0100 - - lost: clang-format for coherent indentation and coding style - -commit cc7c00bf65ee76dc8e774e034c38224ad90023ca -Author: Victor Seva -Date: Sat Nov 11 00:29:35 2023 +0100 - - log_systemd: clang-format for coherent indentation and coding style - -commit 24b693365a4a1b7f713bd005f46320b3d004de5f -Author: Victor Seva -Date: Sat Nov 11 00:29:35 2023 +0100 - - log_custom: clang-format for coherent indentation and coding style - -commit 707eafe3b36c6562bc1ae44f20464d8e19d3e3ca -Author: Victor Seva -Date: Sat Nov 11 00:29:35 2023 +0100 - - ldap: clang-format for coherent indentation and coding style - -commit 1a00a87277c83ade9868523e0c467211e66ba837 -Author: Victor Seva -Date: Sat Nov 11 00:29:34 2023 +0100 - - lcr: clang-format for coherent indentation and coding style - -commit eb906d05f635bdd5a906c94a9566eb5571f59cbe -Author: Victor Seva -Date: Sat Nov 11 00:29:34 2023 +0100 - - kex: clang-format for coherent indentation and coding style - -commit 987a834de0a75697292a9021d0f7df2010189512 -Author: Victor Seva -Date: Sat Nov 11 00:29:34 2023 +0100 - - kemix: clang-format for coherent indentation and coding style - -commit 5d7e0a64cc6c4f378151272d4a06e3f416f2e5cb -Author: Victor Seva -Date: Sat Nov 11 00:29:34 2023 +0100 - - keepalive: clang-format for coherent indentation and coding style - -commit 0f76f41dec313a292511d2169bd087d2cc0864c3 -Author: Victor Seva -Date: Sat Nov 11 00:29:33 2023 +0100 - - kazoo: clang-format for coherent indentation and coding style - -commit ae3c92b7b49f9e02aa5529b5d8c1380f0fece366 -Author: Victor Seva -Date: Sat Nov 11 00:29:33 2023 +0100 - - kafka: clang-format for coherent indentation and coding style - -commit 8194d2374c474a1d6890183aa601c8fa8a9bfe24 -Author: Victor Seva -Date: Sat Nov 11 00:29:33 2023 +0100 - - jwt: clang-format for coherent indentation and coding style - -commit 61889d2fb6281fdbb11e273f89775de1a54a8c24 -Author: Victor Seva -Date: Sat Nov 11 00:29:33 2023 +0100 - - jsonrpcs: clang-format for coherent indentation and coding style - -commit ef3e56d9a739f1e831f376486363e324bc9b1299 -Author: Victor Seva -Date: Sat Nov 11 00:29:33 2023 +0100 - - jsonrpcc: clang-format for coherent indentation and coding style - -commit 570649b3ccabfa5491538e47b5167f71d40bc8da -Author: Victor Seva -Date: Sat Nov 11 00:29:32 2023 +0100 - - json: clang-format for coherent indentation and coding style - -commit c1435a436204d845d0c70ee4feb9d15ebd28be38 -Author: Victor Seva -Date: Sat Nov 11 00:29:30 2023 +0100 - - janssonrpcc: clang-format for coherent indentation and coding style - -commit 9ce41e86e9725b6b40251cba6d75094f54586f46 -Author: Victor Seva -Date: Sat Nov 11 00:29:30 2023 +0100 - - jansson: clang-format for coherent indentation and coding style - -commit e17cd90547ba1ee70007a8a1ac7c74e0cc1f71c4 -Author: Victor Seva -Date: Sat Nov 11 00:29:30 2023 +0100 - - ipops: clang-format for coherent indentation and coding style - -commit 107c3ba8bd24712c33066c72da25ff4bd0d11f76 -Author: Victor Seva -Date: Sat Nov 11 00:29:29 2023 +0100 - - ims_usrloc_scscf: clang-format for coherent indentation and coding style - -commit b37688e8c387ec445b9da75601103579dacbf0ce -Author: Victor Seva -Date: Sat Nov 11 00:29:29 2023 +0100 - - ims_usrloc_pcscf: clang-format for coherent indentation and coding style - -commit 70e9b22ffbf0f066a4384627811de1046062d37c -Author: Victor Seva -Date: Sat Nov 11 00:29:29 2023 +0100 - - ims_registrar_scscf: clang-format for coherent indentation and coding style - -commit 884d30d62b1006e9cfa675bd23692746da63a505 -Author: Victor Seva -Date: Sat Nov 11 00:29:29 2023 +0100 - - ims_registrar_pcscf: clang-format for coherent indentation and coding style - -commit 19082b1761952fba14c73dc6bb50443311ab25dc -Author: Victor Seva -Date: Sat Nov 11 00:29:28 2023 +0100 - - ims_qos: clang-format for coherent indentation and coding style - -commit 4ec37894980362e51d3fc2dbf801df4781aa8173 -Author: Victor Seva -Date: Sat Nov 11 00:29:28 2023 +0100 - - ims_ocs: clang-format for coherent indentation and coding style - -commit 712c4bfe3c787b26ec81cfbb29b0170f4df768e0 -Author: Victor Seva -Date: Sat Nov 11 00:29:28 2023 +0100 - - ims_isc: clang-format for coherent indentation and coding style - -commit 1685254536ec40f72dc02a14f87b3a8bde1cd15a -Author: Victor Seva -Date: Sat Nov 11 00:29:28 2023 +0100 - - ims_ipsec_pcscf: clang-format for coherent indentation and coding style - -commit 223a1f1b91e2b201b17c22a9e475e6a24b4defeb -Author: Victor Seva -Date: Sat Nov 11 00:29:27 2023 +0100 - - ims_icscf: clang-format for coherent indentation and coding style - -commit c76c657fd4926a7d13354b7f51d2a1086750d38e -Author: Victor Seva -Date: Sat Nov 11 00:29:27 2023 +0100 - - ims_diameter_server: clang-format for coherent indentation and coding style - -commit c3cbfec24f6966bfbe0c74f91496a0a6fc5d56be -Author: Victor Seva -Date: Sat Nov 11 00:29:27 2023 +0100 - - ims_dialog: clang-format for coherent indentation and coding style - -commit 9daef643e895591fd6c0525c2ea893aed958afe6 -Author: Victor Seva -Date: Sat Nov 11 00:29:27 2023 +0100 - - ims_charging: clang-format for coherent indentation and coding style - -commit 9ab04f9a9e3941f24a825fede7edb7d9323fc053 -Author: Victor Seva -Date: Sat Nov 11 00:29:26 2023 +0100 - - ims_auth: clang-format for coherent indentation and coding style - -commit 76e0762a7583ef0c203798e07572c3699d0cbcac -Author: Victor Seva -Date: Sat Nov 11 00:29:26 2023 +0100 - - imc: clang-format for coherent indentation and coding style - -commit 1f3491e67c752fd85d5482a51ddd44a58c1c2a3b -Author: Victor Seva -Date: Sat Nov 11 00:29:26 2023 +0100 - - http_client: clang-format for coherent indentation and coding style - -commit 12332368cd934c434118f53ca429fd4373160220 -Author: Victor Seva -Date: Sat Nov 11 00:29:26 2023 +0100 - - http_async_client: clang-format for coherent indentation and coding style - -commit b63b8c6dfd493141f60b3ce67bce0cfc3c15e536 -Author: Victor Seva -Date: Sat Nov 11 00:29:25 2023 +0100 - - htable: clang-format for coherent indentation and coding style - -commit 0deeb0493fbc3d85780206c0cc0608fffd08bbbe -Author: Victor Seva -Date: Sat Nov 11 00:29:25 2023 +0100 - - h350: clang-format for coherent indentation and coding style - -commit 94b11b63003cac33d92313a59cb648889b5e97b6 -Author: Victor Seva -Date: Sat Nov 11 00:29:25 2023 +0100 - - gzcompress: clang-format for coherent indentation and coding style - -commit f84ba84819af565f49b8df1f9fbb749a577fb3c8 -Author: Victor Seva -Date: Sat Nov 11 00:29:25 2023 +0100 - - group: clang-format for coherent indentation and coding style - -commit 3dfbd256e89a87c633d961cd78b20690b34344d8 -Author: Victor Seva -Date: Sat Nov 11 00:29:24 2023 +0100 - - geoip2: clang-format for coherent indentation and coding style - -commit 5d1ad6edb5883bf798b363a02259ef0561e3fb68 -Author: Victor Seva -Date: Sat Nov 11 00:29:24 2023 +0100 - - geoip: clang-format for coherent indentation and coding style - -commit 709327530b5d741a6df1299bb38075e558eee252 -Author: Victor Seva -Date: Sat Nov 11 00:29:24 2023 +0100 - - exec: clang-format for coherent indentation and coding style - -commit a5da6b42e2b8c2650431449e47cb631ecf301fda -Author: Victor Seva -Date: Sat Nov 11 00:29:23 2023 +0100 - - evrexec: clang-format for coherent indentation and coding style - -commit c5db942d88a7aa7bb909a323b3370a7f82ee3f16 -Author: Victor Seva -Date: Sat Nov 11 00:29:23 2023 +0100 - - evapi: clang-format for coherent indentation and coding style - -commit 908e1be70755329033a8aaa00ba1ebec24915ac0 -Author: Victor Seva -Date: Sat Nov 11 00:29:23 2023 +0100 - - erlang: clang-format for coherent indentation and coding style - -commit 4474d7d661bb70515672d519f0b601fd401847c7 -Author: Victor Seva -Date: Sat Nov 11 00:29:23 2023 +0100 - - enum: clang-format for coherent indentation and coding style - -commit dbc27591789e2d67e60f06ea7ead305d719ceaff -Author: Victor Seva -Date: Sat Nov 11 00:29:22 2023 +0100 - - drouting: clang-format for coherent indentation and coding style - -commit c243719c65a7deede938cf712a707a82397e9c5b -Author: Victor Seva -Date: Sat Nov 11 00:29:22 2023 +0100 - - domainpolicy: clang-format for coherent indentation and coding style - -commit 0cef14d72db1372d0ad35ad9f1a53520f7e4a682 -Author: Victor Seva -Date: Sat Nov 11 00:29:22 2023 +0100 - - domain: clang-format for coherent indentation and coding style - -commit eb0d1a0eefc99129877db81ddf4b60999e2e3861 -Author: Victor Seva -Date: Sat Nov 11 00:29:22 2023 +0100 - - dnssec: clang-format for coherent indentation and coding style - -commit 781dce54e591ed3fc170bee54605404f4de8cc4f -Author: Victor Seva -Date: Sat Nov 11 00:29:21 2023 +0100 - - dmq_usrloc: clang-format for coherent indentation and coding style - -commit 81d8d1dc5d2da2f069d7fad1a292c238b9ef24e3 -Author: Victor Seva -Date: Sat Nov 11 00:29:21 2023 +0100 - - dmq: clang-format for coherent indentation and coding style - -commit 7f4544ecdb7c434a8dcad7930dc9d82a0ff80054 -Author: Victor Seva -Date: Sat Nov 11 00:29:21 2023 +0100 - - dlgs: clang-format for coherent indentation and coding style - -commit 5acac37679e07451d2df6f8835d4d23849bc0e8b -Author: Victor Seva -Date: Sat Nov 11 00:29:21 2023 +0100 - - diversion: clang-format for coherent indentation and coding style - -commit 1efb52c14f05479fae2913b55fbebfa6d173e693 -Author: Victor Seva -Date: Sat Nov 11 00:29:20 2023 +0100 - - dispatcher: clang-format for coherent indentation and coding style - -commit 6100f23f93e61f26e67a59ce45b24f86a669cea2 -Author: Victor Seva -Date: Sat Nov 11 00:29:20 2023 +0100 - - dialplan: clang-format for coherent indentation and coding style - -commit 1b87c9d40b3412d3eda55c6c7842ca296234b390 -Author: Victor Seva -Date: Sat Nov 11 00:29:20 2023 +0100 - - dialog: clang-format for coherent indentation and coding style - -commit 5d56861c02c114b1e2bb376de9d179c3651bcd53 -Author: Victor Seva -Date: Sat Nov 11 00:29:20 2023 +0100 - - debugger: clang-format for coherent indentation and coding style - -commit d3c3d1250d18d9f3ea8dacc7c34da4b18e5ee177 -Author: Victor Seva -Date: Sat Nov 11 00:29:19 2023 +0100 - - db_unixodbc: clang-format for coherent indentation and coding style - -commit 54ba86f4ffb5703cadb06278f45237b02c34195a -Author: Victor Seva -Date: Sat Nov 11 00:29:19 2023 +0100 - - db_text: clang-format for coherent indentation and coding style - -commit ebf22b92286ea49fa2cf3335dfd8978e1bda499e -Author: Victor Seva -Date: Sat Nov 11 00:29:19 2023 +0100 - - db_sqlite: clang-format for coherent indentation and coding style - -commit 71caf413928952edef103375a904a0071c7f180f -Author: Victor Seva -Date: Sat Nov 11 00:29:18 2023 +0100 - - db_redis: clang-format for coherent indentation and coding style - -commit 9570512f168411972b99982dc648d52484f46488 -Author: Victor Seva -Date: Sat Nov 11 00:29:18 2023 +0100 - - db_postgres: clang-format for coherent indentation and coding style - -commit 90200f4a1c4dd1bb37f47792470a867324593ef1 -Author: Victor Seva -Date: Sat Nov 11 00:29:18 2023 +0100 - - db_perlvdb: clang-format for coherent indentation and coding style - -commit 5fe03666fdd2242db43513244d159f8f18f73070 -Author: Victor Seva -Date: Sat Nov 11 00:29:18 2023 +0100 - - db_oracle: clang-format for coherent indentation and coding style - -commit 9bfb2ab204bb4739a7f537c56937570ba2ec1ec6 -Author: Victor Seva -Date: Sat Nov 11 00:29:17 2023 +0100 - - db_mysql: clang-format for coherent indentation and coding style - -commit 47d83e1e37d695137ec0543e089e397f1f2ab5c9 -Author: Victor Seva -Date: Sat Nov 11 00:29:17 2023 +0100 - - db_mongodb: clang-format for coherent indentation and coding style - -commit 87d0d85bbe271edfec2b47c77eb9363453e0ea86 -Author: Victor Seva -Date: Sat Nov 11 00:29:17 2023 +0100 - - db_flatstore: clang-format for coherent indentation and coding style - -commit 0506390fe79adf99e7604e9bd894d64049255a04 -Author: Victor Seva -Date: Sat Nov 11 00:29:16 2023 +0100 - - db_cluster: clang-format for coherent indentation and coding style - -commit 34dbf1f6e9f0fa4594358e86d08e43b3fbef6cda -Author: Victor Seva -Date: Sat Nov 11 00:29:16 2023 +0100 - - db_cassandra: clang-format for coherent indentation and coding style - -commit 2eacd4d1f03809a0c360d72e1544645d13f382a9 -Author: Victor Seva -Date: Sat Nov 11 00:29:16 2023 +0100 - - db_berkeley: clang-format for coherent indentation and coding style - -commit 328c50cf7082a566dc45c4027173407fdc281d1c -Author: Victor Seva -Date: Sat Nov 11 00:29:16 2023 +0100 - - db2_ops: clang-format for coherent indentation and coding style - -commit f74546ea60cc8396963629b2f7ecfdb3eda26c54 -Author: Victor Seva -Date: Sat Nov 11 00:29:15 2023 +0100 - - db2_ldap: clang-format for coherent indentation and coding style - -commit 00a589ae940ad57d23ba20a782bd120b0faea7fb -Author: Victor Seva -Date: Sat Nov 11 00:29:15 2023 +0100 - - ctl: clang-format for coherent indentation and coding style - -commit 4aaed849caa4102e1e6dacaf87cb59e3442ca87b -Author: Victor Seva -Date: Sat Nov 11 00:29:15 2023 +0100 - - crypto: clang-format for coherent indentation and coding style - -commit 6a2ddf46c230f52ba3050de09d7ef51db89705c5 -Author: Victor Seva -Date: Sat Nov 11 00:29:15 2023 +0100 - - cplc: clang-format for coherent indentation and coding style - -commit ac887ff9c60afb3d64a7ad0cac93937722cadd61 -Author: Victor Seva -Date: Sat Nov 11 00:29:14 2023 +0100 - - counters: clang-format for coherent indentation and coding style - -commit e62e59bcc5b3b39ca4edd82bf4b47d46ae06970a -Author: Victor Seva -Date: Sat Nov 11 00:29:14 2023 +0100 - - corex: clang-format for coherent indentation and coding style - -commit 8058e9792d2b6edd0b54305f503ffae09cd7e75f -Author: Victor Seva -Date: Sat Nov 11 00:29:14 2023 +0100 - - cnxcc: clang-format for coherent indentation and coding style - -commit 9c710f9f49eae88eafbd5d48f26bc2004b07acf8 -Author: Victor Seva -Date: Sat Nov 11 00:29:13 2023 +0100 - - cfgutils: clang-format for coherent indentation and coding style - -commit 4b93525ee48addb639d9f2e8f3b48d71bbfd9d6f -Author: Victor Seva -Date: Sat Nov 11 00:29:13 2023 +0100 - - cfgt: clang-format for coherent indentation and coding style - -commit 8e0fcf49e099245d56d6c07cf720d87de2eb9f5f -Author: Victor Seva -Date: Sat Nov 11 00:29:13 2023 +0100 - - cfg_db: clang-format for coherent indentation and coding style - -commit 6c90e6d02177a0c011cc622a0a923961a0e4c2f8 -Author: Victor Seva -Date: Sat Nov 11 00:29:13 2023 +0100 - - cdp_avp: clang-format for coherent indentation and coding style - -commit ab5d0672afe477b73b013d659c699dcace9e69aa -Author: Victor Seva -Date: Sat Nov 11 00:29:12 2023 +0100 - - cdp: clang-format for coherent indentation and coding style - -commit 62d86563ac12b21ca58d4348398c33d541521648 -Author: Victor Seva -Date: Sat Nov 11 00:29:12 2023 +0100 - - carrierroute: clang-format for coherent indentation and coding style - -commit 55e3dad09f7e4713e980fbf6644d225d9f3a5367 -Author: Victor Seva -Date: Sat Nov 11 00:29:12 2023 +0100 - - call_obj: clang-format for coherent indentation and coding style - -commit bc433aad6f5113aa82bb1745ddccf568cd182501 -Author: Victor Seva -Date: Sat Nov 11 00:29:11 2023 +0100 - - call_control: clang-format for coherent indentation and coding style - -commit 4e88c91f7d53c89393679d7cbbf1db6b5c271517 -Author: Victor Seva -Date: Sat Nov 11 00:29:11 2023 +0100 - - blst: clang-format for coherent indentation and coding style - -commit 662d2e7b1bb231ffa4df05647ab459df45e6bc91 -Author: Victor Seva -Date: Sat Nov 11 00:29:11 2023 +0100 - - benchmark: clang-format for coherent indentation and coding style - -commit 52660184954ec006e5fd19019f08d7e43231b2a4 -Author: Victor Seva -Date: Sat Nov 11 00:29:10 2023 +0100 - - avpops: clang-format for coherent indentation and coding style - -commit edb835f358c37ea4f7c1c6d93058df7a64a33620 -Author: Victor Seva -Date: Sat Nov 11 00:29:10 2023 +0100 - - avp: clang-format for coherent indentation and coding style - -commit 356ebfff369b3c31faf5beb0325e5348674f85c4 -Author: Victor Seva -Date: Sat Nov 11 00:29:10 2023 +0100 - - auth_xkeys: clang-format for coherent indentation and coding style - -commit 29a5e486f3b6d718602aa54ecbeab16ded3bd67e -Author: Victor Seva -Date: Sat Nov 11 00:29:10 2023 +0100 - - auth_radius: clang-format for coherent indentation and coding style - -commit 63734c2c9673305fcea19a586e1d8c22ca0896c7 -Author: Victor Seva -Date: Sat Nov 11 00:29:09 2023 +0100 - - auth_identity: clang-format for coherent indentation and coding style - -commit 72d7e1ae51e8d5ef7b7fcd6d6669a751981f18ee -Author: Victor Seva -Date: Sat Nov 11 00:29:09 2023 +0100 - - auth_ephemeral: clang-format for coherent indentation and coding style - -commit efd322c9545aa3ea20479ef9e7b86c9d9b50da88 -Author: Victor Seva -Date: Sat Nov 11 00:29:09 2023 +0100 - - auth_diameter: clang-format for coherent indentation and coding style - -commit c8e63afc3eefb48aa467675564b0e112d7c26461 -Author: Victor Seva -Date: Sat Nov 11 00:29:08 2023 +0100 - - auth_db: clang-format for coherent indentation and coding style - -commit 73220b649e74871b2112fe6986275ad38d3691ca -Author: Victor Seva -Date: Sat Nov 11 00:29:08 2023 +0100 - - auth: clang-format for coherent indentation and coding style - -commit 32128afe1c318ef12930315700aaad90f277e5f3 -Author: Victor Seva -Date: Sat Nov 11 00:29:08 2023 +0100 - - async: clang-format for coherent indentation and coding style - -commit a353fd233fe69b4f68dc13a3f3006d58e7d6c878 -Author: Victor Seva -Date: Sat Nov 11 00:29:05 2023 +0100 - - app_sqlang: clang-format for coherent indentation and coding style - -commit f74712ffa1a046c7f2a1bbfbcfda0a2123c70295 -Author: Victor Seva -Date: Sat Nov 11 00:29:04 2023 +0100 - - app_ruby_proc: clang-format for coherent indentation and coding style - -commit c6c092d06eb67a1adc2b8e9cf41aee37fef20a03 -Author: Victor Seva -Date: Sat Nov 11 00:29:04 2023 +0100 - - app_ruby: clang-format for coherent indentation and coding style - -commit 109dcd5e000f132b2a7bea56dcb5bc26a5df0b8c -Author: Victor Seva -Date: Sat Nov 11 00:29:04 2023 +0100 - - app_python3s: clang-format for coherent indentation and coding style - -commit 36e1b4ddd1fa19d0e2e8be784f542be3d8b7437e -Author: Victor Seva -Date: Sat Nov 11 00:29:03 2023 +0100 - - app_python3: clang-format for coherent indentation and coding style - -commit 7c49badf234fae4c85e142384fd5144edec6fc95 -Author: Victor Seva -Date: Sat Nov 11 00:29:03 2023 +0100 - - app_python: clang-format for coherent indentation and coding style - -commit bead4642b486884c27b04689d1ea6ccee0bebc6c -Author: Victor Seva -Date: Sat Nov 11 00:29:03 2023 +0100 - - app_perl: clang-format for coherent indentation and coding style - -commit 01232021a62be5328863621011888994dcbad0c4 -Author: Victor Seva -Date: Sat Nov 11 00:29:02 2023 +0100 - - app_mono: clang-format for coherent indentation and coding style - -commit 5c1b3d0ca19e211e13c83e4645aaa2612317cd4e -Author: Victor Seva -Date: Sat Nov 11 00:29:02 2023 +0100 - - app_lua_sr: clang-format for coherent indentation and coding style - -commit 97a2b7f2a7ee93506e9c0f4bb87a49ff561993b2 -Author: Victor Seva -Date: Sat Nov 11 00:29:02 2023 +0100 - - app_lua: clang-format for coherent indentation and coding style - -commit a1f0ffa96d2ff4812661abdfb3b09b446b06b516 -Author: Victor Seva -Date: Sat Nov 11 00:29:01 2023 +0100 - - app_jsdt: clang-format for coherent indentation and coding style - -commit b3d2f6098ad6872682599caef06fde5a7667ba32 -Author: Victor Seva -Date: Sat Nov 11 00:29:01 2023 +0100 - - app_java: clang-format for coherent indentation and coding style - -commit 2c8f49c133e8cda2f12c4d062fce1c1b9f6d13e4 -Author: Victor Seva -Date: Sat Nov 11 00:29:01 2023 +0100 - - acc_json: clang-format for coherent indentation and coding style - -commit d5cd8420ab58a0d0aafa9d52f205139c12f3fcd4 -Author: Victor Seva -Date: Sat Nov 11 00:29:00 2023 +0100 - - acc_diameter: clang-format for coherent indentation and coding style - -commit 9eda893ec73636c19cd3bad027c6cdd02274fa1a -Author: Victor Seva -Date: Sat Nov 11 00:29:00 2023 +0100 - - acc: clang-format for coherent indentation and coding style - -commit 9cc724115a21331621d126d04f7e83cad0de7227 -Author: Victor Seva -Date: Sat Nov 11 00:12:51 2023 +0100 - - lib: clang-format for coherent indentation and coding style - -commit 2c98a073ecddb8dae8107e2bc30f5a3c78665ace -Author: Victor Seva -Date: Sat Nov 11 00:11:22 2023 +0100 - - core: clang-format for coherent indentation and coding style - -commit 7af9dc940e29fa3aecda011096820e011de0b254 -Author: Victor Seva -Date: Mon Oct 23 14:36:49 2023 +0200 - - pv_headers: pvh_xavi_get_child() fix fallback logic - - * don't fallback to Initial request headers for Replies - - (cherry picked from commit 19a32b863d9a79c0cbaf04a7a9864e0c08a914f7) - -commit 02958e56fed877275b98a5cf0c568cc4e9175a8c -Author: Daniel-Constantin Mierla -Date: Mon Oct 16 10:46:34 2023 +0200 - - jwt: use proper internal function for jwt_verify_key() - - (cherry picked from commit 319df7fc417e898e945cac0d44e978c9ff151e3c) - -commit bfbabc3407b984028fd47afdfde5217aef3d6fe5 -Author: Daniel-Constantin Mierla -Date: Fri Oct 6 13:48:42 2023 +0200 - - pkg/kamailio/scripts: wrap param around quotes to avoid invalid syntax on empty - - Cherry-pick from 18b23187dd - -commit 42f203569bc3dd2e4a6adb56803f34290f581c08 -Author: S-P Chan -Date: Thu Oct 5 10:55:26 2023 +0800 - - pkg: RPM - add mock config for EL8/EL9 based on alma+epel-(8|9)-x86_64 - - This mock config can be used to build RPM packages from a kamailio src.rpm. - - update pkg/kamailio/obs/README -> README.md to include mock - instructions - - add script create-src-rpm.sh to create src.rpm for package - building - - Cherry-pick from 9de780b8a7 - -commit 04ef5978df1937a8b23f245edb5f51a0bf544cae -Author: S-P Chan -Date: Thu Oct 5 09:45:23 2023 +0800 - - pkg: add example script to create tarball with submodules instantiated - - In preparation for packaging of tls_wolfssl, add an example script to - create source tarball with submodule code. - - Cherry-pick from aed35ddb6a - -commit c94a185e36709241438cb07f38b7c26f72f40e05 -Author: S-P Chan -Date: Fri Oct 6 07:22:28 2023 +0800 - - Update wolfSSL to v5.6.3-stable - -commit ee9ed43318c8e49432445d33b475c67a3643d761 -Author: S-P Chan -Date: Thu Oct 5 00:58:57 2023 +0800 - - tls_wolfssl: clean up build - - Allow module to build if user specifies prefix= exec-prefix= on - commandline - - Cherry-pick from a327cc0e3e - - -===================== 2023-09-27 Version 5.7.2 Released ===================== - -===================== Changes Since Version 5.7.1 =========================== - - -commit 0a91d8a6f25c83094e0ff7cc0f16ecfe3488b378 -Author: Daniel-Constantin Mierla -Date: Wed Sep 27 09:00:32 2023 +0200 - - Makefile.defs: version set to 5.7.2 - -commit 5b31a87cb90c4f81bc48b4f0f1fbd52825967de3 -Author: Daniel-Constantin Mierla -Date: Wed Sep 27 08:45:03 2023 +0200 - - pkg: deb specs updated for v5.7.2 - -commit 549e7903ef40086d933c756b43e35a1d22a38401 -Author: Daniel-Constantin Mierla -Date: Wed Sep 27 08:43:49 2023 +0200 - - pkg: version set to 5.7.2 for rpms and alpine specs - -commit 5d07b647680543752512ae89b8ec23fa9a2cbd8a -Author: Daniel-Constantin Mierla -Date: Wed Sep 27 08:01:48 2023 +0200 - - kamctl: updated the version to reflect kamailio series - -commit 2f0b2189f52927cdcb17c63087d31e637c4b716f -Author: Daniel-Constantin Mierla -Date: Wed Sep 27 08:01:04 2023 +0200 - - etc/kamailio.cfg: updated the version in comments - -commit f764cef139d55adb5d38ffc6a1a65fd14bda5f4c -Author: Daniel-Constantin Mierla -Date: Tue Sep 26 08:06:42 2023 +0200 - - rabbitmq: backport of RABBITMQ_ERR_CREATE needed for handling allocation error - -commit e202f597e1725c204eb33fa7b6266d9ce934be09 -Author: Kamailio Dev -Date: Mon Sep 25 20:02:22 2023 +0200 - - modules: readme files regenerated - modules ... [skip ci] - -commit 1f27bdfc5cc25b9d2f06204169131d9843cc252a -Author: Daniel-Constantin Mierla -Date: Mon Sep 25 19:51:26 2023 +0200 - - Revert "pv_headers: compare result of pvh_set_xavi() with NULL for error cases" - - This reverts commit 3bb59945d59ae438897a8f797dc2f06489728459. - -commit 9be895a16c91bcf4eb299ce0ffb14624755baa48 -Author: Дилян Палаузов -Date: Fri Aug 25 20:54:52 2023 +0200 - - [app_lua] clarify the file scripts can be in source or bytecode - - (cherry picked from commit a8747aa02ff3fbffd7a63bdc1e5c06188472edfa) - -commit 59d0ebe41017c2270b62f6171285bae02673da3a -Author: Daniel-Constantin Mierla -Date: Thu Sep 7 14:16:49 2023 +0200 - - core: parser - set via->params.len when body is finished - - (cherry picked from commit 82b0f273e1cf65051b6c50301c5073dce56c1149) - -commit 35f0efadeceaecc8e3315f4682d9ac4eba36e363 -Author: Daniel-Constantin Mierla -Date: Wed Aug 23 13:03:02 2023 +0200 - - msilo: cast to fix storage size warning - - (cherry picked from commit c11fcbbe9ed19bc54b800100d15d9ae269735f0c) - -commit 34885ab83c0c259376ffda04b41253eb9271780f -Author: Daniel-Constantin Mierla -Date: Wed Aug 23 10:55:35 2023 +0200 - - pv_headers: compare result of pvh_set_xavi() with NULL for error cases - - - the function returns a pointer - - (cherry picked from commit 5633026f90e46f7d6da8c1a658d425e8926f6949) - -commit fac1995c8730a83c24036c9d01d52b674291860b -Author: Daniel-Constantin Mierla -Date: Mon Sep 25 19:30:25 2023 +0200 - - db_redis: free db_keys in case of failure - - - backport of 027c2b30b39a7596c8630c06995ddc49bb42d789 - -commit 3a217af6b9229989b3c7a788a01609e9513024c4 -Author: Daniel-Constantin Mierla -Date: Tue Aug 22 17:09:37 2023 +0200 - - rabbitmq: proper check for allocated pointer - - (cherry picked from commit 4d58141ab84cf248e8c44a96181642ad0f187e80) - -commit 34a2d87479d1bcc37d74f3d8fcb4186aea90fc84 -Author: Rick Barenthin -Date: Tue Aug 15 22:30:58 2023 +0200 - - core: cfg.y typo in parsing XAVPVIAFIELDS - - In the XAVPVIAFIELDS block there is the string written to the wrong variable. - - The string is stored in _ksr_xavp_via_params.s but the lenght is stored in _ksr_xavp_via_fields.len. This breaks XAVPVIAPARAMS and XAVPVIAFIELDS. - - (cherry picked from commit 722a79a9ba8ca2608e699ec14684ce004ae10d60) - -commit 516894e37e53bf17d29a4c95add29df7f70bcb8f -Author: Henning Westerholt -Date: Tue Aug 15 14:16:07 2023 +0000 - - ims_ipsec_pcscf: typo in spi_add function definition, GH #3513 - - - fix typo in spi_add function definition - - patch from jbipre2, GH #3513 - - (cherry picked from commit a053bcc391f0680ecd5f458d2512e57f69499d39) - -commit 774b464af7c561e49253066e8ce3b4ee55463d9a -Author: Daniel-Constantin Mierla -Date: Sat Aug 12 13:30:39 2023 +0200 - - xhttp: note about available variables during http request processing - - (cherry picked from commit 170067e633ef32ea7b17adad46fdfe2c85fadda0) - -commit 5b1592900920143c9ce5c188e2835c1afd27d489 -Author: Daniel-Constantin Mierla -Date: Fri Aug 11 20:16:37 2023 +0200 - - http_async_client: docs - dependency on libevent - - - list style for dependencies and links to projects - - (cherry picked from commit f16d2658bbefb7a9f43076cbaa958fb3a27f6a0c) - -commit 90bd4424e17bc07a9073fd50bbd6d8b608ad4da9 -Author: Дилян Палаузов -Date: Sat Jul 22 14:15:09 2023 +0200 - - etc/ typos - - (cherry picked from commit 6e9335ff2245596b74bc1c749d1e7805bf186f02) - -commit 9276342ea90acffc3d631c6175c1f70c5c4fbacc -Author: Дилян Палаузов -Date: Wed Jun 21 21:29:41 2023 +0200 - - mohqueue: typo - - (cherry picked from commit 0dcaaed5148cba775cebfd88d8e4a593f8c4297d) - -commit 3e197c7c41c97badece29cbc6477119180b8dcad -Author: MVONDO Eric OBS/OINIS -Date: Tue Jun 20 10:22:48 2023 +0100 - - siptrace: fix pseudo var direction attribute length - - (cherry picked from commit 508886c3054a8470fe4469e78e63aa37ae93922d) - -commit 1b42a7036714a0e50bc61bd9e0619f9a2d36bcf8 -Author: Daniel-Constantin Mierla -Date: Fri Jul 7 17:41:15 2023 +0200 - - registrar: increase max size for user and domain building aor - - - renamed max aor lenght define to match the user and domain style - - (cherry picked from commit b1356efd61e56eaa3426d8e2e813ea6730b4f2c9) - -commit ba7b3155611fd983f7d3d244e7b525a483998d3f -Author: Daniel-Constantin Mierla -Date: Thu Jul 6 21:26:28 2023 +0200 - - kex: safety checks when iterating stats list - - - GH #3186 - - (cherry picked from commit 883f6b77211a76b35a9df570a8ddbbc344b05472) - -commit b59009089ad2b7cc33af27b637a81396b240660d -Author: Henning Westerholt -Date: Wed Jul 5 07:04:46 2023 +0000 - - tm: remove obselete comment, add clarification for reply_wait mode 2 - - (cherry picked from commit 2dbaa727a38e29da0f887fa5d0d8d20392839f9b) - -commit 80b26beb7d4f9cd4b3858e9e2dae4588feec8e28 -Author: Norbert Koppány Legyes -Date: Tue Jul 4 17:27:17 2023 +0200 - - xlog: fix docs example for modparam methods_filter - - (cherry picked from commit b5a37683e364f596b6c5b4ebbba1fff951d7be84) - -commit e681aa8236b502de31ad6600932517a259b6b62e -Author: Daniel-Constantin Mierla -Date: Fri Jun 30 08:49:19 2023 +0200 - - jansson: print unknown type in log message - - (cherry picked from commit b8cae4fbcd026ffb81e8242500212582d9672ad5) - -commit 704cc393dd310c9db6db34214597e3134b40367f -Author: Stefan-Cristian Mititelu -Date: Fri Aug 18 10:59:57 2023 +0300 - - ims_dialog: kemi export some functions - - (cherry-picked from commit 3994410) - -commit c51bc6c05428e8d66ddd6addcc1c0b4bbf4705f1 -Author: Stefan-Cristian Mititelu -Date: Wed Aug 16 11:01:08 2023 +0300 - - ims_qos: kemi export - - (cherry picked from commit eb23e6b) - -commit 1cf389829bebad2013a6cf3b4ab919fa6b78a7c2 -Author: Victor Seva -Date: Thu Jul 20 14:04:30 2023 +0200 - - crypto: SHA1_Init deprecated at openssl 3.0 - - From https://www.openssl.org/docs/man3.0/man7/migration_guide.html - - > Use of low-level digest functions such as SHA1_Init(3) have been informally - > discouraged from use for a long time. Applications should instead use the - > high level EVP APIs EVP_DigestInit_ex(3), EVP_DigestUpdate(3) and - > EVP_DigestFinal_ex(3), or the quick one-shot EVP_Q_digest(3). - - related to #3502 - - (cherry picked from commit e55a6ed0f24c9b81d8d3ad27ba25d4d88c474483) - -commit 20be29ab3638d803341ec376b02edd7c14a9174a -Author: Stefan Mititelu -Date: Wed Jul 19 13:48:09 2023 +0300 - - dialog: set cbs list to NULL after destroying - - (cherry picked from commit 6881faadec45dd16dd896b13db44862e7df70422) - -commit 44130062640ccbbc7e796cc748d432fe3382c328 -Author: Stefan Mititelu -Date: Wed Jul 5 13:56:21 2023 +0300 - - ims_qos: check and log for NULL sessionId - - (cherry picked from commit 1b291315b43da1148cee5f3821ddbe49b0c86b7f) - -commit 7630473f57c7c0ad600067cea7a89693d9926a81 -Author: Daniel-Constantin Mierla -Date: Mon Jul 3 08:26:07 2023 +0200 - - http_client: use LIBCURL_VERSION_NUM instead of CURL_AT_LEAST_VERSION - - - older distros have compilers that don't cope with the later - - (cherry picked from commit 7cd32bf9631a81c7c4382d45f498bdc9c7f9b34c) - - - -===================== 2023-06-28 Version 5.7.1 Released ===================== - -===================== Changes Since Version 5.7.0 =========================== - - -commit aaadeb3a1d75a2525ee2e209c3c41cf1b5a0a6ea -Author: Daniel-Constantin Mierla -Date: Wed Jun 28 09:37:37 2023 +0200 - - Makefile.defs: version set to 5.7.1 - -commit 8e39591a6a2a94c34ab01844d267642acfbb944b -Author: Daniel-Constantin Mierla -Date: Wed Jun 28 09:36:40 2023 +0200 - - pkg: deb specs updated for v5.7.1 - -commit 39e18a7f38a06cd4d436e05ab3af5ff2b840f090 -Author: Daniel-Constantin Mierla -Date: Wed Jun 28 09:35:05 2023 +0200 - - pkg: version set to 5.7.1 for rpms and alpine specs - -commit 402bab6f63b515a13a72ac2dad6e40075ded1479 -Author: Victor Seva -Date: Fri Jun 23 09:06:43 2023 +0200 - - utils/kamcmd: fix memory leak - - fixes #3478 - - (cherry picked from commit badc81cb427ba5aaf03ca26e4c2654d58ee08588) - -commit 9905c4ffc181f5a3e32bc20965c78542c7f15d12 -Author: Daniel-Constantin Mierla -Date: Wed Jun 21 14:15:24 2023 +0200 - - tls: enable locking for rand ctx if libssl version is 3.0+ - - (cherry picked from commit 81be9e78c3731d45734480285d7afc17f8f9e87a) - -commit 2bd813b0c4c1b942ee634eca5e68a025be9fab8e -Author: Daniel-Constantin Mierla -Date: Thu Jun 22 14:37:18 2023 +0200 - - http_client: fix depecration of CURLOPT_REDIR_PROTOCOLS - - - GH #3492 - - (cherry picked from commit 4d8263f9be97a541a24cbc6acc9855509640780b) - -commit ff0e0d7aafa3905526599e604ff91542529a5b32 -Author: Victor Seva -Date: Thu Jun 22 17:29:48 2023 +0200 - - tls: fix build for openssl < 1.1.1 - - OPENSSL_INIT_ATFORK was introduced in libssl 1.1.1 - error introduced at 9d6bfb96528c49e6aaa39aa47be877ca528c3537 - - (cherry picked from commit 82f5fcbf88ee3058bd9da520b528c86393cc422a) - -commit 23a121e5d8ffa172f71433c2ef74f323a54e8315 -Author: Daniel-Constantin Mierla -Date: Wed Jun 21 09:27:28 2023 +0200 - - http_client: fix depecration of CURLOPT_PROTOCOLS and CURLINFO_SIZE_DOWNLOAD - - - GH #3484 - - (cherry picked from commit b7b3c67fc1205d114fadf360a594930ef69835a3) - -commit 8cc9ec410ff359e3d93e994c210977a8baa578c4 -Author: Victor Seva -Date: Mon Jun 19 20:12:17 2023 +0200 - - tls: disable tls_rand for openssl >= 3.0 - - From https://www.openssl.org/docs/man3.0/man3/RAND_set_rand_method.html - - > All of the functions described on this page are deprecated. - > Applications should instead use RAND_set_DRBG_type(3), EVP_RAND(3) and - > EVP_RAND(7). - - (cherry picked from commit c4b04696a6bfe31fdd65fa56529b0d46f2774067) - -commit d4b7333ca126ae7c77ec8f095f8728234d0dfe43 -Author: Victor Seva -Date: Mon Jun 19 13:36:53 2023 +0200 - - tls: disable engine for openssl >= 3.0 - - From https://www.openssl.org/docs/man3.0/man7/migration_guide.html - - > The refactoring to support Providers conflicts internally with the APIs - > used to support engines, including the ENGINE API and any function that - > creates or modifies custom "METHODS" - - From https://www.openssl.org/docs/man3.0/man3/ENGINE_init.html: - - > All of the functions described on this page are deprecated. Applications - > should instead use the provider APIs. - - (cherry picked from commit a0a9373ccb3d3da3a1e9e1335d904fcf013d9ebd) - -commit 6669c0befcd69f5d5e196c53188bed58a6a9e1c2 -Author: Victor Seva -Date: Tue Jun 13 12:37:21 2023 +0200 - - tls: OPENSSL_fork_[prepare|parent|child] deprecated at openssl 3.0 - - From https://www.openssl.org/docs/man3.0/man3/OPENSSL_fork_prepare.html: - - > OPENSSL_fork_prepare, OPENSSL_fork_parent, OPENSSL_fork_child have been - > deprecated since OpenSSL 3.0. - > - > These methods are currently unused, and as such, no replacement methods - > are required or planned. - > - > OpenSSL has state that should be reset when a process forks. For - > example, the entropy pool used to generate random numbers (and therefore - > encryption keys) should not be shared across multiple programs. The - > OPENSSL_fork_prepare(), OPENSSL_fork_parent(), and OPENSSL_fork_child() - > functions are used to reset this internal state. - > - > OPENSSL_init_crypto(3) will register these functions with the - > appropriate handler, when the OPENSSL_INIT_ATFORK flag is used - - (cherry picked from commit 9d6bfb96528c49e6aaa39aa47be877ca528c3537) - -commit f1ebf365e8054fbca260b8574bea502b32435382 -Author: Daniel-Constantin Mierla -Date: Tue Jun 20 09:14:48 2023 +0200 - - Makefile.groups: added posops to extra group - - (cherry picked from commit 87959c23aacf4cfa7ed8acd214f70775939c8a01) - -commit 85e3a2bce7ba4d8c6e9c167c732dad11706f99d3 -Author: Kaufman -Date: Sun Oct 9 11:14:37 2022 -0400 - - pkg/docker: submodule update [skip ci] - -commit 6005e8e4e3e0d9488693eca1484122dfed303ac6 -Author: Sergey Safarov -Date: Mon Jun 12 22:20:57 2023 +0300 - - pkg/kamailio/alpine: packaged lwsc - - (cherry picked from commit 768dd96da6f52e46bc227d9815f7225b33042295) - -commit 3e510ac68a4b9bc99b6ade5cb7cc862adcbb9eb9 -Author: Kamailio Dev -Date: Mon Jun 19 14:17:02 2023 +0200 - - modules: readme files regenerated - modules ... [skip ci] - -commit 8087b2fed765115bf0fd238c0c987fdbb12e1d31 -Author: Daniel-Constantin Mierla -Date: Mon Jun 19 13:18:59 2023 +0200 - - core: kemi - propagate bool as a return value type - - - some scripting languages differentiate bool false|true vs int 0|1 values - - (cherry picked from commit f36744cf15c7fcddc7422f97a508cad600ca7d98) - -commit 91cb5d0adf887db6a34e2a394ab34aae51f475bf -Author: Ovidiu Sas -Date: Mon Jun 12 12:00:13 2023 -0400 - - mqueue: fix documentation to match the code - - (cherry picked from commit 23d43645332451ec1ec6dab11da777f9c3bfe304) - -commit faf7941042c1e00a68f6ac36d14568b35a666dbc -Author: Daniel-Constantin Mierla -Date: Mon Jun 12 17:16:53 2023 +0200 - - cdp: check setsockopt() return code - - (cherry picked from commit 39f09877e650d66e820ca7eb0d61416818d174fc) - -commit a8094a3b0bb73be70500b4cbbfb2e99e00d15243 -Author: Daniel-Constantin Mierla -Date: Mon Jun 12 16:27:46 2023 +0200 - - auth_diameter: free req in some cases of errors - - (cherry picked from commit fb19f0ea4c656afe7b60788efb8804e552fd37f9) - -commit 39262e50389d41c50d0e6ff2ae2b0a2521f91640 -Author: Daniel-Constantin Mierla -Date: Mon Jun 12 15:53:38 2023 +0200 - - dialplan: restructured condition on input and output params - - (cherry picked from commit f99b116e876170709ad364ac2b8093969a939d4a) - -commit c6af81fad763114c1cec74927787388afffce66d -Author: Daniel-Constantin Mierla -Date: Mon Jun 12 11:16:51 2023 +0200 - - Makefile: fixed paths for init.d scripts install on debian and centos - - - GH #3476 - - (cherry picked from commit c285b16bc066ca4236ee00cf3e7fb24539fa9f2b) - -commit 4f3c32e48b79688ab905802c173b981f92c54e56 -Author: Henning Westerholt -Date: Mon Jun 12 08:24:01 2023 +0000 - - tools: use python3 for route_graph.py tool, for old systems with both python2/python3, fix file closing - - (cherry picked from commit 7b1fe0483b684693c7baea9b62b471b64c6e22a9) - -commit 14638ef43f9b2ef710ae3a6464fb5db0b9de3377 -Author: Akash Gupta -Date: Sat Jun 10 14:48:03 2023 +0530 - - tool: port the route_graph.py script to python version 3.x - - (cherry picked from commit fa2a69e2ae919b7ba221e87e2001bde83113ce2a) - -commit cd665a135e0046b915af7afd9135a2c29a7933df -Author: Ovidiu Sas -Date: Mon Jun 12 00:24:15 2023 -0400 - - mqueue: fix support for db_text - - db_operations are safe only after db mod_init() - - closes #3474 - - (cherry picked from commit 848d55388dda0c135820d9f24950561946249bbc) - -commit 9c78c0f55dc2aefa53872b26162ddae5b553d66a -Author: Daniel-Constantin Mierla -Date: Thu Jun 1 13:39:47 2023 +0200 - - ims_usrloc_scscf: docs - type int for hash_size parameter - - (cherry picked from commit 1217c9098bc8790e659959a7df97e441e84b54ff) - -commit b68cb1ace4d44ba0a471a9fd9a6138f3738efef4 -Author: Daniel-Constantin Mierla -Date: Wed May 31 11:53:14 2023 +0200 - - async: use _async_timer_exec_last_slot = UINT_MAX for initial value - - (cherry picked from commit bc544daea2ee4bb568cf0314f6d32b8aa0c81ecc) - -commit febfc9722f83d992a3c1643fa373468b73cb3fa0 -Author: Daniel-Constantin Mierla -Date: Wed May 31 09:01:13 2023 +0200 - - sst: fix condition on sst_min_se for sst_check_min() - - (cherry picked from commit a059af04ac47fd31238ca4f22ad868529e035c43) - -commit 3b6d0bd508d62b6f6cd0176551311d25225bf63e -Author: Daniel-Constantin Mierla -Date: Tue May 30 17:00:27 2023 +0200 - - cfgt: reworked test on dest.s for freeing - - (cherry picked from commit b2f99145fa7f4088c80dd3e759372445f93f5492) - -commit c29d5299650ddabb9a5b61c7b6a72a69a68c5b9e -Author: Daniel-Constantin Mierla -Date: Mon May 29 08:56:19 2023 +0200 - - cdp: reworked switch for setting x->state = ACC_CC_ST_DISCON - - (cherry picked from commit cb6332982edff5fd2f10b6ee41c22388cc9a39b3) - -commit e95a79eef0589be2f7d0470bfe6ba19b006730c6 -Author: Daniel-Constantin Mierla -Date: Wed May 24 21:06:45 2023 +0200 - - siprepo: check if list is set on insert - - (cherry picked from commit 423a818cf6e8f6d672630a0365e13877a173508f) - -commit 408643ec916bc00f9f9447952e553d129f8ec896 -Author: Daniel-Constantin Mierla -Date: Tue May 23 09:41:13 2023 +0200 - - ipops: create container items if not found for srv and naptr functions - - - GH #3419 - - (cherry picked from commit 7971d825361bee29d65fcea69f2978d7af31eeaa) - -commit 1c23c2ff23b5c25c943856f5064739794d71bc7f -Author: Daniel-Constantin Mierla -Date: Fri Jun 2 21:20:59 2023 +0200 - - pv: exported {val} transformation - - (cherry picked from commit 79b82198075250420cb08d6b5fd5b100ff672606) - -commit da7944e2f4c7e6f344d125da325c388e1836662f -Author: Henning Westerholt -Date: Thu May 18 10:52:52 2023 +0000 - - dispatcher: fix force send socket functionality, was not working in some TCP scenarios - - (cherry picked from commit 6183319381573e42b882d05ae1748539f7547d8c) - - -===================== 2023-05-17 Version 5.7.0 Released ===================== - -===================== Changes Since Version 5.6.0 =========================== - - -commit 4ef477e6c33af829d9b7064019741eefcfdbfc44 -Author: Daniel-Constantin Mierla -Date: Wed May 17 11:30:37 2023 +0200 - - Makefile.defs: version set to 5.7.0 - -commit c5a22a4bfc9310f41facf8dfe8aa9c610f432817 -Author: Daniel-Constantin Mierla -Date: Wed May 17 11:21:08 2023 +0200 - - Makefile.defs: set LIBSSL_SET_MUTEX_SHARED by default to 1 - - - one can set LIBSSL_SET_MUTEX_SHARED=0 in make command line to switch - to detection mode if it is need to set it or not based on libssl - version - - GH #3458, GH #3384 - - (cherry picked from commit 5e0fb402a7755ea22c41c0b8fcefbdf9694442b8) - -commit 520d1b4acb749b1052a13c12a51fae188df1378d -Author: Daniel-Constantin Mierla -Date: Wed May 17 09:57:20 2023 +0200 - - topoh: don't set 0 twice at the end of masked/unmasked call-id - - - fomatting updates - - (cherry picked from commit 4c524547e1fdd4aa6dfa0ed0ada57b002296a258) - -commit f34ae12f63f0ed8d0577de3b36843cd5b96a7a36 -Author: Daniel-Constantin Mierla -Date: Wed May 17 09:52:37 2023 +0200 - - topos: small formatting fixes - - (cherry picked from commit 991de5e51e799a0110b7aa489eb27f4f01f5dfd2) - -commit ac118abdcb89e5e4ace524d9dbd27c0795f178d9 -Author: harish -Date: Wed May 17 00:21:21 2023 +0530 - - topoh: memory leak fix for API call - - th_mask_callid_str & th_unmask_callid_str funtions used for API call to - encode/decode call-ID uses static array declaration for callid_mbuf was - unable to free callid data lump after use and leads to memory leak. - when these futions was used through API call for topos memory leak bug - as reported - qm_free(): BUG: bad pointer 0x7faec4a7xxxx (out of memory block!) called - from core: core/data_lump.c: free_lump(470) - - (cherry picked from commit 85b62cefa8d33bc736f1ab16e7c40646c903c812) - -commit a651304380283854f916b8e6fae8ff0a4937d411 -Author: Sergey Safarov -Date: Wed May 17 09:23:07 2023 +0300 - - pkg/kamailio/obs: packaged math module - - (cherry picked from commit bafefbc841eb7a6929baeff0b3fbe185860f4290) - -commit 72db97b7b8618e6cc9eed80ef670495547b7c2d0 -Author: Victor Seva -Date: Tue May 16 12:58:47 2023 +0200 - - pkg/kamailio/deb: version set 5.7.0 [skip ci] - -commit 422d469fb52c31074ff00eec445eff45fdfebb39 -Author: Kamailio Dev -Date: Tue May 16 18:16:35 2023 +0200 - - modules: readme files regenerated - modules ... [skip ci] - -commit 7e53506f27a6198d5f64799f2a8d672c5212d69c -Author: Daniel-Constantin Mierla -Date: Tue May 16 13:32:35 2023 +0200 - - topos: formatting and debug cleanup after last commit with callid masking - - (cherry picked from commit f4dc688548aa7753af93ce6e9089b53e9fc4c7ec) - -commit 7e1f330e2dc916138aa9a899da49c452b9f59740 -Author: harish -Date: Fri Jan 27 01:20:59 2023 +0530 - - Topos: Added CallID Mask Document for Topos - - Added document for Call-ID Mask in Topos Module - - (cherry picked from commit 14d4b2422c0fed27fecf01665197f9d0669aa24e) - -commit a16f4e43b75da4bf9c486efd5127cde223f16416 -Author: harish -Date: Fri Jan 27 01:15:46 2023 +0530 - - Topos: Added Call ID mask when sending to Downstream - - Added Call-ID mask while sending the request to Downstream and unmasking - when receiveing from downstream - - (cherry picked from commit d98ff2aab3d3e379fa27da187fbd069c23fb0fe9) - -commit 27ab4b757805083c231ceb109a46f5501b1baa7c -Author: Daniel-Constantin Mierla -Date: Tue May 16 17:28:02 2023 +0200 - - htable: set dbload filed on empty db result - - (cherry picked from commit ba9d663c5d382edef3c98b31aa4341b21c307a34) - -commit 94717b13f2b75522fcc60180ab192710bdc7ca71 -Author: Daniel-Constantin Mierla -Date: Tue May 16 12:45:57 2023 +0200 - - core: use unsigned long (j) for rpc core.shmmem - - - GH #3450 - - (cherry picked from commit 94dd64a5238b4bf60ca21e09e216c01166f4a93f) - -commit 20ca1f8164dd5da70b0490300f2a57f65ff9a663 -Author: Daniel-Constantin Mierla -Date: Tue May 16 12:20:36 2023 +0200 - - jsonrpcs: give spath parameter for storing result - - (cherry picked from commit 1d5722e18e04e8935b342d303fe265c5d8f06e8e) - -commit 55b39daa32c46c33d01d610c3a1dcf836d4dfb3c -Author: Daniel-Constantin Mierla -Date: Tue May 16 09:02:51 2023 +0200 - - ChangeLog: preparing content for v5.7.0 - -commit 2cff2d5117521ce02a2847cc7d1db54203bbccce -Author: Daniel-Constantin Mierla -Date: Tue May 16 08:45:33 2023 +0200 - - README: version updated to 5.7 - -commit 87aebe3be58a757843d3846174bc3b6224cf36c8 -Author: Victor Seva -Date: Mon May 15 22:33:33 2023 +0200 - - Revert "tls_wolfssl: use wolfssl lib from system if available" - - This reverts commit 8ed9cf81c045d7946b07d8c98686acf92cd68776. - -commit 8c18824c8f754f2e4ef2cef44c32f124fb088ffe -Author: Victor Seva -Date: Mon May 15 22:33:23 2023 +0200 - - Revert "pkg/kamailio/deb: introduce wolftls package" - - This reverts commit c9de94ede7e6127b824c7d0667b306eef5c11127. - -commit 1b55a80b71bf9a7edfe29eb40627b472565ace69 -Author: Henning Westerholt -Date: Mon May 15 13:22:09 2023 +0000 - - topos: fix early-dialog b-side UPDATE requests routing (GH #3437) - - (cherry picked from commit 091dc9a76bcec5c8a4bc73e863ed10b1b9d76c92) - -commit 8ed9cf81c045d7946b07d8c98686acf92cd68776 -Author: Victor Seva -Date: Mon May 15 13:35:48 2023 +0200 - - tls_wolfssl: use wolfssl lib from system if available - - (cherry picked from commit 14b1f79c29f317c74bbcbba75853ce45c353a865) - -commit 5e8ea292e4d5e403509f75016f1685d793912a1f -Author: Victor Seva -Date: Mon May 15 12:17:38 2023 +0200 - - github: refresh branch [skip ci] - -commit c9de94ede7e6127b824c7d0667b306eef5c11127 -Author: Victor Seva -Date: Mon May 15 11:19:42 2023 +0200 - - pkg/kamailio/deb: introduce wolftls package - - (cherry picked from commit 13430c2e8b9fccf7565ddcf38dcab8e516cebef0) - -commit 04b49bb89fe6482a351a06ed08a9e9db5e934faf -Author: Richard Fuchs -Date: Tue May 9 15:05:39 2023 +0200 - - rtpengine: fix unaligned memory access - - Make sure the pointers we return from our continuous memory buffer is - always 64-bit aligned as it's used not only for strings, but also for - structs/objects, and such unaligned memory access is undefined on some - archs and flagged as such by ASAN. - - From https://github.com/sipwise/rtpengine/commit/ade8100d3b10308f1ff63f8cb06fdf292618edca - - fixes #3444 - - (cherry-picked from commit 43ac6b27d7ca7bc522f362c25ebb3c22ab918280) - -commit 5f3ed08b5e234465d4fb909460367a63ed63a550 -Author: Victor Seva -Date: Tue May 9 23:28:04 2023 +0200 - - dialplan: fix ki_dp_translate() checks for input/output parameters - - fixes #3447 - - (cherry picked from commit ab0a2be6b522c1b48a2442447c24e7ab156e3d4e) - -commit 3bab39400f493647f8d6ec98c361b95cb43f0295 -Author: Victor Seva -Date: Thu May 4 20:12:32 2023 +0200 - - lcr: fix crash be calling load_gw* via KEMI - - move the check of lcr_id to the helper - - fixes #3435 - - (cherry picked from commit c88e506fe6a1ba0f588c5866a63ffb18fa25478a) - -commit 14cb08ed98740bd286b89edb2b0555aebd7d69c2 -Author: Victor Seva -Date: Thu May 4 21:43:39 2023 +0200 - - pkg/kamailio/deb: version set 5.7.0~rc0 [skip ci] - -commit 239b374c7d30c1865b749f247ecdc7bb80898063 -Author: Daniel-Constantin Mierla -Date: Thu May 4 20:37:14 2023 +0200 - - Makefile.defs: version set to 5.7.0-rc0 - - - branch 5.7 for 5.7.x release series - -commit e80e877e4c0bab977c80c147b826d3b67b4c02d9 -Author: Daniel-Constantin Mierla -Date: Thu May 4 18:24:45 2023 +0200 +commit 9cb6dae183c7295a3c9753a2747f6b3d92c3ffe8 +Author: Kamailio Dev +Date: Fri Dec 1 13:46:54 2023 +0100 - Makefile.defs: version set to 5.7.0-pre1 + modules: readme files regenerated - ims_ipsec_pcscf ... [skip ci] -commit 20561b66364f2321c604d0655c3029decdd2dff6 +commit c39cdcbf0d8a17bc8fc03656faeb80fe231c3499 Author: Daniel-Constantin Mierla -Date: Thu May 4 14:22:06 2023 +0200 +Date: Fri Dec 1 13:43:25 2023 +0100 - db_flatstore: use unsigned long long for printing time_t value + ims_ipsec_pcscf: docs updated for ipsec_forward() -commit 254c14517ba698e0e8ed8bb85b0bc24948f48f50 +commit d2b5f34e36e862c6485294f54c87e7184faf00b0 Author: Daniel-Constantin Mierla -Date: Thu May 4 14:17:20 2023 +0200 +Date: Fri Dec 1 13:34:00 2023 +0100 - stats: use J for printing timestamp to rpc result + ims_ipsec_pcscf: options for ipsec_forward() to use Via or try TCP + + - option to use Via attributes for routing reply + - option to try over TCP if correxponding UDP socket is not found + + Co-authored-by: Supreeth Herle -commit c5d846d499cdc4fa6829c3bf4d7a120d9dbe16da +commit 580915bade64db034a2ee25c616addc38220c183 Author: Daniel-Constantin Mierla -Date: Wed May 3 20:11:06 2023 +0200 - - dlgs: use PRIu64 to print uint64_t - -commit c394d9b2108443f9cd6146d88f77f51a2a059ba5 -Author: Pantelis Kolatsis -Date: Thu May 4 07:49:18 2023 +0000 - - textopsx: convert to memory error logging helper, add missing logging for allocation errors - -commit b6c3a15518e9b6c7259be7c906193aa0cd510449 -Author: Pantelis Kolatsis -Date: Thu May 4 07:42:27 2023 +0000 - - kafka: convert to memory error logging helper - -commit 40b18ddfe3eca3170ef6c535d39332b2e3c6ce5d -Author: Pantelis Kolatsis -Date: Thu May 4 07:34:57 2023 +0000 - - secfilter: convert to memory error logging helper, add missing mem cleanup on errors - -commit d031d1e483f4c025074e6a6bc95728dc88193c7b -Author: Pantelis Kolatsis -Date: Thu May 4 07:30:08 2023 +0000 - - ims_registrar_pcscf: convert to memory error log helper, add missing mem cleanup during errors +Date: Thu Nov 30 21:01:45 2023 +0100 -commit 8b9e4dbcc29a4ff913039adf1ce1eae941976533 -Author: Pantelis Kolatsis -Date: Thu May 4 07:14:45 2023 +0000 - - lcr: convert to memory error logging helper, add some missing mem cleanup on error + ims_ipsec_pcscf: reparse request buffer to get contact when handling reply + + - clone aor in pkg to store the value + - trim aor value when the parameters start + + Co-authored-by: Supreeth Herle -commit b002a5dcde1f14850ddfc620ed5b9d0a7e8e5962 +commit 57794cd14205a16ed6c649fadb4efffca1561986 Author: Daniel-Constantin Mierla -Date: Mon May 1 20:51:10 2023 +0200 - - auth_db: exported www_authenticate() to kemi - -commit db8258bf9ab7ca772923d237f40fce4381dbcde4 -Author: Pantelis Kolatsis -Date: Sat Apr 29 19:15:28 2023 +0000 - - debugger: convert to memory error logging helper, add missing mem error handling - -commit 11831568d9eaef233fe6e482ad2c63788b04bbd9 -Author: Pantelis Kolatsis -Date: Sat Apr 29 19:11:36 2023 +0000 - - crypto: convert to memory error logging helper +Date: Thu Nov 30 18:58:07 2023 +0100 -commit ea31785f3458bb79d14384734f8fd4f7b628ffa2 -Author: Pantelis Kolatsis -Date: Sat Apr 29 19:10:00 2023 +0000 + ims_ipsec_pcscf: fill_contact() check for port size in alias - ldap: convert to memory error logging helper - -commit b1a47746d6097c2d1fe47ee4799108368037283d -Author: Pantelis Kolatsis -Date: Sat Apr 29 19:07:15 2023 +0000 - - pua: convert to memory logging helper, add missing log message and mem error handling - -commit 89927295f23648d9e66fa5285ca3b65a615e89a5 -Author: Pantelis Kolatsis -Date: Sat Apr 29 18:56:02 2023 +0000 +commit 2dc4a4297b0c9e6a693a82f0fe95df4d1572d7df +Author: Kamailio Dev +Date: Thu Nov 30 11:16:57 2023 +0100 - utils: convert to memory logging helper + modules: readme files regenerated - ims_ipsec_pcscf ... [skip ci] -commit d77448b3a6a5dc3cf9e9a8ed85aeb7ae743900b6 -Author: Pantelis Kolatsis -Date: Sat Apr 29 18:54:14 2023 +0000 +commit e4b4b95c8933796b2cf8d5ad478e66347aa8ebf0 +Author: Supreeth Herle +Date: Wed Nov 29 20:00:24 2023 +0100 - websocket: convert to memory logging helper, add missing mem error logging + ims_ipsec_pcscf: add q value to Security-Server header for IPSec -commit 7ae82075ba0b509cdc9c2f5d03e9b055fc3bf117 -Author: Victor Seva -Date: Fri Apr 28 11:48:12 2023 +0200 +commit bb35e0aa112f9c60779692c67f42b6ef2cb1b0c2 +Author: Supreeth Herle +Date: Wed Nov 29 19:55:07 2023 +0100 - github: PR use Github Packages registry [skip ci] + ims_ipsec_pcscf: cope better with some broken In-Dialog routing -commit f27d15ba6e1116a9f47e654d2bd0f4d3b73168a3 +commit 006cca915275f8ca3ea52a9d978961e0842f1dcd Author: Daniel-Constantin Mierla -Date: Thu Apr 27 21:19:31 2023 +0200 +Date: Wed Nov 29 19:39:45 2023 +0100 - auth_db: exported www_authenticate_method() to kemi + ims_ipsec_pcscf: docs for ipsec_destroy_by_contact() -commit f16ba6d4a5305be84d5a2b9d1e6c6a15368c8c76 +commit 0a6e742e7d189dbf1bc2a61cdb638458b49873f4 Author: Daniel-Constantin Mierla -Date: Wed Apr 26 20:36:17 2023 +0200 - - auth: exported auth_get_www_authenticate() to kemi - -commit 1f802a96f0ce4c376d64be65bca27994bb2742cb -Author: Marcus Orchard -Date: Thu Mar 30 08:53:39 2023 -0400 +Date: Wed Nov 29 15:41:55 2023 +0100 - tls: fix formatting in tls_select.c - -commit 7fd502fe433695b798249404cae144365d08b9c7 -Author: root -Date: Wed Mar 29 15:27:28 2023 +0000 - - tls: get san entries by index + ims_ipsec_pcscf: use core fixup helper functions - - adds count pv and sel for DNS, EMAIL, IP, URI - - adds ability to access SAN entries by index - - fix #3400 + - remove unused parameter for w_destroy_by_contact() -commit 42351ec91b38ce3f8eff51978d00010f54481924 -Author: Wolfgang Kampichler -Date: Wed Apr 26 17:56:23 2023 +0200 +commit 279454ff8d4e5804d92a8690c4de3a507efbc44f +Author: Supreeth Herle +Date: Wed Nov 29 15:39:39 2023 +0100 - lost: P-A-I parsing with display name fixed (#3426) + ims_ipsec_pcscf: new function to destroy IPSec based on Contact and received IP and port - - this fix improves P-Asserted-Identity parsing to properly extract - the uri from the header value. The uri (sip/tel) is used as - identity for HELD requests. - -commit 5a2df203a244e79a1868910da312f765091d22f5 -Author: Kamailio Dev -Date: Tue Apr 25 22:16:28 2023 +0200 - - modules: readme files regenerated - call_control ... [skip ci] - -commit 4c8276fcf268a690ea671c4ddeaad1f89e293565 -Author: Дилян Палаузов -Date: Mon Apr 10 10:39:32 2023 +0200 - - kex: typos - -commit 79fc3f1fc9561f43146a107c824d1d97d3a8b021 -Author: Дилян Палаузов -Date: Mon Apr 10 10:38:56 2023 +0200 - - kemix: update Kamailio URLs to HTTP → HTTPS - -commit e7c8dcb9507fbd44cc1d00132b433a2d91705a48 -Author: Дилян Палаузов -Date: Mon Apr 10 10:38:07 2023 +0200 - - keepalive: typos + - the default ipsec_destroy() cannot be used to used destroy IPSec in any route and + needed to be used exactly after all the de-registration process was complete. But, + as per the kamailio P-CSCF config script, ipsec_destroy() was used in reply route of + NATPING, which didn't have any idea about SIP Register message used for de-registration. + Thus, resulting in IPSec not being destroyed even after de-registration was complete. + - the newly introduced function ipsec_destroy_by_contact() takes domain, contact, received host + and received port in order to determine the exact UE's IPSec tunnel to destroy. -commit 67a01aa6757f19397438457c6665d338f6804f24 -Author: Дилян Палаузов -Date: Mon Apr 10 10:34:50 2023 +0200 - - kazoo: typos - -commit 8c5a8ce562e5ab98a7e6bdf163bab833ec3a7cf5 -Author: Дилян Палаузов -Date: Mon Apr 10 10:32:30 2023 +0200 - - jwt: typo algoritm → algorithm - -commit 285a260687d4dce5636531a4ffffc43b0d37e883 -Author: Дилян Палаузов -Date: Mon Apr 10 10:31:41 2023 +0200 - - jsonrpcs: typos - -commit 27e97f1717e542765125f32f0bde98f6bf47e26b -Author: Дилян Палаузов -Date: Mon Apr 10 10:30:52 2023 +0200 - - janssonrpcc: typo - -commit 326ad479fb9e09f4f3a177606f2b5dcc09fbbd62 -Author: Дилян Палаузов -Date: Mon Apr 10 10:30:33 2023 +0200 - - ims_registrar_pcscf: typo - -commit 5335f6d5a80f804257a2303f05a2b2c5edf02322 -Author: Дилян Палаузов -Date: Mon Apr 10 10:30:05 2023 +0200 +commit c10d50e10bc5f2c3f6a73dc685f631b3367f2481 +Author: Supreeth Herle +Date: Wed Nov 29 15:30:23 2023 +0100 - cfgutils: typos + cdp: fix for CER not containing Host-IP-Address AVP -commit b1f783df4ceb2a1d4a525c3802707105b6f1a0c6 -Author: Дилян Палаузов -Date: Mon Apr 10 10:29:28 2023 +0200 +commit 663be945f41d026c1a16f498544a12e2fb58c53c +Author: Daniel-Constantin Mierla +Date: Wed Nov 29 15:18:20 2023 +0100 - call_control: typos + ims_qos: docs for dialog_direction parameter -commit b2b4eda387ec21ebac2db7258cabda2b9c9ed81b -Author: Pantelis Kolatsis -Date: Tue Apr 25 11:52:31 2023 +0000 +commit adbb2bc992d1582aece9d075da6329e0643fb5e3 +Author: Supreeth Herle +Date: Wed Nov 29 14:09:02 2023 +0100 - statistics: convert to memory logging helper + ims_qos: option to set DLG_MOBILE_ORIGINATING for rx_add_media_component_description_avp() + + - alternative to DLG_MOBILE_REGISTER that can be set with mod param + dialog_direction -commit 2264b5ca85256db2c3701575a24865f45b657c6c -Author: Pantelis Kolatsis -Date: Tue Apr 25 11:49:47 2023 +0000 +commit aced7f10a13dc7c578191514c29b2c8e060e11d3 +Author: Daniel-Constantin Mierla +Date: Wed Nov 29 13:50:11 2023 +0100 - call_control: convert to memory logging helper, add cleanup for errors + ims_qos: docs for recv_mode parameter -commit 836dd90007d82a8d6a3bea1969a21ca349203e05 -Author: Pantelis Kolatsis -Date: Tue Apr 25 11:46:12 2023 +0000 +commit b00190ff6927d5ddfcc0ed78a0eb701627eaadbb +Author: Supreeth Herle +Date: Wed Nov 29 13:27:10 2023 +0100 - sipcapture: convert to memory logging helper, add missing mem logging and cleanup on errors + ims_qos: option to use received ip, port and proto from via + + - can help with Rx_AAR_Register when EPC is behind a NAT + - there could be an Rx AAR failure due to wrong IP address + in Framed IP address field of Rx AAR message when EPC is behind a NAT -commit 78e658cd70d23f3665f08f436d8b9a9fa99769f9 -Author: Pantelis Kolatsis -Date: Tue Apr 25 11:29:37 2023 +0000 +commit 9a552096eea7e78baeb16d32278ebd4d586eef82 +Author: Daniel-Constantin Mierla +Date: Wed Nov 29 13:11:50 2023 +0100 - kex: convert to memory logging helper, add missing mem error logging + ims_registrar_pcscf: docs for delete_delay parameter -commit 2c976699e0e066659a2b1d2c1888300823c4b773 -Author: Pantelis Kolatsis -Date: Tue Apr 25 11:26:06 2023 +0000 +commit bc3e758fb32285ba8d0f9f9e1a1489dd1894468d +Author: Supreeth Herle +Date: Wed Nov 29 13:08:06 2023 +0100 - sworker: convert to memory logging helper + ims_registrar_pcscf: option to delay record expiration instead of immediate delete + + - new parameter delete_delay -commit b531f6df91a5dd75fc6fae47e44041a1f1ebe6ca -Author: Pantelis Kolatsis -Date: Mon Apr 24 19:52:42 2023 +0000 +commit 3b2bffc92ab0f684f8731c02f080d8df4392de5d +Author: Supreeth Herle +Date: Wed Nov 29 12:38:53 2023 +0100 - drouting: convert to memory logging helper, add missing logging, free mem in errors + ims_usrloc_scscf: improve contact lookup for an IMPU + + - -commit 04bcef64e0bf0cff3558ce3cb895439ab2cdd5c7 -Author: Pantelis Kolatsis -Date: Mon Apr 24 19:43:37 2023 +0000 +commit e49469c0ce534879a7d366c71374356e7883c6f2 +Author: Supreeth Herle +Date: Wed Nov 29 12:26:00 2023 +0100 - rtimer: convert to memory logging helper + kamctl: mysql/ims_usrloc_scscf-create.sql - support for larger record_route values -commit fc52a1e73812daaef425727fcf5f59ed6b75b2f9 -Author: Pantelis Kolatsis -Date: Mon Apr 24 19:35:41 2023 +0000 +commit e1d9bec0e16727325330c822c21ae29237c7812a +Author: Kristian Hogh +Date: Thu Nov 30 06:19:15 2023 +0000 - prefix_route: convert to memory logging helper, add missing logging + nathelper: add Max-Forwards headers which is mandatory for OPTIONS according to RFC 3261 (GH 3657) + + - add Max-Forwards headers which is mandatory for OPTIONS according to RFC 3261 + - similar patch is used from several large customer installations since many years + - GH #3657 with small formatting change -commit 56a843bb18b5f06d4ef88ed525d446a1ff298b3f -Author: Pantelis Kolatsis -Date: Mon Apr 24 19:32:29 2023 +0000 +commit aef29af56cabaf626e2ae552ae69c3cd2f692a27 +Author: Victor Seva +Date: Wed Nov 29 17:21:59 2023 +0100 - dmq_usrloc: convert to memory logging helper + Makefile.groups: fix ktls when KTLS_INCLUDE_TLSA is not set + + fix #3660 -commit a3fe9388540ee3ba0331b642e1c26170ca572e60 -Author: Pantelis Kolatsis -Date: Mon Apr 24 19:30:54 2023 +0000 +commit 2b27aba7f4f396e4ebd894255abfa8ce20950313 +Author: Daniel-Constantin Mierla +Date: Tue Nov 28 13:21:01 2023 +0100 - path: convert to memory logging helper + topos: use defined values for internal contact mode -commit 4f44adcfbfaf84262f09f03afd8912205ce6c13b -Author: Pantelis Kolatsis -Date: Mon Apr 24 19:27:45 2023 +0000 +commit 1194f59738e87fcbf0d61c95d1d481e5fbb46784 +Author: Victor Seva +Date: Tue Nov 21 15:30:03 2023 +0100 - outbound: convert to memory logging helper + core: timer_proc don't execute timers on shutdown phase -commit 965606b2fbdad7b868637fb2f35f15507279caf6 -Author: Pantelis Kolatsis -Date: Mon Apr 24 19:26:44 2023 +0000 +commit 9117e5ddbffe2a202d24eb39a509835f14090486 +Author: Kamailio Dev +Date: Tue Nov 28 10:32:15 2023 +0100 - rr: convert to memory logging helper + modules: readme files regenerated - jansson ... [skip ci] -commit 19df3ad8f3e10b6c9fa91e69f288fdbd51be7091 -Author: Pantelis Kolatsis -Date: Mon Apr 24 19:24:24 2023 +0000 +commit 3b47b566477baedf687635b2b3f0e2525987e709 +Author: Daniel-Constantin Mierla +Date: Tue Nov 28 10:19:01 2023 +0100 - uid_auth_db: convert to memory logging helper + jansson: rename parameter for janssonmod_get_field() + + - more suggestive relation with the meaning of the field name parameter -commit 6f68f55c1c654e3cb120c10eb6999d538d943ca2 -Author: Pantelis Kolatsis -Date: Mon Apr 24 19:20:16 2023 +0000 +commit 9eeab4396d8ec57781244ab80c4a96539d7338ec +Author: Daniel-Constantin Mierla +Date: Tue Nov 28 10:16:28 2023 +0100 - qos: convert to memory logging helper + jansson: docs updated for jansson_get_field() -commit f7588fb8fb804aa7585db5cb97433b69763ceb62 -Author: Pantelis Kolatsis -Date: Mon Apr 24 19:17:56 2023 +0000 +commit d7b76608595046001cab3ced06d29c1e9a84cb99 +Author: Daniel-Constantin Mierla +Date: Tue Nov 28 08:01:53 2023 +0100 - siputils: convert to memory logging helper + jansson: use key as field name for jansson_get_field() + + - do no try to evaluate it as json path -commit d5ab93a1e642aec9c842c9ffe9cb712c0f41e4c0 -Author: Pantelis Kolatsis -Date: Mon Apr 24 19:08:29 2023 +0000 +commit 525dc4523ac411e1154c3ae8af1ec6f8678d1dbc +Author: Daniel-Constantin Mierla +Date: Tue Nov 28 07:36:55 2023 +0100 - statsc: convert to memory logging helper, free memory in case of error + jansson: reformat exported structures -commit 7747f91f6c482a99cfab4813e3b2ad5e6e970d07 -Author: Pantelis Kolatsis -Date: Mon Apr 24 19:06:41 2023 +0000 +commit 48034ab61482f6b3d9e77ccfc9e0743c44ff4458 +Author: Daniel-Constantin Mierla +Date: Tue Nov 28 07:31:57 2023 +0100 - stun: convert to memory logging helper + jansson: added path evaluatian mode for helper functions -commit 83789e7efe6e1a3479e7742812eaff2ffd7ebdd3 -Author: Sergey Safarov -Date: Wed Apr 19 18:52:30 2023 +0300 +commit 870e4dc86dec7bf51a513bb1a716ad2417a12fa9 +Author: S-P Chan +Date: Thu Oct 5 10:06:45 2023 +0800 - .github/workflows: added GitHub action script to build Alpine based docker image + pkg: RPM packaging add kamailio-tls_wolfssl subpackage -commit 338e3d8bab15eb3422a9804a83d92c077960203c +commit 4840ea7536610d07ad6fda76da60ded04dfeabc7 Author: Daniel-Constantin Mierla -Date: Mon Apr 24 08:32:16 2023 +0200 +Date: Mon Nov 27 19:23:36 2023 +0100 - auth: exported proxy_challenge() to kemi + .github/CONTRIBUTING.md: section for issue and pr automatic management -commit 9643d65a98574e0739b771b4770101bd747b5966 -Author: Sergey Safarov -Date: Fri Apr 21 15:54:25 2023 +0300 +commit 96300556ea4787f6f99926dcc7305ec6e4e3df75 +Author: Daniel-Constantin Mierla +Date: Mon Nov 27 17:11:53 2023 +0100 - submodule udpadate [skip ci] + .github/ISSUE_TEMPLATE: notes about expiration of items and how to reopen -commit f898704e9d4f51f1b8fa65be92ff8cc504dfcd66 -Author: Pantelis Kolatsis -Date: Fri Apr 21 18:01:01 2023 +0000 +commit 5a65791e3959439a699d746ce8e63d438e8db0a5 +Author: Kamailio Dev +Date: Mon Nov 27 14:17:09 2023 +0100 - sdpops: convert to memory logging helper + modules: readme files regenerated - topoh ... [skip ci] -commit 2a9402d4159824f857a5c8b8fcb5f96f42094e5a -Author: Pantelis Kolatsis -Date: Fri Apr 21 17:59:50 2023 +0000 +commit e479abe5a56e0576b5d5707fbdd7b65d33cf3599 +Author: Victor Seva +Date: Mon Nov 27 14:06:15 2023 +0100 - sms: convert to memory logging helper, fix some related wrong log messages + github: rework labels workflow [skip ci] -commit 569714ea692f751580d902900912caf3c56203dd -Author: Pantelis Kolatsis -Date: Fri Apr 21 17:58:01 2023 +0000 +commit 949b00795d748aa6b6af64c4ced8a3e8de369021 +Author: Daniel-Constantin Mierla +Date: Mon Nov 27 14:02:25 2023 +0100 - sl: convert to memory logging helper + topoh: mask_ip initialized again to 127.0.0.8 + + - docs updated + - code formatting updated by pre-commit hooks -commit 4753296c012f9eb90188a4313fb8f797b3f14010 -Author: Pantelis Kolatsis -Date: Fri Apr 21 17:43:25 2023 +0000 +commit 52cee630d367287daa4b15c042b25bec76192e80 +Author: Kamailio Dev +Date: Mon Nov 27 14:02:31 2023 +0100 - topoh: improve mem error handling + modules: readme files regenerated - topoh ... [skip ci] -commit 30f3bb9c0be0de638021ae4c7108db85330d3cbb -Author: Pantelis Kolatsis -Date: Fri Apr 21 17:40:27 2023 +0000 +commit 026e90350d0b4ec64695c373b70fa554d9337c34 +Author: Victor Seva +Date: Mon Nov 27 12:53:47 2023 +0100 - xcap_server: convert to memory logging helper, improve mem error handling + github: react to PR/issue comments [skip ci] + + ``/notstale`` will remove ``stale`` label + ``/notexpired`` will change the status to ``open`` + + > https://github.com/marketplace/actions/github-script -commit 070279f902413023558391249bb579a7717eb391 -Author: Pantelis Kolatsis -Date: Fri Apr 21 17:35:06 2023 +0000 +commit 8bfe55c68a06492c93a327eff6813fa0da8399dd +Author: TorPetterson <32388321+TorPetterson@users.noreply.github.com> +Date: Mon Nov 27 13:50:09 2023 +0100 - xlog: improve memory error handling + topoh: uses socket IP when no mask_ip is defined (#3341) + + * topoh: uses socket IP when no mask_ip is defined + + If the parameter mask_ip is not defined the module finds the socket IP + and uses that as mask IP for the message. + If the socket has an advertised IP it is used, otherwise the socket IP is used. -commit ad687875c190e863d45a99f5d77422dde37223f7 -Author: Pantelis Kolatsis -Date: Fri Apr 21 17:33:17 2023 +0000 +commit 31e86a9250acf276217e514c4ea15269bbae4458 +Author: Kamailio Dev +Date: Sat Nov 25 11:17:04 2023 +0100 - xprint: convert to memory logging helper, improve mem error handling + modules: readme files regenerated - lost ... [skip ci] -commit b65c19fa29976b59403433ed8a5de4b7eef41afc -Author: Daniel-Constantin Mierla -Date: Fri Apr 21 11:32:07 2023 +0200 +commit f7caef5d4ba3fde04425b6480badcacc14f4f6e6 +Author: Wolfgang Kampichler +Date: Sat Nov 25 11:06:21 2023 +0100 - auth: expose www_challenge() to kemi + lost: support of shape representations (as in RFC5491) and new 3d parameter - - GH #3423 + - A Presence Information Data Format Location Object (PIDF-LO) may + contain one of the shape types as listed in RFC5491. A LoST + findService request currently contains only a profile for + two-dimensional geodetic location information, which + is the default setting for this 3d parameter. The parameter + can be set to 1 if a LoST server supports 3d, otherwise a + 3d location is reduced to 2d by the module. -commit 8a144a85c803424be087d7519d65b97b226501c1 +commit 1e6b51a1fb6c3ee2f2fc6c0ea2b8f7ac6270d958 Author: Daniel-Constantin Mierla -Date: Thu Apr 20 12:53:53 2023 +0200 +Date: Fri Nov 24 12:45:15 2023 +0100 - Makefile.groups: added math to group extra + core/mem: qm - use mem_add_size value -commit 58ab05d02d8ac8d2fee046c5d9505ba7a5ee2a8c -Author: Sergey Safarov -Date: Mon Dec 12 10:33:09 2022 +0300 - - pkg/docker: submodule update - -commit 15c7f861d72c57ee57f41c108d948027e50a0a27 +commit 5430f7e1ea98f268b0ba7aef88a7e471e6940c4d Author: Daniel-Constantin Mierla -Date: Wed Apr 19 08:02:44 2023 +0200 +Date: Fri Nov 24 12:14:14 2023 +0100 - siprepo: translate pointers to the new buffer + core: added core parameter mem_add_size - - GH #3418 + - default value 0 + - to be used to add extra space to allocated chunks for safety purposes + when external libraries expose buffer overflows -commit 287600cc1560d2a035b766700fb2aba85456605c -Author: Daniel-Constantin Mierla -Date: Tue Apr 18 11:21:59 2023 +0200 +commit 4b500ae453df1695aec7f7251a7ca4cead3cfe06 +Author: Victor Seva +Date: Fri Nov 24 12:49:29 2023 +0100 - tm: fix setting t->callid_val after previous changes to keep shortcuts + pkg/kamailio/deb: don't build tlsa for xenial [skip ci] - - GH #3417 - -commit 77c41d9a56ee99fbae48dd075bfca3349ae4da4e -Author: Kamailio Dev -Date: Mon Apr 17 09:16:25 2023 +0200 - - modules: readme files regenerated - math ... [skip ci] + We are getting errors on build: + > gcc -shared -g -m64 -Wl,-O2 -Wl,-E -Wl,-Bsymbolic-functions -Wl,-z,relro -pthread -rdynamic "-ldl" -Wl,-Bsymbolic-functions tls_domain.o tls_cfg.o tls_init.o tls_verify.o tls_locking.o tls_select.o tls_dump_vf.o tls_bio.o tlsa_mod.o tls_server.o tls_rpc.o tls_ct_wrq.o tls_rand.o tls_map.o tls_util.o tls_config.o -lm /usr/lib/x86_64-linux-gnu/libssl.a /usr/lib/x86_64-linux-gnu/libcrypto.a -o tlsa.so + > /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libssl.a(s3_meth.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC + > /usr/lib/x86_64-linux-gnu/libssl.a: error adding symbols: Bad value + > collect2: error: ld returned 1 exit status + > ../../Makefile.rules:191: recipe for target 'tlsa.so' failed -commit 0cf5148d31b8e9f088ea9d8ed047553eb6cd590c +commit 90692361c5158516bf9570dcdd139204e3ccf4df Author: Victor Seva -Date: Mon Apr 17 09:09:04 2023 +0200 +Date: Fri Nov 24 10:44:06 2023 +0100 - pkg/kamailio/deb: set 5.7.0~pre0 [skip ci] + pkg/kamailio/deb: include tlsa in tls package [skip ci] -commit cc0ef8e5bcdb6fd325572cbffb3ddcf6aaa32435 +commit a49c8d8d968e31a539e47db6c06a0756e4be55e3 Author: Daniel-Constantin Mierla -Date: Mon Apr 17 09:09:09 2023 +0200 +Date: Fri Nov 24 10:38:49 2023 +0100 - math: docs for math_sqrt() + Makefile.groups: tlsa in packaging group ktls if KTLS_INCLUDE_TLSA=yes + + - if not, then it is in separate group module_group_ktlsa -commit c4c7b50bb9f164d430af582c5844b0e0aacf2bb3 +commit 93609b53d70df84788741800fc2b80c5502a3358 Author: Daniel-Constantin Mierla -Date: Sat Apr 15 08:30:44 2023 +0200 +Date: Thu Nov 23 12:35:48 2023 +0100 - Makefile.defs: version set to 5.7.0-pre0 + websocket: use literal module name for stats group - - testing phase for v5.7.x series + - prevent conflicts with global exports -commit adb5249d10e6f37c80bdae69f61678ea0994617f +commit 186ae3eef7f3e1b5ad6222c98a2f35a487deb316 Author: Daniel-Constantin Mierla -Date: Sat Apr 15 08:29:29 2023 +0200 +Date: Thu Nov 23 12:35:47 2023 +0100 - Makefile.defs: version set to 5.7.0-dev4 + usrloc: use literal module name for stats group - - mark the end of development for 5.7.x series + - prevent conflicts with global exports -commit 388a12b455da982c590472741b1007ef42cc8b91 +commit a9d29645ab417c9b0f7afc6745e6dd54bdac07b4 Author: Daniel-Constantin Mierla -Date: Fri Apr 14 22:55:28 2023 +0200 - - math: added math_sqrt() function - -commit bb3c781ba0021881957c7ce2e8afffb8d48f73a5 -Author: Kamailio Dev -Date: Fri Apr 14 12:01:12 2023 +0200 +Date: Thu Nov 23 12:35:47 2023 +0100 - modules: readme files regenerated - math ... [skip ci] + tsilo: use literal module name for stats group + + - prevent conflicts with global exports -commit 31c029ca47123de80f0f89e7526ddbb97af80768 +commit d4c0e1bbcb0e423a545650aad4fbb4b2da8bb488 Author: Daniel-Constantin Mierla -Date: Fri Apr 14 11:57:51 2023 +0200 +Date: Thu Nov 23 12:35:47 2023 +0100 - math: docs - proper names for exported functions + tmx: use literal module name for stats group + + - prevent conflicts with global exports -commit 0920992eb2b60b1c98b187ddfd411dff8a8ba63a +commit 96bdd69945af9f08e6c89fb725248b8b268ee71a Author: Daniel-Constantin Mierla -Date: Fri Apr 14 11:56:22 2023 +0200 +Date: Thu Nov 23 12:35:47 2023 +0100 - math: renamed math_log() to math_logN() to be more suggestive + sst: use literal module name for stats group + + - prevent conflicts with global exports -commit 17d8a04033a19d6781f8f14c9ae610cd070c2a47 +commit 92cdcb4bd280850743b3a952f1b6003be69daaf2 Author: Daniel-Constantin Mierla -Date: Fri Apr 14 11:53:02 2023 +0200 +Date: Thu Nov 23 12:35:47 2023 +0100 - math: additional logarithm functions + siptrace: use literal module name for stats group + + - prevent conflicts with global exports -commit 2cf7d05beac75923998e2287c6856d49d4b6ccff +commit 01abed3ef17f6a5f0f215675a2980f0b9a4267fd Author: Daniel-Constantin Mierla -Date: Fri Apr 14 10:48:50 2023 +0200 +Date: Thu Nov 23 12:35:47 2023 +0100 - math: new module to collect math functions + sipcapture: use literal module name for stats group + + - prevent conflicts with global exports -commit ab67d11064f71ad4d3661edaa533d30b023fad7a +commit 0516fb802628ddb659a130aa2959df5b0b8e0c96 Author: Daniel-Constantin Mierla -Date: Thu Apr 13 18:21:36 2023 +0200 +Date: Thu Nov 23 12:35:47 2023 +0100 - Makefile.defs: do not set -O2 flag for darwin linker + registrar: use literal module name for stats group + + - prevent conflicts with global exports -commit 61018e4774b0f6f7bda75aad7c74a56f9d14bb4a +commit a951cb44ecbcd0f9cba937176ea5117c6a1d15b6 Author: Daniel-Constantin Mierla -Date: Tue Apr 11 21:11:20 2023 +0200 - - jsonrpcs: define size for _jsonrpcs_stored_id buffer - -commit 57a22811bd91a1c86a59f2343522bbe7821b45fd -Author: Kamailio Dev -Date: Wed Apr 12 11:46:50 2023 +0200 - - modules: readme files regenerated - dialog ... [skip ci] - -commit 87d11496a15806481c9abf963c6dc13faa661b50 -Author: Victor Seva -Date: Wed Apr 12 10:39:55 2023 +0200 +Date: Thu Nov 23 12:35:47 2023 +0100 - dialog: dlg_get_var() support early dialogs + p_usrloc: use literal module name for stats group - to_tag can be empty + - prevent conflicts with global exports -commit d7c00bce2b191b237254939a1b5029abc37a8004 +commit f35f327a528670dcca0d7a767643a222f1aebd89 Author: Daniel-Constantin Mierla -Date: Mon Apr 10 08:28:40 2023 +0200 +Date: Thu Nov 23 12:35:47 2023 +0100 - jsonrpcs: cast to long long int to print value without warning + nat_traversal: use literal module name for stats group + + - prevent conflicts with global exports -commit 46455859652ad4fddd6271235298bd83f96e0556 +commit 609960812c572d2d19ba774b064fdf7e2ac45765 Author: Daniel-Constantin Mierla -Date: Fri Apr 7 20:22:22 2023 +0200 - - dispatcher: use PRIu64 to print uint64_t values - -commit a0fac2aaa14a5d4a2054128095cf68d79304d3c2 -Author: Kamailio Dev -Date: Mon Apr 10 08:16:28 2023 +0200 - - modules: readme files regenerated - benchmark ... [skip ci] - -commit f2fae3c00908cd63fc4cfb13535587f2ad564d3e -Author: Дилян Палаузов -Date: Sun Apr 2 15:32:18 2023 +0200 - - http_client: typos - -commit 7437d4d9977f50640efefbec4cc06056c4957b18 -Author: Дилян Палаузов -Date: Sun Apr 2 15:29:07 2023 +0200 - - http_async_client: typos - -commit c1007b900dd99deb8b3610e9c4da823f2cd2cd02 -Author: Дилян Палаузов -Date: Sun Apr 2 15:28:26 2023 +0200 - - htable: typos - -commit 6a4ab71566d9e7bb3da290c2d60b35e56923a705 -Author: Дилян Палаузов -Date: Sun Apr 2 15:26:39 2023 +0200 - - exec: typo - -commit 1112b6855797d93024977adeb73e021cc309a7b7 -Author: Дилян Палаузов -Date: Sun Apr 2 15:26:20 2023 +0200 - - evapi: typo - -commit feb5d27f8a063b0c533d294be9e4726f75b96a0a -Author: Дилян Палаузов -Date: Sun Apr 2 15:25:49 2023 +0200 - - enum: typos - -commit 4fdeda75a7227492f917e55ce523faf81f4fe965 -Author: Дилян Палаузов -Date: Sun Apr 2 15:25:21 2023 +0200 - - crypto: typo - -commit e8ada7caaf34231f47c04f9eea4f6f31048b7f6c -Author: Дилян Палаузов -Date: Sun Apr 2 15:24:52 2023 +0200 - - corex: typos - -commit d251ec90ee9567cf121f4179f3387c00e859a226 -Author: Дилян Палаузов -Date: Sun Apr 2 15:24:08 2023 +0200 - - ctl: typos - -commit 129fb5621b9de9a88b0c34f35fcb8b5acb5f667d -Author: Дилян Палаузов -Date: Sun Apr 2 15:22:43 2023 +0200 - - cplp: typos - -commit 1151b0854f5c24ef3e9b7ee209efc31ce7ef0519 -Author: Дилян Палаузов -Date: Sun Apr 2 15:20:58 2023 +0200 - - cnxcc: typos - -commit f9927657ba42dc2feca692291437ec10a20a06a8 -Author: Дилян Палаузов -Date: Sun Apr 2 15:18:46 2023 +0200 - - cdp: typos - -commit 5ab455814cc5baf8b34b5fc8023f32a58c7c92b7 -Author: Дилян Палаузов -Date: Sun Apr 2 15:15:06 2023 +0200 - - carrierroute: typos - -commit 28f01c863b2533b077be634f966dc43c113e2677 -Author: Дилян Палаузов -Date: Sun Apr 2 15:13:10 2023 +0200 - - benchmark: typo - -commit b26cfeda773867e8f346f3eb0f5c31e8cd408ac9 -Author: Дилян Палаузов -Date: Sat Apr 8 21:02:39 2023 +0200 +Date: Thu Nov 23 12:35:47 2023 +0100 - rtpengine clarifications + msilo: use literal module name for stats group - See http://lists.sipwise.com/pipermail/spce-user_lists.sipwise.com/2023-April/030012.html and - https://github.com/sipwise/rtpengine/issues/1595#issuecomment-1382378886 - -commit 16e6bfe4ed950851807c735cc3039046b77d6e6b -Author: Kamailio Dev -Date: Sat Apr 8 08:01:15 2023 +0200 - - modules: readme files regenerated - tm ... [skip ci] - -commit a4970749b2be40cd598d4ce5cf2eaa6b38fc2307 -Author: Ovidiu Sas -Date: Sat Apr 8 01:48:11 2023 -0400 - - tm: enhance documentation for on_sl_reply param - -commit 31083121a75ef29a6f10cceed35b89f4ee74b621 -Author: Kamailio Dev -Date: Thu Apr 6 22:31:26 2023 +0200 - - modules: readme files regenerated - nats ... [skip ci] - -commit a725b4fd224c27d84a9f5623faa5af3c3873a2e5 -Author: Seven Du -Date: Tue Mar 21 19:08:00 2023 +0800 - - nats: add a reply param to nats_publish and expose as nats_publish_request in KEMI - -commit 8bba1aa866b736f1fd98dace67fe4a4b1eeca5c7 -Author: Victor Seva -Date: Thu Apr 6 14:03:57 2023 +0200 - - github: use Github Packages registry [skip ci] + - prevent conflicts with global exports -commit 1c5fbac8c4314eb5a8c4f599de2b57f3840f2167 -Author: Victor Seva -Date: Thu Apr 6 08:45:28 2023 +0200 +commit d29b3d6515f74d4cd7417dc9030d8ca53d57054e +Author: Daniel-Constantin Mierla +Date: Thu Nov 23 12:35:47 2023 +0100 - nats: fix build after a6caaabe4bc85e1b41d5bd9b0b8938069eace309 + ims_usrloc_pcscf: use literal module name for stats group - GH #3401 + - prevent conflicts with global exports -commit a6caaabe4bc85e1b41d5bd9b0b8938069eace309 +commit 641d29820f8536247c49d5fb4caa882764dbd9af Author: Daniel-Constantin Mierla -Date: Wed Apr 5 12:55:06 2023 +0200 +Date: Thu Nov 23 12:35:47 2023 +0100 - nats: safety check on destroy for poll field + ims_registrar_scscf: use literal module name for stats group - - GH #3401 + - prevent conflicts with global exports -commit ccdd2edbeea51f9141654b48d396abe381cd2318 +commit 39514660001b37eabfe3af6818949586fae9a4bf Author: Daniel-Constantin Mierla -Date: Tue Apr 4 08:00:51 2023 +0200 +Date: Thu Nov 23 12:35:47 2023 +0100 - evapi: move clients structure to shm for access from internal workers + ims_icscf: use literal module name for stats group + + - prevent conflicts with global exports -commit 789deca1842bf278c7539fa05962ab9554c2697e +commit 524eeca084e0a0e61ad80f349ea79f8b1c3031f6 Author: Daniel-Constantin Mierla -Date: Mon Apr 3 21:48:12 2023 +0200 +Date: Thu Nov 23 12:35:47 2023 +0100 - evapi: safety check on log message during queue get + ims_auth: use literal module name for stats group + + - prevent conflicts with global exports -commit d68671f00097de3b498f4b67175c743bbf79ee72 +commit 407168804cc1806b857c2ce78399e02a81692d1e Author: Daniel-Constantin Mierla -Date: Mon Apr 3 20:37:38 2023 +0200 +Date: Thu Nov 23 12:35:47 2023 +0100 - evapi: more debug messages + imc: use literal module name for stats group + + - prevent conflicts with global exports -commit 757cb48d3606ef23192812a17a66b48c1ce2ea0f -Author: Wolfgang Kampichler -Date: Sat Apr 1 11:03:03 2023 +0200 +commit 40dd9f4e0fbe54046b7786e3572b491103af03d1 +Author: Daniel-Constantin Mierla +Date: Thu Nov 23 12:35:47 2023 +0100 - lost: additions to path element and corrected loop detection + http_async_client: use literal module name for stats group - - LosT requests that allow recursion now include a element that - contains one or more elements. A loop error is indicated if a - returned target is already in the server list in the element. + - prevent conflicts with global exports -commit c7e228eae76a432ea93fac7e95f50fe50979d79e +commit d434270933f06b4de43cdf6d4b464bd264a3cb92 Author: Daniel-Constantin Mierla -Date: Fri Mar 31 18:34:00 2023 +0200 +Date: Thu Nov 23 12:35:47 2023 +0100 - pua: updates for the new t field names + dialog: use literal module name for stats group + + - prevent conflicts with global exports -commit c321f28ff657c921b8de2b84e66908f281d35d78 -Author: Daniel-Constantin Mierla -Date: Fri Mar 31 18:22:23 2023 +0200 +commit 26d57116abc86e5d10bb1e5fe05c555e70e731c4 +Author: Victor Seva +Date: Thu Sep 14 12:34:58 2023 +0200 - tm: use header attribute shortcuts to match inside t_lookup_callid() + sca: update rr if necessary for subscriptions -commit 2bd1227b2440dd376c18e6c964f569e0e9ba4730 +commit e45c97d112c7c396ae0a11b7a431582a71361e5b Author: Daniel-Constantin Mierla -Date: Fri Mar 31 15:18:13 2023 +0200 +Date: Wed Nov 22 14:52:59 2023 +0100 - tm: keep shortcut the cseq header method + dialog: do not print module name in log messages + + - it is added automatically -commit 734fd2910cd437205da870ad1e329eaefe2f043a +commit 463d5b34390e330a2b733deb673c1c77e5be9fcb Author: Daniel-Constantin Mierla -Date: Fri Mar 31 08:05:10 2023 +0200 +Date: Wed Nov 22 14:52:18 2023 +0100 - sca: updates for the new t field names + avp: do not print module name in log messages + + - it is added automatically -commit ecd906dabbc5dc19d0fabb35d22320e2ba3fccf0 +commit 89a95ce1abefd772c0f09054473b07bbfc5426bc Author: Daniel-Constantin Mierla -Date: Fri Mar 31 08:04:59 2023 +0200 +Date: Wed Nov 22 14:26:23 2023 +0100 - lcr: updates for the new t field names + avpops: do not print module name in log messages + + - it is added automatically -commit 8f39d0ff741a3ba5819c6c0f96b8f575d30ab770 +commit ba1c0424732f1f2ab01bfd078ee272221a6b3e10 Author: Daniel-Constantin Mierla -Date: Fri Mar 31 08:04:43 2023 +0200 +Date: Wed Nov 22 14:20:13 2023 +0100 - keepalive: updates for the new t field names + textops: do not print module name in log messages + + - it is added automatically -commit 927a2451e084e886d2548fdae3f5f4cd3abd0a4b -Author: Daniel-Constantin Mierla -Date: Fri Mar 31 08:04:11 2023 +0200 +commit 145659f9b81a0d489548fa8a0f75c0bd05660e2e +Author: Victor Seva +Date: Wed Nov 22 14:50:21 2023 +0100 - dispatcher: updates for the new t field names + github: set ``expired`` label when closing PR or issues automatically [skip ci] -commit 8d69c0d68347198ccaea57a8ac4eeb040d19287a +commit 65322a8ea66ed18fb2d089ade54702341e064944 Author: Daniel-Constantin Mierla -Date: Fri Mar 31 08:02:10 2023 +0200 +Date: Wed Nov 22 14:02:59 2023 +0100 - tm: rename shortcuts to from/to/callid/cseq headers - - - reflect better that they are with header names - - new fields to point to callid value and cseq number to facilitate use - of them directly without new parsing or printing with header names + app_ruby: use module name prefix for exports structure -commit ea30efdbae2b33988e6157ba5e17aba16db156d4 -Author: Muhammad Shahzad Shafi -Date: Thu Mar 23 08:58:14 2023 +0000 +commit a81e3c45dad338378fc8cf417bb0e9da1172a854 +Author: Daniel-Constantin Mierla +Date: Wed Nov 22 13:59:14 2023 +0100 - tcpops: added tcp_get_conid() for kemi + app_jsdt: use module name prefix for exports structure -commit 6f8c1bf967ca3d101a70631df8d77cc7855b3a72 +commit e59c4415707f0995a0d5315b5601ae518b4f1ed5 Author: Kamailio Dev -Date: Thu Mar 30 19:31:38 2023 +0200 +Date: Wed Nov 22 10:17:01 2023 +0100 - modules: readme files regenerated - acc ... [skip ci] - -commit 0b986aeeffa7faa14f7e954df01cfb0ef4bea8da -Author: Дилян Палаузов -Date: Tue Feb 14 17:49:20 2023 +0200 - - avpops: typos + modules: readme files regenerated - ims_ipsec_pcscf ... [skip ci] -commit 1fd32a957a136214ed7d521595eb13592c51e9fa -Author: Дилян Палаузов -Date: Tue Feb 14 17:49:33 2023 +0200 +commit 57ed2639259f7116795f6214ca505cc86bb7ccb5 +Author: Daniel-Constantin Mierla +Date: Wed Nov 22 10:06:24 2023 +0100 - auth_radius: typos + ims_ipsec_pcscf: do not change msg r-uri with ipsec_destroy() param + + - only changing r-uri shortcut inside sip msg field can have side + effects, avoid it by providing the parameter to fill_contact() + - use core fixup function for handling config parameter for aor -commit da353c293ba46abbb21b5bcbbfa8e750955e9db1 -Author: Дилян Палаузов -Date: Tue Feb 14 17:49:47 2023 +0200 +commit ef3f50db619490509f127eba87b75190a98a1b3e +Author: Daniel-Constantin Mierla +Date: Wed Nov 22 09:50:14 2023 +0100 - auth_identiy: typos + ims_ipsec_pcscf: docs updated for ipsec_destroy() -commit 22535e19236c1d1cefca02d0b1d50b563362a1cc -Author: Дилян Палаузов -Date: Tue Feb 14 17:49:57 2023 +0200 +commit e3f6c3c8d23b379779369005f7a4b56ba8e0a588 +Author: bishoja +Date: Wed Nov 22 09:44:35 2023 +0100 - auth_ephemeral: typos + ims_ipsec_pcscf: add optional AoR argument to ipsec_destroy() -commit 95b9ad47fbf4f8444aa94aeb39c8c44b33f0f789 -Author: Дилян Палаузов -Date: Tue Feb 14 17:50:05 2023 +0200 +commit ba3eca2b41091e169a279be30827495d8269a1a0 +Author: Kamailio Dev +Date: Wed Nov 22 09:47:01 2023 +0100 - auth_diameter: typos + modules: readme files regenerated - ims_charging ... [skip ci] -commit 2d88dbe4dada18784a75cd228f55e8a7baf46b26 -Author: Дилян Палаузов -Date: Tue Feb 14 17:51:12 2023 +0200 +commit 48f0e7fc9bd95b509e8fb619d8aafb59c125d2c8 +Author: Morten Tryfoss +Date: Wed Nov 15 12:50:56 2023 +0100 - auth_db: typos + cdp: Avoid deadlock for callback on diameter timeout + + Callback function might do an operation which creates a new transaction, + which will result in a deadlock. + + Fixes #3641 -commit 0cb433212526537624ff51eb659cb22393e42b2d -Author: Дилян Палаузов -Date: Tue Feb 14 17:51:07 2023 +0200 +commit e17b554ba918dc33c60f41c2cee50ad2578fbbd3 +Author: Morten Tryfoss +Date: Tue Nov 14 10:12:16 2023 +0100 + + ims_charging: Various changes to make module compatible to other charging servers + + - Use origin-host of CCR response as destination-host of subsequent CCR requests, + to make sure those requests are routed to the same charging server (when using relay). + - use str_dup and str_free from ims_getters instead of locally defined. + - Honour AVP_Time_Quota_Threshold in CCR response, as an alternative to static configured + modparam "timer_buffer". + - Add new modparam "strip_plus_from_e164" to enable sending subscription id with correct + format according to specified type in the AVP. + - Moved subscription id formatting into a common function. + - Handle CCR response without AVP_Validity_Time set correctly. Was interpreted as + immediate expire. + - Handle IMS_RAR (Re-auth) request from charging server. Triggers an immediate interim + update if the session is alive. + - Handle IMS_ASR (Abort) request from charging server. Triggers an immediate termination + of the session/call. + - Fixed issue with signed/unsigned int related to check for Expires header. + cscf_get_expires_hdr() returns signed (-1 for not found), while that value was added + to the outgoing diameter request unsigned. That again resulted in an Expires AVP with + a really large value, and was rejected by the charging server. + +commit 6cd9f310a0af9bf6024696d436b6b96491808832 +Author: Morten Tryfoss +Date: Fri Nov 10 10:40:59 2023 +0100 - auth: typos + cdp: Add support for re-auth on ro sessions initiated from charging server + + - handle missing valid_for in CCA correctly, for chargings server not using it + - add AVP_Time_Quota_Threshold AVP, to support server controlled CCR-U threshold -commit 3f0c5103c661f73c9d172cd3728226ed3f7e4bdb -Author: Дилян Палаузов -Date: Tue Feb 14 17:51:02 2023 +0200 +commit 70449bfcb04eb44260fc8bd80ab6b77a86e82339 +Author: Daniel-Constantin Mierla +Date: Wed Nov 22 09:01:28 2023 +0100 - async: typos + topos: reformat exports structures -commit fe06f13c4d41cff9ee2b0d62926102d49d8436cc -Author: Дилян Палаузов -Date: Tue Feb 14 17:50:58 2023 +0200 +commit 35e191e1bea5463e766cb6f8f2ffb4862bd812a8 +Author: Daniel-Constantin Mierla +Date: Tue Nov 21 15:43:11 2023 +0100 - app_sqlang: typos + app_lua: use module name prefix for exports structure -commit 909e339becdc5db93830d9c3f0934a656bd16bb7 -Author: Дилян Палаузов -Date: Tue Feb 14 17:50:56 2023 +0200 +commit c6feb52c97bbd3fc33dc837d2b23e56c75f09583 +Author: Daniel-Constantin Mierla +Date: Tue Nov 21 15:39:21 2023 +0100 - app_ruby: typos + app_lua: reformat exports structures -commit f57dae9081d54b364285fe4950426f86e8d52e75 -Author: Дилян Палаузов -Date: Tue Feb 14 17:51:25 2023 +0200 +commit ebe77a2068c5073b436a1f8fefdfd689c9010816 +Author: Daniel-Constantin Mierla +Date: Tue Nov 21 15:35:04 2023 +0100 - app_python: typo + app_python3s: use module name prefix for exports structure -commit f833583fb02a9d26665692b02b4a2cfaab7c3d83 -Author: Дилян Палаузов -Date: Tue Feb 14 17:51:32 2023 +0200 +commit 9fb9cbddee8974a1733b999807cc1943248753f7 +Author: Daniel-Constantin Mierla +Date: Tue Nov 21 15:32:57 2023 +0100 - app_perl: typos + app_python3s: reformat exports structures -commit 051af44ddb92a3b31f0236e4b430edcc1ffd9866 -Author: Дилян Палаузов -Date: Tue Feb 14 17:51:55 2023 +0200 +commit 114d6fe510d7c1876782054ed89e4017d39d5f69 +Author: Daniel-Constantin Mierla +Date: Tue Nov 21 15:29:49 2023 +0100 - app_mono: typos + app_python3: use module name prefix for exports structure -commit f066bc53bf64791719ee3f97f2641aafbf76f6d7 -Author: Дилян Палаузов -Date: Tue Feb 14 17:52:02 2023 +0200 +commit 042bb9d10e12a256f9e4461031347e09b89fbe98 +Author: Daniel-Constantin Mierla +Date: Tue Nov 21 15:26:23 2023 +0100 - app_lua_sr: typos + app_python3: reformat exports structures -commit 9083ee603161475e805beb729ce4d11dc18a0e7a -Author: Дилян Палаузов -Date: Tue Feb 14 17:52:07 2023 +0200 +commit 1623f9ed1728455b72abf0a74f06bfd24365cefb +Author: Daniel-Constantin Mierla +Date: Tue Nov 21 15:14:39 2023 +0100 - app_lua: typos + core: resolve - variables initialisation -commit ca2c51143aab9ffafbb4f0a5474beb252f00deb4 -Author: Дилян Палаузов -Date: Tue Feb 14 17:52:17 2023 +0200 +commit dc7f2eca21eb6493f3c215eeb21e0a37a6e813c6 +Author: Daniel-Constantin Mierla +Date: Tue Nov 21 14:33:29 2023 +0100 - app_jsdt: typos + core: tcp - init local variables and define function only when needed -commit 0a062c9e52f61b48f6daf46756aeebbebb204646 -Author: Дилян Палаузов -Date: Tue Feb 14 17:52:26 2023 +0200 +commit d0a353342b559191aafc732174773e132554694a +Author: Daniel-Constantin Mierla +Date: Tue Nov 21 13:57:52 2023 +0100 - app_java: typos + core/mem: tlsf - cast to char* for pointer operations -commit 7e6942f283237033da9c211d5342e96148adbe5e -Author: Дилян Палаузов -Date: Tue Feb 14 17:52:39 2023 +0200 +commit 30c42aab767d777e3beb1493165458489957e92d +Author: Daniel-Constantin Mierla +Date: Tue Nov 21 13:30:26 2023 +0100 - alias_db: typo + core: resolve - cast after pointer operations for RES_AR -commit 63044aab8a915484f90fc21a16c50349d9b2bda4 -Author: Дилян Палаузов -Date: Tue Feb 14 17:53:01 2023 +0200 +commit 2da8060f67f09949e11f77a281fcb4e3e5def582 +Author: Daniel-Constantin Mierla +Date: Tue Nov 21 13:27:24 2023 +0100 - acc_radius: typo + pipelimit: init cpu load metrics and check returned value of fscanf() -commit f5cfafa396c5925b8b4694c3e962564706fd4e12 -Author: Дилян Палаузов -Date: Tue Feb 14 17:52:47 2023 +0200 +commit d439a0400caee337419cb2645b549d4926ede04e +Author: Daniel-Constantin Mierla +Date: Tue Nov 21 12:58:17 2023 +0100 - acc_json: typos + sms: more printing to buffer with size limit -commit d394cc62e48fe4636d4c9b2cf9ca8d54e0f1cfbd -Author: Дилян Палаузов -Date: Tue Feb 14 17:53:06 2023 +0200 +commit 1ded1730c7fe81596d874fdc314dab64a7dab25b +Author: Daniel-Constantin Mierla +Date: Tue Nov 21 12:04:01 2023 +0100 - acc: typo + mediaproxy: print to buffer with size limit -commit 5c8eed0ce78d029f28a1819262516940b7dd749e +commit 7a2ad1190553911770e3a78246ef037c6de49e5c Author: Daniel-Constantin Mierla -Date: Thu Mar 30 12:48:44 2023 +0200 +Date: Tue Nov 21 11:49:12 2023 +0100 - ndb_redis: fix index on parsing sentinel address + sms: print to buffer with size limit -commit 2c540b67a8a3f15835583926bfdef7cf6b71b4bf -Author: Henning Westerholt -Date: Wed Mar 29 13:44:44 2023 +0000 +commit 20b690a31ee0d3fbaa86fdf87790d842a982bcf5 +Author: Daniel-Constantin Mierla +Date: Tue Nov 21 11:35:21 2023 +0100 - Revert "pike: use pkg_malloc/pkg_free instead of system malloc" - - This reverts commit 6492a6f905075fa73d911c345fe784f2d3c085e5. + topos: open db connection in mod init only when checking table version -commit 18698fa9f8e242cf59273538baca448ea68d6194 -Author: Pantelis Kolatsis -Date: Wed Mar 29 11:36:15 2023 +0000 +commit 650117ebc0a3e0369dd47015f7e96358515fedc9 +Author: Kamailio Dev +Date: Tue Nov 21 11:32:12 2023 +0100 - gzcompress: convert to memory logging helper + modules: readme files regenerated - topos ... [skip ci] -commit 93011f8292c568f67bf5127ae7e092ec773df1a7 -Author: Pantelis Kolatsis -Date: Wed Mar 29 11:34:50 2023 +0000 +commit dab123bf9c19bbd67eab05cbadf9efea5682c0dc +Author: Xenofon Karamanos +Date: Mon Nov 20 14:37:50 2023 +0000 - misctest: convert to memory logging helper + topos: Add version_table documentation -commit 41c814b7cfbed2d89099840c29580d99b2a3cc47 -Author: Pantelis Kolatsis -Date: Wed Mar 29 11:32:56 2023 +0000 +commit 356f4f9e1319ecfdede4b46f636de3143b85ca5e +Author: Xenofon Karamanos +Date: Mon Nov 20 14:26:32 2023 +0000 - imc: convert to memory logging helper + topos: Add version_table parameter -commit 246e25f0e8c6ca933accf1bd57fea1f43e8346f5 -Author: Pantelis Kolatsis -Date: Wed Mar 29 11:27:56 2023 +0000 +commit 132a0024394494da8766c31c94f42822c79a0a51 +Author: Xenofon Karamanos +Date: Wed Nov 15 12:15:39 2023 +0000 - nathelper: convert to memory logging helper + topos: Close db connection -commit 0f559ea761e2b1b140096d414b6f3d624068366b -Author: Pantelis Kolatsis -Date: Wed Mar 29 10:40:16 2023 +0000 +commit c06390319a7afcca498a4a72cdcd0c11b7bb2ff2 +Author: Xenofon Karamanos +Date: Mon Nov 13 16:31:31 2023 +0000 - ipops: convert to memory logging helper, add missing error logging + topos: Add db version check -commit 7be6d78f5f9ee7aacef1a73321d4a384a7722077 -Author: Pantelis Kolatsis -Date: Wed Mar 29 09:52:04 2023 +0000 +commit 26ba1d9f42c77362de5ceb185d2fc1d1bb3f2d0c +Author: Xenofon Karamanos +Date: Wed Nov 15 09:44:15 2023 +0000 - msrp: convert to memory logging helper + dmq: Add find dmq node by IP + + - Add find_dmq_node_ip + - Add cmp_dmq_node_ip + - Add check in notification peer -commit 6492a6f905075fa73d911c345fe784f2d3c085e5 -Author: Henning Westerholt -Date: Wed Mar 29 09:50:20 2023 +0000 +commit 775b819bc90a46d33d231572013bf82fb021f004 +Author: Victor Seva +Date: Tue Nov 21 08:33:23 2023 +0100 - pike: use pkg_malloc/pkg_free instead of system malloc + pkg/kamailio/deb: set WOLFSSL_INTERNAL=no -commit fb1f01c333f9fc7189b6b3b6e39ddd28d30a5046 -Author: Pantelis Kolatsis -Date: Wed Mar 29 09:44:07 2023 +0000 +commit 159f476265ba9ee37650c3dc6aadd7b73f7612ec +Author: Victor Seva +Date: Tue Nov 21 08:15:37 2023 +0100 - pike: convert to memory logging helper, return error in case of allocation problem + pkg/kamailio/deb: introduce wolftls package -commit ab17b6811c94730f6428c218c9587d6365c9faa5 -Author: Pantelis Kolatsis -Date: Wed Mar 29 09:29:53 2023 +0000 +commit 10aa4442ac68024e062f7776000cfc0b93129c5a +Author: Daniel-Constantin Mierla +Date: Mon Nov 20 13:52:03 2023 +0100 - pdb: convert to memory logging helper, properly free memory in error cases + core: cfg.y - copy number string value with memcpy() -commit 3d60451ba47b14ce5e406a62b18547ad7d7d9165 -Author: Pantelis Kolatsis -Date: Wed Mar 29 09:16:31 2023 +0000 +commit 4b11820cb4337718854f1b80963e204764bc23b1 +Author: Daniel-Constantin Mierla +Date: Mon Nov 20 13:27:33 2023 +0100 - db_cluster: convert to memory logging helper + rtpproxy: print the ip address directly to local buffer + + - avoid extra copy -commit 19c9d56f3f6a53433949d2dac5494ad7b3b393a0 -Author: Pantelis Kolatsis -Date: Wed Mar 29 09:14:24 2023 +0000 +commit 71969c6126e6885f2ba312c692c9c646d8f870ef +Author: Daniel-Constantin Mierla +Date: Mon Nov 20 13:03:52 2023 +0100 - auth_ephemeral: convert to memory logging helper + mohqueue: switch to use snprintf() for a couple of string formatting cases -commit bc47875c2da39e755009c81ba1f2b4e7267b905e -Author: Pantelis Kolatsis -Date: Wed Mar 29 09:11:41 2023 +0000 +commit 1eb943773f52ea659c8dd812226ad07bcd15caaa +Author: Daniel-Constantin Mierla +Date: Mon Nov 20 10:43:19 2023 +0100 - auth_diameter: add missing allocation checks, convert to memory logging helper, clarify logging + core: review and update/remove old comments -commit 811ede41167455369518adadff338a2064645d55 -Author: Henning Westerholt -Date: Wed Mar 29 08:26:53 2023 +0000 +commit 34edbfa0194ba29e0e671551d44df3710beb93b6 +Author: Daniel-Constantin Mierla +Date: Mon Nov 20 10:18:58 2023 +0100 - acc_diameter: convert to memory logging helper + core: tcp_main - remove old comments -commit 0b9442b14adccdc7305ba222833a149e64488d66 -Author: Henning Westerholt -Date: Wed Mar 29 08:23:13 2023 +0000 +commit e51ccd11fe51f2d53dd7719b8fdec561a6ba7494 +Author: Daniel-Constantin Mierla +Date: Mon Nov 20 10:07:50 2023 +0100 - acc: convert to memory logging helper, properly free memory in case of errors + core: set proto on fixing forward actions -commit ba365102fe9faa403717eb30f36d363bad13114b +commit c9fbf2640ad74e9f42b43bded80877f8c4ce3f5d Author: Daniel-Constantin Mierla -Date: Tue Mar 28 17:31:31 2023 +0200 +Date: Mon Nov 20 09:42:50 2023 +0100 - evapi: initialize internal message queue + xcap: clang format -commit cc9501663d6dd0fa91aef23ce00a7cdf86319201 +commit a84e8bf031994d1b8d71e7b778204df0cbd7475b Author: Daniel-Constantin Mierla -Date: Tue Mar 28 08:12:00 2023 +0200 +Date: Mon Nov 20 09:42:50 2023 +0100 - ndb_redis: break on finding a server via sentinel + srdb2: clang format -commit f5bd2748a7d06d0592fc5ab835bf970b3c023eaa +commit 4d4311b355b111ec4b22c748f8d9dd0960ae4c4f Author: Daniel-Constantin Mierla -Date: Mon Mar 27 16:32:48 2023 +0200 +Date: Mon Nov 20 09:42:50 2023 +0100 - evapi: remove static specifier for evapi workers variable - - - it is exposed with extern + srdb1: clang format -commit f44e93a4171668d1c1182b186bea8c41db0a9300 -Author: Henning Westerholt -Date: Fri Mar 24 14:20:13 2023 +0000 +commit 3893cea9ebf83513ed68d2064113dd4fa67900bc +Author: Daniel-Constantin Mierla +Date: Mon Nov 20 09:42:50 2023 +0100 - carrierroute: remove redundant capabilities check, related to commit cf147ab7888c4e2 + shm_regex: clang format -commit ef94da7bac8e2aaf5a452d7b7dc3e2b544153ff6 -Author: Victor Seva -Date: Fri Mar 24 10:26:15 2023 +0100 +commit 3539a0c4d3579055172f1c12a81bb804d3fabbe7 +Author: Daniel-Constantin Mierla +Date: Mon Nov 20 09:42:50 2023 +0100 - app_lua: fix crash on exausted memory scenario + print: clang format -commit cf147ab7888c4e2b26db9dd44e494001bb71a61c -Author: Henning Westerholt -Date: Thu Mar 23 18:21:26 2023 +0000 +commit 62fafc2501bb6f213e8bc68f5485a25f8737b0bb +Author: Daniel-Constantin Mierla +Date: Mon Nov 20 09:42:50 2023 +0100 - carrierroute: check during startup for required DB capabilities (GH #3405) + presence: clang format -commit ffbb6ad2837326e7309be342ce62527c16f6db16 +commit dbe5851eaab6de1e56caf2eb3063a487d23bbd2c Author: Daniel-Constantin Mierla -Date: Wed Mar 22 19:38:48 2023 +0100 +Date: Mon Nov 20 09:42:50 2023 +0100 - nats: register cfg child procs and trigger init - - - GH #3395 + ims: clang format -commit b9de5009f81e27934a2108c06eae27ea748ead37 -Author: Henning Westerholt -Date: Wed Mar 22 12:58:56 2023 +0000 +commit f21732981789fa8317327a7e8c8edd7901df6d74 +Author: Daniel-Constantin Mierla +Date: Mon Nov 20 09:42:50 2023 +0100 - benchmark: fix order of free operation + cds: clang format -commit 43751e7b0071135d433258cc0423cc00546a31e6 -Author: Henning Westerholt -Date: Wed Mar 22 12:52:09 2023 +0000 +commit e70a52944af73fba31981f529101b28fe635e16e +Author: Daniel-Constantin Mierla +Date: Mon Nov 20 09:42:50 2023 +0100 - app_sqlang: restore some details related to one memory error log + binrpc: clang format -commit 7378aa0f7dcbde237bb5701f40b8a2d008d78b45 -Author: Pantelis Kolatsis -Date: Wed Mar 22 12:15:35 2023 +0000 +commit c99f0f49a5aca0181a5d24e5798361b37a28cea3 +Author: Daniel-Constantin Mierla +Date: Mon Nov 20 09:32:24 2023 +0100 - cfgutils: convert to memory error logging helper, add missing free in error case + lib/trie: clang format -commit af9f95da42bd07ea9bf3de0ea5cbd264f384bc02 -Author: Pantelis Kolatsis -Date: Wed Mar 22 12:13:47 2023 +0000 +commit f967d2ba2f0f6699fddf25c587fa007493d9b727 +Author: Daniel-Constantin Mierla +Date: Mon Nov 20 09:25:41 2023 +0100 - cplc: convert to memory error logging helper, add one missing free in error case + lib/trie: proper support for very long numbers -commit d7770cae2ee68be7184298b2bb41cb0ba3ebb47d -Author: Pantelis Kolatsis -Date: Wed Mar 22 11:20:08 2023 +0000 +commit a59bc67cd4bd1df3e81bdb494896b5a076f9d40d +Author: Daniel-Constantin Mierla +Date: Sat Nov 18 15:57:17 2023 +0100 - benchmark: properly free previous allocated memory in case of error + pv: transformation number parmeter kept long value to match pv field type -commit 9e001534589a3428cd5f8908e84fe327ffc20fb6 -Author: Pantelis Kolatsis -Date: Wed Mar 22 11:17:22 2023 +0000 +commit 6cc8f126391476a05f8d90a35d6d57eec7c4e8d8 +Author: Daniel-Constantin Mierla +Date: Fri Nov 17 19:34:51 2023 +0100 - avpops: convert to memory error logging helper + app_jsdt: length checks for resolving js module path -commit fcf733ce205221a40f68414662f841b918dea48f -Author: Pantelis Kolatsis -Date: Wed Mar 22 10:19:30 2023 +0000 +commit e54a41874de6393d71b50368ffb8a4982aed2d2d +Author: SPChan +Date: Sat Nov 18 19:21:40 2023 +0800 - db_flatstore: convert to memory logging helper + tls_wolfssl: enable building with external package + + - build with git submodule: make ...WOLFSSL_INTERNAL=yes... - the default + - build with external package: make ...WOLFSSL_INTERNAL=no... + + Debian recommended environment is libwolfssl41 5.6.4, libwolfssl-dev 5.6.4 -commit d45eb770b0a8e17533f12e16dfc1d23dc5e7d951 -Author: Pantelis Kolatsis -Date: Wed Mar 22 10:14:39 2023 +0000 +commit 38aa7e5fffcb68979a9bb5771aaa6ef9e14b517d +Author: SPChan +Date: Sat Nov 18 19:07:59 2023 +0800 - auth_xkeys: convert to memory logging helper + tls_wolfssl: update internal submodule to v5.6.4, and target 5.6.x for distro package -commit 01e82b38c41d344c1e94b2e0f574981ef0ce4318 -Author: Pantelis Kolatsis -Date: Wed Mar 22 10:07:02 2023 +0000 +commit dea9b25299ee273e45b0e08acacff8de87b7ceb9 +Author: SPChan +Date: Sat Nov 18 12:21:03 2023 +0800 - auth_db: fix goto for memory allocation error, convert to memory logging helper + tls_wolfssl: re-enable optimizations as qm/fm default to 16-byte alignment -commit 0702a7e0d9df2867cbc86188c06d95363d484d5a -Author: Pantelis Kolatsis -Date: Wed Mar 22 09:55:14 2023 +0000 +commit 9898c586095bd75cd31f0ca383ba0a347bfc4891 +Author: frederic +Date: Thu Nov 16 14:25:46 2023 +0100 - app_sqlang: convert to memory logging helper + topos: BYE sent by caller before call was connected was badly managed + regression introduced by patch 091dc9a76bcec5c8a4bc73e863ed10b1b9d76c92 + topos: fix early-dialog b-side UPDATE requests routing (GH #3437) -commit 66e9b02f7fc99084341d6519ac94cd580b334ac7 -Author: Pantelis Kolatsis -Date: Wed Mar 22 09:52:17 2023 +0000 +commit c26e9877419ac53fb109a24aefb3fcd711fae1d7 +Author: Daniel-Constantin Mierla +Date: Thu Nov 16 19:50:13 2023 +0100 - app_lua_sr: convert to memory logging helper + core: copy the value between quotes for #!defexps + + - GH #3631 -commit 8bf54822b9f610eceae1b5c6006ab6cc5ed96d00 -Author: Pantelis Kolatsis -Date: Wed Mar 22 09:49:48 2023 +0000 +commit 996b61ebfdabcae8729725b5d06f268aefcd33a4 +Author: Daniel-Constantin Mierla +Date: Thu Nov 16 18:26:27 2023 +0100 - app_jsdt: fix log message for system memory allocation + kamctl: missing space from previous commit -commit eef779ca7b5b203d216f76fbec56025d595f6e6d -Author: Pantelis Kolatsis -Date: Wed Mar 22 09:48:05 2023 +0000 +commit 64cd9336039bc05944fd9693e08edfab5fbd2f14 +Author: Xenofon Karamanos +Date: Thu Nov 16 10:09:18 2023 +0000 - app_java: add missing free in error case + kamctl: Fix source order + + - Add check for already sourced rc file in kamctl -commit b9d397c84cb3e0911e9823386b6eb4944b02c9ed -Author: Pantelis Kolatsis -Date: Tue Mar 21 16:22:24 2023 +0000 +commit 06ce65a2bbea826b890a3712cf1ac4f8b53e54cd +Author: Daniel-Constantin Mierla +Date: Thu Nov 16 08:09:31 2023 +0100 - async: convert to memory error logging helper + topos: detect direction for early dialog NOTIFY -commit 9cc9a177daf6d5ce11fbdef714bd576716dc5a2f -Author: Victor Seva -Date: Mon Mar 20 16:56:03 2023 +0100 +commit 243951bc487c5c67c81062445d4f4d7ee725684f +Author: Ovidiu Sas +Date: Thu Nov 16 11:27:21 2023 -0500 - p_usrloc: use PRIu64 macro to find out what format is needed for uint64_t since it depends on architecture + core: fix indentation on tcp_main.c -commit 1b3224c514105d69c3099c11edc5ef20ca02c567 -Author: Victor Seva -Date: Mon Mar 20 16:53:15 2023 +0100 +commit 34054fbd144102d414318249de217cedf8e5bd39 +Author: Ovidiu Sas +Date: Thu Nov 16 09:29:00 2023 -0500 - rtpengine: use PRIu64 macro to find out what format is needed for uint64_t since it depends on architecture + core: fix compilation for older kernels -commit 452af935fbcc60572541941612091cbc0535a310 -Author: Kamailio Dev -Date: Mon Mar 20 16:31:24 2023 +0100 +commit 4e614ba6b7a5663bd88f353a3ce7a0976d8e878f +Author: Ovidiu Sas +Date: Wed Nov 15 22:45:34 2023 -0500 - modules: readme files regenerated - evapi ... [skip ci] + pua_dialoginfo: safety check for request pointer -commit ab1831efc20816e18a89e6322d16c8e394b59abd +commit b7aecd5a6ad7e1c8102ace0cc0fab69820a8c729 Author: Daniel-Constantin Mierla -Date: Sun Mar 19 21:24:04 2023 +0100 +Date: Mon Nov 13 15:36:12 2023 +0100 - core: skip warning for atomic ops with locking for some dev os-es - - - do not print the compile warning for non-native memory barier/atomic - ops on some devel platforms, for now macos with apple silicon cpu + xprint: docs - removed trailing spaces -commit d4be0b2ec72159c5769fc6d7d0cee57e3576a668 +commit daf0e24b009070928b2ff179b24db14767c3549e Author: Daniel-Constantin Mierla -Date: Sat Mar 18 11:37:23 2023 +0100 +Date: Mon Nov 13 15:36:12 2023 +0100 - evapi: docs - updates to workers parameter + xmpp: docs - removed trailing spaces -commit 1dc0eac9a3a3abd6e128aa5f1d17d5f909efd963 +commit 8fb54d6b92a1248789ad974abca4b0fbface927c Author: Daniel-Constantin Mierla -Date: Fri Mar 17 10:53:24 2023 +0100 +Date: Mon Nov 13 15:36:12 2023 +0100 - evapi: if workers is 0, execute callback by evapi receiver + xmlops: docs - removed trailing spaces -commit b044c33c72318c12de78c0d8b7f8ac5ffb9b8772 +commit b49e0c99a16ca3463e7a943a608d95944463695c Author: Daniel-Constantin Mierla -Date: Fri Mar 17 09:54:58 2023 +0100 +Date: Mon Nov 13 15:36:12 2023 +0100 - evapi: docs for wait_increase parameter + xlog: docs - removed trailing spaces -commit 6e4ba9bd7421bf483cdbc7e5484f21d68b8acd8f +commit 111675c15a17bec29b19010f970ef0f988e00530 Author: Daniel-Constantin Mierla -Date: Thu Mar 16 19:30:04 2023 +0100 +Date: Mon Nov 13 15:36:12 2023 +0100 - evapi: wait increase limit made modparam + xhttp_rpc: docs - removed trailing spaces -commit 58bd64200e4d2f237f192acf6f88074aa983a396 +commit e23ab76d7b76f3359ef6b45a11fba2f5d6f6c8e0 Author: Daniel-Constantin Mierla -Date: Wed Mar 15 10:16:17 2023 +0100 +Date: Mon Nov 13 15:36:12 2023 +0100 - evapi: support for adaptive wait on idle to spare cpu when not busy + xhttp_prom: docs - removed trailing spaces -commit 7000f437ac8f3fb40c7a55c8c7a3c2c8dfc3fb1b +commit 65a1c779ba58fa92bd3e20c11902db0a991de177 Author: Daniel-Constantin Mierla -Date: Tue Mar 14 11:01:13 2023 +0100 +Date: Mon Nov 13 15:36:11 2023 +0100 - jsonrpcs: docs for tcp_socket parameter + xhttp_pi: docs - removed trailing spaces -commit 1400e8cb6aebdd93a5b0c6979a444a81922e37d2 +commit 6ef1e0da887737e9d3538ed1ffa54d2756f4badc Author: Daniel-Constantin Mierla -Date: Tue Mar 14 10:56:09 2023 +0100 +Date: Mon Nov 13 15:36:11 2023 +0100 - jsonrpcs: more debug messages when handling tcp commands + xhttp: docs - removed trailing spaces -commit b34e24770a6435577097b173cafab30c6d19e8d1 +commit f0c5c413f8b8615386ae462067da9ccaa6e1d43e Author: Daniel-Constantin Mierla -Date: Tue Mar 14 08:00:40 2023 +0100 +Date: Mon Nov 13 15:36:11 2023 +0100 - jsonrpcs: initial support for tcp transport - - - one rpc command per connection, which is closed after the response is - sent + xcap_server: docs - removed trailing spaces -commit 3bff060dcb74a081782abdbdade830b61be66557 +commit 0559b9eecb83415e69b9243715199b37d16af185 Author: Daniel-Constantin Mierla -Date: Fri Mar 10 16:21:51 2023 +0100 +Date: Mon Nov 13 15:36:11 2023 +0100 - evapi: use internal workers to handle client messages + xcap_client: docs - removed trailing spaces -commit 3b99e09dc10ff38024b2821b26f2efe7c82d699d +commit 9d3a4903a81bbc614cf296ec6468654ff46c742c Author: Daniel-Constantin Mierla -Date: Fri Mar 10 13:01:11 2023 +0100 +Date: Mon Nov 13 15:36:11 2023 +0100 - evapi: docs for wait_idle modparam + websocket: docs - removed trailing spaces -commit 4c998de5f54ee941f7516e589e2940593b20f827 +commit f65336962e7969857eba0c9d09082ed972bfa4a7 Author: Daniel-Constantin Mierla -Date: Fri Mar 10 12:50:46 2023 +0100 +Date: Mon Nov 13 15:36:11 2023 +0100 - evapi: wait when idle made a modparam + uuid: docs - removed trailing spaces -commit 569db2eeaef17f3034f692e808f340103cdbe71e +commit 83484821e43f6d8e31e99683d7ed06fc233b364d Author: Daniel-Constantin Mierla -Date: Thu Mar 9 11:50:53 2023 +0100 +Date: Mon Nov 13 15:36:11 2023 +0100 - pipelimit: docs for rpc command pl.reset_pipe + utils: docs - removed trailing spaces -commit e0713531bf6ea2aa9b249503dc346ac0d4510a93 +commit 847a0f2edb62b3a1ceb8bdd9fbd32f3bea8d7953 Author: Daniel-Constantin Mierla -Date: Wed Mar 8 08:44:01 2023 +0100 +Date: Mon Nov 13 15:36:11 2023 +0100 - pipelimit: new rpc command pl.reset_pipe - reset associated values + usrloc: docs - removed trailing spaces -commit 6c0b62c464bcbc67e485c1e2193b7a6c96e471fb +commit 1cd2f20fc62597e76e4c347ad7343da74986811f Author: Daniel-Constantin Mierla -Date: Tue Mar 7 11:18:00 2023 +0100 +Date: Mon Nov 13 15:36:11 2023 +0100 - pipelimit: docs for rpc command pl.rm_pipe + userblocklist: docs - removed trailing spaces -commit e27823f746eb8fca834474945e45bfef27c3d50c +commit 0a93d0930c1021bbd5f6c0b867865654ef8b3df9 Author: Daniel-Constantin Mierla -Date: Mon Mar 6 14:57:35 2023 +0100 +Date: Mon Nov 13 15:36:11 2023 +0100 - pipelimit: added rpc command pl.rm_pipe + uri_db: docs - removed trailing spaces -commit 1b5caab3479bb32c2986906e6e07ea9d5be38a8c +commit 29dc670f3ba4a148d2ea8be7a4317ff6dce7dd68 Author: Daniel-Constantin Mierla -Date: Mon Feb 20 20:20:44 2023 +0100 +Date: Mon Nov 13 15:36:11 2023 +0100 - kamctl: option to set store path for rpc commands + uid_uri_db: docs - removed trailing spaces -commit 4fec664327410db4e5ff7036a459e99abfa539bc +commit 3de666db926f6235199a3b0b456c91a4016a6e21 Author: Daniel-Constantin Mierla -Date: Sun Feb 19 09:17:08 2023 +0100 +Date: Mon Nov 13 15:36:11 2023 +0100 - jsonrpcs: implemented result storing for rpc over fifo + uid_gflags: docs - removed trailing spaces -commit 161ec6d14b702cb92406171152d127b0bb85c329 +commit d8cbd0969a36474a84b4b81d042a767221d75367 Author: Daniel-Constantin Mierla -Date: Sat Feb 18 14:09:12 2023 +0100 +Date: Mon Nov 13 15:36:11 2023 +0100 - jsonrpcs: protocol extended to allow storing response in a file - - - implemented for udp sockets + uid_domain: docs - removed trailing spaces -commit e29ce594466385a7c35634fda4b4664d92484622 +commit 16219f9f0418ca99ec5af6c39dc5cef5cd96b6e9 Author: Daniel-Constantin Mierla -Date: Fri Feb 17 14:07:04 2023 +0100 +Date: Mon Nov 13 15:36:11 2023 +0100 - p_usrloc: cast to uint64_t when using time_t value + uid_avp_db: docs - removed trailing spaces -commit 926ba9473775878d8f38b175764a50dee15fac69 +commit acfcbf39c7214367dee0fb01257138eff9b123f6 Author: Daniel-Constantin Mierla -Date: Fri Feb 17 13:42:22 2023 +0100 - - rtpengine: cast to uint64_t when using time_t value - -commit 135f7b5e2114617b0bc408175ec146d248d01d3a -Author: Kamailio Dev -Date: Mon Mar 20 11:01:25 2023 +0100 - - modules: readme files regenerated - ims_registrar_pcscf ... [skip ci] - -commit 38d72c3f8248b32b3ba0ff24abd1f2f7407f9d8f -Author: Annemarie Mandl -Date: Mon Dec 21 11:19:34 2020 +0100 +Date: Mon Nov 13 15:36:11 2023 +0100 - ims_registrar_pcscf: changes for ul db_mode DB_ONLY - - Enable registration of pcscf contact callback during download - from db location table and inserting pcontact (normally this - callback is registered during handling of REGISTER). - Refuse REGISTER when pcontact is expired since [0 to 20] seconds. - Within this time window a NOTIFY is expected from scscf and in order - to avoid race time conditions between scscf and pcscf REGISTER - will be refused. Refuse REGISTER when pcontact is expired longer - than 20 seconds - send PUBLISH (contact expired) to scscf to trigger - NOTIFY. In both REGISTER refused scenarios routing script should reply - 500 - Deregistration in progress. - - undo changes in ul_callback.c & ul_callback.h - - corrections after comments from Henning - -commit e8520177f6fd70676251cfd2307c0ab40701a701 -Author: Pantelis Kolatsis -Date: Tue Mar 14 21:13:20 2023 +0000 - - auth_identity: add missing error handling for allocation errors, convert to memory log macros - -commit 7e617ab89f5275f1b269382ae2c1fee508854cf1 -Author: Pantelis Kolatsis -Date: Tue Mar 14 21:10:04 2023 +0000 - - dmq: add missing memory allocation checks, convert to memory log macros - -commit aa4d015a58bb24ba5bda6e6133b0e9f314e2318e -Author: Henning Westerholt -Date: Tue Mar 14 17:20:14 2023 +0000 - - dispatcher: small formatting adaption related to 6aee3bd7c - -commit 6aee3bd7c86a1874cc140a7874b740981f14f5f5 -Author: Pantelis Kolatsis -Date: Tue Mar 14 17:17:28 2023 +0000 - - dispatcher: add missing memory allocation checks, convert to memory log macros - -commit ef0427ead03bfb738b6214b91c1763913e70a52d -Author: Victor Seva -Date: Tue Mar 14 17:08:46 2023 +0100 - - nat_traversal: - -commit 8841257671b6c5f3c4cfee3f1b7bb46d54faaf65 -Author: Victor Seva -Date: Tue Mar 14 17:03:45 2023 +0100 - - core: use PRIu64 macro to find out what format is needed for uint64_t - - since it depends on architecture - -commit ebfacdb7d7c3dfceb68e9550eec72b89d695fd4b -Author: Victor Seva -Date: Tue Mar 14 12:07:27 2023 +0100 - - core: tmrec fix build warning introduced at dd6339f817822cd0590aec2a9a467330bde499dd - - > core/utils/tmrec.c: In function 'ac_print': - > core/utils/tmrec.c:275:32: warning: format '%llu' expects argument of type 'long long unsigned int', but argument 2 has type 'long unsigned int' [-Wformat=] - > 275 | printf("\nSys time: %llu\nTime: %02d:%02d:%02d\n", (uint64_t)_atp->time, - > | ~~~^ ~~~~~~~~~~~~~~~~~~~~ - > | | | - > | long long unsigned int long unsigned int - > | %lu - -commit 6e032019d992625abc2a3739423df9ea1c964356 -Author: Victor Seva -Date: Tue Mar 14 12:01:32 2023 +0100 - - nat_transversal: fix warning introduced at f301ca9cdcc044dd05e9d82139e1db368be6dc5c - - > nat_traversal.c: In function 'get_register_expire': - > ../../core/parser/../dprint.h:321:73: warning: format '%llu' expects argument of type 'long long unsigned int', but argument 11 has type 'long unsigned int' [-Wformat=] - > 321 | fprintf(stderr, "%2d(%d) %s: %.*s%s%s%s" fmt, \ - > | ^~~~~~~~~~~~~~~~~~~~~~~~ - -commit 781ee072593f16a100ef00b5ef71fcfd6f8ded2b -Author: Victor Seva -Date: Tue Mar 14 11:55:34 2023 +0100 - - lcr: fix building warnings initializating values - - > https://kamailio.sipwise.com/job/kamailiodev-nightly-binaries/architecture=amd64,distribution=bookworm/2381/consoleText - > [...] - > lcr_mod.c:2630:9: warning: 'tmp_tag.len' may be used uninitialized [-Wmaybe-uninitialized] - -commit 6fa5a8fa8ddfe09bdab2fb445bee94e51d86b7fc -Author: Dennis -Date: Fri Mar 10 17:46:21 2023 +0300 - - auth_ephemeral: fix authentication with secrets added at runtime (#3390) - - * auth_ephemeral: fix authentication with secrets added at runtime - - - proper way to work with shm pointer to secret list - - * fix: free secret_struct shm - - Free shm secret_struct in case the allocation error of secret_list pointer. - -commit e3b8b76d7a8773af4e10ce011682931429cd4a87 -Author: Gustavo Almeida -Date: Fri Mar 3 23:47:50 2023 +0000 - - utils/kamctl: allow the definition of a specific startup file at start process - - - Added the possibility to specify an alternative file different from the default: kamailio.cfg, when starting kamailio, using the kamctl tool. - This makes it possible to start kamailio by passing a startup file located in a specific folder (via ETCDIR env variable) and with a specific name, instead of using the default name: kamailio.cfg. - -commit b15db86e93120824dcfc879099432f3ec1c3b0c7 -Author: Pantelis Kolatsis -Date: Mon Mar 6 10:44:19 2023 +0000 - - sqlops: do not allow empty name component in URL - -commit 212675d350b64b5c9abb6a6eb844f41b6efb8693 -Author: Kamailio Dev -Date: Wed Mar 1 13:46:32 2023 +0100 - - modules: readme files regenerated - rtpengine ... [skip ci] + uid_auth_db: docs - removed trailing spaces -commit bd497411f2e8e9ee6bd7e47d838add607019e761 +commit 309c7b525a0141fc2e35259830313e5be317b8e6 Author: Daniel-Constantin Mierla -Date: Wed Mar 1 13:31:12 2023 +0100 +Date: Mon Nov 13 15:36:11 2023 +0100 - rtpengine: spell fixes in the comments + uac_redirect: docs - removed trailing spaces -commit 5a9d8634e742fe28b3b5c733b9e727b1dc7917ce +commit 07efcaec57f1d28d0c398af9d2f268f6dc205945 Author: Daniel-Constantin Mierla -Date: Wed Mar 1 13:29:47 2023 +0100 +Date: Mon Nov 13 15:36:11 2023 +0100 - rtpengine: docs for SDES-nonew and SDES-pad flags - - - spell fixes + uac: docs - removed trailing spaces -commit 1f2622fc7e0d7b81bab311728b1b3b6856790ace +commit 6a3fe1d72d02d5f35aaa5ed695735f75b3f222c5 Author: Daniel-Constantin Mierla -Date: Wed Mar 1 13:20:41 2023 +0100 +Date: Mon Nov 13 15:36:11 2023 +0100 - sl: print rpc result fields as unsigned long - - - GH #3386 + tsilo: docs - removed trailing spaces -commit 9a7c4025b6a4b90125c1c30dfd1d994100ae965e -Author: Kamailio Dev -Date: Wed Mar 1 08:46:34 2023 +0100 +commit d1b97f91445561b2f0acd362ebcb7f4d881980f6 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:11 2023 +0100 - modules: readme files regenerated - htable ... [skip ci] + topos: docs - removed trailing spaces -commit 714c9eb99e6ba73e05a98df2bc6f4b339e9a97c9 -Author: Henning Westerholt -Date: Wed Mar 1 07:37:53 2023 +0000 +commit e9005cc999fe8b00dda5b1dc107a4cd2f3b02fcf +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:11 2023 +0100 - rtpengine: small spelling fix related to codec-mask example, related to e8c294f33f8b + tmx: docs - removed trailing spaces -commit 70d8308bbf849b00be69d5c3091b57dfe214b81b -Author: Henning Westerholt -Date: Wed Mar 1 07:34:43 2023 +0000 +commit 904636632c2ed13688e5a2202d8d9f9c5a197cc4 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:11 2023 +0100 - htable: fix XML syntax errors introduced in 23c67322c244fc4bf + tmrec: docs - removed trailing spaces -commit 05b4fdebcf2eb9c82739a643ff48b799b8046bbd -Author: Kamailio Dev -Date: Tue Feb 28 11:01:24 2023 +0100 +commit 07c5e3b4f9a8fa4986d4414c6691792af5f12121 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:10 2023 +0100 - modules: readme files regenerated - htable ... [skip ci] + tm: docs - removed trailing spaces -commit 23c67322c244fc4bf6e990379d2fd876b55b2cbe -Author: Ihor Olkhovskyi -Date: Tue Feb 28 09:40:04 2023 +0100 +commit 3bbbc39a32db95e0faaaf440e3369fb0a419734d +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:10 2023 +0100 - doc/htable: adding examples in a case of key value is an integer + tls: docs - removed trailing spaces -commit b75b6e4b5d7425ca995aa125171edebec52bf82b -Author: Kamailio Dev -Date: Mon Feb 27 20:16:29 2023 +0100 +commit f15b88c5c054a8286a149d13ae59629be0201bbc +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:10 2023 +0100 - modules: readme files regenerated - rtpengine ... [skip ci] + textopsx: docs - removed trailing spaces -commit e8c294f33f8b867b0f67d78c14b7327dc22dd726 -Author: Julien Chavanton -Date: Fri Feb 24 18:15:12 2023 -0500 +commit 15fa5db61a4baa7a01ceea7b5c492fce8705e046 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:10 2023 +0100 - rtpengine: doc add codec-accept with an example + textops: docs - removed trailing spaces -commit a229d230bca5e785670edc3901f849e93989f9fe -Author: POIROTTE Francois -Date: Fri Feb 17 15:43:22 2023 +0100 +commit da569f99deb12b8c6b636e586833db9c348f3c6c +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:10 2023 +0100 - kamctl: hide errors raised by "which" - - Hide error messages from "which" to avoid polluting kamctl's output - (e.g. when a JSON document is returned) in environments where STDOUT - and STDERR may be combined into a single stream (e.g. containers) + tcpops: docs - removed trailing spaces -commit ac0edd34b491dc78bca6979d2f1444c50bfb7399 -Author: Carsten Bock -Date: Thu Feb 16 16:27:39 2023 +0100 +commit 1861bb8b0e6e81fe77f526b53ae4c0729feda3fe +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:10 2023 +0100 - dialog: Do not trigger bye_reply_cb for in-dialog requests + stun: docs - removed trailing spaces -commit 2f7da809d53ffadff017681e257b8d86bec3a5ce +commit d220239083e7b85b211b6209f53178d6e5ad4003 Author: Daniel-Constantin Mierla -Date: Thu Feb 16 12:16:26 2023 +0100 +Date: Mon Nov 13 15:36:10 2023 +0100 - statsc: cast to uint64_t when using time_t value + stirshaken: docs - removed trailing spaces -commit c78910a71226f3a567ad396ce5e834036ce75f97 +commit 52db0859dc71a93757a5f01f8659ce8e35ad5236 Author: Daniel-Constantin Mierla -Date: Thu Feb 16 12:07:26 2023 +0100 +Date: Mon Nov 13 15:36:10 2023 +0100 - uac: cast to uint64_t when using time_t value + statsd: docs - removed trailing spaces -commit bd0ce126109f40f5217053f20e687b93b2268164 -Author: Richard Fuchs -Date: Tue Feb 14 15:01:22 2023 -0500 +commit 51fce41ae4064e6d89350d56cd9638e9f5787de1 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:10 2023 +0100 - rtpengine: avoid repeated queries to same node - - If we know which node handles a particular call from the hash table, - only query that node once and then return error if it's dead, instead of - going into a pointless loop looking for other nodes to query which don't - exist. - - closes #3370 + statistics: docs - removed trailing spaces -commit f301ca9cdcc044dd05e9d82139e1db368be6dc5c +commit ac328ba6bff81d5a76fae7a4f30a061c0172b0f4 Author: Daniel-Constantin Mierla -Date: Wed Feb 15 09:33:56 2023 +0100 +Date: Mon Nov 13 15:36:10 2023 +0100 - nat_traversal: cast to uint64_t when using time_t value + sst: docs - removed trailing spaces -commit 929345896700fb116facc41e3542125dfbb79b41 +commit d57e3c4f9a62bca0ff86af5e885395b41274ace1 Author: Daniel-Constantin Mierla -Date: Wed Feb 15 09:28:03 2023 +0100 +Date: Mon Nov 13 15:36:10 2023 +0100 - avpops: cast db value for avp number field as long + sqlops: docs - removed trailing spaces -commit e203aaf7294b5f320ede58636649246167974983 -Author: Kamailio Dev -Date: Tue Feb 14 17:31:29 2023 +0100 +commit b7e9bfe1e5f648c7585d702f28fc1d23bd5d92f9 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:10 2023 +0100 - modules: readme files regenerated - presence ... [skip ci] + snmpstats: docs - removed trailing spaces -commit 6b30c100e7618cabf4d241f4b5b28bb334cf5340 +commit b0a37464485a86cbec459a8fd096ebcea7526169 Author: Daniel-Constantin Mierla -Date: Tue Feb 14 17:16:19 2023 +0100 +Date: Mon Nov 13 15:36:10 2023 +0100 - presence: docs for presence.watcher_list rpc command + smsops: docs - removed trailing spaces -commit 9cbebc1d7c0eda71162ce3d90de1ac3110c10bb0 +commit 99d43051d548e339b7aaf454010958aef48b646a Author: Daniel-Constantin Mierla -Date: Tue Feb 14 17:13:09 2023 +0100 +Date: Mon Nov 13 15:36:10 2023 +0100 - presence: added presence.watcher_list rpc command - - - list the watchers for a presentity uri + sms: docs - removed trailing spaces -commit f66a071d18820fc71e421d1a73ebd959c4423655 +commit f0deffa60d94710f683a9131f3826cf0726fff43 Author: Daniel-Constantin Mierla -Date: Tue Feb 14 12:07:50 2023 +0100 +Date: Mon Nov 13 15:36:10 2023 +0100 - auth: use time_t instead of casting to int in nonce check - - - use unsigned int instead of int for building the nonce + sl: docs - removed trailing spaces -commit 41cd4fe940e2867a348d45840363dfef2b9e05dc +commit e69484a11c9fd0ecfa975a3953c8cbfd1c83e52a Author: Daniel-Constantin Mierla -Date: Tue Feb 14 11:08:11 2023 +0100 +Date: Mon Nov 13 15:36:10 2023 +0100 - acc_radius: cast to uint64_t when using time_t value + siputils: docs - removed trailing spaces -commit e9f1a426b6ca5fb9b4c9dc67f2b3f744c20f40b0 -Author: Henning Westerholt -Date: Tue Feb 14 10:27:25 2023 +0000 +commit 0e4c3e1c0572a99360e4abb821c0022c12f3f51c +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:10 2023 +0100 - sipcapture: remove not used parameter table_time_suffix + siptrace: docs - removed trailing spaces -commit f3ab1aa02955493dd3f095d0ebbcb64d2d6751e5 -Author: Kamailio Dev -Date: Tue Feb 14 11:01:49 2023 +0100 +commit 1e57dc7178cca5245e86c85ed237c48313c09ce5 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:10 2023 +0100 - modules: readme files regenerated - sctp ... [skip ci] + sipt: docs - removed trailing spaces -commit a308dc748aa819b46aab82c148b7bdaad81db651 -Author: Дилян Палаузов -Date: Tue Feb 14 08:29:37 2023 +0200 +commit 8a2a56fc0007638b771a5ba0852f5678cb46098d +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:10 2023 +0100 - sworker: typos + sipcapture: docs - removed trailing spaces -commit 698a92dd87a067bfbba68689e98232811668f580 -Author: Дилян Палаузов -Date: Tue Feb 14 08:28:29 2023 +0200 +commit ebbc9f470f7860f0efb5ac448b563a7d49efd22c +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:10 2023 +0100 - stun: typos + secfilter: docs - removed trailing spaces -commit f8f94e46baa85a811dcf1f8be82ca4e0d62205c0 -Author: Дилян Палаузов -Date: Tue Feb 14 08:30:33 2023 +0200 +commit 0640ad52cabfbb16334387a5ebe4c1488eca5b35 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:10 2023 +0100 - stirshaken: typos + seas: docs - removed trailing spaces -commit a8367fa4fa8519193f5ed5693e78c1414cc1c8d6 -Author: Дилян Палаузов -Date: Tue Feb 14 08:30:48 2023 +0200 +commit 785a8c2dc13c7c99487f51ba9718827c4c57fe48 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:09 2023 +0100 - statsc: typos + sdpops: docs - removed trailing spaces -commit 8e899ee6e2efd5287fb627412209a38eb9410b5d -Author: Дилян Палаузов -Date: Tue Feb 14 08:28:22 2023 +0200 +commit 4f962480259a8530feb284076f99a2f1ae623f23 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:09 2023 +0100 - sst: typos + sctp: docs - removed trailing spaces -commit ac16ccd332ba8b0a3ac41d0074080492cdac4cf8 -Author: Дилян Палаузов -Date: Tue Feb 14 08:28:16 2023 +0200 +commit 3b2a1e0920a7655a442fafe24b1750e83685734c +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:09 2023 +0100 - sqlops: typo + sanity: docs - removed trailing spaces -commit 4235d2e8300a8e135ec9768e27797bac79af8e7c -Author: Дилян Палаузов -Date: Tue Feb 14 08:30:21 2023 +0200 +commit cb07964b535cb2563b8e188128dc6c2d038eae50 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:09 2023 +0100 - snmpstats: typo + rtpproxy: docs - removed trailing spaces -commit 88bcbef21d570e0b853262d7880ba21d4bc8dabc -Author: Дилян Палаузов -Date: Tue Feb 14 08:28:09 2023 +0200 +commit e2b79a7226eaa03f76a3874c9facebe989290fc4 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:09 2023 +0100 - smsops: typos + rtpengine: docs - removed trailing spaces -commit 766824a3da2798cb9efa4802c05680611618eab5 -Author: Дилян Палаузов -Date: Tue Feb 14 08:28:03 2023 +0200 +commit 176dfae5babb5c601186cb62bd45f5598194559a +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:09 2023 +0100 - sms: typos + rtp_media_server: docs - removed trailing spaces -commit f9b6fc83ef7106bb6ee5fd96695e84edd9d5a98e -Author: Дилян Палаузов -Date: Tue Feb 14 08:29:31 2023 +0200 +commit 13ae71d4a3209add4f63b88c14fb7c4f6dd640a0 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:09 2023 +0100 - slack: typos + rtjson: docs - removed trailing spaces -commit 80aeb90fd837f20c4b6524b3df64cc783fa948b7 -Author: Дилян Палаузов -Date: Tue Feb 14 08:27:57 2023 +0200 +commit ecb4a6558e2c58aeb1a649c0eb40b490dbee2ee4 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:09 2023 +0100 - sl: typos + rtimer: docs - removed trailing spaces -commit d79f5c2d69920edd6feea68b6fd89f30e0af25a3 -Author: Дилян Палаузов -Date: Tue Feb 14 08:29:25 2023 +0200 +commit 58460ede458d7a784d22c3a80e4884af604feb33 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:09 2023 +0100 - siptrace: typos + rr: docs - removed trailing spaces -commit 469f86fd958fd79bdc24aebbaf168307ca086b72 -Author: Дилян Палаузов -Date: Tue Feb 14 08:27:51 2023 +0200 +commit 31282c6d799fd67229e82a781a8d43da2b60845c +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:09 2023 +0100 - sipt: typos + rls: docs - removed trailing spaces -commit 70910e72000d1be7513d1869ac0c4e61cd55d6fb -Author: Дилян Палаузов -Date: Tue Feb 14 08:29:18 2023 +0200 +commit ad521b06959729893a7a84934bfdf00869b91762 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:09 2023 +0100 - sipjson: typos + registrar: docs - removed trailing spaces -commit a763ee9faa95dd616542b2e25f54b156d755b366 -Author: Дилян Палаузов -Date: Tue Feb 14 08:27:36 2023 +0200 +commit 8dab772bb15934119384d7a13010bc3e7d2c4b6b +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:09 2023 +0100 - sipcapture: typos + regex: docs - removed trailing spaces -commit f175444552745f33796ef1dded89a623e8e76c81 -Author: Дилян Палаузов -Date: Tue Feb 14 08:30:06 2023 +0200 +commit 5aae3ddc58f147a3c59dc5d6a1be93a461e08fff +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:09 2023 +0100 - secsipid_proc: typos + ratelimit: docs - removed trailing spaces -commit 47c9ddf2ae08c07e222dfbe98d314adc5148d00f -Author: Дилян Палаузов -Date: Tue Feb 14 08:30:00 2023 +0200 +commit 68ebc2a4d190c8bc912ac186a14af229ea3d0662 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:09 2023 +0100 - secsipid: typos + rabbitmq: docs - removed trailing spaces -commit d08cef5bc5b1cacbfcb70c3f5298f6173bd7b8c1 -Author: Дилян Палаузов -Date: Tue Feb 14 08:29:50 2023 +0200 +commit 9645efb7937ab944eb0ef671b892225c35235f11 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:09 2023 +0100 - secfilter: typo + qos: docs - removed trailing spaces -commit 334efbb1d2e1ed4a1086694e60063655ae223c63 -Author: Дилян Палаузов -Date: Tue Feb 14 08:29:08 2023 +0200 +commit 06f32c1291f8be836a4fb2c4aa1c8584b248fe10 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:09 2023 +0100 - sdpops: typos + pv_headers: docs - removed trailing spaces -commit 0c8226457ae2d94ec615719fed71b1babcf43e69 -Author: Дилян Палаузов -Date: Tue Feb 14 08:28:58 2023 +0200 +commit 87f623c93e8eec0ad3d080a44584f20428376ab6 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:09 2023 +0100 - sctp: typos + pv: docs - removed trailing spaces -commit 21ce3506dea9a8873ba4b127f4a8ad68b9ed7491 -Author: Дилян Палаузов -Date: Tue Feb 14 08:28:52 2023 +0200 +commit 0d4ec6aaefcc1f059b15d836369be3c81691d572 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - sca: typos + pua_xmpp: docs - removed trailing spaces -commit 63a7b8932adf1b2d0f76d40b960df03fa87b56fc -Author: Дилян Палаузов -Date: Tue Feb 14 08:28:46 2023 +0200 +commit bf79c325e179ee9f02fe86096a09408fa5383e08 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - sanity: typos + pua_usrloc: docs - removed trailing spaces -commit 4f201cbd2e9d0c645e1f6618e6db95389731ef95 -Author: Kamailio Dev -Date: Mon Feb 13 21:46:37 2023 +0100 +commit 4839c998d77d9d94cba28278e73642d6b93d8832 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - modules: readme files regenerated - db_berkeley ... [skip ci] + pua_reginfo: docs - removed trailing spaces -commit 6b1c1e7727f8f210f7d20f1473458c8c152926ff -Author: Дилян Палаузов -Date: Mon Feb 13 21:01:20 2023 +0200 +commit e88a299fc4e87233ce5a193f7a2b35aeaa18e4af +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - db2_ldap: typos + pua_json: docs - removed trailing spaces -commit e0e6adfcb27d336ecb156e3b88c4d72ce36d37f0 -Author: Дилян Палаузов -Date: Mon Feb 13 21:01:14 2023 +0200 +commit 6fddcdfa24a81dc859d2aa2ce7f7c0f6f71424c6 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - db2_ops: typo + pua_dialoginfo: docs - removed trailing spaces -commit ceb4ca6b2a25e04df5029949fb6d1d92c0972662 -Author: Дилян Палаузов -Date: Mon Feb 13 21:01:05 2023 +0200 +commit 37c6b2513535e8e2f6ca7de9814b0363db6fa8ef +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - db_berkeley: typos + pua_bla: docs - removed trailing spaces -commit e09bb7e1880ab7204b915efc86c29490c9774dfc -Author: Дилян Палаузов -Date: Mon Feb 13 21:00:58 2023 +0200 +commit 4ac5ab55f8b3be12cf6c48104082ebb162699879 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - db_cassandra: typos + pua: docs - removed trailing spaces -commit fa77972687a0117290ae979f45b3767c2b1465d2 -Author: Дилян Палаузов -Date: Mon Feb 13 21:00:45 2023 +0200 +commit ee0c084f2945a9c180cc72ba80083f81c7463bd7 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - db_cluster: typos + print_lib: docs - removed trailing spaces -commit 9920c228856289af92294396959710e7ee1f344d -Author: Дилян Палаузов -Date: Mon Feb 13 21:00:37 2023 +0200 +commit cbf367dc21cb92893ed33cc3cd4cb60799a51d0b +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - db_flatstore: typos + print: docs - removed trailing spaces -commit 1c500b7881c2e4677371acd66236a45f6343949c -Author: Дилян Палаузов -Date: Mon Feb 13 21:00:29 2023 +0200 +commit 6b8907bea375a794a49c677097d4677ec4aaf221 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - db_mongodb: typos + presence_xml: docs - removed trailing spaces -commit 8aee342bd9149f22e8423b75e23fea27bc78345e -Author: Дилян Палаузов -Date: Mon Feb 13 21:00:21 2023 +0200 +commit 23daf2155a6797e3dc4c80d60e9733d6180e60f2 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - db_mysql: typos + presence_reginfo: docs - removed trailing spaces -commit 9459b93dfb85bd4916e0b9ae6f567f692df725ae -Author: Дилян Палаузов -Date: Mon Feb 13 21:00:13 2023 +0200 +commit 224b1fb6b996166a4e86362f8ded24fe706a2081 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - db_unixodbc: typos + presence_profile: docs - removed trailing spaces -commit 0291d13584caef9fb491cca18c0194d9e202aa0d -Author: Дилян Палаузов -Date: Mon Feb 13 21:00:00 2023 +0200 +commit 1314b7ddd2464d99fe7e067801bbadb15dc65fac +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - db_oracle: typos + presence_mwi: docs - removed trailing spaces -commit 7699387c163ad94f0b96d3460d33a748ba648010 -Author: Дилян Палаузов -Date: Mon Feb 13 20:59:53 2023 +0200 +commit 638549475635090c02ceeb093a40d68b6a0b6d91 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - db_perlvdb: typos + presence_dialoginfo: docs - removed trailing spaces -commit 0b6013a2c739a6270820b211097016916683d29f -Author: Дилян Палаузов -Date: Mon Feb 13 20:59:43 2023 +0200 +commit 8c289179ab814b75485c3a616b496294f35a1211 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - db_redis: typo + presence_conference: docs - removed trailing spaces -commit 1a743d094762edb26721184fa4671a74366c0992 -Author: Дилян Палаузов -Date: Mon Feb 13 20:59:37 2023 +0200 +commit 41d60bdddbbd11045ceb8a7f2f50f407f2bf6c65 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - db_postgres: typos + presence: docs - removed trailing spaces -commit 78c25be36d0c0bcbf721d03903b6869a392b6be7 -Author: Дилян Палаузов -Date: Mon Feb 13 20:59:30 2023 +0200 +commit 3011e9df28decefaece9fa8dafbc2439c8a68c17 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - db_text: typos + prefix_route: docs - removed trailing spaces -commit f63cf3cc56e9cad458e5531d07bd579cba62f1f2 -Author: Дилян Палаузов -Date: Mon Feb 13 20:59:23 2023 +0200 +commit da7c1920aa5e1dd45ece49c421690cb16b205193 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - debugger: typos + pipelimit: docs - removed trailing spaces -commit 2822cc8067d2dd7f865f724228cda8c45513d393 -Author: Дилян Палаузов -Date: Mon Feb 13 20:59:12 2023 +0200 +commit 6b0ffbd7d3735b5343dac78794a8bf93ff04c1c3 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - dialog: typos + pike: docs - removed trailing spaces -commit dd07a5cd5762d9142f95c5ab367d2f366f03578d -Author: Дилян Палаузов -Date: Mon Feb 13 20:59:06 2023 +0200 +commit c5f378f1255e7989460b25390b4286a8e037b239 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - dialplan: typos + permissions: docs - removed trailing spaces -commit c871fd693676c51ce18f017e7f3f63132671eac7 -Author: Дилян Палаузов -Date: Mon Feb 13 20:58:58 2023 +0200 +commit a5b3106a404af39fdb05013e0a14a7c5566db5f1 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - dispatcher: typos + peering: docs - removed trailing spaces -commit 0723d3cd4da5ed03118bdbee6d960b431ae75b23 -Author: Дилян Палаузов -Date: Mon Feb 13 20:58:49 2023 +0200 +commit 27f996ccf7afe802c8db9c9d16959b0c4b95b8f1 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - dmq_usrloc: typo + pdt: docs - removed trailing spaces -commit bd2f9d7ab113f351f75d3121db3ffb9f1f9ef229 -Author: Дилян Палаузов -Date: Mon Feb 13 20:58:30 2023 +0200 +commit e1f268aca59457159b197d02b746ce5e188e5a61 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - dlgs: typos + pdb: docs - removed trailing spaces -commit e0a42350d019f55163cf55bd72f1e65c71121156 -Author: Дилян Палаузов -Date: Mon Feb 13 20:58:22 2023 +0200 +commit 98c93e89b432eda707d85178fdfa755443ee2075 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - dmq: typos + path: docs - removed trailing spaces -commit f68ea71a12f236f2d19b537f87754564f9ae6408 -Author: Дилян Палаузов -Date: Mon Feb 13 20:58:14 2023 +0200 +commit 7d2ad3f4987acaa38a34b1c253fe1cab510d7e01 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:08 2023 +0100 - domain: typo + p_usrloc: docs - removed trailing spaces -commit c7d5f359b4f1bd4872ef924c52597b3c63c63612 -Author: Дилян Палаузов -Date: Mon Feb 13 20:58:06 2023 +0200 +commit 117d8112dfae599536988964dc8987bf5fbd7423 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:07 2023 +0100 - domainpolicy: typos + outbound: docs - removed trailing spaces -commit dd61ae2a6a1bc01c662fdcc6c33d86f76882f66e -Author: Дилян Палаузов -Date: Mon Feb 13 20:57:54 2023 +0200 +commit e1653d87b44f1fc1a06bfc163870889dbc269507 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:07 2023 +0100 - drouting: typos + osp: docs - removed trailing spaces -commit c572bcc113097efb7641f98deb729258ff4ec02a -Author: Kamailio Dev -Date: Mon Feb 13 21:31:15 2023 +0100 +commit 762f3edcd0dbc3e60efa3b4ce42491230446ec1b +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:07 2023 +0100 - modules: readme files regenerated - presence ... [skip ci] + nsq: docs - removed trailing spaces -commit 911d5786da6bbd22f954908f7157b5421bdf47f7 +commit 1dcd50ec375040d2e62b872f6c354690762dfbfc Author: Daniel-Constantin Mierla -Date: Mon Feb 13 21:15:42 2023 +0100 +Date: Mon Nov 13 15:36:07 2023 +0100 - presence: docs - fix example for presence.presentity_show + nosip: docs - removed trailing spaces -commit e4f0c082422bbd9478cf0607a68c6e7c6bef47ad -Author: Kamailio Dev -Date: Mon Feb 13 20:31:26 2023 +0100 +commit 7e58b377e0e20362e22dd132d81c7b6babc95cff +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:07 2023 +0100 - modules: readme files regenerated - presence ... [skip ci] + ndb_redis: docs - removed trailing spaces -commit c167c4738fce31cec292edc803160d607a3faaf6 +commit 4af553b12968f3cebd7c2d6f32dae58e30d2eae6 Author: Daniel-Constantin Mierla -Date: Mon Feb 13 20:19:09 2023 +0100 +Date: Mon Nov 13 15:36:07 2023 +0100 - presence: docs for rpc presence.presentity_show command + ndb_mongodb: docs - removed trailing spaces -commit 2aaa77b11a89cc088393d4ad7fe63f2e54bbd8ce +commit 7cce695361f0e782820a2a332357aa13e73cce65 Author: Daniel-Constantin Mierla -Date: Mon Feb 13 19:45:36 2023 +0100 +Date: Mon Nov 13 15:36:07 2023 +0100 - presence: added rpc command presence.presentity_show - - - get records filtering by user and/or domain + ndb_cassandra: docs - removed trailing spaces -commit 446892331900c2303e531da55bcb494ccb2d8bce +commit d3f11edebfe850729544304078180216654a2ec3 Author: Daniel-Constantin Mierla -Date: Mon Feb 13 13:25:28 2023 +0100 +Date: Mon Nov 13 15:36:07 2023 +0100 - topos: use proper field for datetime value + nathelper: docs - removed trailing spaces -commit bbb62e2a163cf0ba6c711074cbed2f1c3cb8ee7c -Author: Kamailio Dev -Date: Mon Feb 13 19:46:22 2023 +0100 +commit d0ac71154dbd8010065bc1754049ee40e01ed54f +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:07 2023 +0100 - modules: readme files regenerated - pdb ... [skip ci] + nat_traversal: docs - removed trailing spaces -commit a89170a2e08584be33da9464f75ee09154afa5e1 -Author: Дилян Палаузов -Date: Mon Feb 13 13:27:54 2023 +0200 +commit 515ca5a0c55a5cba201934638f83db45c8de8fc6 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:07 2023 +0100 - pv_headers: typos + mtree: docs - removed trailing spaces -commit 1d26ac7aecf122528dcfd576ea6a3e9c4bbab9c7 -Author: Дилян Палаузов -Date: Mon Feb 13 13:26:54 2023 +0200 +commit f5526422fcc6c9c42326e9e7e31e117bbd796f43 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:07 2023 +0100 - pv: typos + msrp: docs - removed trailing spaces -commit 3b8608770862ab37b3cd82414f06992b80bb1b80 -Author: Дилян Палаузов -Date: Mon Feb 13 13:27:42 2023 +0200 +commit a4c0c8269a4c67fb92c44b39270d4459d4b7e693 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:07 2023 +0100 - pua_xmpp: typos + msilo: docs - removed trailing spaces -commit b9f7591ad595e396feb85bad9d70e21d5ca8defc -Author: Дилян Палаузов -Date: Mon Feb 13 13:57:33 2023 +0200 +commit 073cd20f24119c11c403669d60b8ee2228ca2f2f +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:07 2023 +0100 - pua_reginfo: typos + mqueue: docs - removed trailing spaces -commit 8275f3742a44bb686e953c4b9e4d7a461cceddf1 -Author: Дилян Палаузов -Date: Mon Feb 13 13:27:33 2023 +0200 +commit 2b317a03f36a292cecc8ec982f815d26b5183a10 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:07 2023 +0100 - pua_dialoginfo: typos + mqtt: docs - removed trailing spaces -commit 2272fba9d98dea9dec541c4c6b7ede8e5031f3cb -Author: Дилян Палаузов -Date: Mon Feb 13 13:27:22 2023 +0200 +commit 924ad9d99321f986b06d8f6d85a0466dc12870d8 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:07 2023 +0100 - pua: typos + misctest: docs - removed trailing spaces -commit 6d05d873f42e268bbe275a4938a11c505b3d200e -Author: Дилян Палаузов -Date: Mon Feb 13 13:57:21 2023 +0200 +commit 1a7e3306bb4d6eb64506ad6b4172e1c99451de71 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:07 2023 +0100 - print_lib: typo + misc_radius: docs - removed trailing spaces -commit f7e7ddd74093ddd83a93a75e1e37b24a82be9ebc -Author: Дилян Палаузов -Date: Mon Feb 13 13:57:10 2023 +0200 +commit 0cb995e314501d5572a77e67e650013f644a7222 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:07 2023 +0100 - presence_xml: typos + memcached: docs - removed trailing spaces -commit f82553b2ce4693c618744ddfdc06163c799fbdc4 -Author: Дилян Палаузов -Date: Mon Feb 13 13:57:03 2023 +0200 +commit 9a915c58b0828e70659cd8b0fed2eebc7c5f617b +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:07 2023 +0100 - presence_reginfo: typos + maxfwd: docs - removed trailing spaces -commit 38f90a4bd6585b9c54b628620e9ced01b291da8b -Author: Дилян Палаузов -Date: Mon Feb 13 13:27:00 2023 +0200 +commit ad2f94d4aa31c7d968dcdd4834639e20be55d87d +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:07 2023 +0100 - presence_profile: typo + matrix: docs - removed trailing spaces -commit b22d7686895f45dc93fc1979faf70ef4ba607a25 -Author: Дилян Палаузов -Date: Mon Feb 13 13:27:07 2023 +0200 +commit c62d56fba007fcdaa9e96f32e1b1115b4af1bc73 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:07 2023 +0100 - presence_mwi: typo + mangler: docs - removed trailing spaces -commit 3b848a3878ac1655ef236505f05040a313f5127b -Author: Дилян Палаузов -Date: Mon Feb 13 13:56:53 2023 +0200 +commit 816cb22463a733438bfd354c1e2a1c7e1b05773d +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:07 2023 +0100 - presence_dialoginfo: typos + lrkproxy: docs - removed trailing spaces -commit 256848273d867beb273d0f80fd7ee419b8a8767a -Author: Дилян Палаузов -Date: Mon Feb 13 13:56:45 2023 +0200 +commit 502e636514c2e1a20b83f89cbb52a215bdcba248 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:07 2023 +0100 - presence_conference: typos + lost: docs - removed trailing spaces -commit d355a590feebf34e8c1d1d2b5e7b3a19052485b4 -Author: Дилян Палаузов -Date: Mon Feb 13 13:56:35 2023 +0200 +commit 261d93a4b6ee56a2e95c30a56b0be3837d90b644 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:07 2023 +0100 - presence: typos + log_systemd: docs - removed trailing spaces -commit 55868bfcc966931176f6e23fbb104570918cfdac -Author: Дилян Палаузов -Date: Mon Feb 13 13:56:17 2023 +0200 +commit 7e8d5fa0fe841cdc422872ed8735c02ee9439e17 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:07 2023 +0100 - pipelimit: typo + log_custom: docs - removed trailing spaces -commit dc4d1ffa9aabeaa119fefe1c3eaebcf05661d041 -Author: Дилян Палаузов -Date: Mon Feb 13 13:28:43 2023 +0200 +commit b0f99cb538a2a3e2f7328fb310d2296a8686e989 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:07 2023 +0100 - pike: typos + ldap: docs - removed trailing spaces -commit 9c52dcbbfa6ae9a39e035fc6cc256121b98a3626 -Author: Дилян Палаузов -Date: Mon Feb 13 13:56:26 2023 +0200 +commit 9adfc9c660e9ed2c17ab3c8e40cf41c13dbdbfc3 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:07 2023 +0100 - permissions: typos + lcr: docs - removed trailing spaces -commit 8832136ca6c638d6bb39c647262cd3504fd0f29d -Author: Дилян Палаузов -Date: Mon Feb 13 13:28:31 2023 +0200 +commit 522c4577c49a3bedf26f22d4cc8a481f12c93021 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:06 2023 +0100 - peering: typo + kex: docs - removed trailing spaces -commit e56fce96beae5be8339fb202a395bb33245506c4 -Author: Дилян Палаузов -Date: Mon Feb 13 13:28:21 2023 +0200 +commit ca72119d36e97d62c6ccb5e3f836fbeb8ad9f8b8 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:06 2023 +0100 - pdb: typos + keepalive: docs - removed trailing spaces -commit ea7baa2bca20899f354129f8a83d04c55727ea80 -Author: Дилян Палаузов -Date: Mon Feb 13 13:28:12 2023 +0200 +commit 2375d9d870cf602b416fbf5ebd9e25290466c500 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:06 2023 +0100 - p_usrloc: typos + kazoo: docs - removed trailing spaces -commit d87120dfb77d018cdf571cbcf18cf1950ce61987 -Author: Kamailio Dev -Date: Mon Feb 13 13:16:18 2023 +0100 +commit 8928cd94211e95699de2708912c0debd1ff10cdb +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:06 2023 +0100 - modules: readme files regenerated - nathelper ... [skip ci] + kafka: docs - removed trailing spaces -commit ff106fb93c5b872e529106f58a1b42c4fa092349 +commit d942b4156668aa69782c45570f99e065ed843d23 Author: Daniel-Constantin Mierla -Date: Mon Feb 13 13:00:58 2023 +0100 +Date: Mon Nov 13 15:36:06 2023 +0100 - nathelper: docs - updates to the nat pinging types + jsonrpcc: docs - removed trailing spaces -commit fdf72bec2d6cc20618bc30d0978d7f24f8106d44 -Author: Kamailio Dev -Date: Mon Feb 13 13:01:34 2023 +0100 +commit 4aaa25e5ae661e729ee2a5e312af70c703ea7ce6 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:06 2023 +0100 - modules: readme files regenerated - nathelper ... [skip ci] + json: docs - removed trailing spaces -commit 8218c14d144ef4539c94c8aabe5e73b5c8a11b08 -Author: Дилян Палаузов -Date: Thu Jan 26 20:57:25 2023 +0200 +commit 3d3fecc1067664250b70a6f2473229723fb2485f +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:06 2023 +0100 - nathelper: ping_nated_only sends 4-bytes UDP-packet pings + janssonrpcc: docs - removed trailing spaces -commit d81e26fb399c5fadda2d70de1d95e008d47bd3d5 -Author: Kamailio Dev -Date: Mon Feb 13 12:31:34 2023 +0100 +commit 59d1358c0cd82feaa29e7695a5fcfae3fe3a1565 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:06 2023 +0100 - modules: readme files regenerated - dmq_usrloc ... [skip ci] + jansson: docs - removed trailing spaces -commit f3d00c91a7919207dac23ada58e59a13b9f334d8 -Author: Victor Seva -Date: Thu Feb 9 11:45:29 2023 +0100 +commit 37ed51906cfdb49ccbe1d7dd6d032d79d915ce71 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:06 2023 +0100 - usrloc: correct AOR value on usrloc:contact-expired - - previously $ulc(x=>aor) had only the user part even with use_domain set - - fix #3365 + ipops: docs - removed trailing spaces -commit d2e73f9c51630f47fa7660b4c4831fcecd661f87 +commit 8540902ccb3eda13ec81b38e37410a1951acfbad Author: Daniel-Constantin Mierla -Date: Mon Feb 13 12:20:37 2023 +0100 +Date: Mon Nov 13 15:36:06 2023 +0100 - dmq_usrloc: check if socket name is set when replicating + ims_usrloc_scscf: docs - removed trailing spaces -commit 353d7e6a5f8d751fc647fd687716cc2e0fb1aa77 -Author: Bastian Triller -Date: Thu Feb 2 10:02:37 2023 +0100 +commit e6f84a515297853303aeeaf6d7a803bd7ef27ebf +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:06 2023 +0100 - dmq_usrloc: Add option to replicate socket via its name + ims_usrloc_pcscf: docs - removed trailing spaces -commit cc2342908d08ee5322fd6830b0db9fd762bef38f -Author: Kamailio Dev -Date: Mon Feb 13 12:17:06 2023 +0100 +commit 5526ee6bb2f2bcf9aa2a117fd541a165c7d86794 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:06 2023 +0100 - modules: readme files regenerated - imc ... [skip ci] + ims_registrar_scscf: docs - removed trailing spaces -commit c28b3a0ae61c9fd1fc8e8b2972686a0f8424c44a -Author: Дилян Палаузов -Date: Wed Feb 8 15:37:02 2023 +0200 +commit 9fe7e64cb64458f59a879e2b699222ec16eced4e +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:06 2023 +0100 - ipops: typos + ims_registrar_pcscf: docs - removed trailing spaces -commit 398cf4dd9645f8a9f7a1e4f1bb9659814bc2d041 -Author: Дилян Палаузов -Date: Wed Feb 8 15:37:12 2023 +0200 +commit 68b692a2c7a4a0c4014ddbf4c51aa3002dc35848 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:06 2023 +0100 - ims_usrloc_scscf: typos + ims_qos: docs - removed trailing spaces -commit 94c1fa3123042e1f262750e2b23fad640717c5e1 -Author: Дилян Палаузов -Date: Wed Feb 8 15:37:42 2023 +0200 +commit 8627d7e9e782a5aade7dd3ea945b767665f50678 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:06 2023 +0100 - ims_usrloc_pcscf: typos + ims_ocs: docs - removed trailing spaces -commit b89353cd766769552655f16a44d44ea0e55a8fea -Author: Дилян Палаузов -Date: Wed Feb 8 15:37:27 2023 +0200 +commit 5bcd7204b5e3ac6d314df6a080389ba76f4512ad +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:06 2023 +0100 - ims_registrar_pcscf: typos + ims_isc: docs - removed trailing spaces -commit 4f3faaa42006ce4b2a0ae2b684975fd385deea43 -Author: Дилян Палаузов -Date: Wed Feb 8 15:39:12 2023 +0200 +commit 64c8375f9acb06bc0d7ddd3495ba81fde9020fdd +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:06 2023 +0100 - ims_registrar_scscf: typos + ims_icscf: docs - removed trailing spaces -commit b14a420834744b8bef871b10fd2fdeb6a5e7cd89 -Author: Дилян Палаузов -Date: Wed Feb 8 15:38:57 2023 +0200 +commit 7ebb5db566ace70e04c6a35c74e1626bf07f5846 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:06 2023 +0100 - ims_qos: typos + ims_diameter_server: docs - removed trailing spaces -commit 911739c041a0c0717edbadd2296e65e0d388df72 -Author: Дилян Палаузов -Date: Wed Feb 8 15:39:37 2023 +0200 +commit 135ec859b11c64dce63068ce284959e5c94f2de1 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:06 2023 +0100 - ims_ocs: typos + ims_charging: docs - removed trailing spaces -commit 46df335ccfacb159a1f8ad1bc6e549967da30a91 -Author: Дилян Палаузов -Date: Wed Feb 8 15:38:38 2023 +0200 +commit adbaa6130e20422f9738544efb3718310df3929b +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:06 2023 +0100 - ims_isc: typos + ims_auth: docs - removed trailing spaces -commit 6dbb0d6ec6c9676e2191e06ca73fb712d8f4e4bd -Author: Дилян Палаузов -Date: Wed Feb 8 15:38:49 2023 +0200 +commit 5b33e3544da65ba44f6131eace5d3d73c8a6c1f7 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:06 2023 +0100 - ims_ipsec_pcscf: typos + imc: docs - removed trailing spaces -commit 8fefea2ef7f75b2e792601cee0f8de2652c8b598 -Author: Дилян Палаузов -Date: Wed Feb 8 15:39:49 2023 +0200 +commit 7019d4d3713b541bf319815dfcd701b8e605efd0 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:06 2023 +0100 - ims_icscf: typos + http_async_client: docs - removed trailing spaces -commit db62e0372eedce8708af23f806cce59d531817e6 -Author: Дилян Палаузов -Date: Wed Feb 8 15:38:26 2023 +0200 +commit 288fe44bfdf4d7afeb1682eb629cc149e8fb849a +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:06 2023 +0100 - ims_diameter_server: typos + htable: docs - removed trailing spaces -commit c2f1da1bf804690766cdd9199b59e7261f0dcbaa -Author: Дилян Палаузов -Date: Wed Feb 8 15:38:16 2023 +0200 +commit 0a5329f80817430703c17c382e05d8c217544985 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:06 2023 +0100 - ims_dialog: typos + h350: docs - removed trailing spaces -commit aa2cace532cdf0891d48698e8a9386a5d8a96f07 -Author: Дилян Палаузов -Date: Wed Feb 8 15:38:07 2023 +0200 +commit 49709926f03c6ecc78e172e18fdbb0efe4f8061a +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:05 2023 +0100 - ims_charging: typos + gzcompress: docs - removed trailing spaces -commit 6dded07a538d1a68ff766c80e971b6e59535bb52 -Author: Дилян Палаузов -Date: Wed Feb 8 15:37:57 2023 +0200 +commit 0702a904ee07ba248aa23290cf57b77a96715137 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:05 2023 +0100 - ims_auth: typos + group: docs - removed trailing spaces -commit 53f3bcd0eca4934b00eb4db05080a7ee33b11c92 -Author: Дилян Палаузов -Date: Wed Feb 8 15:39:57 2023 +0200 +commit b6a01d88c4b4817966a4c9b19865ef103e683aca +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:05 2023 +0100 - imc: typo + geoip2: docs - removed trailing spaces -commit 34ce0de749c20e1b5a2e58fdaaca841d75622d2c +commit 3cd9db9bab7206444213063b2fdc66aa749af602 Author: Daniel-Constantin Mierla -Date: Mon Feb 13 09:51:24 2023 +0100 +Date: Mon Nov 13 15:36:05 2023 +0100 - presence: cast to uint64_t when using time_t value - - - startup time stored as unsigned int insted of signed int + geoip: docs - removed trailing spaces -commit 0259eaedd507c314161c59b72eaa4564effac555 +commit f63951c203dbf7a7f66e26502a0fb143d86f5048 Author: Daniel-Constantin Mierla -Date: Mon Feb 13 09:41:02 2023 +0100 +Date: Mon Nov 13 15:36:05 2023 +0100 - xmlrpc: cast to uint64_t when using time_t value + exec: docs - removed trailing spaces -commit c464add1531aea5fda3f7c5a6670bd90e7ac594b +commit 519d614dbaf856ed05dc56a9495a9ecadc600094 Author: Daniel-Constantin Mierla -Date: Mon Feb 13 09:27:53 2023 +0100 +Date: Mon Nov 13 15:36:05 2023 +0100 - xprint: cast to uint64_t when using time_t value + evapi: docs - removed trailing spaces -commit 33b319353a097ba8fd80e45dc4f008c2e9dfe813 +commit a16fb200156a45d29981221b3e4b69ff3bea376b Author: Daniel-Constantin Mierla -Date: Sun Feb 12 15:48:14 2023 +0100 +Date: Mon Nov 13 15:36:05 2023 +0100 - core: sruid - cast to uint64_t when using time_t value + erlang: docs - removed trailing spaces -commit ae3e52daec9be45c4663708cb216b13864521a35 +commit 3d808df3cb2d5cdf8e07d76cc708a85dfd4c76b6 Author: Daniel-Constantin Mierla -Date: Sun Feb 12 15:25:35 2023 +0100 +Date: Mon Nov 13 15:36:05 2023 +0100 - core: select - cast to uint64_t when using time_t value + enum: docs - removed trailing spaces -commit cc3ec58c1e3c203c76c59b17ccc14e24ffc6f8cf +commit a4762436d4ce365162d0c76157dacc071219facf Author: Daniel-Constantin Mierla -Date: Sat Feb 11 12:26:02 2023 +0100 +Date: Mon Nov 13 15:36:05 2023 +0100 - kmeix: cast to uint64_t when using time_t value + domainpolicy: docs - removed trailing spaces -commit c7217d147b615da6ebf3841a3915055aa529dd70 +commit d0e7e8e947be29db66c85fad8c0449e73d907b0f Author: Daniel-Constantin Mierla -Date: Sat Feb 11 12:25:45 2023 +0100 +Date: Mon Nov 13 15:36:05 2023 +0100 - mtree: cast to uint64_t when using time_t value + domain: docs - removed trailing spaces -commit 7e29c28e4da5c7286a75422d6f538b932961a168 +commit e717b2b665b0d236c4d8e8334c66b8397421f83a Author: Daniel-Constantin Mierla -Date: Sat Feb 11 12:24:33 2023 +0100 +Date: Mon Nov 13 15:36:05 2023 +0100 - drouting: cast to uint64_t when using time_t value + dnssec: docs - removed trailing spaces -commit 05ea223549f4834c5e3b92f9025d5cf8a2b73890 -Author: Kamailio Dev -Date: Mon Feb 13 09:31:40 2023 +0100 +commit fa816a371591d71bf01cfcf01e784c5fea7ce724 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:05 2023 +0100 - modules: readme files regenerated - auth ... [skip ci] + dmq_usrloc: docs - removed trailing spaces -commit a22aadf3b51f5bfff5b50a3de9a354fe07c216f4 -Author: Bastian Triller -Date: Sat Feb 11 14:20:48 2023 +0100 +commit c2ca6be1e6b59202dfb348baed15ed1c724ff8d8 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:05 2023 +0100 - secsipid: docs fixes + dmq: docs - removed trailing spaces -commit 0df94c3ba0fe249e29db52691176bbe751e556b6 -Author: Bastian Triller -Date: Sat Feb 11 14:20:08 2023 +0100 +commit 22bc428a36d37cbd1e8598f59079a9f23a441f72 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:05 2023 +0100 - auth: docs fixes + diversion: docs - removed trailing spaces -commit 1bbe87261d17219dfc3b7b98e1f9f16f4e0f48b9 -Author: Bastian Triller -Date: Sat Feb 11 14:15:42 2023 +0100 +commit 35be076aa1a8c74d75eb26e261da4b910988da2e +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:05 2023 +0100 - uri_db: docs fixes + dispatcher: docs - removed trailing spaces -commit fdb3637460b16ddfea86ba67b9181a40d1466395 -Author: Bastian Triller -Date: Sat Feb 11 14:15:12 2023 +0100 +commit 7e461f6f30c6c4627f6f3ccf7124a16c7c313dd3 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:05 2023 +0100 - uid_uri_db: docs fixes + dialplan: docs - removed trailing spaces -commit 9ffe7b06b094a4af558a0033c1baa16e5c61977b -Author: Bastian Triller -Date: Sat Feb 11 14:14:25 2023 +0100 +commit 34a51df3726016faca735bf434de263a49e02a7f +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:05 2023 +0100 - uid_avp_db: docs fixes + dialog: docs - removed trailing spaces -commit 4889531912e7c04c0e1d04dd81dec21f4520455c -Author: Bastian Triller -Date: Sat Feb 11 14:12:48 2023 +0100 +commit 8dd4eedd85a9c1b4fbddfe734647fcd56c8a5b64 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:05 2023 +0100 - tsilo: docs fixes + debugger: docs - removed trailing spaces -commit 73830ac71534efecc2b38816a20f6f113c27aaf2 -Author: Bastian Triller -Date: Sat Feb 11 14:12:17 2023 +0100 +commit ca806610f2540b8d82a8f79a30860817d7c22fac +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:05 2023 +0100 - pua_usrloc: docs fixes + db_unixodbc: docs - removed trailing spaces -commit beee3a4a872601bda2d440da2e79ec684c18a8bc -Author: Bastian Triller -Date: Sat Feb 11 14:11:51 2023 +0100 +commit 3c085a3835ba13b9018802ef51424a28f5169378 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:05 2023 +0100 - ims_usrloc_scscf: docs fixes + db_text: docs - removed trailing spaces -commit a10f6fbcd0c62663102fc3cd7caf82096d3c8a7f -Author: Bastian Triller -Date: Sat Feb 11 14:10:39 2023 +0100 +commit 5643032d87490c1f24c83326cb4b4ff39e4eab4b +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:05 2023 +0100 - dispatcher: docs fixes + db_postgres: docs - removed trailing spaces -commit 4fd411126d72402278c886895518c44a916bebfc -Author: Bastian Triller -Date: Sat Feb 11 14:09:36 2023 +0100 +commit 1bd546394faebdc0701439b1098a6a7fe8c5b938 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:05 2023 +0100 - dlgs: docs fixes + db_perlvdb: docs - removed trailing spaces -commit 2384c38947ce351a421b92727ae304fcbec211a4 -Author: Kamailio Dev -Date: Fri Feb 10 18:01:22 2023 +0100 +commit e07004bbbd8df4dfcc5783d42c4b9bce0278e279 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:05 2023 +0100 - modules: readme files regenerated - ctl ... [skip ci] + db_oracle: docs - removed trailing spaces -commit 44381746e0e826e8db04597942fa4cee6cbf9175 +commit 40d7260d54032d3c1a949a03d949a77da6bf0a9f Author: Daniel-Constantin Mierla -Date: Fri Feb 10 17:53:42 2023 +0100 +Date: Mon Nov 13 15:36:05 2023 +0100 - ctl: doc - binrpc_buffer_size can get only integer value + db_mysql: docs - removed trailing spaces -commit db634e7fb3e5913238561afb4381363bbfe58882 -Author: Sergey Safarov -Date: Fri Feb 10 16:46:04 2023 +0300 +commit 09d4a5baac4db13afde696fa81e1b7957888156d +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:05 2023 +0100 - pkg/kamailio: fixed rpm packging for CentOS 6 + db_mongodb: docs - removed trailing spaces -commit 857d777b73d3802d157042b0ea7126b7b8dd45f8 +commit 480d79f96378de2f620c5cdebb524d7a84051d8b Author: Daniel-Constantin Mierla -Date: Fri Feb 10 08:04:24 2023 +0100 +Date: Mon Nov 13 15:36:04 2023 +0100 - dlgs: cast to uint64_t when using time_t values + db_flatstore: docs - removed trailing spaces -commit 8f5a1c20a6816e18f9f08f3b0273691dc5f8cc2c +commit 1a1840e8358c9e36fc5a28fc2fefb5c173e6546d Author: Daniel-Constantin Mierla -Date: Thu Feb 9 17:16:43 2023 +0100 +Date: Mon Nov 13 15:36:04 2023 +0100 - dispatcher: cast to uint64_t when using time_t value + db_cluster: docs - removed trailing spaces -commit dd6339f817822cd0590aec2a9a467330bde499dd +commit d877d67833d36fc9d5fec992a6dbe7079955fe5f Author: Daniel-Constantin Mierla -Date: Thu Feb 9 12:38:53 2023 +0100 +Date: Mon Nov 13 15:36:04 2023 +0100 - core: tmrec - cast to 64b types when using time_t value + db_cassandra: docs - removed trailing spaces -commit 0a3c15239a620474bbbc7f4d2f57dda0e9aa0f58 +commit 072335aa8bad9ede26c221f6c8930651c0837ed0 Author: Daniel-Constantin Mierla -Date: Wed Feb 8 15:51:37 2023 +0100 +Date: Mon Nov 13 15:36:04 2023 +0100 - async: catch up on possible skipped slots due to slow tasks + db_berkeley: docs - removed trailing spaces -commit 6be85c8a72bc37b2bb4b1f4be59c5d0c20996850 -Author: Kamailio Dev -Date: Wed Feb 8 14:16:31 2023 +0100 +commit 5ccb10b79140154c92b7c29a5f73a39b5aa5f495 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:04 2023 +0100 - modules: readme files regenerated - seas ... [skip ci] + db2_ops: docs - removed trailing spaces -commit ec6f3b122f9c41b437ccfcb07b0952e2ffcc2719 -Author: Дилян Палаузов -Date: Wed Feb 8 13:01:24 2023 +0200 +commit aa4fb1f9f738979d0f6fcfd65e3922b8dbaf1376 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:04 2023 +0100 - xprint: typos + db2_ldap: docs - removed trailing spaces -commit c86b5d85a8aa86c1c59b5eed2ded87aee4fd1682 -Author: Дилян Палаузов -Date: Wed Feb 8 13:01:14 2023 +0200 +commit 7be3f5f32772374df5b6912c2d89505266c32f3b +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:04 2023 +0100 - xmlrpc: typos + ctl: docs - removed trailing spaces -commit e07960d74570aa9a94075e83b5bf4fc9cf418864 -Author: Дилян Палаузов -Date: Wed Feb 8 13:16:17 2023 +0200 +commit bd423bb6591f856edf951de0251d61431277ae0e +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:04 2023 +0100 - xhttp_rpc: typos + crypto: docs - removed trailing spaces -commit d9445d60ea6432664447858dff3852be94c04196 -Author: Дилян Палаузов -Date: Wed Feb 8 13:01:01 2023 +0200 +commit c6fe3ce9d340928df7db0c0336cbdd5c586c6089 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:04 2023 +0100 - xhttp_prom: typo + cplc: docs - removed trailing spaces -commit 5ec0a3c5be9abd51cb2b3316a5dd9edf6e1d030e -Author: Дилян Палаузов -Date: Wed Feb 8 13:00:49 2023 +0200 +commit d0c5adba50e36af4903cbacb0fc5ed7ef91fac10 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:04 2023 +0100 - xhttp_pi: typos + counters: docs - removed trailing spaces -commit 44c1c181bd250c0f81ffe0bb6b6566b4148b8b0f -Author: Дилян Палаузов -Date: Wed Feb 8 13:00:29 2023 +0200 +commit 7a3c97061b957595639fac6616103b321346d8bb +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:04 2023 +0100 - xhttp: typo + corex: docs - removed trailing spaces -commit 45537397d7a8e1b2e340252cd7d6dec3bb1cd08e -Author: Дилян Палаузов -Date: Wed Feb 8 13:00:16 2023 +0200 +commit a23bcb93029c69b5ce8f675cf40b14a833b753b2 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:04 2023 +0100 - xcap_server: typos + cnxcc: docs - removed trailing spaces -commit c69002ae65ec103a7e88451501c0cf984ad9cc86 -Author: Дилян Палаузов -Date: Wed Feb 8 13:00:06 2023 +0200 +commit 790b03f751e60dcf1b14c2f3102f8154394ae376 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:04 2023 +0100 - xcap_client: typos + cfgutils: docs - removed trailing spaces -commit 2cdb861cef1bce38f239a82b17bd1e4915ae2a04 -Author: Дилян Палаузов -Date: Wed Feb 8 13:03:14 2023 +0200 +commit cffaf03a269eec91161bbec011b2b9785c827a94 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:04 2023 +0100 - tls_wolfssl: typos + cfgt: docs - removed trailing spaces -commit 968f3faf3b1834b18266aaf9f7866b29a2492d92 -Author: Дилян Палаузов -Date: Wed Feb 8 13:03:00 2023 +0200 +commit b58ac929a08d89ba950c062befa1816680118a9f +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:04 2023 +0100 - tls: typos + cfg_db: docs - removed trailing spaces -commit 17aec5c930e2681431c4da779cd24e3fc070b6eb -Author: Дилян Палаузов -Date: Wed Feb 8 13:02:38 2023 +0200 +commit 8ac7b71721ebdf859d0536251744ee2b5c7981c2 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:04 2023 +0100 - siputis: typos + cdp_avp: docs - removed trailing spaces -commit 1bed2095504e9d81eb2b881a2d71216372b3c822 -Author: Дилян Палаузов -Date: Wed Feb 8 13:16:27 2023 +0200 +commit 3d58521685c859d205b43bc5f7fbbcf078d865d1 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:04 2023 +0100 - seas: typos + cdp: docs - removed trailing spaces -commit c13b8d4cf35b7f9ece143b61514eec9a082f4ac5 -Author: Дилян Палаузов -Date: Wed Feb 8 13:02:13 2023 +0200 +commit a2fdd7c8918b83555d58e63f81bfc053d1e842b6 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:04 2023 +0100 - doc/scripts: typos + carrierroute: docs - removed trailing spaces -commit 3ee5c995778be835b1c79ec0a543f42105bdef8d +commit ca61f326f33264c75f4dd04029d2e2731715e074 Author: Daniel-Constantin Mierla -Date: Wed Feb 8 11:58:47 2023 +0100 +Date: Mon Nov 13 15:36:04 2023 +0100 - lib/srdb1/2: fixed typos + call_obj: docs - removed trailing spaces -commit df66ebba19ff313011fc5ad369045b8118aac670 -Author: Kamailio Dev -Date: Wed Feb 8 11:46:26 2023 +0100 +commit 096d723c5cde3da0a385c2025564565bcd06a401 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:04 2023 +0100 - modules: readme files regenerated - acc ... [skip ci] + call_control: docs - removed trailing spaces -commit 8fbd788c5ae29df35b9fbde2ec60efd3fa4df0df -Author: Дилян Палаузов -Date: Sat Feb 4 15:31:23 2023 +0200 +commit 58b13b8cef853e6a6fb705ceadcf37eab2272ed9 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:04 2023 +0100 - acc_diameter: typos + blst: docs - removed trailing spaces -commit 901d9cac2f69b78d3d7d2ff52696a37276446b3b -Author: Дилян Палаузов -Date: Sat Feb 4 15:28:48 2023 +0200 +commit 3d6d44e2cb485ef9d0e7b03aff7bab42d9977c80 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:04 2023 +0100 - acc: typos + benchmark: docs - removed trailing spaces -commit fdce4fe980dda02fd76dc06912dac585992d6759 -Author: Дилян Палаузов -Date: Sat Feb 4 15:27:39 2023 +0200 +commit e6a918767c9d08a4f94ee87a54a9354eb95e78b9 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:04 2023 +0100 - src/lib: typos + avpops: docs - removed trailing spaces -commit 6c4f9b049e784fc9aff65bfcef6f366b78fff48e -Author: Дилян Палаузов -Date: Sat Feb 4 15:20:34 2023 +0200 +commit 24f6515431c298860419cb153acff30513b0e8d0 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:04 2023 +0100 - usrloc: typos + avp: docs - removed trailing spaces -commit 46e9963e07a44077184ac503cc72ff9d57c532d0 -Author: Kamailio Dev -Date: Wed Feb 8 11:01:27 2023 +0100 +commit 062cf5eb7297bd30d030aa8e8d0c993f39396eec +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:03 2023 +0100 - modules: readme files regenerated - uac ... [skip ci] + auth_xkeys: docs - removed trailing spaces -commit 76df53900b96852345d1ef368e5539197a3c5570 -Author: ovoshlook -Date: Sun Feb 5 22:19:16 2023 +0100 +commit d1430e3fe47d900cf20be729766cc07f631019d3 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:03 2023 +0100 - uac: allow uac_auth* functions call from t_on_branch_failure event route + auth_radius: docs - removed trailing spaces -commit 63095ef1bef36a35952ed265f41d87ccbc1bba70 +commit 250b8df7525138796786fbf052adcd91fa977ebc Author: Daniel-Constantin Mierla -Date: Tue Feb 7 12:57:04 2023 +0100 +Date: Mon Nov 13 15:36:03 2023 +0100 - lib/ims: check return of strtok(...) + auth_identity: docs - removed trailing spaces -commit 7a960bd9d0002516dcbb50b89dd5d4ab5c38eb61 -Author: Kamailio Dev -Date: Fri Feb 3 19:01:20 2023 +0100 +commit 5548cce15e392eef9900b5db9afcb31a3eaf0639 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:03 2023 +0100 - modules: readme files regenerated - websocket ... [skip ci] + auth_diameter: docs - removed trailing spaces -commit d7ef61788fcf84ff86b000f972aff99a300c5237 -Author: Дилян Палаузов -Date: Fri Jan 27 14:54:25 2023 +0200 +commit 39ac631e8585f3ad28bf92fdf12f658447853082 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:03 2023 +0100 - websocket: typos + auth: docs - removed trailing spaces -commit 4341b27e391e8180d285ab98c8770e7fef70cebb -Author: Дилян Палаузов -Date: Fri Feb 3 12:23:33 2023 +0200 +commit a8e23f7f67406769a071bf95551e264c148a0173 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:03 2023 +0100 - core: typos + app_python3: docs - removed trailing spaces -commit 809d2c752687f8addb14a9e3fb40a50f513bdec0 -Author: Дилян Палаузов -Date: Fri Feb 3 17:07:35 2023 +0200 +commit c4af9c560e5fb2444894f8c6f6b637c13a64d663 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:03 2023 +0100 - core: include DBG_SYS_MEMORY and MEM_JOIN_FRE on flags: output + app_python: docs - removed trailing spaces -commit 609b689e6071c272e8230901e95db183334391d1 -Author: Kamailio Dev -Date: Fri Feb 3 09:46:31 2023 +0100 +commit d7b8e382555a9f6ecc8f322021cc98cfb56a8c21 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:03 2023 +0100 - modules: readme files regenerated - rr ... [skip ci] + app_perl: docs - removed trailing spaces -commit b3af149e280cf4e48eaeb2771c59431c2a55d23e -Author: Дилян Палаузов -Date: Thu Jan 26 10:52:20 2023 +0200 +commit cd142be4598c9dbd01aae8ac1cb11705f251faa9 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:03 2023 +0100 - snmpstats: typos + app_mono: docs - removed trailing spaces -commit 039cce694a784e5373cbc5f976d8cd723f2b663d -Author: Дилян Палаузов -Date: Thu Jan 26 10:51:57 2023 +0200 +commit b9017f5a286880adc10961a93b1d31d825d7fb63 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:03 2023 +0100 - test/ : typos + app_lua_sr: docs - removed trailing spaces -commit 9b237a311049a2689252b2a177062fe2e3db348c +commit 1c96f978f667f395eb3fc5295f282adc616db12e Author: Daniel-Constantin Mierla -Date: Fri Feb 3 09:39:55 2023 +0100 +Date: Mon Nov 13 15:36:03 2023 +0100 - rr: fixed typos in comments + app_lua: docs - removed trailing spaces -commit 022fa0cfc75d150fde219b8ae4f9a99b3fa2f132 +commit 9284827387f2df0a0d931c77a79aa940d5ef0fa5 Author: Daniel-Constantin Mierla -Date: Fri Feb 3 09:38:26 2023 +0100 +Date: Mon Nov 13 15:36:03 2023 +0100 - rr: doc - fixed typos and use the proper param name add_username instead of enable_username + app_java: docs - removed trailing spaces -commit 51fa3da96c1eacd4d679598a3305180c9e818cfb +commit 0d6ee69bb74f67c3b40035157ce84ff7948ce234 Author: Daniel-Constantin Mierla -Date: Fri Feb 3 09:28:58 2023 +0100 +Date: Mon Nov 13 15:36:03 2023 +0100 - core: typos in comments and EoL after log when parse msg fails - - - GH #3348 + alias_db: docs - removed trailing spaces -commit 8821d9a91ab3823d5b1d78d84332ab9965a7c6b2 -Author: Дилян Палаузов -Date: Wed Feb 1 14:21:09 2023 +0200 +commit 8bd1c1e20217d88c702caf100234e4fa3404f65e +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:03 2023 +0100 - doc/tutorials/dns: USE_NAPTR is on by default + acc_json: docs - removed trailing spaces -commit 56cdee753a2c7ef17d7cb1f4572f19eae2caf18a -Author: Victor Seva -Date: Tue Jan 31 19:38:37 2023 +0100 +commit fff71f15cc5a299a5318c2b3ce12c6c1ab24290c +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:36:03 2023 +0100 - Makefile: support parallelism on install-modules-doc rule + acc: docs - removed trailing spaces -commit b28a972a20188ac01831723d58dbe5dd78e972b9 -Author: Victor Seva -Date: Mon Jan 30 17:45:25 2023 +0100 +commit 3764c79c2133473a465b2e188a0106cbbf8cf4fb +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:33:45 2023 +0100 - pkg/kamailio/deb: rework debian/rules, take four [skip ci] + test/mod_httpapitest: removed trailing spaces -commit ecad587d58162dc1db5b2bbd6c63bdef24fbeed3 -Author: Victor Seva -Date: Mon Jan 30 16:52:34 2023 +0100 +commit 892c21deb2fb0a0cdd7bfa578f8f5e62fcc42549 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:33:27 2023 +0100 - pkg/kamailio/deb: rework debian/rules, take three [skip ci] + utils/pdbt: removed trailing spaces -commit 13581d56524aaa37167bd3ae67a769c14478d9c6 -Author: Victor Seva -Date: Mon Jan 30 16:28:54 2023 +0100 +commit a7b5d55f051519788b51658fc53ad9cc1492f449 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:33:07 2023 +0100 - pkg/kamailio/deb: rework debian/rules, take two [skip ci] + utils/db_oracle: removed trailing spaces -commit c3acd700719ca9d5802d56476d7e997e968220ce -Author: Victor Seva -Date: Mon Jan 30 15:07:13 2023 +0100 +commit 34b823772cf3ee92f6bb5957413a1f51ce0ea75f +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:32:49 2023 +0100 - pkg/kamailio/deb: rework rules, try to fail properly on build [skip ci] - - https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1027440 + utils/db_berkeley: removed trailing spaces -commit 387a8ca53f179437ae173b0bd5cb8d2d4922b60d -Author: Victor Seva -Date: Fri Jan 27 08:30:30 2023 +0100 +commit 4b10338c23dd5c3e3e36f9c3270a28a145f8691f +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:32:01 2023 +0100 - pkg/kamailio/deb: remove warning build-depends-on-obsolete-package [skip ci] - - > W: kamailio source: build-depends-on-obsolete-package Build-Depends: libncurses5-dev => libncurses-dev + test/misc/code: removed trailing spaces -commit 03755f93f98608d85591ba8aa184733e3871b92c -Author: Victor Seva -Date: Fri Jan 27 08:23:45 2023 +0100 +commit 275b9e1b87df15a2e6ab1c7d51dfe63348a905ca +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:31:30 2023 +0100 - pkg/kamailio/deb: remove lsb-base dependency [skip ci] - - * on newer version, there's no need to add it - - > E: kamailio: depends-on-obsolete-package Depends: lsb-base + lib/xcap: removed trailing spaces -commit 815d21ca1569edcd9dfc5edf4f1e873fdada3b58 -Author: Kamailio Dev -Date: Thu Jan 26 15:01:15 2023 +0100 +commit 8764ba09ee16e1793c747f96c6a78bbecaec9ced +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:31:14 2023 +0100 - modules: readme files regenerated - textops ... [skip ci] + lib/srdb2: removed trailing spaces -commit 945267c56615d4579e3385f334bdfec7dfea6bcb +commit fd9ccb42845058808049186cc9b7bb165d823a69 Author: Daniel-Constantin Mierla -Date: Thu Jan 26 14:59:02 2023 +0100 +Date: Mon Nov 13 15:30:49 2023 +0100 - textops: docs for str_any_in(...) + lib/srdb1: removed trailing spaces -commit 797442522a8e996179059de7400332f4e96037b6 +commit c278d4dbfa7d14071d90b3e8002567ed84a58d88 Author: Daniel-Constantin Mierla -Date: Thu Jan 26 14:54:40 2023 +0100 +Date: Mon Nov 13 15:30:24 2023 +0100 - textops: new function to check if a character in a list is found in string - - - str_any_in(txt, clist) - look if any char in clist is inside txt + lib/print: removed trailing spaces -commit 3047da057b54fdbfab8fbae3eefae9c94ed4b365 -Author: Kamailio Dev -Date: Thu Jan 26 09:31:25 2023 +0100 +commit f6f258591f455d2147159d1dbb372a18f0df8670 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:29:49 2023 +0100 - modules: readme files regenerated - ims_dialog ... [skip ci] + lib/presence: removed trailing spaces -commit a4150741748779bba8e14bed286c6d64b1df7f17 +commit 7d8ba21a20f78d781f8aec69054a32ac34012531 Author: Daniel-Constantin Mierla -Date: Thu Jan 26 09:20:31 2023 +0100 +Date: Mon Nov 13 15:28:36 2023 +0100 - ims_dialog: fix module name in modparam examples + lib/ims: removed trailing spaces -commit efacfb572acdc027a35ba3104ecec080f5bfa94a -Author: Kamailio Dev -Date: Thu Jan 26 09:16:22 2023 +0100 +commit 1cff98a0131e3f11d4c027ad9bf2073759bdd6a1 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:28:10 2023 +0100 - modules: readme files regenerated - erlang ... [skip ci] + lib/cds: removed trailing spaces -commit 83951cc248bf4b0334c7d4f89deaaac456806a42 -Author: dilyanpalauzov -Date: Thu Jan 26 09:10:14 2023 +0100 +commit 6ffa465f0a4968e820b440431f989a8897fe96dc +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:27:52 2023 +0100 - pkg/kamailio: http urls updated to https and typo fixes + lib/binrpc: removed trailing spaces -commit 51b5cd040074330574ec53b7a091ff8b1fc09129 -Author: dilyanpalauzov -Date: Thu Jan 26 09:09:28 2023 +0100 +commit 831407a82a250e8951e24c7e471477db40c6d2ca +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:27:22 2023 +0100 - pkg/kamailio/deb: http urls updated to https + core: removed trailing spaces -commit 3c85f1cafd715f893e0ba4ad84592dddc3eb2cb0 -Author: dilyanpalauzov -Date: Thu Jan 26 09:08:32 2023 +0100 +commit db1e37699be9f72dd0124b20edab8e8b6f6d0532 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:26:32 2023 +0100 - README.md: updated links to mailing lists + misc/tools: pike_top - removed trailing spaces -commit f9c3c270be33e790402834951c29d65fdf7240b6 -Author: dilyanpalauzov -Date: Thu Jan 26 09:08:01 2023 +0100 +commit ae89b59ed837892bc1d29159786cd841f47ca820 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:56 2023 +0100 - INSTALL: updates to http urls and typo fixes + xmpp: removed trailing spaces -commit 7af3e9cc6e903665bca68f55d026c30f5b15064f -Author: dilyanpalauzov -Date: Thu Jan 26 09:07:04 2023 +0100 +commit 5fd8711e4eca196dd10b9567019bfffeca733733 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:56 2023 +0100 - lib/srdb1: typo fixes + xlog: removed trailing spaces -commit 49c1ae28188c6df2d130a26d4180d1db4538575e -Author: dilyanpalauzov -Date: Thu Jan 26 09:06:02 2023 +0100 +commit e7d2024f7ecc20bc496aa19247533563bb93b8d5 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:55 2023 +0100 - .github: typo fixes and updates to mailing lists links + xhttp_pi: removed trailing spaces -commit 9eed6ff9592347d9d01fa043a9e2370f26ad1f77 -Author: dilyanpalauzov -Date: Thu Jan 26 09:05:07 2023 +0100 +commit 43fade2748ae5968a188235dbd2d047a4cd8e12c +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:55 2023 +0100 - erlang: typos fixes + xcap_server: removed trailing spaces -commit 6c372bf644e1c9afa867433e5992e347c8fc4ff6 -Author: Henning Westerholt -Date: Wed Jan 25 07:59:39 2023 +0000 +commit 37b7d25542da3385e4e0c8caae6f34ddc116964e +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:55 2023 +0100 - core: fix memory leak related to Require header parsing, this header also need to be freed + xcap_client: removed trailing spaces -commit 5dabd1e7aa3574a41fc30ead60f9e3f68de0f471 -Author: Kamailio Dev -Date: Wed Jan 25 08:31:17 2023 +0100 +commit b4043ee89d4410bea5ac90fe71d881fc3025c994 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:55 2023 +0100 - modules: readme files regenerated - tls ... [skip ci] + utils: removed trailing spaces -commit 331aa5753beccd3ddb241219cf1988a506fa2de3 +commit 9ad12b5abce6a6d49cc37bee8edc23cd53642a49 Author: Daniel-Constantin Mierla -Date: Wed Jan 25 08:26:09 2023 +0100 +Date: Mon Nov 13 15:23:55 2023 +0100 - tls: update docs for init_mode with details about fork prepare option + usrloc: removed trailing spaces -commit cb424135c4164be10dd3c12086b548b8fec0d830 +commit de6011c9a461df739b6b6737a5278d3aac0f7115 Author: Daniel-Constantin Mierla -Date: Wed Jan 25 08:19:52 2023 +0100 +Date: Mon Nov 13 15:23:55 2023 +0100 - tls: new option for init_mode to use openssl api for fork prepare - - - flag 2 (value 2) has to be set + userblocklist: removed trailing spaces -commit 79eae59c4e104dab0b195bfbeb01b58f9d144092 +commit 12f5581c6ab8584644d9f2e99c82e93be8e5fd83 Author: Daniel-Constantin Mierla -Date: Tue Jan 24 11:36:53 2023 +0100 +Date: Mon Nov 13 15:23:55 2023 +0100 - tls: renamed the module destroy function + uri_db: removed trailing spaces -commit d0cd1905652e1aeb0be92c5a723b5d42f4171a13 -Author: Kamailio Dev -Date: Tue Jan 24 09:31:26 2023 +0100 +commit d8893cf100936e02e9ce038a6ba1b1b1700fb2c4 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:55 2023 +0100 - modules: readme files regenerated - tls ... [skip ci] + uid_avp_db: removed trailing spaces -commit 220cc9633092f166611432c704796353da46668c +commit d2dffc3e79a96e4bf492345cc8fd34c3a57deaa7 Author: Daniel-Constantin Mierla -Date: Tue Jan 24 09:29:32 2023 +0100 +Date: Mon Nov 13 15:23:55 2023 +0100 - tls: docs updated to rename lock_mode to init_mode + uac_redirect: removed trailing spaces -commit 2056194d086c773469af4855e371776615793e44 +commit e38f06dac2a2b10e0d0284250445060f5d6cedb4 Author: Daniel-Constantin Mierla -Date: Tue Jan 24 09:25:04 2023 +0100 +Date: Mon Nov 13 15:23:55 2023 +0100 - tls: renamed lock_mode to init_mode in order to reuse for other purposes - - - init the pthread lock - - conditions on init mode for locking/unlocking + uac: removed trailing spaces -commit 840b4d9b1529ab8794af3472665ee110cfb3e07d -Author: Kamailio Dev -Date: Mon Jan 23 15:31:34 2023 +0100 +commit 2e962cbee954b371cbc15a3d2dd1e630ba19a089 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:55 2023 +0100 - modules: readme files regenerated - tls ... [skip ci] + tm: removed trailing spaces -commit 72e4042bf645650ea5275a9c46230fc131441cf3 +commit 6693411081abba2a37139ce0ba154cc7ee4c9344 Author: Daniel-Constantin Mierla -Date: Mon Jan 23 14:55:10 2023 +0100 +Date: Mon Nov 13 15:23:55 2023 +0100 - tls: docs for lock_mode parameter + textops: removed trailing spaces -commit c8182116870fb706a750c6c4277df968aa78349d +commit 943154650bd21604a3268384e4df703eded3a37e Author: Daniel-Constantin Mierla -Date: Mon Jan 23 14:45:22 2023 +0100 +Date: Mon Nov 13 15:23:55 2023 +0100 - tls: option to wrap memory management operations within pthread lock + stun: removed trailing spaces -commit 4f296b4058b75ef27b16a9f8fc2bf3ec2d8e896c -Author: Kamailio Dev -Date: Mon Jan 23 14:31:57 2023 +0100 +commit 6c6ed10aa250f4492603239ef3ef6d2751d28ba3 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:55 2023 +0100 - modules: readme files regenerated - exec ... [skip ci] + statistics: removed trailing spaces -commit 3e6cf06c775eac9b55029e1820519cf1b0322122 -Author: Дилян Палаузов -Date: Sun Jan 22 15:43:08 2023 +0200 +commit dfa5771273aec19a372af0f5b27c11e33b7a4755 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:55 2023 +0100 - doc/tutorials: typos + snmpstats: removed trailing spaces -commit f351f9d7fc5dbebe3a78a82bd69d1c19d8914ddc -Author: Дилян Палаузов -Date: Sun Jan 22 15:42:48 2023 +0200 +commit ddb8fc5af9ad8970f67e9c5c8d04a22093678ca2 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:55 2023 +0100 - utils/kamctl: typos + sms: removed trailing spaces -commit 4e8022451dcf85c62401434f1f555ad6aac36eab -Author: Дилян Палаузов -Date: Fri Jan 20 13:18:15 2023 +0200 +commit 5afb7edbdf50bb967698807ad6824fd556f29f9b +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:55 2023 +0100 - replace SIGINFO64_WORKARROUND with SIGINFO64_WORKAROUND - - by calling - - sed -i "sMSIGINFO64_WORKARROUNDMSIGINFO64_WORKAROUNDM" `git grep -l SIGINFO64_WORKARROUND` + sl: removed trailing spaces -commit f81f0e77c5ab67431af1f62f0e027379a3445951 -Author: Sandro Gauci -Date: Mon Jan 23 13:38:17 2023 +0100 +commit 3725f149c0a70d7910028537efc200515c9092be +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:55 2023 +0100 - exec: docs - added security warning - - - Added warning about potential for OS Command Injection - - Updated invalid examples - - previous example gives the following error: - pv_parse_spec2(): error searching pvar "rU.txt" + sipt: removed trailing spaces -commit a45f4d901371e3ecdfad1652603a761ca30ac05e -Author: Kamailio Dev -Date: Fri Jan 20 12:31:20 2023 +0100 +commit 5fa1c25e59c86bf06666f204ab362030629d12c5 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:55 2023 +0100 - modules: readme files regenerated - topoh ... [skip ci] + sipjson: removed trailing spaces -commit 3cfbb8f8e2be64a2bec02ddc25ca8877c0f778f1 +commit 63536017ca22a38157b9308bc5c27f2c7eadb2e1 Author: Daniel-Constantin Mierla -Date: Fri Jan 20 12:22:27 2023 +0100 +Date: Mon Nov 13 15:23:55 2023 +0100 - topoh: added docs for use_mode parameter + sipcapture: removed trailing spaces -commit 5b9f22c0f45e6970e47a972f26eeac920860b4d7 +commit 8249a6807d6aaa92552aed2f440c14d3f5ea45f0 Author: Daniel-Constantin Mierla -Date: Fri Jan 20 12:16:03 2023 +0100 +Date: Mon Nov 13 15:23:55 2023 +0100 - topoh: added mod param use_mode - - - if set to 1, the module is initialized only for use as a library, via - inter-module api functions - - default: 0 - initialized for use to process sip messages + secfilter: removed trailing spaces -commit bca9c5587472df76e61a374d99b7a8dcefd63b2e +commit d9d5ef42a6bf1e31733b172539b8f50ff3215e1a Author: Daniel-Constantin Mierla -Date: Fri Jan 20 12:05:50 2023 +0100 +Date: Mon Nov 13 15:23:55 2023 +0100 - topoh: added inter-module api function for masking call-id + seas: removed trailing spaces -commit ca2e3bbabc4d6fa9ce4ca68d1b102f3aab8b7b3b -Author: Kamailio Dev -Date: Fri Jan 20 12:01:13 2023 +0100 +commit 865ed137878923133137e78bd1ee9b6f21a996ca +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:55 2023 +0100 - modules: readme files regenerated - websocket ... [skip ci] + sctp: removed trailing spaces -commit 3112e49aac274c75cc893693e820da894125403b -Author: Дилян Палаузов -Date: Sun Jan 15 15:48:16 2023 +0200 +commit f4ada96b5cfe05aff3878907a601acd7fbbd4fa7 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:55 2023 +0100 - websocket: example must listen on ports 80 and 443 - - otherwise the code below always matches: - - if ($Rp != 80 && $Rp != 443) { + sca: removed trailing spaces -commit d5b42fca13d2107590f9178c5d7c1a9d765adf73 +commit 30cc021f1bc9dc80ba8c14680fca1b2ec59db73a Author: Daniel-Constantin Mierla -Date: Fri Jan 20 11:34:14 2023 +0100 +Date: Mon Nov 13 15:23:55 2023 +0100 - core: snexpr - increase local buffer to avoid compile warning - - - GH #3330 + rtpengine: removed trailing spaces -commit ea99c8fc235334d4dd48868f74ab5c62662942e6 -Author: Sergey Safarov -Date: Thu Jan 19 11:56:18 2023 +0300 +commit 8b0562b97c7cfb78fdcd07c1385c63f51254f13b +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:55 2023 +0100 - pkg/kamailio/obs: used mariadb connector instead of mysql + rtp_media_server: removed trailing spaces -commit 34c3c42b7fe44dbe88110415ec78400a7defde61 +commit 0ab4fbd0b4b82bd9d58ee645b4d6666af52fc769 Author: Daniel-Constantin Mierla -Date: Mon Jan 16 12:54:48 2023 +0100 +Date: Mon Nov 13 15:23:55 2023 +0100 - websocket: ignore keepalive in state WS_S_REMOVING - - - GH #3331 + rr: removed trailing spaces -commit ac4c2d4579f121395876de2cc6f7649f3cb2fba7 -Author: Sergey Safarov -Date: Sun Jan 15 06:18:54 2023 +0300 +commit d01d6b50af3eb88ab0850759ea1a31f5291f0f50 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - pkg/kamailio/obs: added new modules into pec file + rls: removed trailing spaces -commit fc75b4c3f8f9bdba320f74ddf942686c09316b56 +commit 4ff9f350c78e3fd660df98a8809bfe535b2568b8 Author: Daniel-Constantin Mierla -Date: Fri Jan 13 12:41:12 2023 +0100 +Date: Mon Nov 13 15:23:54 2023 +0100 - app_python3: use Py_SET_TYPE() from python 3.9 + ratelimit: removed trailing spaces -commit 9d3c0d0d424c0bf8395465d7a6e14e89611aad0d +commit 9138f9b07e092c7ce648631924897407abf33657 Author: Daniel-Constantin Mierla -Date: Fri Jan 13 12:35:21 2023 +0100 +Date: Mon Nov 13 15:23:54 2023 +0100 - app_python3s: proper check of PY_VERSION_HEX for python 3.11 + rabbitmq: removed trailing spaces -commit 8546fb87e3277b675bd47eba9435f739cf3bb69d +commit c9b6e950321d65732636f525c7b5fc7cc2294492 Author: Daniel-Constantin Mierla -Date: Fri Jan 13 12:33:20 2023 +0100 +Date: Mon Nov 13 15:23:54 2023 +0100 - app_python3: proper check of PY_VERSION_HEX for python 3.11 + qos: removed trailing spaces -commit ddefe42e610edea35554a195742234079307cc8a -Author: Дилян Палаузов -Date: Wed Jan 11 17:21:34 2023 +0200 +commit aa67e3293bf004d095187ba907fc1db45bea568b +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - xmlrpc: remove double #include<>d headers + pv: removed trailing spaces -commit ff5e31adbbd6ca145edfc66307b74575d79e31ba -Author: Дилян Палаузов -Date: Wed Jan 11 17:21:04 2023 +0200 +commit 72b1a63391f4784af329949a10d7e01eda0d53d9 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - xhttp_prom: remove double #include<>d headers + pua_xmpp: removed trailing spaces -commit b5954933ecafdc3d953980fac169fa6fc0e8a9a3 -Author: Дилян Палаузов -Date: Wed Jan 11 17:20:51 2023 +0200 +commit 7a81ecbecd9bf48f110ccef4fb66c72b15b4002f +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - usrloc: remove double #include<>d headers + pua: removed trailing spaces -commit 8f663a2abd321ddd04bd0ae482afe16b2571667c -Author: Дилян Палаузов -Date: Wed Jan 11 17:20:33 2023 +0200 +commit 303c7c00a9064cec6569594c8db83a359f357dd3 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - uac_redirect: remove double #include<>d headers + presence: removed trailing spaces -commit 51150f6b4cb068ff4351b9f5018f5d5eeb91755d -Author: Дилян Палаузов -Date: Wed Jan 11 17:20:17 2023 +0200 +commit 12d90ab8893448a7ea15897200956cd19108ab90 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - tm: remove double #include<>d headers + pipelimit: removed trailing spaces -commit 7582d583b1d5e71c890b13082e680bb0d5083855 -Author: Дилян Палаузов -Date: Wed Jan 11 17:20:05 2023 +0200 +commit a7d22c4862da247651d3248c8035dcb5f50e0e87 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - tls_wolfssl: remove double #include<>d headers + peering: removed trailing spaces -commit 791eae5c8250bd283afee1f5a2efc421ef100594 -Author: Дилян Палаузов -Date: Wed Jan 11 17:19:52 2023 +0200 +commit 3a20e7a77e3ee01fb9e136ce62c3a27065ba50c4 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - tls: remove double #include<>d headers + pdt: removed trailing spaces -commit 318e65b7b594418dd3fb87bbea259994e12eafad -Author: Дилян Палаузов -Date: Wed Jan 11 17:19:43 2023 +0200 +commit 1dee112b558d4ed5faeb4039bb38ba4018fe0dba +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - timer: remove double #include<>d headers + pdb: removed trailing spaces -commit ea91c83d680a086ea10747193bf8dda596190591 -Author: Дилян Палаузов -Date: Wed Jan 11 17:19:35 2023 +0200 +commit f2c035a05717565ff606858e76482df08eb91980 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - siprepo: remove double #include<>d headers + p_usrloc: removed trailing spaces -commit c8b111ba1bf9c9ac00f0834a6ab735f22c903c55 -Author: Дилян Палаузов -Date: Wed Jan 11 17:19:25 2023 +0200 +commit 82a9932d5c598070fbcf09a463e72f227228f5e1 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - seas: remove double #include<>d headers + osp: removed trailing spaces -commit 8b9fc90db3cffdd61f8cadc95f052f4454fcdcb9 -Author: Дилян Палаузов -Date: Wed Jan 11 17:19:11 2023 +0200 +commit 2ef9e45c32856e560e05d35dd89b4ac02c70fd69 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - rtpengine: remove double #include<>d headers + ndb_redis: removed trailing spaces -commit 87460524321f52fc2272158b519c5b9e0b0ec3de -Author: Дилян Палаузов -Date: Wed Jan 11 17:18:59 2023 +0200 +commit abb9ece66fb84a79156ec9fce4ec84ddf4d0abaa +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - rtimer: remove double #include<>d headers + ndb_mongodb: removed trailing spaces -commit 38a39d9fefda28a28c14276627cac2a8ed2dba4d -Author: Дилян Палаузов -Date: Wed Jan 11 17:18:50 2023 +0200 +commit 453fdc62080236a1bc631f321cf49f3c88fd7693 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - rabbitmq: remove double #include<>d headers + msilo: removed trailing spaces -commit 95afba3dc92877afb0e51106211a95143b8147ae -Author: Дилян Палаузов -Date: Wed Jan 11 17:18:41 2023 +0200 +commit 55ca1698f2cfc2861f77a9f5d2468142b2427577 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - pua: remove double #include<>d headers + mqtt: removed trailing spaces -commit 238d572f45d2945bb1130bf315304e2f1963a02b -Author: Дилян Палаузов -Date: Wed Jan 11 17:18:33 2023 +0200 +commit a92657c0c79a3536cf865eb81974629f39cf4eb6 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - permissions: remove double #include<>d headers + misc_radius: removed trailing spaces -commit ef9c9d282a531bf57d7eaa9d083ab5fd1d82d1b2 -Author: Дилян Палаузов -Date: Wed Jan 11 17:18:19 2023 +0200 +commit 1e698f889dcef22359d21a3013b02613922da5b0 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - p_usrloc: remove double #include<>d headers + mediaproxy: removed trailing spaces -commit 8967e3d80fc600053bc94b286cb883431a7ba39b -Author: Дилян Палаузов -Date: Wed Jan 11 17:18:09 2023 +0200 +commit 1748464bb228c30f5175d6b16f7f7062d48f7941 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - lwsc: remove double #include<>d headers + mangler: removed trailing spaces -commit 7d7a41595c460efdffab2c702387794ea216ee05 -Author: Дилян Палаузов -Date: Wed Jan 11 17:17:58 2023 +0200 +commit a1c488a2cd1613e25e0612aefe65106a640aaf70 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - lcr: remove double #include<>d headers + lost: removed trailing spaces -commit 083665647474e2bad4e13a6b48312fa1cbe715eb -Author: Дилян Палаузов -Date: Wed Jan 11 17:17:44 2023 +0200 +commit 29912b20fd1e03d5936e6d79554dc1bf209e7669 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - ims_usrloc_scscf: remove double #include<>d headers + ldap: removed trailing spaces -commit 2b4255fcc013b66201ef58a6b52a14705c59a0dc -Author: Дилян Палаузов -Date: Wed Jan 11 17:16:35 2023 +0200 +commit 044f6c6db52aec4d6f14d332559c9b18ceb817f9 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - ims_usrloc_pcscf: remove double #include<>d headers + lcr: removed trailing spaces -commit c2cf9c710e2eabf6a693e748e140a295438511fc -Author: Дилян Палаузов -Date: Wed Jan 11 17:16:10 2023 +0200 +commit 949a9407d0ab5fa5eab931eb3162e7a2160cfa35 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - ims_qos: remove double #include<>d headers + kazoo: removed trailing spaces -commit f88eafd360be2b7193567f10862d18e1b001917a -Author: Дилян Палаузов -Date: Wed Jan 11 17:15:40 2023 +0200 +commit 8f4acd7469886be60b9a38cfab9a3cc372024e8e +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:54 2023 +0100 - ims_dialog: remove double #include<>d headers + kafka: removed trailing spaces -commit 736649b3dbcc262e2901095ee6f06911861024a0 -Author: Дилян Палаузов -Date: Wed Jan 11 17:15:22 2023 +0200 +commit 75ab52d6ee6809889516008db6a7a91521a52709 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:53 2023 +0100 - ims_charging: remove double #include<>d headers + ipops: removed trailing spaces -commit 6aa8e5a8cfc946cfbfa7ba5a839d02cce370406c -Author: Дилян Палаузов -Date: Wed Jan 11 17:14:56 2023 +0200 +commit 5989b2f7e26b8c4af6f653ad9e8a4f79df121a65 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:53 2023 +0100 - http_async_client: remove double #include<>d headers + ims_usrloc_scscf: removed trailing spaces -commit 5fef1210e9652b91a7ecc0a517498e3f637792c5 -Author: Дилян Палаузов -Date: Wed Jan 11 17:14:41 2023 +0200 +commit 16a833598e199de2e2f0bc46c77ae6bcc14491f6 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:53 2023 +0100 - evapi: remove double #include<>d headers + ims_usrloc_pcscf: removed trailing spaces -commit 1888e4027797b737c5c84fcdf55bd2b94465fe34 -Author: Дилян Палаузов -Date: Wed Jan 11 17:14:18 2023 +0200 +commit 215461d91ce759dd111065fdf2febadd21a60aee +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:53 2023 +0100 - dialog: remove double #include<>d headers + ims_registrar_scscf: removed trailing spaces -commit eedde26a2698b9c63df39d03cacc2bdf79f300e0 -Author: Дилян Палаузов -Date: Wed Jan 11 17:13:57 2023 +0200 +commit da6896cca55910450c5aaf4e910d0af0d5ceafcc +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:53 2023 +0100 - cplc: remove double #include<>d headers + ims_registrar_pcscf: removed trailing spaces -commit 8563960f745735f5d80f744b85d8882ee151a513 -Author: Дилян Палаузов -Date: Wed Jan 11 17:13:25 2023 +0200 +commit 3c617641bea46a6ff997fe89f66adda4bb075e26 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:53 2023 +0100 - auth_ephemeral: remove double #include<>d headers + ims_qos: removed trailing spaces -commit 5005cc8abd46bd4ba1ff62411035dc4822e3a1e6 -Author: Дилян Палаузов -Date: Wed Jan 11 17:12:52 2023 +0200 +commit 78b690bcfb14db870972f83809230d1672962222 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:53 2023 +0100 - auth_diameter: remove double #include<>d headers + ims_ocs: removed trailing spaces -commit aec302e92edde165cfb25a04d6f636459bee6cbd -Author: Дилян Палаузов -Date: Wed Jan 11 17:12:21 2023 +0200 +commit 37e43241d23bea9e158e9d71e79350fbaf911343 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:53 2023 +0100 - app_java: remove double #include<>d headers + ims_isc: removed trailing spaces -commit 3a3c801e4512f50069b836103e94caddb6da2aa8 -Author: Дилян Палаузов -Date: Wed Jan 11 17:11:09 2023 +0200 +commit 511b268eaa6674f53daa74ec88be62899874eae9 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:53 2023 +0100 - core: remove double #include<>d headers + ims_icscf: removed trailing spaces -commit f2c78a09fb25717c31bb27d85009984289f2f77e -Author: Denis Prusov -Date: Thu Jan 12 07:07:20 2023 +0000 +commit 22fe687b6b2769d365865de949d909bbf196c3b2 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:53 2023 +0100 - cdp: make ip_proto parameter case insensitive + ims_diameter_server: removed trailing spaces -commit c6a74dd1574815aaf96085362facf47c5c4fcdaa -Author: Denis Prusov -Date: Tue Jan 10 11:36:15 2023 +0000 +commit cdc10b0ae42413d176d8f164a8df26145a513f75 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:53 2023 +0100 - cdp: Add SCTP support + ims_dialog: removed trailing spaces -commit 81db6113bdab17d8c5e202a2ddce61dabc6314c0 -Author: Kamailio Dev -Date: Wed Jan 11 16:46:42 2023 +0100 +commit a39ea855a4497deae8488c2efe90bdc4b787d1ec +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:53 2023 +0100 - modules: readme files regenerated - carrierroute ... [skip ci] + ims_charging: removed trailing spaces -commit 188ee311a1db1c2f2dd628f3dafa65994a90fcc4 -Merge: b86c9b5ddc ecb8cbb51a -Author: Lucian Balaceanu -Date: Wed Jan 11 17:36:02 2023 +0200 +commit 2c95b6e501cd517d757f7067f89e4721c354ca95 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:53 2023 +0100 - Merge pull request #3325 from mshary/master - - carrierroute module functions export to kemi + ims_auth: removed trailing spaces -commit b86c9b5ddc169d3257bfc6ef47cee732567a9fda -Author: Kamailio Dev -Date: Wed Jan 11 14:19:32 2023 +0100 +commit 7c66940deafa89f5cf9a61c27bd26f0f27f164eb +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:53 2023 +0100 - modules: readme files regenerated - acc ... [skip ci] + imc: removed trailing spaces -commit 7919e9160cff6998a492b2d17ffa0df45a90e5d2 +commit 971a4d9032b48234ce19bf16831296550ef77a71 Author: Daniel-Constantin Mierla -Date: Wed Jan 11 14:07:37 2023 +0100 +Date: Mon Nov 13 15:23:53 2023 +0100 - INTALL/README: updated the link to wiki site + http_client: removed trailing spaces -commit 78c95e59fb1eb54b31f82c8e4ed19fea1654efdb +commit c92c040c6536bb5d8718a6965f1ca8f37af61ed9 Author: Daniel-Constantin Mierla -Date: Wed Jan 11 14:07:11 2023 +0100 +Date: Mon Nov 13 15:23:53 2023 +0100 - doc: updated the link to wiki site + htable: removed trailing spaces -commit e5bdceba953e2aeef14d5e44eec4c2efc9b61295 +commit 7b281258835932b0f5eb3c9edcbcef3f286ebef4 Author: Daniel-Constantin Mierla -Date: Wed Jan 11 14:06:50 2023 +0100 +Date: Mon Nov 13 15:23:53 2023 +0100 - misc/examples: updated the link to wiki site + h350: removed trailing spaces -commit 67e50d2f802562c5d290af3fdd18b4c0b89cd69d +commit 68322dfbdf7de0c653547c9155e4003e17f1c9c8 Author: Daniel-Constantin Mierla -Date: Wed Jan 11 14:06:31 2023 +0100 +Date: Mon Nov 13 15:23:53 2023 +0100 - app_java: updated the link to wiki site + group: removed trailing spaces -commit 9d8d020d26777d5448b1020c5d4ff99687ca7e8e +commit d2c158a3cff5e106d3298dedfca46fb6d1daa423 Author: Daniel-Constantin Mierla -Date: Wed Jan 11 14:06:01 2023 +0100 +Date: Mon Nov 13 15:23:53 2023 +0100 - .github/CONTRIBUTING.md: updated the link to wiki site + enum: removed trailing spaces -commit 6e3d8f6c704abc619aff4229579e58ba581c00f6 +commit 964da8ff9ba8d9f6019495f1ba83bd9fcd0e21ef Author: Daniel-Constantin Mierla -Date: Wed Jan 11 14:05:34 2023 +0100 +Date: Mon Nov 13 15:23:53 2023 +0100 - etc/kamailio.cfg: updated the link to wiki site + drouting: removed trailing spaces -commit 55f4a473e705a918ed8b41ebe7eadd9a277bbca5 +commit 2cf0555f172bf440f2bdcda207d3f680e81ccf6b Author: Daniel-Constantin Mierla -Date: Wed Jan 11 14:05:10 2023 +0100 +Date: Mon Nov 13 15:23:53 2023 +0100 - acc: docs - updated the link to wiki site + domainpolicy: removed trailing spaces -commit 3ebec4db10aa021a77c45da0e244a77a40ef832a +commit 614bbe6479546cdd6c1456f8ca67bf9115b4c0ac Author: Daniel-Constantin Mierla -Date: Wed Jan 11 14:04:46 2023 +0100 +Date: Mon Nov 13 15:23:53 2023 +0100 - test: updated the link to wiki site + domain: removed trailing spaces -commit f9d45feec21efa77b7c5b5957f896732e486580e -Author: Victor Seva -Date: Tue Jan 10 14:08:05 2023 +0100 +commit 72a0cc9e661de2a7f3d031239a4ea274bb17f5f0 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:53 2023 +0100 - pkg/kamailio/deb: version set 5.7.0~dev3 [skip ci] + dmq: removed trailing spaces -commit c9e33ad739e4cf3ded314e86d231b2265e7ab775 +commit ce5cc17294588176e250504b059b85cbb4f00f3d Author: Daniel-Constantin Mierla -Date: Tue Jan 10 13:48:24 2023 +0100 +Date: Mon Nov 13 15:23:53 2023 +0100 - Makefile.defs: version set to 5.7.0-dev3 + diversion: removed trailing spaces -commit f717c142b0184b5785c9ff1b128868f7b7814136 +commit 097d49f47130481d415147c8d000cc7bfaf916bd Author: Daniel-Constantin Mierla -Date: Tue Jan 10 13:46:58 2023 +0100 +Date: Mon Nov 13 15:23:53 2023 +0100 - app_python3s: use local var to avoid overlapping values when casting + dispatcher: removed trailing spaces -commit 9142d58906eb9327a24290737b833d79dc2d605c +commit cb61576fd2ed8ca769a37ee3a35f2bc03c6cd876 Author: Daniel-Constantin Mierla -Date: Tue Jan 10 13:46:48 2023 +0100 +Date: Mon Nov 13 15:23:52 2023 +0100 - app_python3: use local var to avoid overlapping values when casting + dialplan: removed trailing spaces -commit a5dcd9794d6a26469968f8d9d3ee79af8a6e0142 +commit feb318635de4d540408a3b11486f423a4ec02d4b Author: Daniel-Constantin Mierla -Date: Tue Jan 10 13:46:06 2023 +0100 +Date: Mon Nov 13 15:23:52 2023 +0100 - app_python: use local var to avoid overlapping values when casting + dialog: removed trailing spaces -commit f8fdd336504702d9353b1ab7a1ffabca5ff4723e +commit 6f51280f63b57c9d499ec0df9ef1ff67686ac73e Author: Daniel-Constantin Mierla -Date: Tue Jan 10 13:28:50 2023 +0100 +Date: Mon Nov 13 15:23:52 2023 +0100 - rtp_media_server: return or continue on null values inside rms_dialog_action_check() + db_unixodbc: removed trailing spaces -commit ebe0466a35b9ef3ed1f754c8cb63d5df766ae499 +commit 4fa1fee7efec9abae82bfdf49fd6c52a676b7f07 Author: Daniel-Constantin Mierla -Date: Tue Jan 10 13:26:15 2023 +0100 +Date: Mon Nov 13 15:23:52 2023 +0100 - rtp_media_server: safety check on error inside rms_dialog_new() + db_text: removed trailing spaces -commit 04d0269298b9816a384a70439fa75b1bee20df46 +commit 3f611b107bede232dba661257708f95b77f8d95a Author: Daniel-Constantin Mierla -Date: Tue Jan 10 13:24:37 2023 +0100 +Date: Mon Nov 13 15:23:52 2023 +0100 - rtp_media_server: check before free + db_postgres: removed trailing spaces -commit 72cd0ac533d4e6b881aa5e4f2e1724c6da312ca2 +commit 816d8264219ac2a2cb1fe4248cf7e8f5f6ff9986 Author: Daniel-Constantin Mierla -Date: Tue Jan 10 13:21:27 2023 +0100 +Date: Mon Nov 13 15:23:52 2023 +0100 - app_python3s: checks for function execution handler + db_perlvdb: removed trailing spaces -commit c818c34d7d70a24c07d25e61b862971388f635f4 +commit f4c2562af88e051da196f3956b737875a3a795b3 Author: Daniel-Constantin Mierla -Date: Tue Jan 10 13:17:24 2023 +0100 +Date: Mon Nov 13 15:23:52 2023 +0100 - rtp_media_server: safety checks for call media leg variable + db_mongodb: removed trailing spaces -commit 408cad8cd67f1c3568fddb0f6b6fcc715ecec181 +commit 0e450c1deb0dc51c73600c9679b16afc6a2ce0a8 Author: Daniel-Constantin Mierla -Date: Tue Jan 10 13:13:11 2023 +0100 +Date: Mon Nov 13 15:23:52 2023 +0100 - rtp_media_server: reorder code for rms_payload_type_new() to update field after memset + db_flatstore: removed trailing spaces -commit f6dd56c8405189d0dcc16bd5d79927e919e8b572 +commit 9617e44d9bf78adb944ad0c795bf4cc89b6e5740 Author: Daniel-Constantin Mierla -Date: Tue Jan 10 13:12:06 2023 +0100 +Date: Mon Nov 13 15:23:52 2023 +0100 - rtp_media_server: safety check for shm allocation + db_cassandra: removed trailing spaces -commit 1938780339677596bf547794c4b54b7923405166 +commit 1074ced46aa912519e2c6a014440b0991e68c74e Author: Daniel-Constantin Mierla -Date: Tue Jan 10 13:07:58 2023 +0100 +Date: Mon Nov 13 15:23:52 2023 +0100 - app_python3s: restore backup reference to sip msg + db_berkeley: removed trailing spaces -commit db5ec271134f8c442bcaa91e8adfaaf3c6db5cba +commit 1363722bf1153a9bb7382f5e3dc7ac70164cb8a6 Author: Daniel-Constantin Mierla -Date: Tue Jan 10 12:58:27 2023 +0100 +Date: Mon Nov 13 15:23:52 2023 +0100 - rtp_media_server: removed fl variable which is not updated, thus not really used + db2_ops: removed trailing spaces -commit 72270c67fa76d653f09c132933460d268645a568 +commit d2d9a3e0b69ba4fa65fea4a4cb159af0cb96bb8a Author: Daniel-Constantin Mierla -Date: Tue Jan 10 12:51:51 2023 +0100 +Date: Mon Nov 13 15:23:52 2023 +0100 - rtp_media_server: removed unnecessary condition + db2_ldap: removed trailing spaces -commit ecb8cbb51a81186e46949eb70cccffe8907efbab -Author: Muhammad Shahzad Shafi -Date: Mon Jan 9 11:02:39 2023 +0000 +commit ab659ab7a2d6d4231d926091e967bc72ec517f76 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:52 2023 +0100 - carrierroute: updated module docs + ctl: removed trailing spaces -commit 7a52c634d73fa18b7f8d5faa41505f340a2c008d -Author: Muhammad Shahzad Shafi -Date: Mon Jan 9 11:01:45 2023 +0000 +commit 23515b124ea2298a253b586f1f7458e0d098b39e +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:52 2023 +0100 - carrierroute: added helper methods to simplify config and kemi functions, also some code clean up + cplc: removed trailing spaces -commit 401753b012fdbf6c995d523105c22a705b779061 -Author: Muhammad Shahzad Shafi -Date: Mon Jan 9 10:59:50 2023 +0000 +commit 3e0f45dce60cc9d9c6d71ab4034c541c170cb964 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:52 2023 +0100 - carrierroute: exported cr_load_next_domain(), cr_route() and cr_nofallback_route() to kemi + counters: removed trailing spaces -commit 8f011ff01a0881b387deb08bbed9986879eea994 -Author: Muhammad Shahzad Shafi -Date: Mon Jan 9 10:58:31 2023 +0000 +commit 3c19a034ecc15cbd443b8256c0365d4d8e438fe9 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:52 2023 +0100 - carrierroute: added fixup free functions + cdp_avp: removed trailing spaces -commit c83d234629c0d34a83926771b6df18438d0f43f1 -Author: Kamailio Dev -Date: Mon Jan 9 09:01:42 2023 +0100 +commit d840a524ea33ddbb6bdc37d926e4db370002c259 +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:52 2023 +0100 - modules: readme files regenerated - p_usrloc ... [skip ci] + carrierroute: removed trailing spaces -commit ff647697724decb7440dfe3758857a06ab008979 -Author: Henning Westerholt -Date: Mon Jan 9 07:57:26 2023 +0000 +commit 82ab176121eb63120a81fa294c5433f54c44e37e +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:52 2023 +0100 - p_usrloc: fix default transaction isolation level (gh #3324) + benchmark: removed trailing spaces -commit 5fbc0c6b88b171bb04e98d4319e57e6c2c6ed0d8 +commit 0e467f0bbf1f8b677fc61ec147fe1c227c5d4e66 Author: Daniel-Constantin Mierla -Date: Sun Jan 8 18:45:01 2023 +0100 +Date: Mon Nov 13 15:23:52 2023 +0100 - xmlrpc: check if rpc command has execution limit with delta interval + auth_radius: removed trailing spaces -commit 67f27ea223a20721ac288508635b5148e6264d56 +commit b09224343db0e6897e35539ad95c5fb65bc0925e Author: Daniel-Constantin Mierla -Date: Sat Jan 7 12:45:01 2023 +0100 +Date: Mon Nov 13 15:23:52 2023 +0100 - clt: check if rpc command has execution limit with delta interval + auth_ephemeral: removed trailing spaces -commit 2442d0748ef079c2152461792c64fc391e4def83 +commit 62917a50277e04b81ecf8cdb0e6dc321517905bf Author: Daniel-Constantin Mierla -Date: Fri Jan 6 09:27:05 2023 +0100 +Date: Mon Nov 13 15:23:52 2023 +0100 - jansson: avoid warning when long and long long have same size + auth_diameter: removed trailing spaces -commit e638232ff51793d683868a4cc7beba8014fcba47 +commit fb460f478b846c7b9a87bfda885cc7138b518f19 Author: Daniel-Constantin Mierla -Date: Fri Jan 6 08:03:27 2023 +0100 +Date: Mon Nov 13 15:23:52 2023 +0100 - jansson: use JSON_INTEGER_IS_LONG_LONG macro for type of json integer field + auth_db: removed trailing spaces -commit 10c0c1889be5b1aed27a41a87c45b5c5e8a92cf3 -Author: Kamailio Dev -Date: Thu Jan 5 15:01:40 2023 +0100 +commit 5cb7a874de69bae0b04cf22701d40351ee81c25c +Author: Daniel-Constantin Mierla +Date: Mon Nov 13 15:23:52 2023 +0100 - modules: readme files regenerated - permissions ... [skip ci] + app_python3: removed trailing spaces -commit 09bbe96a32f70ff7328eac431ea2efb48a3a8175 +commit c40b591c5124d018415cbbdcac80ee21ce926ea6 Author: Daniel-Constantin Mierla -Date: Thu Jan 5 15:00:17 2023 +0100 +Date: Mon Nov 13 15:23:52 2023 +0100 - permissions: docs - note that rpc reload commands are exported with RPC_EXEC_DELTA flag + app_python: removed trailing spaces -commit 5d9ed676dad76729253ee734d20a805e2a0dcc5c +commit 9e447120c3f5003c8a60d7399387b1c949246a6b Author: Daniel-Constantin Mierla -Date: Thu Jan 5 14:59:37 2023 +0100 +Date: Mon Nov 13 15:23:52 2023 +0100 - tls: docs - note that rpc reload command is exported with RPC_EXEC_DELTA flag + app_perl: removed trailing spaces -commit d0b1d6cc15b1c4e98ac65e4d90c6f53f2da63218 +commit b5c0b637451d069ae93344ea2921c363438f0739 Author: Daniel-Constantin Mierla -Date: Thu Jan 5 13:16:27 2023 +0100 +Date: Mon Nov 13 15:23:51 2023 +0100 - permissions: set the RPC_EXEC_DELTA flag for RPC reload commands + app_jsdt: removed trailing spaces -commit bb0c08676ccf33fabd7a0de27129c2ad98ac2208 +commit ac126d2cabd75c3e2b8afb509b661d89d7348f24 Author: Daniel-Constantin Mierla -Date: Thu Jan 5 12:22:31 2023 +0100 +Date: Mon Nov 13 15:23:51 2023 +0100 - core: replaced RET_ARRAY flag with RPC_RET_ARRAY + app_java: removed trailing spaces -commit a49dcf0cee005585222dacaa25d5d97e4934245e -Author: Daniel-Constantin Mierla -Date: Thu Jan 5 11:15:07 2023 +0100 +commit e997473fd2dea1056b601ab76693e071f3480866 +Author: Morten Tryfoss +Date: Thu Nov 9 13:16:15 2023 +0100 - tls: set RPC_EXEC_DELTA flag for tls.reload rpc command + cdp: Support for diameter routing agent (DRA) / relay - - related to GH #3319 + If an endpoint responds with a CEA indicating support for relaying + (application-id 0xffffffff), let this endpoint be used for any application. -commit 6c3cff35a2ae2c29a93f0c2bd8507ccbed00464c +commit 0da5925282d0f52bd3847c63657563df2ec0aca8 Author: Daniel-Constantin Mierla -Date: Wed Jan 4 10:26:22 2023 +0100 +Date: Mon Nov 13 11:08:43 2023 +0100 - jsonrpcs: check if rpc command has execution limit with delta interval + lcr: init local variable for parameter handling -commit cc482ee970ef1abd3cabd15aa5907ad995e57cfe +commit 1f4e0faac577a1bd4826e0bafe451d66b8aa360c Author: Daniel-Constantin Mierla -Date: Wed Jan 4 10:25:05 2023 +0100 +Date: Mon Nov 13 10:58:01 2023 +0100 - xhttp_rpc: updates to use the new structure from rpc_sarray + pv: trans - check for number parameter limit -commit 8b3112774fe08f5b6d808ee916431c3331a2e819 +commit d27bf087dfca0146a6589148b5701818ef635b02 Author: Daniel-Constantin Mierla -Date: Wed Jan 4 10:23:24 2023 +0100 +Date: Mon Nov 13 10:39:29 2023 +0100 - core: export core rpc commands later when shm is initialized + core: cast to deal with analyzer warning -commit 017089c04f2d6876fcb43ea494f287e687efc5d9 +commit 1677880999927b12bdbf62cb44ae61887d1585bc Author: Daniel-Constantin Mierla -Date: Wed Jan 4 10:22:00 2023 +0100 +Date: Sun Nov 12 19:19:18 2023 +0100 - core: new rpc command core.echo_delta - - - example of rpc command exported with RPC_EXEC_DELTA flag + core: init socket mcast using pkg_mallocxz() + +commit 2b9666445a9fd31f75bf86b9924658daffb7ac85 +Author: Henning Westerholt +Date: Fri Nov 10 14:01:47 2023 +0000 + + kamailio.cfg: use xalert instead of old format for xlog, similar as done in other cfg places -commit e65c5784fee4952d1260016b1f1d94177f8f405d +commit 80d1f10507190ae1a42c25f0c173188b8326b5b9 Author: Daniel-Constantin Mierla -Date: Wed Jan 4 10:20:35 2023 +0100 +Date: Fri Nov 10 14:08:09 2023 +0100 - core: new parameter rpc_exec_delta to set rpc command delta interval execution + core: qm/fm memory align size can be set with define KSR_MEMORY_ALIGN - - value is seconds - - default is 0 (no delta interval execution) + - flexibility to be set at compile time via make or compiler parameter -commit a71a6ed626266db8265a7a88375be5ef3b2be495 +commit 7cc22301b37ae2a214900af9628b148f59dcce21 Author: Daniel-Constantin Mierla -Date: Wed Jan 4 10:18:51 2023 +0100 +Date: Fri Nov 10 08:24:51 2023 +0100 - core: rpc - support for executing commands with a delta interval limit + core: mem - fm memory manager updated to align to 16 - - RPC_EXEC_DELTA flag has to be set on RPC command export + - same as malloc() on linux 64b + - https://www.gnu.org/software/libc/manual/html_node/Aligned-Memory-Blocks.html + - some libraries (e.g., libwolfssl) expect such alignement for specific optimizations + - done even for 32b, expected rather low overhead in average, not expected many + chunks under 16 bytes versus those over + - malloc optimization factor increased to 15 -commit 6a5483a1767f689bc5ad261e2ead86da33c0dc73 +commit d56b96f79c21c23957051eee1b6f7aa22cb075f1 Author: Daniel-Constantin Mierla -Date: Tue Jan 3 11:17:28 2023 +0100 +Date: Fri Nov 10 07:58:24 2023 +0100 - core: rpc - removed define switch for copying rpc export - - - set for many years without change + core: mem - qm check for alignment of main block structure -commit 7a3573002fddffd74999c4cd5a859a4019d0227a +commit 695dc54dc1547fdee18b00cfa8e4d15f047834a5 Author: Daniel-Constantin Mierla -Date: Tue Jan 3 11:06:00 2023 +0100 +Date: Fri Nov 10 07:31:38 2023 +0100 - core: rpc - removed old todo, whitespacing and define guards coherence + app_python3: enable error log mode for some of missing callback functions + + - tm-specific callbacks should trigger error log messages if not found -commit 7364a8a67e19960d51a632108f39d7d2d289f8ce +commit eabd1e2c49b3e67455d5d8b13809332832036fa8 Author: Daniel-Constantin Mierla -Date: Wed Dec 28 10:37:04 2022 +0100 +Date: Fri Nov 10 07:29:51 2023 +0100 - xmlrpc: coherent check of RET_ARRAY as a flag + core: mem - qm malloc optimization factor increased to 15 -commit 971ae411a5eca66b2ce2bc95230b76510c132b09 -Author: Kamailio Dev -Date: Wed Dec 28 10:32:49 2022 +0100 +commit a5bc1c03968b797ac03d5b648ad3b417dfee265d +Author: Daniel-Constantin Mierla +Date: Thu Nov 9 20:33:31 2023 +0100 - modules: readme files regenerated - alias_db ... [skip ci] + core: mem - qm memory manager updated to align to 16 + + - same as malloc() on linux 64b + - https://www.gnu.org/software/libc/manual/html_node/Aligned-Memory-Blocks.html + - some libraries (e.g., libwolfssl) expect such alignement for specific optimizations + - done even for 32b, expected rather low overhead in average, not expected many + chunks under 16 bytes versus those over -commit 6dadb322af4c7e9eff36b29e66680f6f015a5d95 -Author: Дилян Палаузов -Date: Sat Dec 24 22:39:12 2022 +0200 +commit 7bdd7fb4aa666b5f56ae3e554770126ad5b68c2e +Author: Daniel-Constantin Mierla +Date: Thu Nov 9 15:32:39 2023 +0100 - examples/kemi: align the list of unfriendly UAs to the native cnf file + dialog: use memcpy to fill profile uid -commit 182b948ae97dc2f797fc5dd01503cb8d4f22c2b5 -Author: Дилян Палаузов -Date: Sat Dec 24 22:36:16 2022 +0200 +commit 36806bea261f7a29dc1d2a8aedac837a06043968 +Author: Daniel-Constantin Mierla +Date: Thu Nov 9 14:54:13 2023 +0100 - .github/CONTRIBUTING.md: typo + imc: coverted some static global str variables to macros -commit 31396205dfb02b75877a73b19584fcc14c0b9563 -Author: Дилян Палаузов -Date: Sat Dec 24 19:31:52 2022 +0200 +commit 9b01012b5fab43ca3b1ddc7d7493b0edc69cdceb +Author: Daniel-Constantin Mierla +Date: Thu Nov 9 10:42:55 2023 +0100 - utils/kamclt: typo + core: use string building functions with explicit lenght -commit f1e0b326438eada3c074651f7cbf53232dbb8401 -Author: Дилян Палаузов -Date: Sat Dec 24 19:34:36 2022 +0200 +commit 8269b719775ce704eade4a832ae8abb56af08841 +Author: Kamailio Dev +Date: Thu Nov 9 09:32:21 2023 +0100 - test: typos + modules: readme files regenerated - rtpengine ... [skip ci] -commit c35bdece4340ac669989bf7afb74c15eb67fff0f -Author: Дилян Палаузов -Date: Sun Dec 18 10:45:10 2022 +0200 +commit af86d0e27b9a66cff392fd5e462901864bc3dc18 +Author: Kamailio Dev +Date: Mon Nov 6 13:47:21 2023 +0100 - xmlrpc: typo typos + modules: readme files regenerated - ims_charging ... [skip ci] -commit f209380de74dc6d34a3042d142efaff9f1a80266 -Author: Дилян Палаузов -Date: Sat Dec 24 18:35:33 2022 +0200 +commit aab0e4a3b86f309f8a0333d20f632fec1158af9f +Author: Daniel-Constantin Mierla +Date: Thu Nov 9 09:27:07 2023 +0100 - xcap_client: typo + rtpengine: remove mistaken statement for set_rtpengine_set() about rtpengine_manage() -commit 6184fa0d0f20c47b839235ca094c15b638899c05 -Author: Дилян Палаузов -Date: Tue Dec 20 07:54:50 2022 +0200 +commit 12dcdd3664bbb990cd749872bea3744bb7eff315 +Author: Victor Seva +Date: Wed Nov 8 23:32:42 2023 +0100 - websocket: typo a/an Access-Control-Allow-Origin header + devcontainer: use prebuild image [skip ci] -commit f0e12136e41aaae3c80a1606d6753cf97b44ee3a -Author: Дилян Палаузов -Date: Sat Dec 24 18:07:36 2022 +0200 +commit 721bfc880a7c01b1792e5770a26fc7d5fe4faa42 +Author: Victor Seva +Date: Wed Nov 8 22:30:26 2023 +0100 - uri_db: typo its → it is + devcontainer: add github-cli -commit d171f379135371d4d2503fc051439385fa27e9bf -Author: Дилян Палаузов -Date: Sat Dec 24 16:22:09 2022 +0200 +commit 38585ea29773543d9c2fe3559005487511ac90ce +Author: Victor Seva +Date: Wed Nov 8 21:50:41 2023 +0100 - usrloc: typos + github: prebuild devcontainer image -commit 42c5dccb0581cdd806771fbdeea814b0a45ac3ca -Author: Дилян Палаузов -Date: Tue Dec 27 12:13:21 2022 +0200 +commit 9b4fe94d71c25e9ac3a43a5010a5dece7adaf14c +Author: Victor Seva +Date: Wed Nov 8 20:14:05 2023 +0100 - uid_domain: typos + devcontainer: add gitlens extension [skip ci] -commit d8d2c14ea0210532d3982fc5d9c5eb528e5afea8 -Author: Дилян Палаузов -Date: Sat Dec 17 14:26:39 2022 +0200 +commit 6aa940f7acbc565545ae9199b288d16a50bafcab +Author: Victor Seva +Date: Wed Nov 8 20:53:53 2023 +0100 - uid_avp_db: typo succesSful + dialplan: reformat exported structures more human friendly + + revert to the format it had before 01d0d1de2c8 -commit 7fd8c064e175f77697afe26bca3f39304a2c68d8 -Author: Дилян Палаузов -Date: Tue Dec 20 06:56:00 2022 +0200 +commit 4642a12c109939f71f91ba7807ded1491e241e26 +Author: Victor Seva +Date: Wed Nov 8 20:03:49 2023 +0100 - uac_redirect: typos + debugger: reformat exported structures more human friendly + + revert to the format it had before 656e147c470 -commit 0f4e6e3e03a038fbee6f93a0df311ccfbbe5c117 -Author: Дилян Палаузов -Date: Tue Dec 20 07:54:28 2022 +0200 +commit f0cf082effe6a0fd8893299e49a519d90bfc6151 +Author: Victor Seva +Date: Wed Nov 8 19:44:38 2023 +0100 - uac: typos + dialog: reformat exported structures more human friendly + + revert to the format it had before 783a416f1a5 -commit 257a176ccebf81ad754925bb488937f4d655924e -Author: Дилян Палаузов -Date: Sat Dec 24 18:38:33 2022 +0200 +commit a62d7118a2f86a82fd080ed4a89a0833e8c4d1a2 +Author: Daniel-Constantin Mierla +Date: Wed Nov 8 18:44:58 2023 +0100 - tsilo: typos + core: utils/srjson - use snprintf() for silenting analyzers -commit cb525b19f0ab73f692413fa8ccf6433f4833146c -Author: Дилян Палаузов -Date: Sat Dec 24 19:11:39 2022 +0200 +commit 8f84f6681570d5eb1018e6fe45f280173451bf62 +Author: Daniel-Constantin Mierla +Date: Wed Nov 8 11:06:17 2023 +0100 - tmx: typo + topos: update headers for stateless cancel and non-2xx ack -commit 2558c00599070a7af5110f653b9e60ac470f8c1e -Author: Дилян Палаузов -Date: Sat Dec 24 19:00:50 2022 +0200 +commit e1c151fdcb1da37f2cf2ffd76f364ec025a8d6e6 +Author: Victor Seva +Date: Wed Nov 8 09:50:03 2023 +0100 - tm: typos + github: decrease operations-per-run [skip ci] -commit e3a2bf5a9f0b702259ffa47652975bae51e4e16a -Author: Дилян Палаузов -Date: Sat Dec 17 14:26:09 2022 +0200 +commit 4564ba265a0e3fee45103553dc959b044272094b +Author: Victor Seva +Date: Wed Nov 8 09:15:41 2023 +0100 - tls_wolfssl: typos + github: increase operations-per-run [skip ci] -commit 8bf11c857736983b66f2d5eba8bd66a91cbc2636 -Author: Дилян Палаузов -Date: Sat Dec 17 14:23:39 2022 +0200 +commit d6335767223f7841a448689e4f54a6f7709e2cc8 +Author: Victor Seva +Date: Wed Nov 8 08:52:11 2023 +0100 - tls: typos + github: allow execute issue_management from panel [skip ci] + + * change order since we are hitting operations-per-run + > https://github.com/marketplace/actions/close-stale-issues#ascending -commit 5ac1ce58dfd5fe872c4b142d7a062f782f786437 -Author: Дилян Палаузов -Date: Tue Dec 27 12:12:22 2022 +0200 +commit ba76a0f115f17f65bccc59d59ffc798a7109393c +Author: Victor Seva +Date: Wed Nov 8 08:51:23 2023 +0100 - textopsx: typo build → built + .devcontainer: add github-actions extension [skip ci] -commit b111ef210fa6044c5bc291d09eb1a856e1f959f0 -Author: Дилян Палаузов -Date: Sat Dec 24 18:58:45 2022 +0200 +commit ca613b491412a7ebb6f3d59956a8cbbde1cb725a +Author: Victor Seva +Date: Tue Nov 7 23:20:33 2023 +0100 - textops: typos + github: close-stale-issues + + As discussed at Kamailio developers meeting 2023 -commit d687f75b6afee6c3a5e00f9faa01639bf254346b -Author: Дилян Палаузов -Date: Tue Dec 27 11:20:50 2022 +0200 +commit 4587d46d06fe4fe1d7c754b46b0f68910cbca633 +Author: Daniel-Constantin Mierla +Date: Tue Nov 7 17:19:44 2023 +0100 - systemdops: typo + core: set atexit to default to no -commit 16a99036161df45426ccd022606b62068b6f9717 -Author: Дилян Палаузов -Date: Sat Dec 24 16:27:09 2022 +0200 +commit b141f267ce1fe1068de1541d8bd5b5dc53c1d6d9 +Author: Christian Marangi +Date: Mon Nov 6 16:13:55 2023 +0100 - stirshaken: typo wHich + kamcmd: Makefile - use CUSTOM_NAME for specifying custom binary name + + - previous use of NAME can clash with environment variable NAME that + could be set by OS or by Kamailio modules installation + - GH #3628 -commit 2402c8f30d76b347a8c381f72fcd96b29e672d4f -Author: Дилян Палаузов -Date: Sat Dec 24 16:21:03 2022 +0200 +commit 511964bd91d0fb0099dab14a69296d21d37abffa +Author: Daniel-Constantin Mierla +Date: Mon Nov 6 14:20:53 2023 +0100 - sst: clarify that sst_flag must be set + topos: handle NOTIFY during call setup - and typos + - GH #3627 -commit 8d9a0d68ea37d57c5c46520ebeb4e666f438858a -Author: Дилян Палаузов -Date: Sat Dec 17 14:20:38 2022 +0200 +commit 184417a1089397baf47ed91a096660f1a421276c +Author: Daniel-Constantin Mierla +Date: Mon Nov 6 13:46:15 2023 +0100 - snmpstats: typos + tm: reformat exported structures more human friendly -commit f98980f53f50c79d911bc1dba1f1243c74662c81 -Author: Дилян Палаузов -Date: Tue Dec 20 07:53:37 2022 +0200 +commit becebaa826597eba250c1c90fdfa2ffaa90f1712 +Author: Morten Tryfoss +Date: Mon Oct 30 13:14:23 2023 +0100 - sms: typo a/an SMS + ims_charging: Implemented restore of Ro sessions from database + + - realtime and shutdown mode support + - removed duplicate entry in doc about "ro_auth_expiry" -commit 259373e3a19a38071dd61d6b317ea2c7f02adcc4 -Author: Дилян Палаузов -Date: Sat Dec 24 14:29:55 2022 +0200 +commit 70ecd99e3d8069d0f89444a5b893f61dd1edd1b3 +Author: Morten Tryfoss +Date: Mon Nov 6 11:14:36 2023 +0100 - sl: typos + tm: T_ASYNC_SUSPENDED flag not removed when cancelling a suspension -commit 6c09b14e08b1915fefb58ade46e5da54e19c9dc6 -Author: Дилян Палаузов -Date: Mon Dec 19 13:22:35 2022 +0200 +commit 4cec039ce1b7fa2d1980f8f30dd7bb1012e3c9cb +Author: Kamailio Dev +Date: Sun Nov 5 22:02:26 2023 +0100 - siputils: typos + modules: readme files regenerated - tm ... [skip ci] -commit 528dbe39af2f17f535b4098d844b7f2a0d87a55d -Author: Дилян Палаузов -Date: Sat Dec 24 16:29:22 2022 +0200 +commit 9bbf86a8a7e598a67254e2907dcc430af98f5689 +Author: Daniel-Constantin Mierla +Date: Sun Nov 5 21:48:43 2023 +0100 - siptrace: typo + tm: docs updated for t_reply_error() -commit 424dfe77cd8b304c72098e901479202a825c0533 -Author: Дилян Палаузов -Date: Sat Dec 24 16:41:31 2022 +0200 +commit c86950841dfc0ca18ad1956efd1dc374a4eb064b +Author: Daniel-Constantin Mierla +Date: Sat Nov 4 16:42:46 2023 +0100 - sipdump: typo fuNction + tm: enable t_reply_error() in same routing blocks like t_reply() -commit 028693c2b94bf626f9e1ca94a0dbd0050adb8d3b -Author: Дилян Палаузов -Date: Tue Dec 27 11:38:40 2022 +0200 +commit 0def9a071343c963ab3a497540534d8ea3b8eebc +Author: Daniel-Constantin Mierla +Date: Fri Nov 3 11:40:29 2023 +0100 - seas: missing space + db_redis: wrapp field version_code.s with ZSW() to be safer when it is not set -commit 8dc47d749a9a556f45453771746b0e22f2ac098c -Author: Дилян Палаузов -Date: Sat Dec 24 16:29:43 2022 +0200 +commit e24df12d10d8b88582907481d161c6a2db5cf8f1 +Author: Daniel-Constantin Mierla +Date: Fri Nov 3 11:00:34 2023 +0100 - ruxc: 200ok → 200 OK + db_redis: init allocated redis table structure -commit 731be1d0eef4f5cbf05f638a25a738ff8bf6fd05 -Author: Дилян Палаузов -Date: Sat Dec 24 16:17:14 2022 +0200 +commit d4995bf2791bd1048ac8a7f32e51ae6949562ce3 +Author: Kamailio Dev +Date: Fri Nov 3 09:17:27 2023 +0100 - rtpproxy: typo + modules: readme files regenerated - sl ... [skip ci] -commit 8c228d9c41b5ab190ce33473b659424dd180d082 -Author: Дилян Палаузов -Date: Sat Dec 24 16:17:28 2022 +0200 +commit cb5295234a1b106473c3fdb9ff25c23bfc9fbcd1 +Author: Daniel-Constantin Mierla +Date: Fri Nov 3 09:06:38 2023 +0100 - rtpengine: formatting + sl: docs for send_reply_error() -commit c58a6ec1cb87c79b3219df8e9f68ebfd3f2c1024 -Author: Дилян Палаузов -Date: Sat Dec 24 16:12:12 2022 +0200 +commit 130dc00c1700839248a044f8ae6d4a9e9c97d301 +Author: Daniel-Constantin Mierla +Date: Fri Nov 3 09:00:14 2023 +0100 - rr: typos + sl: added send_reply_error() + + - wrapper around t_reply_error() and sl_reply_error() -commit 67d8b44ead9c9a8b5f716269d2fb5b593a04b31c -Author: Дилян Палаузов -Date: Sat Dec 24 16:29:58 2022 +0200 +commit 2097922746d12d332ce923193af9c624429b7f96 +Author: Daniel-Constantin Mierla +Date: Fri Nov 3 08:41:08 2023 +0100 - rls: typos + tm: exposed t_reply_error() to intermodule API -commit dc245a45309c1aca3c6704d122a39f54d1611e51 -Author: Дилян Палаузов -Date: Sat Dec 24 19:00:11 2022 +0200 +commit 21eeb977c882dec4540703b2d8b4ff5131e6c446 +Author: Daniel-Constantin Mierla +Date: Thu Nov 2 14:01:58 2023 +0100 - registrar: reword + core: add transport parameter for ws/wss advertised proto -commit ae89ec8da8689ffaf4aa5c57cbcbe14941e0569d -Author: Дилян Палаузов -Date: Sat Dec 17 14:20:13 2022 +0200 +commit ef5e889dce3e2ff077b300f183b6d3262aeab9f8 +Author: Daniel-Constantin Mierla +Date: Thu Nov 2 13:15:55 2023 +0100 - ratelimit: typo unsuccesSful + pdt: return 0 when add_to_tree() detect duplicated prefix with pdt mode 1 + + - GH #3626 -commit 9592d9f39114bf1778e1020283f7a85ff84f82ca -Author: Дилян Палаузов -Date: Sat Dec 24 17:11:22 2022 +0200 +commit d9189306f38e8f79c16e3a9ea38a2fe90fc82fb7 +Author: Kamailio Dev +Date: Thu Nov 2 13:16:27 2023 +0100 - pv_headers: use flags numbers below 32 + modules: readme files regenerated - http_client ... [skip ci] -commit 3c01356e1c02aabc40025aa5445c488a9b1927cd -Author: Дилян Палаузов -Date: Tue Dec 20 06:55:31 2022 +0200 +commit ba72724fd1c3547feccb56ae68bd8bed11a3d19a +Author: Morten Tryfoss +Date: Wed Oct 25 08:49:53 2023 +0200 - pv: typos + cdp: Fix for undefined symbols when using older/unsupported OpenSSL + + This was originaly fixed in #3601, but that did not handle the change in #3612 very well. -commit 3ae6fdfddea2ed2192d91f7769bd06f08124f6be -Author: Дилян Палаузов -Date: Tue Dec 20 07:53:23 2022 +0200 +commit 02dd4e2c883585601f4dbcea0b63b858b4dd24d6 +Author: Benjamin <92934023+tietzsg@users.noreply.github.com> +Date: Thu Nov 2 13:09:57 2023 +0100 - pua_xmpp: typo a/an xmpp + http_client: add information about parameter loading (#3619) + + * http_client: add information about parameter loading + + - Inform that the order of the parameters is important when httpcon is loaded first + + * http_client: docs - typos from previous commit + + --------- + + Co-authored-by: Daniel-Constantin Mierla -commit 8513046cd76263211d2b4531e8458211c65dd6ec -Author: Дилян Палаузов -Date: Sat Dec 24 19:11:19 2022 +0200 +commit 370991cfab3bd42fe0ca3cbff7dca7b40319f3f4 +Author: Daniel-Constantin Mierla +Date: Thu Nov 2 10:25:52 2023 +0100 - pua_dialoginfo: typo + core: accept ws and wss as advertised protocol -commit 7e8193ed2ea47623c6bf79e078bc6327caeba7c2 -Author: Дилян Палаузов -Date: Sat Dec 24 18:39:48 2022 +0200 +commit b9a49de69c9c184b7b3332a14ffaa85e60205ec2 +Author: Kamailio Dev +Date: Thu Nov 2 09:32:06 2023 +0100 - pua_bla: typo singular/plural + modules: readme files regenerated - tm ... [skip ci] -commit 0b460c80a6409c0a5a27b638999776e6c8a6fcb0 -Author: Дилян Палаузов -Date: Mon Dec 19 13:22:25 2022 +0200 +commit f8981605f01c755b963a9045a96e22398cca7201 +Author: Daniel-Constantin Mierla +Date: Thu Nov 2 09:29:41 2023 +0100 - pua: typo + tm: docs for t_reply_error() function -commit a9dade2b5db6077518c0940822d4154ef58f31c4 -Author: Дилян Палаузов -Date: Sat Dec 24 16:39:25 2022 +0200 +commit ae0b671c30f85d97883c1670928128e6c0d6cac7 +Author: Daniel-Constantin Mierla +Date: Thu Nov 2 09:25:39 2023 +0100 - presence_reginfo: typo fuNction + tm: new function t_reply_error() + + - send stateful reply based on internal error code -commit 9de462febb8a85302c741babdf5b0ef233f5fd6a -Author: Дилян Палаузов -Date: Sat Dec 24 16:39:15 2022 +0200 +commit c76444da502325c90eb7ac0cbcc24e7bf16dd5d1 +Author: Daniel-Constantin Mierla +Date: Wed Nov 1 08:55:29 2023 +0100 - presence_dialoginfo: typo fuNction + tm: update return code for EoH check failure -commit 192ab41af01a5ae225c6f4b7c14803f754b19b3d -Author: Дилян Палаузов -Date: Sat Dec 24 16:38:59 2022 +0200 +commit e34d41557e3a88cfb76571fb3f2793d85d264710 +Author: Daniel-Constantin Mierla +Date: Wed Nov 1 08:21:46 2023 +0100 - presence_conference: typo fuNction + core: new code for internal processing error -commit dba3b5d758fb69111d579fe441e958f4bbff87b4 -Author: Дилян Палаузов -Date: Sat Dec 24 22:39:51 2022 +0200 +commit 7e7aec0a8db7538a30ab7b932ad2fc0b401521b1 +Author: Kamailio Dev +Date: Tue Oct 31 20:17:18 2023 +0100 - presence: typos + modules: readme files regenerated - tls ... [skip ci] -commit afaec13cafbcf7e0dd7058457f699d5584fb0b1f -Author: Дилян Палаузов -Date: Sat Dec 17 14:19:53 2022 +0200 +commit d157aed3fc69d3584cb9e6ca0112e47ab917e88e +Author: Daniel-Constantin Mierla +Date: Tue Oct 31 20:04:34 2023 +0100 - pipelimit: typo unsuccesSful + tls: note about db_mysql module parameter opt_ssl_mode -commit 170771546bfb15f9f265373fc7f7a7d1cb2d684a -Author: Дилян Палаузов -Date: Tue Dec 27 11:36:10 2022 +0200 +commit 1e4bf66d37afcded52fcaa2a0dd61a87bb1f2c67 +Author: Daniel-Constantin Mierla +Date: Tue Oct 31 18:35:06 2023 +0100 - pike: typo build → built + core: error - better message for E_OUT_OF_MEM -commit 0f56abd0cd3596fed474d81ce291e0accb6ec7c1 -Author: Дилян Палаузов -Date: Sat Dec 24 16:32:43 2022 +0200 +commit 4a26208c4351e978671980dd9ccf18ee351dec0f +Author: Daniel-Constantin Mierla +Date: Tue Oct 31 14:56:27 2023 +0100 - permissions: space after comma + secsipid_proc: remove files imported from libsecsipid project + + - they should be found in libsecsipid install folders -commit dccba45e556409c480cda657f4ccfe3f712eb723 -Author: Дилян Палаузов -Date: Sat Dec 24 18:50:59 2022 +0200 +commit a2468e66f530822094569cf847796d91b17d4be9 +Author: Daniel-Constantin Mierla +Date: Tue Oct 31 14:54:54 2023 +0100 - p_usrloc: typos + secsipid_proc: Makefile - look for secsipid include and libs in localbase + + - done when pkg-config cannot find libsecsipid install details -commit 5d54a68bd06305fc722a14426ecd5d3866390134 -Author: Дилян Палаузов -Date: Tue Dec 27 11:35:26 2022 +0200 +commit f4d8235e5da98e7b99fdc1431505b44ee1672f63 +Author: Victor Seva +Date: Tue Oct 31 09:58:22 2023 +0100 - nat_traversal: typo build → built + secsipid: fix build errors for older versions of secsipid lib -commit e9c7513628b37d5920fcbf50236217f5d3228206 -Author: Дилян Палаузов -Date: Sat Dec 17 14:25:37 2022 +0200 +commit 9b63c3a7400bb255f102c786b914ea241e68bbab +Author: Kamailio Dev +Date: Mon Oct 30 13:33:19 2023 +0100 - nathelper: typo statefulLy + modules: readme files regenerated - secsipid ... [skip ci] -commit 3a630f40787577273a49e31f287f540d6672c7a2 -Author: Дилян Палаузов -Date: Sun Dec 18 22:10:11 2022 +0200 +commit 1cfd694e3bad62e9c4fc31073fcebe7707c5968c +Author: Daniel-Constantin Mierla +Date: Mon Oct 30 13:27:49 2023 +0100 - msilo: typos + secsipid: docs for secsipid_sign_prvkey() -commit 9512b0e465ab521dbefb7e914e72a2385dda5844 -Author: Дилян Палаузов -Date: Sat Dec 24 22:39:42 2022 +0200 +commit c8d56ed3afa19c29279e54fffd40b9810bb0d67c +Author: Daniel-Constantin Mierla +Date: Mon Oct 30 13:11:03 2023 +0100 - maxfwd: typo + secsipid: new config function to sign providing private key data -commit f9d0ecb8ad7085e16afe8f28d31c2c4e74bdfc07 -Author: Дилян Палаузов -Date: Tue Dec 27 11:34:51 2022 +0200 +commit 57de8b62025a3dedced7c3783b29f8c3517fdc36 +Author: Daniel-Constantin Mierla +Date: Mon Oct 30 13:03:47 2023 +0100 - mangler: missing space + secsipid_proc: updates for latest libsecsipid API + + - bind SecSIPIDSignJSONHPPrvKey(...) -commit 04c4b97d4bc1f09b6aa88b4c5dca7b1c63f66c68 -Author: Дилян Палаузов -Date: Sat Dec 24 18:51:24 2022 +0200 +commit 2bc2bdf2ff158510f4f570a1f5abe3f72745234c +Author: Daniel-Constantin Mierla +Date: Mon Oct 30 13:02:09 2023 +0100 - lrkproxy: typo + secsipid: extended interal API with SecSIPIDSignJSONHPPrvKey() -commit 1a3c580afdfd82f07b3c94fd33df037eddd38e5e -Author: Дилян Палаузов -Date: Sat Dec 17 14:19:11 2022 +0200 +commit 55b3ce67709e56be116bb7077931ba7f4c79dff5 +Author: Kamailio Dev +Date: Thu Oct 26 13:47:02 2023 +0200 - keepalive: typo unsuccesSful + modules: readme files regenerated - usrloc ... [skip ci] -commit f2938f16bb519a24584e38850e12fc22585bc41c -Author: Дилян Палаузов -Date: Sat Dec 24 16:40:39 2022 +0200 +commit c1bc5f7095659182401e6dd2b25bfaf7f963466a +Author: Daniel-Constantin Mierla +Date: Thu Oct 26 13:41:12 2023 +0200 - kazoo: typo fuNction + usrloc: docs for ka_reply_codes parameter -commit 7cf5a1cebae839c175a7ee7190cd6d23249775ed -Author: Дилян Палаузов -Date: Sat Dec 24 16:35:15 2022 +0200 +commit 8797e7454f5948c0c8166bf2b938a489b3092f2d +Author: Daniel-Constantin Mierla +Date: Thu Oct 26 13:34:51 2023 +0200 - jwt_admin: doc/jwt_generate - fix function declaration + usrloc: new parameter to specify reply codes for keepalive handling + + - comma separated list of reply codes or reply class to be considered + valid for keepalive handling -commit 8fbf69181c750f678ced602d45f187c2f2d55ec6 -Author: Дилян Палаузов -Date: Sat Dec 24 16:40:25 2022 +0200 +commit 9a50e380216b7557b53a2e8a0e4068f81ecf635e +Author: Daniel-Constantin Mierla +Date: Wed Oct 25 18:30:54 2023 +0200 - json: typo fuNction + usrloc: reformat exported structures to be more readable -commit 64786dbb33e6b24ed61d63a9ebcf0cdbeadc448b -Author: Дилян Палаузов -Date: Sat Dec 24 16:33:40 2022 +0200 +commit f97149aec9da71085df9dcf4541abba7b756939c +Author: Daniel-Constantin Mierla +Date: Wed Oct 25 18:06:36 2023 +0200 - ipops: typo singular/plural + dmq_usrloc: avoid needless second local socket search + + - remove overwriting local socket string value with received item -commit 920eb7208b5dd5a0b2504ff62eefc6236670d631 -Author: Дилян Палаузов -Date: Tue Dec 27 11:33:47 2022 +0200 +commit 19a32b863d9a79c0cbaf04a7a9864e0c08a914f7 +Author: Victor Seva +Date: Mon Oct 23 14:36:49 2023 +0200 - ims_usrloc_scscf: toggled comma-space + pv_headers: pvh_xavi_get_child() fix fallback logic + + * don't fallback to Initial request headers for Replies -commit e9e0e8aeaa7f6f7aca85f4368eb334a08b165c8c -Author: Дилян Палаузов -Date: Sat Dec 24 16:34:37 2022 +0200 +commit dc42a1892282ffb7a95f731224a9ae88ac16c17d +Author: Kamailio Dev +Date: Tue Oct 24 20:47:06 2023 +0200 - ims_registrar_scscf: 200OK → 200 OK + modules: readme files regenerated - http_client ... [skip ci] -commit 88d9d2ddfb6d813c2089794c77f638fc3852fb9a -Author: Дилян Палаузов -Date: Tue Dec 27 12:41:24 2022 +0200 +commit b882db36bbb7f7f13366bcc8f1db9f50910d2c0c +Author: Nicolas C +Date: Tue Oct 24 17:10:09 2023 +0200 - fixup ims_registrar_pcscf + http_client: Add parameter timeout_mode (timeout in seconds or milliseconds) + + A new parameter timeout_mode is added. + This parameter defines if timeouts are enabled, and in which unit timeout values are expressed. + - 0 - Timeouts are disabled. + - 1 - Timeout values are in seconds (default). + - 2 - Timeout values are in milliseconds. + + Implementation detail: + + default global timeout = 0 (unconfigured). + + Parse connections as usual. If they have a timeout configured, use it. + + In mod_init: + if global timeout == 0 (unconfigured), and timeout_mode is 1 or 2: + if timeout_mode == 1 -> global timeout = 4 (seconds) + if timeout_mode == 2 -> global timeout = 4000 (milliseconds) + + for each connection "conn" (fixup): + if timeout_mode is not 1 or 2 -> conn.timeout = 0 (to reflect the fact that no timeout will be handled) + else if conn.timeout is not configured -> conn.timeout = global timeout (in seconds or milliseconds, depending on timeout_mode). + + When doing Curl requests (curL_request_url): + if timeout_mode == 1: set CURLOPT_TIMEOUT + if timeout_mode == 2: set CURLOPT_TIMEOUT_MS -commit b254787c69ddc8973216ed674a98f41e1dd665a8 -Author: Дилян Палаузов -Date: Sat Dec 17 14:25:13 2022 +0200 +commit 4ec11b1a851d321959a0a38041bc7a6ea8107f39 +Author: Xenofon Karamanos +Date: Tue Oct 24 21:07:36 2023 +0300 - ims_registrar_pcscf: typo successfulLy + cdp: Add and apply cdp_openssl_clear_errors function (#3612) + + * cdp: Add and apply cdp_openssl_clear_errors function + - add new function to clear OpenSSL errors prior to any SSL_* call -commit dd99c7d5c67d0cabe1f825a0b4aa5e928f50863d -Author: Дилян Палаузов -Date: Sun Dec 18 13:24:57 2022 +0200 +commit 16378fd6435355749d9a6602769132be7ef0aa6d +Author: Daniel-Constantin Mierla +Date: Tue Oct 24 20:05:03 2023 +0200 - ims_dialog: typo this makeS sense + core: use advertised proto to build lump-based recv/send values -commit fc827e31027c171826f2ae4a55721632fe4bc3e3 -Author: Дилян Палаузов -Date: Sat Dec 17 14:18:49 2022 +0200 +commit 558afc14d71913214fa11c926f66ec2337a1ec3a +Author: Daniel-Constantin Mierla +Date: Tue Oct 24 17:18:11 2023 +0200 - ims_auth: typo succesSful + core: via builder can use proto from xavp fields or advertised address -commit 6b9d60a4a5d73cdcb3e46e40a7a856b1275ad005 -Author: Дилян Палаузов -Date: Tue Dec 27 11:31:10 2022 +0200 +commit 296ed155be83bc854507892f944748cb8864b704 +Author: Daniel-Constantin Mierla +Date: Tue Oct 24 17:16:16 2023 +0200 - imc: typo joininG + core: helper function to get proto id from str -commit 6d078c0fc0a3aa88f9af9f184c42b002a4d6c558 -Author: Дилян Палаузов -Date: Sat Dec 24 16:30:49 2022 +0200 +commit 309565b08f6294fdbd3d31163a73bd75a680a7e0 +Author: Morten Tryfoss +Date: Tue Oct 24 09:51:53 2023 +0200 - exec: typo variabLes + ims_dialog: Add function to get dialog by hash entry and id -commit 1453b2c6917f5b6b7f80a7bd7575a6fa54669640 -Author: Дилян Палаузов -Date: Sat Dec 24 19:34:46 2022 +0200 +commit 111d9f70cf55eca08b78e21213f3452fa8622d21 +Author: Konstantin Tumalevich +Date: Tue Oct 24 15:23:26 2023 +0600 - erlang: typo + app_ruby: Fix rpc documentation typo -commit 2766455c77db644692469b7a22f029560d5b1ae7 -Author: Дилян Палаузов -Date: Tue Dec 27 11:30:48 2022 +0200 +commit 7731fc3a1d793ffc7204e5c042a8bfc38d97e691 +Author: Henning Westerholt +Date: Tue Oct 24 11:13:36 2023 +0000 - domainpolicy: typo build → built + tls: add log line-break, increase buffer size (related to GH 3612 and GH 3607) -commit 255c34081bca441e17ae06ac8c16bddbb04fe577 -Author: Дилян Палаузов -Date: Tue Dec 27 11:30:27 2022 +0200 +commit 0a98a0d504f79cc6aa0cac13e2b30a00e6181636 +Author: Daniel-Constantin Mierla +Date: Mon Oct 23 10:41:48 2023 +0200 - dnssec: missing space + corex: read fmatch as str rpc parameter for shm.rprint -commit b3e1b3bbee181e3bfd4487c66bb63f7bedd00508 -Author: Дилян Палаузов -Date: Sat Dec 24 16:30:15 2022 +0200 +commit 1ebdc5c2dd7640b778c0efac2baafe1894a75b77 +Author: Daniel-Constantin Mierla +Date: Sun Oct 22 21:16:12 2023 +0200 - dlgs: typos + core: mem - print line after file name in qm_status_filter() -commit 809586788659c32fed73f5e6cb4eeaf824f21128 -Author: Дилян Палаузов -Date: Sat Dec 24 18:39:01 2022 +0200 +commit 338f848c2dedac837c09914dafd29e1d39c22842 +Author: Victor Seva +Date: Mon Oct 23 10:33:51 2023 +0200 - dialplan: typo + github: CODEOWNERS to protect workflows [skip ci] + + > https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners + > https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-codeowners-to-monitor-changes -commit b39af6aab4c1ec46dfaeda2387366cbb88ec3f09 -Author: Дилян Палаузов -Date: Sun Dec 18 13:24:50 2022 +0200 +commit e5ecb666abd24433b0de030980f79e2521439524 +Author: Daniel-Constantin Mierla +Date: Sat Oct 21 09:05:44 2023 +0200 - dialog: typos + topos: remove check of th_param_mask_callid() for api callid masking + + - functions are not for topoh internal usage, but for intermodule API + - reported as part of GH #3606 -commit 11591861fd1af1b83329f8cb6db42948663805c3 -Author: Дилян Палаузов -Date: Sat Dec 24 16:16:42 2022 +0200 +commit 37aa5b5f885d9c6a4915a3b3283d3cbbc04ecedd +Author: Daniel-Constantin Mierla +Date: Sat Oct 21 09:03:45 2023 +0200 - db2_ops: space after comma + core: set shm xsetfunc api field + + - fix wrong variable added in previous commit for pkg api -commit f6a8f43482df5169ee778295d83f4ac781eb6698 -Author: Дилян Палаузов -Date: Sat Dec 24 18:49:10 2022 +0200 +commit e4f2cde596387cc81ff0a26d89654d9d0e24ae10 +Author: Daniel-Constantin Mierla +Date: Fri Oct 20 21:45:16 2023 +0200 - db2_ldap: typos + core: mem - set xstatus_filter api field -commit 1ebda62a4fb85d6d742bc5da518f8348af67e62e -Author: Дилян Палаузов -Date: Tue Dec 27 11:30:13 2022 +0200 +commit 664a788e9ed40c72f34310e65a5b6b85f80eead3 +Author: Kamailio Dev +Date: Fri Oct 20 20:16:19 2023 +0200 - db_text: typo singular/plural + modules: readme files regenerated - ims_dialog ... [skip ci] -commit 3b39da405b8ddf1153bd883db4f7014a8d0aab5c -Author: Дилян Палаузов -Date: Sat Dec 24 16:15:42 2022 +0200 +commit cd54fdde0572c62dc26fb8a8d11ddf60073a67a9 +Author: Morten Tryfoss +Date: Fri Oct 13 10:05:09 2023 +0200 - ctl: typos + ims_dialog: Add support for database backend -commit 972176b06a2004c60af212ef5824173bddf7c8f5 -Author: Дилян Палаузов -Date: Sat Dec 24 16:15:28 2022 +0200 +commit 54868f83f09691a5283a0d7eb57e230e7b8a2514 +Author: Daniel-Constantin Mierla +Date: Fri Oct 20 16:48:33 2023 +0200 - cplc: typos + corex: rpc corex.list_sockets prints advertise as full socket string + + - new field to print socket string field also for bind address -commit 84876ec6c5b0b3ddad5cc2ebe588b883d1158988 -Author: Дилян Палаузов -Date: Sat Dec 24 22:39:28 2022 +0200 +commit 54d8cce28a5c4cbd944d39b1523571fbb5776baa +Author: Daniel-Constantin Mierla +Date: Fri Oct 20 16:39:08 2023 +0200 - corex: typo + core: use advertised proto to build advertised sock string -commit 8178106a7a0a8ccd39f95565b144b21a381a3130 -Author: Дилян Палаузов -Date: Sat Dec 24 18:47:40 2022 +0200 +commit b6148ef161a8652b398080ec136e207fb6ee3b1a +Author: Daniel-Constantin Mierla +Date: Fri Oct 20 15:53:39 2023 +0200 - cfgutils: typo + corex: rpc corex.list_sockets use now lowercase for field names -commit 721bb93454d914b972e4d021de238b85342867d9 -Author: Дилян Палаузов -Date: Sat Dec 24 18:47:26 2022 +0200 +commit e5c145f69508658a692be9be219f466ee2aca5d9 +Author: Daniel-Constantin Mierla +Date: Fri Oct 20 14:55:53 2023 +0200 - cdp: typo + corex: rpc corex.list_aliases use now lowercase for field names + + - better coherence with the other rpc commands -commit e051cc907b3c4c452069e154aa4d239a0d969257 -Author: Дилян Палаузов -Date: Tue Dec 27 11:29:29 2022 +0200 +commit c2e8baad3b39b2e5871c0cdc796b3be48462c2a9 +Author: Daniel-Constantin Mierla +Date: Fri Oct 20 14:51:17 2023 +0200 - carrierroute: missing space + core: allow proto in advertise for a couple of listen variants -commit b920b8f267622280f307bc8cb12e3f9fbe73ae39 -Author: Дилян Палаузов -Date: Tue Dec 27 11:29:15 2022 +0200 +commit fe8eafd31327c14e7b081cd8f4a6532953e0a1c6 +Author: Daniel-Constantin Mierla +Date: Fri Oct 20 10:34:21 2023 +0200 - avpops: typo singular/plural + tls: include file to fix warning about tls_openssl_clear_errors() -commit 80ec8f8b0f5962f3e5dbd4e299d67a480e6c2f0f -Author: Дилян Палаузов -Date: Sat Dec 24 18:53:52 2022 +0200 +commit 91eca5aaa20f7b22488b14fdf89127daaeea47d3 +Author: Daniel-Constantin Mierla +Date: Thu Oct 19 18:30:58 2023 +0200 - avp: space after comma + core: print advertised proto on startup -commit 74467e57443e0550a53020c5248c04648bb46e0a -Author: Дилян Палаузов -Date: Tue Dec 27 11:27:45 2022 +0200 +commit 91c31a8e406b84ef026def7fcec0d429356e424d +Author: Kamailio Dev +Date: Fri Oct 20 10:02:17 2023 +0200 - auth_diameter: typo - build → built + modules: readme files regenerated - rtpproxy ... [skip ci] -commit 2e8f9829d360b22e611d5241fc034c26dcee4c2b -Author: Дилян Палаузов -Date: Sat Dec 17 14:24:41 2022 +0200 +commit 190ef9a54df33b4d053a4225e9d6257e0a045008 +Author: Maksym Sobolyev +Date: Tue Oct 10 11:23:49 2023 -0700 - auth: typo statefulLy + rtpproxy: Update rtpproxy module documentation. + + o Correct description of the timeout_socket; + + o Document timeout_tag_pv; + + o Update (c); + + o Remove reference to the ngcp-mediaproxy-ng which does not exist + anymore. -commit d50905a2ee368e07c814939434e7cbeecb5d4b9b -Author: Дилян Палаузов -Date: Sat Dec 24 19:10:47 2022 +0200 +commit 8ac570943f1dfd47f9d02686cc399d3cd1cdcd92 +Author: Maksym Sobolyev +Date: Tue Oct 10 11:21:31 2023 -0700 - app_sqlang: typo dor → does + rtpproxy: Make timeout notification feature useable. + + Add an new "timeout_tag_pv" option to set notify tag along + with the notification socket path. Both are required by the + RTPProxy. + + Reported by: James Lipski -commit 5609b064bf53f2458c2eaf4468cc01aa9510f735 -Author: Дилян Палаузов -Date: Tue Dec 20 07:52:43 2022 +0200 +commit f27eda6fe3d99d1352d4df86d79e4646b0a4c17a +Author: Victor Seva +Date: Tue Oct 17 14:12:57 2023 +0200 - app_perl: typos + presence: active_watcher cleanup timer + + related #3074 -commit bd573ddda9df163b53fe2cccd72010bc42b87da1 -Author: Дилян Палаузов -Date: Sat Dec 24 19:31:40 2022 +0200 +commit 110ebbafadcc225f4e88749287f06ae29a6cfa2e +Author: Xenofon Karamanos +Date: Thu Oct 19 12:18:38 2023 +0000 - app_lua: typo + tls: Add and apply tls_openssl_clear_errors function -commit db1dbfb5cd455ce852ea8d77caccea417c4a6892 -Author: Дилян Палаузов -Date: Sat Dec 24 16:09:38 2022 +0200 +commit 5077127b0fe1a2d803e42abe19cfcd93339f0519 +Author: Juha Heinanen +Date: Thu Oct 19 13:36:32 2023 +0200 - alias_db: space after comma + core: change tcp_check_timer initialization + + - make tcp_check_timer default to depend on tcp_msg_data_timeout and + ksr_tcp_msg_read_timeout values, set to half of the minimum of the + two, it is not explicitely set + - GH #3608 -commit d66b3fa5b7d00707d78d7023e4ac034951895be5 -Author: Дилян Палаузов -Date: Tue Dec 27 11:27:03 2022 +0200 +commit 976da8c72e9a056b724f584a803a4a8114f70d30 +Author: VoIPNuggets.com +Date: Tue Oct 17 19:19:48 2023 +0530 - acc_diameter: typo - build → built + tools: route_graph - added README file and updated reference URL [skip ci] -commit 06ffb667b7fa4672cb9c7701d476047f5ec6db09 -Author: Дилян Палаузов -Date: Sat Dec 24 16:38:35 2022 +0200 +commit 93fc6bc9c965391aa1e4ca546119ce2cc8699fbd +Author: Kamailio Dev +Date: Wed Oct 18 10:02:28 2023 +0200 - acc: typo fuNction + modules: readme files regenerated - topos ... [skip ci] -commit e6bdf6579a800377786b054957f68fc1535bb1e8 -Author: Дилян Палаузов -Date: Sat Dec 17 12:56:52 2022 +0200 +commit d2f0e1c31920e5b2b38ddbc823c6bc332fac86a5 +Author: Henning Westerholt +Date: Wed Oct 18 07:54:44 2023 +0000 - misc/examples: update comments + topos: spelling fix in docs -commit d7061b4aaeb84d1edf2b5144734729ed72e2ea85 -Author: Дилян Палаузов -Date: Tue Dec 20 07:52:24 2022 +0200 +commit ac69e7d7e65d2e65bc182d189ece8df28acfc5c3 +Author: Victor Seva +Date: Wed Oct 18 09:50:11 2023 +0200 - doc/tutorials: typos + github: codeql remove downloaded packages [skip ci] -commit 509bd8e8f37996202442759acc2a92537ba0ca7f -Author: Дилян Палаузов -Date: Tue Dec 27 11:23:38 2022 +0200 +commit 70ff7c298f257bec48809b9bc80fd06cfe87c7b4 +Author: Victor Seva +Date: Wed Oct 18 09:41:01 2023 +0200 - lib/srdb1: add missing spaces + github: disable CodeQL scan for pull requests [skip ci] + + job is failling due to "java.io.IOException: No space left on device" -commit d712a568f3cc49cd724d0b6d24c70f0b407e0c6b -Author: Дилян Палаузов -Date: Sun Dec 18 10:41:21 2022 +0200 +commit 4747f724325e69033a052d078b161186dc2e5c21 +Author: Victor Seva +Date: Tue Oct 17 14:19:01 2023 +0200 - lib/ims: typos succesS + presence: clang-format -commit 7799920ef6074e466e265f003a3b605da2dca388 -Author: Дилян Палаузов -Date: Tue Dec 20 06:54:57 2022 +0200 +commit b7b3f75537e9d816833b3718b7f6290a655c9f45 +Author: Kamailio Dev +Date: Mon Oct 16 15:46:34 2023 +0200 - lib/cds: typo asSigned + modules: readme files regenerated - ims_qos ... [skip ci] -commit a8976a5ad77a2ca5ec21acf3f892c59b226715bc -Author: Дилян Палаузов -Date: Sat Dec 17 12:54:52 2022 +0200 +commit 672b72d65aba0b30fb363d60ab648f9705810ba7 +Author: Henning Westerholt +Date: Mon Oct 16 13:36:42 2023 +0000 - core: typos + ims_qos: spelling fix for suspend_transaction docs, more sensible value for example docs -commit c181362533ca2c7178218aa5b3724219d5deb58c -Author: Olle E. Johansson -Date: Wed Dec 21 14:57:01 2022 +0100 +commit 319df7fc417e898e945cac0d44e978c9ff151e3c +Author: Daniel-Constantin Mierla +Date: Mon Oct 16 10:46:34 2023 +0200 - DMQ: Add debug line when creating list and adding first notification address + jwt: use proper internal function for jwt_verify_key() -commit 5c90e6e2885a60a1dc5de5ff697c93d6fe59a9cb -Author: Olle E. Johansson -Date: Wed Dec 21 14:54:34 2022 +0100 +commit 241127c5f0820614a3e2ac1467e9f8cb8a0eeb23 +Author: Daniel-Constantin Mierla +Date: Mon Oct 16 09:09:08 2023 +0200 - DMQ: dmq_notification_address_list is initialized to NULL + core: added tcp_accept_iplimit parameter - This code led to random and unpredictable behaviour when loading a configuration with - multiple notification nodes. + - set limit for accepted connections from the same ip address + - default 1024 -commit 507a6ce2206cf31129fc0cb64a115b2e68493a2d -Author: Olle E. Johansson -Date: Tue Aug 16 08:53:15 2022 +0200 +commit 213e19108699ed4ea5c962caf673b0a60ce41480 +Author: Daniel-Constantin Mierla +Date: Mon Oct 16 08:57:32 2023 +0200 - http_client: Add SPDX identifiers + core: added tcp_msg_data_timeout parameter + + - duration in seconds for how long to wait till data is received on a + new tcp connection + - default 20 -commit 7712a856776d5cd9edec62bccc4b37bfd2ec2b8b +commit 1acede64041307b783ed90736ca114917bafbc14 Author: Daniel-Constantin Mierla -Date: Wed Dec 21 15:21:03 2022 +0100 +Date: Mon Oct 16 08:35:09 2023 +0200 - app_ruby_proc: new function to handle error from ruby + core: added tcp_check_timer parameter + + - set the check interval (in seconds) for tcp connections + - default 10 -commit a33c9bb24f01195c5654e9699079eb3d4548692e +commit 92feec4fa026a153d1f9ed79e5893bf1086db909 Author: Daniel-Constantin Mierla -Date: Tue Dec 20 11:17:07 2022 +0100 +Date: Sun Oct 15 19:20:13 2023 +0200 - core: utils/tmrec - removed unused function + core: added tcp_msg_read_timeout parameter + + - specify read timeout for tcp messages -commit 0f3ce4029ee1f52804566dc945c7e0914f01405d +commit b56037fab181037d48bfc90802f25b85ae8bee04 Author: Daniel-Constantin Mierla -Date: Tue Dec 20 11:15:30 2022 +0100 +Date: Sat Oct 14 16:49:20 2023 +0200 - cplc: removed unused function + core: added msg_recv_max_size global parameter + + - set limit for max size of received tcp or upd messages -commit 5fedf169d256e7e24fe2ce2b593af9a865ac9578 -Author: Kamailio Dev -Date: Tue Dec 20 10:46:41 2022 +0100 +commit a902e4a032a85a7755de32eeadac800a1312e64f +Author: Daniel-Constantin Mierla +Date: Fri Oct 13 17:33:07 2023 +0200 - modules: readme files regenerated - app_ruby ... [skip ci] + core: tcp - limit number of accepted connections per src ip + + - default 1024 -commit 4b5cdf184a77e60d75f1ddf1cd666c6f36a76d48 +commit ddfe15f860555048f1ad6884727d4eb52f11910f Author: Daniel-Constantin Mierla -Date: Mon Dec 19 21:36:11 2022 +0100 +Date: Fri Oct 13 16:36:39 2023 +0200 - app_ruby: docs updated for xval_mode param + core: tcp - exclude crlf ping from data exchage state -commit 599c75a5d0988ee0dd78f524cd348900d1ee5448 +commit ef86402d2397ff7b0416bc17ab0a2ba906402215 Author: Daniel-Constantin Mierla -Date: Mon Dec 19 21:33:15 2022 +0100 +Date: Fri Oct 13 16:31:10 2023 +0200 - app_ruby: xval_mode set to 1 + core: tcp - close connection without data traffic at all + + - default timeout: 20sec + - cleanup is done on timer, it can take another 10sec -commit bcb37da492fad5c6811784370cfd25cb5efdcf64 -Author: S-P Chan -Date: Mon Dec 19 11:58:09 2022 +0800 +commit f5b46efc3a97aa45d090f46990a40bcc9dd91390 +Author: Daniel-Constantin Mierla +Date: Fri Oct 13 16:02:12 2023 +0200 - tlsa: add clarification comment about LIBSSL_STATIC_SRCPATH - - * if LIBSSL_STATIC_SRCPATH is set to the installation folder - of libssl.a and libcrypto.a, - then headers will be in $LIBSSL_STATIC_SRCPATH/../include + core: tcp - set limit for reading a message - * this covers the case where tlsa is built on a system with a local - installation of OpenSSL without the source code available + - default 10sec - if message is not read, close connection + - cleanup is done on timer, it can take an additional 10sec to clean up + connection -commit 681ff651ce5c0594adc0919c4a0a76e1931c981d -Author: S-P Chan -Date: Mon Dec 19 11:36:14 2022 +0800 +commit 2df623c78fd8605b9f7f936efc4cb2011d0a60b5 +Author: Victor Seva +Date: Fri Oct 13 12:42:35 2023 +0200 - tlsa: OpenSSL usually installs lib/|lib64/ and include/ as siblings + github: fix cleanup perms [skip ci] -commit 1ae17634deab601e0ef87c9759481bbd388031ec -Author: S-P Chan -Date: Mon Dec 19 05:24:35 2022 +0800 +commit 097295616f6387d192c5774ce7fc1a95b1913542 +Author: Victor Seva +Date: Fri Oct 13 12:35:35 2023 +0200 - tls_wolfssl: update build flags + github: move cleanup of untagged packages to its own workflow [skip ci] -commit 51bda43f5ebcbd239c986e80bb7a4ffeabf0d3c0 -Author: S-P Chan -Date: Mon Dec 19 04:46:03 2022 +0800 +commit 5632d34677eb9d6feeacda9dba12244f0c5de838 +Author: Victor Seva +Date: Fri Oct 13 10:13:06 2023 +0200 - tls: clean up trailing whitespace + github: allow trigger actions manually from panel [skip ci] -commit a21e99ac92d2f19e1fe478f7b62fc2082473a7bf -Author: S-P Chan -Date: Mon Dec 19 04:41:24 2022 +0800 +commit 7f4fdfa61444ab38b49b74829a40d9ec6d1e050a +Author: Victor Seva +Date: Fri Oct 13 09:54:08 2023 +0200 - tls_wolfssl: clean up trailing whitespace + pkg/kamailio/alpine: switch to pcre2 [skip ci] -commit b3f20baaa8e7b26de890285329929d539e6f936c -Author: S-P Chan -Date: Mon Dec 19 04:17:53 2022 +0800 +commit 2f212ba4deab4841382690eed08f9afcae1ec46f +Author: Daniel-Constantin Mierla +Date: Thu Oct 12 17:46:00 2023 +0200 - tls_wolfssl: updated for avp long value field + core: added proto file to use info structure - * match commit 6a22d4168a for tls/ + - can be set via socket global parameter structure -commit 5b9651d31dcbe915e813f35fe330b41652e29578 -Author: S-P Chan -Date: Mon Dec 19 04:15:21 2022 +0800 +commit 4045f3d7c0302ae47f0d6c2160160767d56826eb +Author: Morten Tryfoss +Date: Wed Oct 11 12:40:16 2023 +0200 - tls_wolfssl: switch to long pvar field - - * match commit 17bc73c9dc for tls/ + cdp: changed format -commit 79862f37fdd81c1f9397d7a393bc780b0ea92915 -Author: S-P Chan -Date: Mon Dec 19 04:08:32 2022 +0800 +commit 8d84c6210fa7071d3ea96f219d486cc1b41dc119 +Author: Morten Tryfoss +Date: Wed Oct 11 12:32:09 2023 +0200 - tls_wolfssl: update wolfSSL to v5.5.3-stable + cdp: Disable TLS support for openssl versions older than 1.1.0 -commit 5b7a915cd496007dde289b71d3e7274a54ac0b20 +commit 54c18ebb4b471af95aa403a81d4a37b71c9c4a14 Author: Daniel-Constantin Mierla -Date: Sat Dec 17 18:43:29 2022 +0100 +Date: Tue Oct 10 22:10:00 2023 +0200 - kamcmd: updates to rpc command names + core: mem/shm - wrapper marcro to check if xsetfunc is implemented -commit a5f69e46613af05097debf1c373a138dd69fbdaf -Author: Kamailio Dev -Date: Sat Dec 17 13:31:18 2022 +0100 - - modules: readme files regenerated - registrar ... [skip ci] - -commit 49f42b36b586a2b08b9f5a327263bfa9124df77b -Author: Дилян Палаузов -Date: Sat Dec 17 12:56:52 2022 +0200 - - misc/examples: update comments - -commit 9cff22564db3664faa7b4b5bef86f5f71ff87bc8 -Author: Дилян Палаузов -Date: Sat Dec 17 12:54:52 2022 +0200 +commit d1d14f9b832401f8282b4e6ade9cfe7ea1751e6a +Author: Victor Seva +Date: Wed Oct 11 11:23:38 2023 +0200 - core: typo instaNces + pkg/docker: submodule update [skip ci] -commit c738a65c2fd0a40c3cdc236a3d3b48b0d18add21 -Author: Дилян Палаузов -Date: Sat Dec 17 12:54:30 2022 +0200 +commit 65ccf80c90e007d7636e973009d8cb2446cd8821 +Author: mtryfoss +Date: Tue Oct 10 14:01:38 2023 +0200 - registrar: typo + smsops: avoid c99 error (#3597) -commit 877f1b47fddf4979222c30781fc34f7b53250bdd +commit a86db7b642feaf4bb7367280463a9b22e33ffae5 Author: Kamailio Dev -Date: Fri Dec 16 19:32:17 2022 +0100 - - modules: readme files regenerated - acc ... [skip ci] - -commit 5e7c0dfc626117f9069846cc791bacb5371c0346 -Author: Дилян Палаузов -Date: Mon Dec 12 19:29:35 2022 +0200 - - xmlrpc: typos an → and +Date: Mon Oct 9 14:16:24 2023 +0200 -commit 4a11beabb586f8615e3518456642088cf398de29 -Author: Дилян Палаузов -Date: Mon Dec 12 19:45:49 2022 +0200 - - xcap_client: typos a/an + modules: readme files regenerated - corex ... [skip ci] -commit aeb5d17914d8674bd6d4769b8c695fd775ceeea5 -Author: Дилян Палаузов -Date: Mon Dec 12 19:41:25 2022 +0200 +commit 6e02521739992a4e7dde0ebfae71186b8e866624 +Author: Daniel-Constantin Mierla +Date: Mon Oct 9 14:07:28 2023 +0200 - usrloc: typos a/an + corex: docs for shm.rprint rpc command -commit 3559be38f361ce58330d9f20248774200248362f -Author: Дилян Палаузов -Date: Mon Dec 12 20:00:16 2022 +0200 +commit 8f3d76e9808024bff1d816acddeb81667e1df0d2 +Author: Daniel-Constantin Mierla +Date: Mon Oct 9 13:51:47 2023 +0200 - userblocklist: typos a/an allowlist + corex: rpc command to print shm status report to file based on filter -commit 435f39330bc1534cde53501df3e87cfd21f00899 -Author: Дилян Палаузов -Date: Mon Dec 12 21:22:51 2022 +0200 +commit 2b899606dd56b841d57eb5bbd94725bd6e5c184d +Author: Daniel-Constantin Mierla +Date: Mon Oct 9 13:48:33 2023 +0200 - uid_uri_db: typo a/an backwards incompatible + core: mem - qm_status_filter - change filter from start-with to include -commit 74dbc074740b3173ac74c8a3a4b97272ff97c7ba -Author: Дилян Палаузов -Date: Mon Dec 12 21:23:08 2022 +0200 +commit 18b23187dd89e3b36c0dd95d4796484bef3d2e62 +Author: Daniel-Constantin Mierla +Date: Fri Oct 6 13:48:42 2023 +0200 - uri_db: typo a/an backwards incompatible + pkg/kamailio/scripts: wrap param around quotes to avoid invalid syntax on empty -commit b2ead7fc6356e0d4479217ddc713cbcb9edfebc2 -Author: Дилян Палаузов -Date: Mon Dec 12 21:22:27 2022 +0200 +commit f16ec35fa448d03613e6bbbff4c354012f56073e +Author: Daniel-Constantin Mierla +Date: Fri Oct 6 12:32:53 2023 +0200 - uid_domain: typo a/an backwards incompatible + kamdbctl: check if kamctlrc is readable -commit 4639db37a599e31cdabadcca29a28345d01e4109 -Author: Дилян Палаузов -Date: Mon Dec 12 21:22:05 2022 +0200 +commit 0518410eea14f8949260faec5fb70c97badaa74e +Author: Victor Seva +Date: Fri Oct 6 12:25:08 2023 +0200 - uid_avp_db: typos a/an extra + pkg/docker: submodule update [skip ci] -commit 793da45e083713f958b8ca33f99fad67f82b3a5a -Author: Дилян Палаузов -Date: Mon Dec 12 21:21:43 2022 +0200 +commit 9de780b8a7a1ac4c3a936b86d324c9a5f1527e3d +Author: S-P Chan +Date: Thu Oct 5 10:55:26 2023 +0800 - uac: typos a/an PV; is send → sent + pkg: RPM - add mock config for EL8/EL9 based on alma+epel-(8|9)-x86_64 + + This mock config can be used to build RPM packages from a kamailio src.rpm. + - update pkg/kamailio/obs/README -> README.md to include mock + instructions + - add script create-src-rpm.sh to create src.rpm for package + building -commit 861ba0a277f276c577d3d3234c75265b548e09e0 -Author: Дилян Палаузов -Date: Mon Dec 12 19:46:21 2022 +0200 +commit aed35ddb6aac8d12cdd60b07ce5bbc1e57a71b94 +Author: S-P Chan +Date: Thu Oct 5 09:45:23 2023 +0800 - tm: typos a/an + pkg: add example script to create tarball with submodules instantiated + + In preparation for packaging of tls_wolfssl, add an example script to + create source tarball with submodule code. -commit 6d8acd1632156f733bff2c7b7ef94789dfcf8a17 -Author: Дилян Палаузов -Date: Mon Dec 12 20:07:18 2022 +0200 +commit a3fd3b12ca9b1c3688255e9d645085947052bc6d +Author: Daniel-Constantin Mierla +Date: Fri Oct 6 08:19:18 2023 +0200 - tls: typos a/an + kamctl: check if kamctlrc is readable + + - related to GH #3594 -commit cabb462bfbc6a1fc9c5dc59c882b6199217be1a7 -Author: Дилян Палаузов -Date: Mon Dec 12 20:07:42 2022 +0200 +commit e01d1cbfb61e0111a4f73e58e36a2bd689a2f91f +Author: Victor Seva +Date: Fri Oct 6 00:43:23 2023 +0200 - sst: typos a/an + github: define DOCKER_REPO at alpine workflow [skip ci] + + > https://github.com/kamailio/kamailio-ci/commit/524fa4769d3b48add204c2bbd8303f60dfde2d61 -commit 14aeceffebd5f093ae9f23287b7b74b34c2936ca -Author: Дилян Палаузов -Date: Mon Dec 12 20:05:20 2022 +0200 +commit 022f0f4cfd49e7a46efb2b6b4e1b9640c399e535 +Author: Daniel-Constantin Mierla +Date: Thu Oct 5 18:05:00 2023 +0200 - snmpstats: typos a/an + misc/examples/kemi: add the option for using rtpengine in common cfg file + + - updated lua script removing the check of rtpproxy define, not being in + the commng cfg file -commit 18cbc0fa0a1839b01b3d0134bd593372ab95818e +commit f04f8539fccfc2afefb5e0badb4747adead2e378 Author: Дилян Палаузов -Date: Mon Dec 12 20:13:35 2022 +0200 +Date: Sun Oct 1 14:53:59 2023 +0200 - siputils: typos a/an + examples/kamailio-basic-kemi-lua.lua: Add example for rtpengine -commit 3b31fbe6090e46cf87cb27039589d7774a94939e -Author: Дилян Палаузов -Date: Mon Dec 12 21:21:18 2022 +0200 +commit ec14d7094374f6cb6184c997ec35951ba0134933 +Author: S-P Chan +Date: Thu Oct 5 01:22:24 2023 +0800 - sipt: typos a/an ISUP + tls_wolfssl: update to v5.6.3-stable of wolfSSL -commit dcd357649571d32e2d2689ab332ffe9590b3f44f -Author: Дилян Палаузов -Date: Mon Dec 12 21:21:03 2022 +0200 +commit a327cc0e3e0a2d99680840667ba2985857fbe7fa +Author: S-P Chan +Date: Thu Oct 5 00:58:57 2023 +0800 - sipcapture: typos a/an listen + tls_wolfssl: clean up build + + Allow module to build if user specifies prefix= exec-prefix= on + commandline -commit 48f9b1f6cb57096a1d6c1a9d6bebd8275fd00a97 -Author: Дилян Палаузов -Date: Mon Dec 12 20:29:07 2022 +0200 +commit ac0ecee2932f4dc1243847ece4d03d27601778a8 +Author: Victor Seva +Date: Wed Oct 4 15:43:05 2023 +0200 - seas: typos a/an + github: move permissions definitions to jobs [skip ci] -commit d9bdb46f98f4ff047e05e0dbebb5b8099c37aaec -Author: Дилян Палаузов -Date: Mon Dec 12 20:32:40 2022 +0200 +commit d9111c6978cdbb2742eb1ea7fd16dcb083a2c6f4 +Author: Daniel-Constantin Mierla +Date: Wed Oct 4 10:21:44 2023 +0200 - rtpproxy: typos a/an + pv: removed unnecessary break -commit 550a46a6bd432cd15307fd50e027ce153252be70 -Author: Дилян Палаузов -Date: Mon Dec 12 20:32:14 2022 +0200 +commit b5cf0da2fbae5ed0b887b0323b8bf8a44e29d80d +Author: Daniel-Constantin Mierla +Date: Wed Oct 4 09:46:37 2023 +0200 - rtpengine: typos a/an + pv: return via variable oc value as it is -commit bcf5f74e3358ac525eff0be41f3f8a6cef76fc6a -Author: Дилян Палаузов -Date: Mon Dec 12 21:20:38 2022 +0200 +commit d2d17049b5e82b497c44b6b4a2a461917eaed4bb +Author: Victor Seva +Date: Tue Oct 3 08:45:56 2023 +0200 - rls: typos a/an + github: move login to ghcr.io on top [skip ci] -commit 78a60f39c74d89f84abccad23aa4fe5dbd3f5dd4 -Author: Дилян Палаузов -Date: Mon Dec 12 21:20:17 2022 +0200 +commit 2bf06119773761ceb1446d3742c158d7f29fbda1 +Author: Victor Seva +Date: Tue Oct 3 08:39:05 2023 +0200 - registrar: typo double a + github: define alpine permissions [skip ci] + + > unauthorized: access token has insufficient scopes -commit 04fa3a2e6a8c5c45e1ebb7d6b9c14b61e55448b4 -Author: Дилян Палаузов -Date: Mon Dec 12 21:16:42 2022 +0200 +commit 6b6c0663d3ae894e8e686eb32288f71387739cc7 +Author: Daniel-Constantin Mierla +Date: Mon Oct 2 11:48:41 2023 +0200 - ratelimit: typo a/an Kamailio + corex: reformat exports structures -commit 063d06b78c88eb3d7727cba369089481847bb7de -Author: Дилян Палаузов -Date: Mon Dec 12 21:18:56 2022 +0200 +commit 0f4058a7ff0abb59785d2d1dd3e65517ab4ceaa4 +Author: Daniel-Constantin Mierla +Date: Mon Oct 2 11:01:44 2023 +0200 - rabbitmq: typo a/an new + core: check if status with filter is implemented by memory manager -commit 64a0f0d99c0de9a60b73010cbc87e4a81b655f3e -Author: Дилян Палаузов -Date: Mon Dec 12 21:18:34 2022 +0200 +commit f221a3eaf29b78671fb1c603813fe7e6c2314fbf +Author: Daniel-Constantin Mierla +Date: Fri Sep 29 15:53:41 2023 +0200 - pv: typo a/an parameters string + core: mem - defines for pkg/shm status filter functions -commit 4756758b30faf5e106f8b9cfe7f762a27e2e1ff9 -Author: Дилян Палаузов -Date: Mon Dec 12 21:18:03 2022 +0200 +commit 7018e978b5c6fa3ac42a64985bb6bac24b7aab27 +Author: Daniel-Constantin Mierla +Date: Fri Sep 29 13:48:43 2023 +0200 - pua_dialoginfo: typo a/an dialog-info + core: mem - api function to print status with filter -commit 10a7e7735b2f85cd0fce6fb4a305222fcf980f21 -Author: Дилян Палаузов -Date: Mon Dec 12 21:17:38 2022 +0200 +commit 1947763c176f33bcd3cbdfc54d980648855dff8a +Author: Kamailio Dev +Date: Thu Sep 28 15:46:23 2023 +0200 - pua: typo a/an transaction + modules: readme files regenerated - ims_qos ... [skip ci] -commit 3cff94c3d5fd2d93e466207182023c42b0945cec -Author: Дилян Палаузов -Date: Mon Dec 12 21:17:15 2022 +0200 +commit 21a685a200e1ff638358dbbee607d4ab55c57359 +Author: Stefan-Cristian Mititelu +Date: Thu Sep 28 16:42:54 2023 +0300 - presence_dialoginfo: typo a/an signed + ims_qos: Rename new parameter's C variable -commit 069b7bde2ba133c4cab4dc976dc064c77f66239d -Author: Дилян Палаузов -Date: Mon Dec 12 21:15:39 2022 +0200 +commit d0262f82fd9cee8670ac01e4f06eb35626b34714 +Author: Stefan-Cristian Mititelu +Date: Wed Sep 20 12:17:50 2023 +0300 - presence: typos a/an + ims_qos: Add suspend_transaction parameter -commit 3e4e735cb78e3d0ed5aeb4da64bdb01a54e36a28 -Author: Дилян Палаузов -Date: Mon Dec 12 21:14:12 2022 +0200 +commit 1bb1ba60992ffa35e8d36ed1dab98fdc36a2ea30 +Author: Daniel-Constantin Mierla +Date: Thu Sep 28 09:03:50 2023 +0200 - pike: typo a/an IP node + core: dns cache - warnings on put for unlinked items -commit e2dda4d4e4d3201080d0a94e534aa320d8e80a95 -Author: Дилян Палаузов -Date: Mon Dec 12 20:30:04 2022 +0200 +commit 27f87c06edfb0a09d745e4341535788fdfbb2be1 +Author: Daniel-Constantin Mierla +Date: Wed Sep 27 08:00:02 2023 +0200 - permissions: typos a/an + etc/kamailio.cfg: update version in comments -commit 29b3f25fa63ef3de9c2b0c8e571e9a1b37a64f93 -Author: Дилян Палаузов -Date: Mon Dec 12 20:35:00 2022 +0200 +commit e4b9157a4be5ceaf9afee3000bb186d2cf59e41d +Author: Victor Seva +Date: Tue Sep 26 23:41:02 2023 +0200 - peering: typos a/an + pkg/kamailio/deb: remove ims module from stretch and xenial [skip ci] + + * libssl >= v1.1.1 is required -commit dd02862266a42fd22ef93f2788648c3a3c78ae95 -Author: Дилян Палаузов -Date: Mon Dec 12 21:13:50 2022 +0200 +commit d8a35b3b6c837b36779e232b65fce61c3aa93387 +Author: Daniel-Constantin Mierla +Date: Tue Sep 26 20:20:56 2023 +0200 - pdt: typo a/an entry + core: dns cache - warn messages on safety checks for items -commit a93b757ea092db2e6e6b1cc89a3e7ddb2fb5c757 -Author: Дилян Палаузов -Date: Mon Dec 12 21:12:51 2022 +0200 +commit 6f332ba8329f1dcbeeb00badc499580eb1ff98cf +Author: Daniel-Constantin Mierla +Date: Tue Sep 26 13:30:56 2023 +0200 - pdb: typo a/an pseudo-variable + tm: print af and proto as strings in log messages -commit 69a72618ceb6438c36301f58868dd7e80022355c -Author: Дилян Палаузов -Date: Mon Dec 12 21:12:24 2022 +0200 +commit dc3d035f75d414c96889aefedd316a5a28bb26ec +Author: Daniel-Constantin Mierla +Date: Tue Sep 26 11:18:50 2023 +0200 - p_usrloc: typos a/an + cdp: tls v1.3 only for libssl 1.1.1f -commit c5d73f86e19172c2fc1293e6e10fa2903032e7c5 -Author: Дилян Палаузов -Date: Mon Dec 12 21:11:37 2022 +0200 +commit dc6ce127441083bc0c9983ba6ebced03b4b515b2 +Author: Daniel-Constantin Mierla +Date: Mon Sep 25 22:04:16 2023 +0200 - osp: typo be send → sent + tm: %llu specifier for printing msg_flags fields + + - GH #3585 -commit b208f915df8b7b5f83bbf95ab622f3773f76c839 -Author: Дилян Палаузов -Date: Mon Dec 12 21:10:54 2022 +0200 +commit 4deb3a7f7eb97fc30d42aa578082e496997e45d2 +Author: Sergey Safarov +Date: Mon Sep 25 21:05:34 2023 +0300 - ndb_cassandra: typo a/an integer + pkg/kamailio: removed CentOS 6 build, no pcre2 deps [skip ci] -commit 5357ffdd0111554967876e34befa14fee2240815 -Author: Дилян Палаузов -Date: Mon Dec 12 21:10:29 2022 +0200 +commit 46430b6e91bd1fbeae9040e80e078380967e0d68 +Author: Sergey Safarov +Date: Mon Sep 25 20:23:41 2023 +0300 - nats: typo a/an event + pkg/kamailio: updated pcre2 deps [skip ci] -commit 942a8a89e53a3a77109acdc2bc3c34468faa1b75 -Author: Дилян Палаузов -Date: Mon Dec 12 21:10:13 2022 +0200 +commit d4e16520a06344ce2bfd07eda4447d68a2c3fce8 +Author: Nikolay Ivanuschak +Date: Mon Jul 24 14:09:31 2023 +0300 - nathelper: typo a/an IPv6 reference + core: fixed wrong network interface selection. + + fixed incorrect source IP address selection for the SIP + messages sending procedure when TCP transport is used or + for UDP with the 'mhomed' setting set as 'mhomed=1'. -commit e69a729fba3ed2b527f66ccf5640156eeb9ae36d -Author: Дилян Палаузов -Date: Mon Dec 12 21:08:57 2022 +0200 +commit 1e52a51a517a08ade0d554544bda2521535e4f98 +Author: Kamailio Dev +Date: Mon Sep 25 17:01:36 2023 +0200 - nat_traversal: typos a/an + modules: readme files regenerated - htable ... [skip ci] -commit 0367dab157f5b755bf9bd2cc0452bae6eaea71e2 +commit b6e600d3865a287f3c677191c8067bc1c57294ba Author: Дилян Палаузов -Date: Mon Dec 12 21:04:39 2022 +0200 +Date: Fri Jul 21 23:13:54 2023 +0200 - mqtt: typos a/an + tls: remove openssl_mutex_shared + + The code from src/modules/tls/utils/openssl_mutex_shared/openssl_mutex_shared.c + is in src/main.c . -commit 7a595ea7acb43149476bf033ac67e7fdd27e06d2 -Author: Дилян Палаузов -Date: Mon Dec 12 21:03:39 2022 +0200 +commit 9c28f6077ff5fc834394af1c571bd3d909290d73 +Author: Tyler Moore +Date: Thu Sep 14 10:40:51 2023 -0400 - matrix: typo a/an pseudo-variable; spelling is send → sent + htable add column packing features + + - add support for changing the column delimeter in a hash table + - add support for changing the column null character -commit 01a70ae52aef6926098feac64ca79605e16fa058 +commit 212fb4086a1bba6779178465a85593e537a12903 Author: Дилян Палаузов -Date: Mon Dec 12 21:03:09 2022 +0200 +Date: Sat Sep 16 11:10:11 2023 +0000 - mangler: typo a/an filter + avp: typo assing → assign -commit 3c36f8577404aa0751d1804746e1b84f58534a78 -Author: Дилян Палаузов -Date: Mon Dec 12 21:02:43 2022 +0200 +commit f8effe32d0599645be97dbc8737051d17e00ead4 +Author: Kamailio Dev +Date: Mon Sep 25 11:17:30 2023 +0200 - lcr: typos double a + modules: readme files regenerated - acc_json ... [skip ci] -commit 648a1b7f4bdf9d0a99815dc6a3b3bd8f3450884c -Author: Дилян Палаузов -Date: Mon Dec 12 21:01:55 2022 +0200 +commit bb33187a0365825db5fde065599538bf5216f45f +Author: Bastian Triller +Date: Mon Sep 25 08:36:27 2023 +0200 - kafka: spellig atTribute + acc_json: Fix parameter name in docs -commit 8165d77587106d17f11785299dabd8fc10d58f87 -Author: Дилян Палаузов -Date: Mon Dec 12 20:57:23 2022 +0200 +commit 90cb4c8a3376b967960a2185b3acc669734f5e33 +Author: Daniel-Constantin Mierla +Date: Fri Sep 22 14:11:04 2023 +0200 - ims_usrloc_scscf: typos a/an IMPU + app_python: use global parameter for request route callback -commit b648b2cb2ef77b4ab1ff42a5cc16db1f059b1e0b -Author: Дилян Палаузов -Date: Mon Dec 12 20:54:38 2022 +0200 +commit eb3895ad2bf666f738ce94ee35ffb9cbfa62d867 +Author: Daniel-Constantin Mierla +Date: Thu Sep 21 15:11:34 2023 +0200 - ims_registrar_scscf: typos a/an + app_python3: use PyErr_Clear() in case of errors -commit 58ba041e536c0f667e4bae8c4e1be48add0c0815 -Author: Дилян Палаузов -Date: Mon Dec 12 20:56:37 2022 +0200 +commit daf0d1722e01b5d1a819a7045f8c3347a948144e +Author: Daniel-Constantin Mierla +Date: Thu Sep 21 15:03:52 2023 +0200 - ims_registrar_pcscf: typo a/an IMPU + app_python3: use global parameter for request route callback -commit 6804318f811833167989d4d9f7bc4e19baa211c8 -Author: Дилян Палаузов -Date: Mon Dec 12 20:56:11 2022 +0200 +commit e44f8cb0bd217cc9a9d619ae031cfeb9933fc582 +Author: Daniel-Constantin Mierla +Date: Thu Sep 21 14:59:14 2023 +0200 - ims_qos: typos a/an + app_python3s: use global parameter for request route callback -commit f5c0ee927c4b61a623b9c93e476f68ac0a050558 -Author: Дилян Палаузов -Date: Mon Dec 12 20:55:04 2022 +0200 +commit be39bc8fd67c38f6a2b9d07047bb990a1ffacf77 +Author: Daniel-Constantin Mierla +Date: Thu Sep 21 14:56:25 2023 +0200 - ims_icscf: typos a/an + app_python3s: use PyErr_Clear() in case of errors -commit e1a8136fdad06bce8bedaca58ad38e0e8d8b1c51 -Author: Дилян Палаузов -Date: Mon Dec 12 20:55:37 2022 +0200 +commit 7e37668208d49cc529bfb920db29e71343b44d8f +Author: Daniel-Constantin Mierla +Date: Thu Sep 21 14:40:08 2023 +0200 - ims_isc: typos a/an + app_lua: proper global parameter for request route callback function + + - fix of previous commit -commit dc5df5d917e9443ef4daa47e60d673fe0e547f85 -Author: Дилян Палаузов -Date: Mon Dec 12 20:53:56 2022 +0200 +commit b045e5314834a312e6a7b6fa772641cafaa5aab6 +Author: Daniel-Constantin Mierla +Date: Wed Sep 20 12:15:39 2023 +0200 - ims_dialog: typos a/an + app_lua: use global parameter for request route callback -commit dc499e21823a676f96fa43137d4eaa58b89de444 -Author: Дилян Палаузов -Date: Mon Dec 12 20:51:06 2022 +0200 +commit 781a53d3ed3e5e7e4b574c15e6d58db0a2ead376 +Author: Daniel-Constantin Mierla +Date: Wed Sep 20 12:05:11 2023 +0200 - ims_charging_mod: typos a/an + core: kemi - parameter for request route callback function name + + - it can be set with: kemi.request_route_callback + - default: ksr_request_route -commit 3846d9fdb24be2e3aeb2e3199a91c66661820423 -Author: Дилян Палаузов -Date: Mon Dec 12 20:50:34 2022 +0200 +commit 485c313d646fd520a1237ce8f391d212ea9bbb69 +Author: Daniel-Constantin Mierla +Date: Tue Sep 19 18:23:10 2023 +0200 - ims_auth: typos a/an + microhttpd: added srcip to $mhttpd(...) variable -commit 6f06537d0e5b661c91d413a1d3a48d2203dd749a -Author: Дилян Палаузов -Date: Mon Dec 12 20:49:37 2022 +0200 +commit 754ee1322073fc7dedaa1fd047539a6c28635f65 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Sep 18 21:47:39 2023 +0000 - imc: typo a/an user + github: [skip ci]: bump docker/build-push-action from 4 to 5 + + Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 4 to 5. + - [Release notes](https://github.com/docker/build-push-action/releases) + - [Commits](https://github.com/docker/build-push-action/compare/v4...v5) + + --- + updated-dependencies: + - dependency-name: docker/build-push-action + dependency-type: direct:production + update-type: version-update:semver-major + ... + + Signed-off-by: dependabot[bot] -commit 830b136f202913887c25ef46968351741d17fda2 -Author: Дилян Палаузов -Date: Mon Dec 12 20:49:20 2022 +0200 +commit 4ad01bad433a649116d3b42a811a80fa630d869c +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Sep 18 21:47:32 2023 +0000 - http_client: typo a/an value + github: [skip ci]: bump docker/metadata-action from 4 to 5 + + Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 4 to 5. + - [Release notes](https://github.com/docker/metadata-action/releases) + - [Upgrade guide](https://github.com/docker/metadata-action/blob/master/UPGRADE.md) + - [Commits](https://github.com/docker/metadata-action/compare/v4...v5) + + --- + updated-dependencies: + - dependency-name: docker/metadata-action + dependency-type: direct:production + update-type: version-update:semver-major + ... + + Signed-off-by: dependabot[bot] -commit 14d4a2203212020df9a8338504636cc9aeb817ed -Author: Дилян Палаузов -Date: Mon Dec 12 20:47:49 2022 +0200 +commit 80c9196e3f5742066268df9a79406f15499145a1 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Sep 18 21:47:26 2023 +0000 - h350: typo a/an Kamailio + github: [skip ci]: bump docker/setup-buildx-action from 2 to 3 + + Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2 to 3. + - [Release notes](https://github.com/docker/setup-buildx-action/releases) + - [Commits](https://github.com/docker/setup-buildx-action/compare/v2...v3) + + --- + updated-dependencies: + - dependency-name: docker/setup-buildx-action + dependency-type: direct:production + update-type: version-update:semver-major + ... + + Signed-off-by: dependabot[bot] -commit fc00785e67797b43b0d3029891d107766a9e20fe -Author: Дилян Палаузов -Date: Mon Dec 12 20:29:40 2022 +0200 +commit 29ce9d8868604005fba8a215b6569a33c6478d3c +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Sep 18 21:47:22 2023 +0000 - gzcompress: typos a/an + github: [skip ci]: bump docker/login-action from 2 to 3 + + Bumps [docker/login-action](https://github.com/docker/login-action) from 2 to 3. + - [Release notes](https://github.com/docker/login-action/releases) + - [Commits](https://github.com/docker/login-action/compare/v2...v3) + + --- + updated-dependencies: + - dependency-name: docker/login-action + dependency-type: direct:production + update-type: version-update:semver-major + ... + + Signed-off-by: dependabot[bot] -commit a4839ae4102d9df742b4c6b7077ab080364563b1 -Author: Дилян Палаузов -Date: Mon Dec 12 20:46:28 2022 +0200 +commit 2741a16ebe5efd352b485fdfc70644e4c68052f8 +Author: Kamailio Dev +Date: Mon Sep 18 15:46:29 2023 +0200 - erlang: typo a/an name + modules: readme files regenerated - cdp ... [skip ci] -commit 895f7339474bfe9d947afe8980234ba7a345bc9b -Author: Дилян Палаузов -Date: Mon Dec 12 20:27:43 2022 +0200 +commit defae2551f8839c5397523f135293fb2a4056704 +Author: Lucian Balaceanu +Date: Mon Sep 18 16:37:19 2023 +0300 - drouting: typos a/an + cdp: add TLS capability (#3548) + + * cdp: adding TLS capability to peer connections + + * cdp: documenting TLS capability related parameters -commit 2d246fb8f4768df2c25d18c47ad1f43a0e698e4c -Author: Дилян Палаузов -Date: Mon Dec 12 20:45:46 2022 +0200 +commit a0ef326f4cc8b8463ec58939c20c978f844053b7 +Author: Daniel-Constantin Mierla +Date: Mon Sep 18 09:32:57 2023 +0200 - domainpolicy: typo a/an backwards + pv: added ocval field for via variables -commit 772e74a5b036974ba856aba0689af21ceefa27c6 -Author: Дилян Палаузов -Date: Mon Dec 12 20:45:17 2022 +0200 +commit 95d61a925959ac8d4c518d34168cdae6570f477a +Author: Daniel-Constantin Mierla +Date: Fri Sep 15 12:01:02 2023 +0200 - domain: typo a/an backwards + core: parse via - field for oc parameter value -commit e8fd436486e69c04a791c29196f353896f85d772 -Author: Дилян Палаузов -Date: Mon Dec 12 20:44:37 2022 +0200 +commit 42704189b49d565bf7341292bf1282bafa9ccc73 +Author: Daniel-Constantin Mierla +Date: Thu Sep 14 10:48:26 2023 +0200 - dispatcher: spelling be send → sent + pv: reformat exported structures for better readability -commit ea6ba98b9a018a07e894100b0ede662648d88edf -Author: Дилян Палаузов -Date: Mon Dec 12 20:42:50 2022 +0200 +commit cadfec9b49404304ee1b2c4f4b49490eaa540bc2 +Author: Kamailio Dev +Date: Wed Sep 13 15:47:06 2023 +0200 - dialplan: typo a/an script + modules: readme files regenerated - pv ... [skip ci] -commit e663654fdea87e1be6b30da355f8bf5020ad4507 -Author: Дилян Палаузов -Date: Mon Dec 12 20:42:05 2022 +0200 +commit 02a39e53b550ee50c61d0b0540282588497ff360 +Author: Daniel-Constantin Mierla +Date: Wed Sep 13 15:43:31 2023 +0200 - debugger: typos a/an breakpoint + pv: docs for xavp_params_implode_qval() function -commit 137680b9ce564bed5c6a40a448feb1bd6f9ff0ce -Author: Дилян Палаузов -Date: Mon Dec 12 20:41:18 2022 +0200 +commit a69c42f830dae5c7b14b03c56c47229f0b85f6c5 +Author: Daniel-Constantin Mierla +Date: Wed Sep 13 15:39:30 2023 +0200 - db_postgres: typos a/an + pv: added function to serialize xavps with quited str values -commit 6bf0eb63f9c3db33e2fa70a2207e3da3bcf74051 -Author: Дилян Палаузов -Date: Mon Dec 12 20:40:29 2022 +0200 +commit 2df3ca7d8fd995650fb937c464b99b457ee7199e +Author: Daniel-Constantin Mierla +Date: Wed Sep 13 15:25:59 2023 +0200 - db_mysql: typo a/an connection + core: xavp - option to quote string values when serializing -commit 918b73c92ed86599e67adda2b1f7a864c500efb5 -Author: Дилян Палаузов -Date: Mon Dec 12 20:37:13 2022 +0200 +commit 670742de0f2cef5ad9d478780bbeacec6597ae30 +Author: Kamailio Dev +Date: Tue Sep 12 13:16:26 2023 +0200 - db_cassandra: typos a/an + modules: readme files regenerated - app_lua ... [skip ci] -commit c5e128fec48d5572bbad898c879c4376f141e619 +commit a8747aa02ff3fbffd7a63bdc1e5c06188472edfa Author: Дилян Палаузов -Date: Mon Dec 12 20:31:31 2022 +0200 +Date: Fri Aug 25 20:54:52 2023 +0200 - dialog: typos a/an + [app_lua] clarify the file scripts can be in source or bytecode -commit 21ce96a931e578be8e9a6897b406af63f18451e5 -Author: Дилян Палаузов -Date: Mon Dec 12 20:28:24 2022 +0200 +commit e927a290afdae7c91d77ebf40e905a3d03416ac3 +Author: Bastian Triller +Date: Tue Sep 12 10:41:48 2023 +0200 - ctl: typos a/an + core: Format changes -commit ab8f951917609f373bc62b6bc93baa33559e336c -Author: Дилян Палаузов -Date: Mon Dec 12 20:36:25 2022 +0200 +commit eb23e6b63b24aa4afdef6d24352eab536c7c7a48 +Author: Stefan-Cristian Mititelu +Date: Wed Aug 16 11:01:08 2023 +0300 - crypto: spelling + ims_qos: kemi export -commit 3ac5a9f78f4c8e1b5b6f660d442b15a72336d80d -Author: Дилян Палаузов -Date: Mon Dec 12 20:35:52 2022 +0200 +commit 399441029be19f7367a0831f297b81086741a9e2 +Author: Stefan-Cristian Mititelu +Date: Fri Aug 18 10:59:57 2023 +0300 - cplc: typos a/an + ims_dialog: kemi export some functions -commit 0e3ad10aba2d82d7eccebbe608fda15e4f49ef20 -Author: Дилян Палаузов -Date: Mon Dec 12 20:35:30 2022 +0200 +commit 888fc7f4cdaf3b179334394a344c6d831b93d25e +Author: Daniel-Constantin Mierla +Date: Tue Sep 12 10:52:20 2023 +0200 - cfgutils: typos a/an + statsd: adding _labels to kemi exported function with duplicated name -commit 96d720c7c7c495ac3cf556700c76b20fedec8ec3 -Author: Дилян Палаузов -Date: Mon Dec 12 20:14:25 2022 +0200 +commit bff7b033d817c6ed63f3de63dfa7f1b45ead2ff8 +Author: Eloy Coto +Date: Sun Jul 30 23:53:17 2023 +0200 - cdp: typos a/an + statsd: Add labels to metrics. + + A user reached me to add a way to add the custom labels into the statsd + module, so a better way to report metrics to the observability platform. + + I keep the same old functions and add a new parameter to the statsd + modules to both interfaces cfg and kemi. + + The full documentation can be found here: + https://docs.datadoghq.com/developers/dogstatsd/datagram_shell/?tab=metrics + + So, each function can be used like this: ``` statsd_set("fooo", 1, + "inbound"); statsd_gauge("NotFound", "+1", "outbound,carrierFoo"); + statsd_gauge("AuthFailed", "+1", "carrier:foo,priority:10"); ``` + + Signed-off-by: Eloy Coto + Tested-by: Alex Antonevych + Signed-off-by: Eloy Coto -commit f5986119f9a55c3c91f61788ad3b3f00f2399585 -Author: Дилян Палаузов -Date: Mon Dec 12 20:26:08 2022 +0200 +commit 31507501b1d35bcf8665f9e6cc70e5fbd0bf38c2 +Author: Bastian Triller +Date: Tue Sep 12 08:07:13 2023 +0200 - carrierroute: typos a/an + core: Add option for increasing socket send buffer size -commit 3f827af3e834d603f72a64b7d2142aa94b83cf52 -Author: Дилян Палаузов -Date: Mon Dec 12 19:51:24 2022 +0200 +commit 34cadf6badb5d7db16780e0e59bf46c6fb54fd45 +Author: Kamailio Dev +Date: Tue Sep 12 10:32:15 2023 +0200 - call_obj: typos a/an increasing + modules: readme files regenerated - pdt ... [skip ci] -commit 2e86db5adf67b4d30989055bd960c2a8632f64d3 -Author: Дилян Палаузов -Date: Mon Dec 12 19:50:46 2022 +0200 +commit 111548639b8cf743d3919048da0ccf971c2340bf +Author: Daniel-Constantin Mierla +Date: Tue Sep 12 10:22:32 2023 +0200 - avp: typos a/an string + pdt: docs for mode parameter + + - GH #3485 -commit f15ef784f9abddabd8b97eb4ca6e89054250b418 -Author: Дилян Палаузов -Date: Mon Dec 12 19:50:20 2022 +0200 +commit ad7df67cfd58713fc0993e2d2365a86d9d6068e1 +Author: Daniel-Constantin Mierla +Date: Tue Sep 12 10:06:58 2023 +0200 - auth_radius: typos a/an + pdt: added mode parameter to allow ignoring duplicated prefixes -commit 5836706a63368d8424dc2bed8426bf1ac4bdc097 -Author: Дилян Палаузов -Date: Mon Dec 12 19:49:09 2022 +0200 +commit 2a10c158cbdc6b654aca328b4bdc42e9a88018ba +Author: Victor Seva +Date: Tue Sep 12 09:53:18 2023 +0200 - auth_identity: typos an other → another + pkg/kamailio/deb: remove pcre3 dependency [skip ci] -commit 4a4dfb6e92c1abf5c37e65ac571cc88e0ec13025 -Author: Дилян Палаузов -Date: Mon Dec 12 19:48:44 2022 +0200 +commit ef8d71197442ffd130a6e80ca147b5feb6c316a4 +Author: Daniel-Constantin Mierla +Date: Tue Sep 12 09:31:32 2023 +0200 - auth_diameter: typos a/an + pdf: reformat export structures -commit c92c396b886f9808935d5103710652a2c365639e -Author: Дилян Палаузов -Date: Mon Dec 12 19:48:16 2022 +0200 +commit e3e2c41e8c46a13bad18dd40fd9e3540020dd5eb +Author: Victor Seva +Date: Mon Aug 21 13:30:36 2023 +0200 - auth_db: typos a/an + lcr: pcre2 migration -commit 0be9582347182271a0a4f1a3bb2c93080d172a03 -Author: Дилян Палаузов -Date: Mon Dec 12 19:59:34 2022 +0200 +commit 374227b15ff7fbed8660beb93d52da15dcb4ba9e +Author: Victor Seva +Date: Mon Aug 21 12:27:43 2023 +0200 - auth: typos a/an opaque + dialplan: migrate to pcre2 -commit 10721533c1b81a840a88178130ca71fe1fe6ddef -Author: Дилян Палаузов -Date: Mon Dec 12 19:28:55 2022 +0200 +commit 5fe367c098123bf2dcbef2d81d1ad7ff940cb092 +Author: herlesupreeth +Date: Sun Aug 27 11:58:58 2023 +0200 - async: typos a/an + smsops: fixes as per static code analyzer report -commit 5591a7dae08bb85f077ab0efa7b2876f9673b8cb +commit e0a058b08129e615f51e051401a41cfae6ffaf46 Author: Дилян Палаузов -Date: Mon Dec 12 19:46:48 2022 +0200 +Date: Tue Sep 12 09:00:44 2023 +0200 - app_sqlang: typos a/an + misc/ typos (#3559) -commit 09b657ad9a646b255e7b69aa402352a83172bad2 -Author: Дилян Палаузов -Date: Mon Dec 12 19:44:58 2022 +0200 +commit d0d6436cfc46ad1d5be485592decee4efe7bcce0 +Author: Victor Seva +Date: Mon Sep 11 08:46:02 2023 +0200 - app_perl: typos a/an + path: fix prepend_path() + + bug introduced at dd04bceb99ba69bd59c67ba103f3c55d47a31dd6 -commit 99201809d08f0d10957860a6fc33ba81cd4ca0d5 -Author: Дилян Палаузов -Date: Mon Dec 12 19:43:08 2022 +0200 +commit ea2babf79d8b66cbfdccdae51ddf806964b16138 +Author: Daniel-Constantin Mierla +Date: Mon Sep 11 16:23:28 2023 +0200 - app_jsdt: typos a/an + pv: allow via oc param names with dashes -commit 932058b9eacb934a75279ab26ce57e53a75c5c79 -Author: Дилян Палаузов -Date: Mon Dec 12 19:28:26 2022 +0200 +commit 06b1a35c727155974eb3c10971eaac2606b430ea +Author: Kamailio Dev +Date: Mon Sep 11 14:46:24 2023 +0200 - acc_diameter: typos a/an + modules: readme files regenerated - textops ... [skip ci] -commit 55c77f09660cb4fc54338ad09138df74a53c9205 -Author: Дилян Палаузов -Date: Mon Dec 12 19:27:44 2022 +0200 +commit fb2be3855c5971d312bad52ffc3c4cb99aeb63d8 +Author: Daniel-Constantin Mierla +Date: Mon Sep 11 14:32:58 2023 +0200 - acc: typos a/an + textops: docs for via_param_rm(...) -commit d5881bad81146b7e3aae7b7866158155df76cf16 -Author: Дилян Палаузов -Date: Mon Dec 12 19:26:33 2022 +0200 +commit 9fb28d509274a659b221b0360f45d4fefafdb041 +Author: Daniel-Constantin Mierla +Date: Mon Sep 11 14:26:30 2023 +0200 - misc/examples: typos + textops: new function via_param_rm("name", idx) + + - remove paramter of a via body at a specific index -commit 59f4690cbdabe80966d71172b455572dfe9e0314 -Author: Дилян Палаузов -Date: Mon Dec 12 19:24:25 2022 +0200 +commit d3acf9cc56f0ee73bee3c7cf1210c052d79a4c46 +Author: Daniel-Constantin Mierla +Date: Mon Sep 11 14:25:47 2023 +0200 - src/Makefile{,.utils}: typos a/an + core: parser - handle comma inside quoted params of via -commit a254a91c79449adf8b744e2b093028d0c3c90093 -Author: Дилян Палаузов -Date: Mon Dec 12 19:23:09 2022 +0200 +commit 499129246e948ec765f5f74d1b15a55a5bb43eb0 +Author: Daniel-Constantin Mierla +Date: Sat Sep 9 15:58:35 2023 +0200 - doc/: typos a/an + uac: updated the type for internal msg flags -commit 039686530730bf4b0a75eca626266255f3932cca -Author: Дилян Палаузов -Date: Mon Dec 12 19:21:02 2022 +0200 +commit 9f9d5df5f5cb5503b685cb1ab3ab7162726d58e5 +Author: Daniel-Constantin Mierla +Date: Fri Sep 8 20:34:29 2023 +0200 - lib/: typos a/an + core: action - updated cast for internal message flags -commit 664e9d1677b5802b08fa26d885f4ec89ddef1ac5 -Author: Дилян Палаузов -Date: Mon Dec 12 19:20:21 2022 +0200 +commit 7000c33ab5d4dc71a3471eb46c1972a3f17b5ceb +Author: Daniel-Constantin Mierla +Date: Fri Sep 8 15:30:03 2023 +0200 - utils/: typos a/an + core: parser - internal msg flags typedefed to unsigned long long + + - type msg_flags_t + - unsigned int size flags were filled -commit e24de6868030747438e7c9c33bbd953f4f687474 -Author: Дилян Палаузов -Date: Mon Dec 12 19:19:30 2022 +0200 +commit 99eb1bd2046fa9501bd9ba599c4eae16b0259373 +Author: Daniel-Constantin Mierla +Date: Thu Sep 7 14:33:52 2023 +0200 - test/: typos a/an + core: debug message about adding xavp params to via -commit 521bf3d52fcb56198386bd4fc23f85693bc3d5f9 -Author: Дилян Палаузов -Date: Mon Dec 12 19:18:35 2022 +0200 +commit 82b0f273e1cf65051b6c50301c5073dce56c1149 +Author: Daniel-Constantin Mierla +Date: Thu Sep 7 14:16:49 2023 +0200 - core: typos a/an + core: parser - set via->params.len when body is finished -commit c9ff3010b523436269bc73a28f9d3181db58f31f +commit cf959e29ed71caa75b789d73fb8d5132cbc4e08a Author: Kamailio Dev -Date: Fri Dec 16 18:46:19 2022 +0100 +Date: Thu Sep 7 08:47:15 2023 +0200 - modules: readme files regenerated - app_lua ... [skip ci] + modules: readme files regenerated - corex ... [skip ci] -commit 3baa075469d4c349b31c558692137318c0533921 -Author: Дилян Палаузов -Date: Fri Dec 16 16:36:04 2022 +0200 +commit d5fa60a96702a5a6f3ee562fa439ac2f23bc2247 +Author: Daniel-Constantin Mierla +Date: Thu Sep 7 08:41:08 2023 +0200 - app_lua: Document that Lua versions 5.2, 5.3 and 5.4 can also be used. - - since commits 2e85bb541ff19e4b007 and 673dab16593d9a70b . + corex: docs - added missing end of section -commit 6b06719d312d338ed5492bf4ef0781f964101b75 -Author: Kamailio Dev -Date: Fri Dec 16 10:01:33 2022 +0100 +commit a7e63e43cc63781c53bd3fc44e55f0530e1754d6 +Author: Daniel-Constantin Mierla +Date: Thu Sep 7 08:39:09 2023 +0200 - modules: readme files regenerated - app_ruby ... [skip ci] + core: better style for serializing via reply xavp params -commit 58d7ca9c6d012c5c0348442f59c4d7a4a21f0d7f +commit 1e5d1e35fbebd25d3d4b81839e40dfbea841f7d2 Author: Daniel-Constantin Mierla -Date: Fri Dec 16 09:47:45 2022 +0100 +Date: Thu Sep 7 08:34:16 2023 +0200 - app_ruby: docs for modproc parameter + core: xavp - helper function to set style when serializing -commit babc87f747ebc771ae08329dc483172e789a381c +commit 1832880c4d8e2e0c5b5444542d414b13bbab47ca Author: Daniel-Constantin Mierla -Date: Thu Dec 15 18:15:04 2022 +0100 +Date: Thu Sep 7 08:16:59 2023 +0200 - Makefile.groups: added app_ruby_proc to ruby group + core: add via reply xavp params for generation when using another reply -commit dd14c5c24adae4e7fdf9f19a4d07f6cd4662c901 +commit c92a73f84c1fc8701f5c1b938a40ba46f5a619c8 Author: Kamailio Dev -Date: Thu Dec 15 14:31:44 2022 +0100 - - modules: readme files regenerated - sanity ... [skip ci] - -commit b96848689837277d9bc0ec9c1b5524de0f1321e1 -Author: Henning Westerholt -Date: Thu Dec 15 13:22:06 2022 +0000 +Date: Thu Sep 7 07:46:59 2023 +0200 - sanity: also add Contact URI check to documentation + modules: readme files regenerated - corex ... [skip ci] -commit f1bac3433c61b0a5b4be08e7738a3a1aa0defe73 -Author: Bastian Triller -Date: Thu Dec 15 10:48:40 2022 +0100 +commit 3ed56db363ace8162abdfda6e5bc0cbd51a73c70 +Author: Daniel-Constantin Mierla +Date: Thu Sep 7 07:39:38 2023 +0200 - sanity: Prevent segfault - - For star Contacts, there are no URIs that can be checked. + pv: proper name id for oc field of via variables -commit b7d1470c50cfdb03c6776bb9c8430c70d929e6a9 +commit faa0bdcc5d87d40cac8a279c524fbe724c1f7f1d Author: Daniel-Constantin Mierla -Date: Wed Dec 14 09:43:59 2022 +0100 +Date: Thu Sep 7 07:38:51 2023 +0200 - app_ruby: added header file with per-process module api + corex: docs for via_reply_add_xavp_params(flags) function -commit 5eae4c2106dfcae3ffc9a01c044cb75211a504ad +commit 1880737b9251a14eb7395f5968b955475848780d Author: Daniel-Constantin Mierla -Date: Wed Dec 14 09:42:30 2022 +0100 +Date: Wed Sep 6 21:09:35 2023 +0200 - app_ruby_proc: new meta module to link to ruby interpreter + cores: new function via_reply_add_xavp_params() - - it is used by app_ruby to offer embedded Ruby code execution, kemi or - inline + - enable adding parameters to top via of replies from xavp fields -commit a6618a951ff5cc214c96e0824782d3c13bd27437 +commit 439eae7aa2154a25a0d9143345e526e22162b24f Author: Daniel-Constantin Mierla -Date: Wed Dec 14 09:40:48 2022 +0100 +Date: Wed Sep 6 21:08:20 2023 +0200 - app_ruby: split code using libruby to app_ruby_proc module + core: ability to add paramters to top via of generated sip replies - - libruby 1.9+ is multi-threaded, it requires initialization in each - forked process to ensure proper threading states + - parameters and values are taken from xavp specified by xavp_via_reply_params -commit a70b6bf09c73d961ebea1947216757fafb951c24 -Author: Henning Westerholt -Date: Wed Dec 14 08:38:12 2022 +0000 +commit cf0e802bbf62ec4a19f26c786c07e7436ba07f0a +Author: Daniel-Constantin Mierla +Date: Wed Sep 6 21:04:16 2023 +0200 - utils/kamcmd: add missing USE_READLINE define for pkg-config build, related to #3284 + core: new internal message flag FL_ADD_XAVP_VIA_REPLY_PARAMS -commit 720a1ca1e243937e009579747c747306d35625fd -Author: LGTM Migrator -Date: Wed Dec 7 08:59:59 2022 +0000 +commit d394724ee79e168786abb9ac94ef1e965f169a7c +Author: Daniel-Constantin Mierla +Date: Wed Sep 6 21:02:42 2023 +0200 - Add CodeQL workflow for GitHub code scanning + core: config parser extended with xavp_via_reply_params parameter + + - allows to specify xavp name that is going to hold parameters to be + added to the top via of replies -commit 899b0f4518b768fd8184fb97b0c8c64cecf3a575 -Author: Henning Westerholt -Date: Mon Dec 12 08:18:24 2022 +0000 +commit 629a5451d3924fff5c9b4e06c37bd498fc6b58db +Author: Daniel-Constantin Mierla +Date: Wed Sep 6 15:05:06 2023 +0200 - core: also print maximum branches parameter compile time value + pv: via-related variables can retun oc parameters + + - overload control - rfc7339 -commit eb19c52d9b89f393d7336b4a9c6be991372e25c8 +commit 062dbc7c7f74ebe705eff711e994c3eec5956e03 Author: Daniel-Constantin Mierla -Date: Mon Dec 12 09:06:14 2022 +0100 +Date: Wed Sep 6 13:00:12 2023 +0200 - Makefile.groups: added app_python3s to mod_list_python3 + dispatcher: added pactive and pinactive for $dsg(key) + + - return percent of active/inactive route in the group -commit 043ce0e75eae04f356cd539f2146df6846a169e2 -Author: Trevor Peirce -Date: Wed Nov 30 13:28:01 2022 -0800 +commit d07eb9e54a075716c6bc96b123c3bbb885466da8 +Author: Kamailio Dev +Date: Tue Sep 5 12:46:34 2023 +0200 - stirshaken: Properly handle intermediary/chain certificates when caching certificates - - - requires patch to libstirshaken (PR 124) to do anything - - if patched version of libstirshaken detected, uses new methods to store all intermediary certs - - unrelated minor logging tweaks + modules: readme files regenerated - dispatcher ... [skip ci] -commit a4fdac93c0eecff68f67f8d48f7d507ec6c7b0e9 +commit b6979b503ffe65314526a8a2824f50b3f46b7a22 Author: Kamailio Dev -Date: Sun Dec 11 11:31:24 2022 +0100 +Date: Mon Aug 21 13:02:22 2023 +0200 + + modules: readme files regenerated - tm ... [skip ci] - modules: readme files regenerated - websocket ... [skip ci] +commit 2e341d961e6a9c24c93316459dbfe5c8fbb8db65 +Author: Daniel-Constantin Mierla +Date: Tue Sep 5 12:39:41 2023 +0200 -commit 35f8935acebb32d80633570031fad4f7235fe68a -Author: Henning Westerholt -Date: Sun Dec 11 10:18:57 2022 +0000 + dispatcher: docs for ds_dsg_fetch() - websocket: spelling fix withing -> within +commit 0e640014019fff58d665e8c3f2d37b7c8d0cfd21 +Author: Daniel-Constantin Mierla +Date: Tue Sep 5 12:34:41 2023 +0200 -commit ee739aa6952b1ea0ce72d17524dbed60627374b7 -Author: Henning Westerholt -Date: Sun Dec 11 10:18:36 2022 +0000 + dispatcher: docs - example for ds_reload() - sca: spelling fix withing -> within +commit fef59a8216e70a0eef47ce9c2eb9da32a16cd764 +Author: Daniel-Constantin Mierla +Date: Tue Sep 5 12:31:32 2023 +0200 -commit c65eaa86c659d9068c8d5bfce4dc0e9c5fd100f4 -Author: Henning Westerholt -Date: Sun Dec 11 10:18:25 2022 +0000 + dispatcher: $dsg(key) - count active/inactive targets in the group - dispatcher: spelling fix withing -> within +commit 873cd24f6aa49b0b567a858ac8ab1b60eba2ef5f +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Sep 4 21:31:49 2023 +0000 -commit b6d4d057a01d29cf9499788432fc9d00ad4737f8 -Author: Henning Westerholt -Date: Sun Dec 11 10:18:16 2022 +0000 + github: [skip ci]: bump actions/checkout from 3 to 4 + + Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. + - [Release notes](https://github.com/actions/checkout/releases) + - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) + - [Commits](https://github.com/actions/checkout/compare/v3...v4) + + --- + updated-dependencies: + - dependency-name: actions/checkout + dependency-type: direct:production + update-type: version-update:semver-major + ... + + Signed-off-by: dependabot[bot] - db_text: spelling fix withing -> within +commit ff323e8d7166fd781763608434da982e0918c7c9 +Author: Daniel-Constantin Mierla +Date: Mon Sep 4 11:29:49 2023 +0200 -commit b772cbade7d4ca9ace16d15dd76271d818cd27d8 -Author: Henning Westerholt -Date: Sun Dec 11 10:17:50 2022 +0000 + dispatcher: new variable $dsg(key) to get attributes of a dispatcher group - db_cassandra: spelling fix withing -> within +commit 4bbeaad235f8db5216380c3b381071a45d469ee0 +Author: Daniel-Constantin Mierla +Date: Fri Sep 1 15:49:33 2023 +0200 -commit fe0a095d4aca5c0dbc8513a88238ec3cb3577ad8 -Author: Henning Westerholt -Date: Sun Dec 11 10:17:42 2022 +0000 + dispatcher: helper function to return dispatcher set - xprint: spelling fix withing -> within +commit f1ef0fa09983969066784f20a78ec604e7ab66d2 +Author: Daniel-Constantin Mierla +Date: Thu Aug 31 15:20:20 2023 +0200 -commit 8f5738de081a874751fcf1fd30e27d8b6ad86781 -Author: Henning Westerholt -Date: Sun Dec 11 10:15:52 2022 +0000 + pv: added $viaX(params) to retun the parameters part of a Via body - cnxcc: spelling fix withing -> within +commit 753a60bf538985a54f8b9eafb98b7ce86b616a63 +Author: Daniel-Constantin Mierla +Date: Wed Aug 30 17:08:07 2023 +0200 -commit d2d2cf9cfbbb79c0b9ec9ca8d0f142c70cd2ff7b -Author: Henning Westerholt -Date: Sun Dec 11 10:15:43 2022 +0000 + core: parser for overflow control parameters in via header + + - RFC7339 - app_java: spelling fix withing -> within +commit b56110aca34a5633029654ae457ff3ed4424e62f +Author: Daniel-Constantin Mierla +Date: Tue Aug 29 17:18:35 2023 +0200 -commit c50cd99a863bed0565f052bcd85d726c5beed410 -Author: Henning Westerholt -Date: Sun Dec 11 10:15:17 2022 +0000 + usrloc: check for enough space to build aor on udomain_contact_expired_cb() - test: spelling fix withing -> within +commit 1435618b71ed749bc33982a00c8caf6b8de7b80a +Author: Daniel-Constantin Mierla +Date: Mon Aug 28 09:06:41 2023 +0200 -commit a8bf7741eeb68ac73161daf10241f6506a4b1cd3 -Author: Henning Westerholt -Date: Sun Dec 11 10:15:04 2022 +0000 + sqlops: number fields kept as long - misc/examples: spelling fix withing -> within +commit 1ea23314d46ce566be97a189569a01bbff5cf477 +Author: Daniel-Constantin Mierla +Date: Fri Aug 25 11:03:52 2023 +0200 -commit 29624e7ebd45e64248dc4d80cb51d3bb447d155a -Author: Henning Westerholt -Date: Sun Dec 11 10:13:06 2022 +0000 + pv: updates for helper functions taking now long instead of int - etc: spelling fix withing -> within +commit 3e6cd549716ab7ee0b2ff0df3ee52784d9478ee1 +Author: Daniel-Constantin Mierla +Date: Thu Aug 24 14:00:01 2023 +0200 -commit 9419fb2f4288149d71b191e05743df2df5fa42f7 -Author: Henning Westerholt -Date: Sun Dec 11 10:12:35 2022 +0000 + cplc: casts for proper adjusting on storage size - docs/tutorials: spelling fix withing -> within +commit 90356a685e8861d89057e8cbbe977599ab4a70b1 +Author: Daniel-Constantin Mierla +Date: Thu Aug 24 13:31:46 2023 +0200 -commit dfddb4b763e4b3bba6e5d29886722ac34bfcb311 -Author: Дилян Палаузов -Date: Sat Dec 10 10:14:49 2022 +0200 + auth_ephemeral: additional cast to avoid storage size warning - test/: add a space between comma and quote +commit 76de00a483c7ed0dbfeadde2685d2800bf291cef +Author: Daniel-Constantin Mierla +Date: Thu Aug 24 10:36:04 2023 +0200 -commit 92c432b0f5ba504a1558e96cb58a2712f1364256 -Author: Дилян Палаузов -Date: Sat Dec 10 10:11:35 2022 +0200 + core: mem - check if fragmet exists before setting function field - etc/: add a space between comma and quote +commit c11fcbbe9ed19bc54b800100d15d9ae269735f0c +Author: Daniel-Constantin Mierla +Date: Wed Aug 23 13:03:02 2023 +0200 -commit ab9bfb58f4efafbb407abdfefb99800cacf12619 -Author: Дилян Палаузов -Date: Fri Dec 9 21:24:43 2022 +0200 + msilo: cast to fix storage size warning - misc/examples: add a space between comma and quote +commit 5633026f90e46f7d6da8c1a658d425e8926f6949 +Author: Daniel-Constantin Mierla +Date: Wed Aug 23 10:55:35 2023 +0200 -commit 4397e6b8b322f5e706b41e08bdef64af3f114a92 -Author: Дилян Палаузов -Date: Fri Dec 9 21:44:13 2022 +0200 + pv_headers: compare result of pvh_set_xavi() with NULL for error cases + + - the function returns a pointer + +commit 027c2b30b39a7596c8630c06995ddc49bb42d789 +Author: Daniel-Constantin Mierla +Date: Wed Aug 23 10:54:52 2023 +0200 - misc/examples: change tls_method SSLv23 → TLSv1.2+ + db_redis: free db_keys in case of failure -commit 5fee7d818f18afcab4d2e17231d2e4eab79b7b48 +commit 81c1ede698f8dd6f2147c71ee6f3bb49ed4a682c Author: Daniel-Constantin Mierla -Date: Fri Dec 9 10:29:37 2022 +0100 +Date: Wed Aug 23 10:54:02 2023 +0200 - core: tcp - debug message on no connect + core: allow space for ending string when creating socket structure at startup -commit fafcf5f9c711d0d1cb32f2f3ab71df374e28bc16 -Author: Kaufman -Date: Sun Oct 9 11:14:37 2022 -0400 +commit 4d58141ab84cf248e8c44a96181642ad0f187e80 +Author: Daniel-Constantin Mierla +Date: Tue Aug 22 17:09:37 2023 +0200 - APKBUILD: remove python2 references - - - Remove python2 references from APKBUILD reported by GH #3257 + rabbitmq: proper check for allocated pointer -commit 8a54c457bd1629ad4920caed4bcc5e10483df6dc +commit efd94f90069d146d8133d7afd6276ce1c188556f Author: Daniel-Constantin Mierla -Date: Thu Dec 8 08:39:27 2022 +0100 +Date: Tue Aug 22 11:09:56 2023 +0200 - misc/examples/kemi: updates to kamailio-basic-kemi-python3s.py + tls: updates to revive TLS_MALLOC_DBG + + - it still requires q_malloc to be used + - GH #3532 -commit 10aafffc86e872de1ad83177529e3a417449b294 +commit 1397682006dd7fc7df0cb95d92ff6424f7ad506f Author: Daniel-Constantin Mierla -Date: Wed Dec 7 14:06:18 2022 +0100 +Date: Tue Aug 22 10:25:53 2023 +0200 - misc/examples/kemi: small update to kamailio-basic-kemi-jsdt.js + core: mem - shm api extended to enable setting func field of the chunk + + - implemented for q_malloc(), being needed for reviving tls extra debug mode -commit b89917952fd3476b81a0fb5f5536e3ebf559bc83 -Author: Kamailio Dev -Date: Wed Dec 7 14:31:27 2022 +0100 +commit a92de0dfc809f9257eb230093c93081606ee107e +Author: Daniel-Constantin Mierla +Date: Mon Aug 21 17:22:17 2023 +0200 - modules: readme files regenerated - imc ... [skip ci] + core: mem - wrapper macros to specify position params for shm allocation -commit 3cab2dd0d2802bf33d0e76cc81a3b40f70611cda -Author: Joey Golan -Date: Fri Dec 2 13:53:08 2022 +0200 +commit 4d8811f562013297c7d9380e392e31bae19a260f +Author: Supreeth Herle +Date: Tue Aug 22 10:12:47 2023 +0200 - imc: propagate content-type header + smsops: Fix conversion from UCS-2 to UTF-8 and viceversa (#3546) -commit c6c5a4e2a1e963b7f7a044a51f4e9f8812a83bd5 -Author: Joey Golan -Date: Fri Dec 2 09:17:16 2022 +0200 +commit 325c7a34fca74770a4351e00e27fcae75d57852e +Author: Victor Seva +Date: Wed Aug 9 10:48:41 2023 +0000 - imc: destroy db only if db_mode is not 0 + regex: migration to pcre2 -commit b94e158e0f7656b574f37a14bd88348fe6548233 -Author: Joey Golan -Date: Fri Dec 2 09:02:42 2022 +0200 +commit b1031c1ad38bd40a9b6fe8849ced58608f1c30ef +Author: Daniel-Constantin Mierla +Date: Mon Aug 21 12:48:39 2023 +0200 - imc: db_mode support + tm: docs - note that t_relay() creates transaction if it does not exist - Support db_mode. if db_mode is 2, synch all operations to DB, otherwise use only memory. + - removed trailing spaces -commit 344ef3dfec5cfc4865f01db845112617c7b5e096 -Author: Joey Golan -Date: Mon Nov 28 17:07:01 2022 +0200 +commit 4bcf0649a86965fc2e5c8ea5f3c6519e2918ba52 +Author: Kamailio Dev +Date: Mon Aug 21 12:46:29 2023 +0200 - imc: call handle_modify + modules: readme files regenerated - tm ... [skip ci] -commit 7d3d94b19f5d93e0100f678b64d92de679c0403e -Author: Joey Golan -Date: Mon Nov 28 16:46:35 2022 +0200 +commit 8ca1fec1c00a19e3386bedf5ccfe8f9983184905 +Author: Дилян Палаузов +Date: Fri Aug 11 21:58:44 2023 +0200 - imc: add support to modify member role + tm: clarify which functions can create a transaction + + I removed the word atomic before transaction, since it implies that there are in addition non-atomic ways to create a transaction. + + Per https://lists.kamailio.org/mailman3/hyperkitty/list/sr-users@lists.kamailio.org/message/V7ZJEQZMXH7BNGRDI32BTYX742GVAWDB/ t_relay() creates a transaction. + + - typos -commit f409a8c9f6fde33eaf8b428887e219b56740b0a5 -Author: Rick Barenthin -Date: Tue Dec 6 10:39:18 2022 +0100 +commit 1599dd829e98cb610ca54903e8564d00fe9e07a0 +Author: Richard Fuchs +Date: Fri Aug 18 08:12:18 2023 -0400 - tm: cleanup parsed body at the end t_continue_helper + rtpengine: set MIME Content-Length - - if t_suspend and t_continue are used for replies - and in the called route in t_continue the body of - the sip message is parsed the pkg memory of the - parsed body is leaked + For MIME multipart SDPs, the embedded MIME section can contain a + Content-Length header. Update this field if preset after rewriting the + SDP. -commit 7f9547ae2b5a5848f693544124f199f4082be22c -Author: Daniel-Constantin Mierla -Date: Wed Dec 7 11:44:56 2022 +0100 +commit 52196f955d9b023d1d1340fadd44dcd09a0e6e67 +Author: Victor Seva +Date: Wed Aug 9 15:43:13 2023 +0200 - misc/examples/kemi: native config upated + pkg/kamailio/deb: add pcre2 + + * first step for migration to pcre2 until all modules are migrated -commit 0f3f02353535034beaf84ea833cdd5bf30cd46a2 -Author: Daniel-Constantin Mierla -Date: Wed Dec 7 10:11:12 2022 +0100 +commit fcdeedb5e84ff31f25daa7ba8ffdb355f909afa9 +Author: Kamailio Dev +Date: Thu Aug 17 18:46:23 2023 +0200 - misc/examples/kemi: updated kamailio-basic-kemi-ruby.rb in sync with kemi samples + modules: readme files regenerated - htable ... [skip ci] -commit 29c9d3af78656f4dba8e9517ab07d2f403327b08 +commit 2c9a135d4272ace414b7b4dd148cdf955f79b614 Author: Daniel-Constantin Mierla -Date: Wed Dec 7 09:12:23 2022 +0100 +Date: Thu Aug 17 18:40:21 2023 +0200 - misc/examples/kemi: fixed line break in kamailio-basic-kemi-ruby.rb + htable: docs for htable.dmqresync -commit b1f9045fc4fa23ecd81689715ee469034755def8 +commit f9dcffc42f10caa638ba3e2cbbe6ffb6206373b7 Author: Daniel-Constantin Mierla -Date: Tue Dec 6 13:16:19 2022 +0100 +Date: Thu Aug 17 18:33:09 2023 +0200 - app_python3: fetch tupple item to get parameters + htable: added rpc htable.dmqresync command + + - reset and dmq sync for a specific hash table -commit af1d9c156e0a69c9e3f39a063f7dd97d1c0a7bf1 -Author: Victor Seva -Date: Mon Dec 5 12:43:11 2022 +0100 +commit 722a79a9ba8ca2608e699ec14684ce004ae10d60 +Author: Rick Barenthin +Date: Tue Aug 15 22:30:58 2023 +0200 - pv_headers: fix t_resume scenario + core: cfg.y typo in parsing XAVPVIAFIELDS + + In the XAVPVIAFIELDS block there is the string written to the wrong variable. + + The string is stored in _ksr_xavp_via_params.s but the lenght is stored in _ksr_xavp_via_fields.len. This breaks XAVPVIAPARAMS and XAVPVIAFIELDS. -commit 3b9eee82d604c14b60d5153e2a8bf356ddf99e0d +commit e859169628ed4c3dc1c5a9230e29046c9cb8fc46 Author: Kamailio Dev -Date: Tue Dec 6 11:01:19 2022 +0100 +Date: Tue Aug 15 23:01:16 2023 +0200 - modules: readme files regenerated - app_python3s ... [skip ci] + modules: readme files regenerated - htable ... [skip ci] -commit d79e00892760f296c851740b33f8df3b5a6324ad +commit 440bab64af7428891527cedfadb20a3e9df2b461 Author: Daniel-Constantin Mierla -Date: Tue Dec 6 10:54:57 2022 +0100 +Date: Tue Aug 15 22:54:14 2023 +0200 - app_python3s: docs for script_child_init parameter + htable: docs for htable parameter of rpc htable.dmqsync -commit b7bae49f9b522f223932375e8e3087a7d2a893f5 +commit 49adf6b697c87c1e0426390511048eeacfe4c826 Author: Daniel-Constantin Mierla -Date: Tue Dec 6 10:50:02 2022 +0100 +Date: Tue Aug 15 22:49:46 2023 +0200 - app_python3s: new parameter script_child_init + htable: option to dmq sync a single htable via rpc + +commit a053bcc391f0680ecd5f458d2512e57f69499d39 +Author: Henning Westerholt +Date: Tue Aug 15 14:16:07 2023 +0000 + + ims_ipsec_pcscf: typo in spi_add function definition, GH #3513 - - specify the name of the function to be executed on child fork and - reload of script + - fix typo in spi_add function definition + - patch from jbipre2, GH #3513 -commit cc96ebfa7f4bebf45b368ee69dc4f9612575ee9b -Author: Daniel-Constantin Mierla -Date: Tue Dec 6 10:28:59 2022 +0100 +commit 9becbcb11005377b9925386e5c0de89d20e39b26 +Author: Kamailio Dev +Date: Tue Aug 15 16:01:18 2023 +0200 - app_python3s: more generic form of the function executing script init callback + modules: readme files regenerated - htable ... [skip ci] -commit 7a1f2be30ea68c4ee7ab71a32c88e31d136e7b71 -Author: petermarianF <62649923+petermarianF@users.noreply.github.com> -Date: Tue Dec 6 10:51:58 2022 +0100 +commit 4d285806b4bb9197c58e0d6e1d4fb33a65865138 +Author: Henning Westerholt +Date: Tue Aug 15 13:49:56 2023 +0000 - ims_usrloc_pcscf: implementation of db_mode DB_ONLY (value 3) (#3279) - - * ims_usrloc_pcscf: implementation of db_mode DB_ONLY (value 3) - In order to support a redundant PCSCF configuration - i.e. a logical PCSCF - consists of 2 physical nodes (node1 and node2) some enhancements were - introduced for handling of contacts. Redundancy means that SIP messages - for a client are normally handled by node1 but in case node1 is not - reachable SIP messages are redirected to node2. Of course the DB_ONLY - mode must work also for single PCSCF node configuration. Important aspects - of this implementation are database integrity - i.e. avoid invalid table - entries (for example data which are expired long time ago or have - invalid states) - and keeping PCSCF cache in sync with database tables. - * A wrapper was built for method get_pcontact which tries to find the pcontact - in cache and if search is not successful tries to download and insert from - db location table - also some effort is added here to find the pcontact if it exists in cache. - The contact expiry handler was modified to sync contact - expiry in cache with db location entry and in case of real contact expiry - sends PUBLISH to SCSCF to let NOTIFY finally delete the contact. - * An audit for older expired pcontacts was introduced which cares for - getting rid of these contacts. - Some code was introduced to help registering callbacks for contacts - which are inserted into cache when being downloaded from database - for - example ims_qos callback as at the time of insertion the message that triggered - the original callback registering is long gone. - * changes required for PR #3279 - * add modparam db_mode to usrloc_api - * remove unused method db_delete_presentity_uri_from_pua - - Co-authored-by: Annemarie Mandl + htable: spelling fix related to commit b612f0791821 -commit ca48d23e569f94e5a59235c5c3b66d1c7c595e17 +commit 0e11b4e8f3b1380043034ea9e66f7643e4623960 Author: Kamailio Dev -Date: Mon Dec 5 16:01:51 2022 +0100 +Date: Tue Aug 15 15:01:14 2023 +0200 - modules: readme files regenerated - app_python3 ... [skip ci] + modules: readme files regenerated - htable ... [skip ci] -commit 0f36ffb2c5a5cd21761c0e8edea7ef66cbab9477 +commit b612f07918212ae872c092562a9e0527a89f7f9e Author: Daniel-Constantin Mierla -Date: Mon Dec 5 15:53:56 2022 +0100 +Date: Tue Aug 15 14:57:15 2023 +0200 - app_python3s: docs for script_init parameter + htable: docs for rpc htable.dmqsync -commit 4ccd5019a5c8300f3193e8261075987e4e41ca8e +commit a50aa8688afdca9e3c4e34e8d3929e96e6f5b3fa Author: Daniel-Constantin Mierla -Date: Mon Dec 5 15:47:20 2022 +0100 +Date: Tue Aug 15 14:52:56 2023 +0200 - app_python3s: added script_init parameter - - - specify function to be executed when the script is (re-)loaded + htable: rpc command to permorm a dmq sync action -commit d53db5e0a24cedf95abf79766509d45b2359da99 -Author: Daniel-Constantin Mierla -Date: Mon Dec 5 13:53:17 2022 +0100 +commit 8bdc40e085edddf1e58d8946e06983707fb15770 +Author: Kamailio Dev +Date: Mon Aug 14 17:16:24 2023 +0200 - app_python3: docs - section for kemi usage + modules: readme files regenerated - dispatcher ... [skip ci] -commit 38eca1994d90897d6fb9912b2cc12da4f3ab039c -Author: Daniel-Constantin Mierla -Date: Sun Dec 4 18:38:38 2022 +0100 +commit 20634fccc59c82a35b45a3da0b8e6a0e64acb37e +Author: Stefan Mititelu +Date: Mon Jul 24 12:24:47 2023 +0300 - app_python3s: docs - section about kemi usage + ims_qos: doc and logs update -commit 637517e7db9ed914196384410246f54e8caeb963 -Author: Daniel-Constantin Mierla -Date: Fri Dec 2 11:08:45 2022 +0100 +commit 2a1a65dba78665b9d663e2e8335cff11a1116ec2 +Author: Charles Chance +Date: Wed Aug 9 10:22:19 2023 +0100 - misc/examples/kemi: engine python for app_python3s + dispatcher: add option to retain existing latency stats when reloading destinations + + - also retain when adding/removing individual destinations via RPC -commit e9c10e408074c09a3f6160e23ac42911d7364fa4 -Author: Daniel-Constantin Mierla -Date: Fri Dec 2 10:53:30 2022 +0100 +commit 2fd5d881563126f7425730f798afcbfc2feeac65 +Author: Kamailio Dev +Date: Sat Aug 12 13:46:24 2023 +0200 - misc/examples/kemi: updated kamailio-basic-kemi.cfg with app_python3s + modules: readme files regenerated - rabbitmq ... [skip ci] + +commit 2475dfa2564346b7c0790012e72cd17a5d9ca7f6 +Author: Joel Centelles +Date: Fri Aug 11 13:23:29 2023 +0200 + + rabbitmq: Enabling rabbitmq_publish for any route and disabling peer + verification - - reorganized defines + Enabling rabbitmq_publish function on any route so we can send events on reply + reception. + Also disabling peer verification on the TLS handshake if no CA file is + configured. -commit a6bbd68438865e153d9bef1c7ae495f607232bee +commit 170067e633ef32ea7b17adad46fdfe2c85fadda0 Author: Daniel-Constantin Mierla -Date: Fri Dec 2 09:02:24 2022 +0100 +Date: Sat Aug 12 13:30:39 2023 +0200 - misc/examples/kemi: added sample config for app_python3s + xhttp: note about available variables during http request processing -commit 0a0d877e1f2e7609f09679e290450c9000bb0c23 -Author: Daniel-Constantin Mierla -Date: Wed Nov 30 16:45:36 2022 +0100 +commit e60ce488db239f717803b0f4f83180646ee47200 +Author: Kamailio Dev +Date: Sat Aug 12 12:31:22 2023 +0200 - app_python3s: regenerated kemi export map code + modules: readme files regenerated - http_async_client ... [skip ci] -commit ad91e860ede6aafcccdf976ad5ff0d4f7aa71fd0 +commit f16d2658bbefb7a9f43076cbaa958fb3a27f6a0c Author: Daniel-Constantin Mierla -Date: Wed Nov 30 16:44:17 2022 +0100 +Date: Fri Aug 11 20:16:37 2023 +0200 - app_python3s: utils - updated too to generate export map code + http_async_client: docs - dependency on libevent + + - list style for dependencies and links to projects -commit 7ff3088ad38edcf28f7bb9ab58cb46a164c17b54 -Author: Kamailio Dev -Date: Wed Nov 30 09:46:17 2022 +0100 +commit 18ae77207409b816d6dffb13b41e3be9c251d62c +Author: Victor Seva +Date: Thu Aug 10 09:56:30 2023 +0200 - modules: readme files regenerated - geoip2 ... [skip ci] + pkg/kamailio/deb: rule to print excluded modules [skip ci] -commit 21817906853140322c701f8cbb8201049d2b58f0 -Author: Vadim Gaysin -Date: Wed Nov 30 09:31:45 2022 +0100 +commit 5c7de00bc0826cf739577010ba7b4882e83819cc +Author: Victor Seva +Date: Wed Aug 9 10:52:47 2023 +0000 - geoip2: new parameter to register result id to get pv work in kemi + regex: convert to memory error logging helper -commit 3cecd97f71c2dc397516dcf6f04aa906a4be8527 -Author: Daniel-Constantin Mierla -Date: Wed Nov 30 09:25:07 2022 +0100 +commit 11b24eb35f4bb1e9825b3191d8f6e0fc9c0a3e28 +Author: Victor Seva +Date: Thu Jul 13 00:26:58 2023 +0200 - app_python3s: new module offering python3 kemi script execution + ctl: use snprintf() to set boundaries - - alternative to app_python3, without dynamic SIP message object - instantiation, only KSR lib static export - - old exported python modules (e.g., Router) no longer available + > https://github.com/kamailio/kamailio/security/code-scanning/1839 -commit 03356132aef31a35b94bd47b4146cbce3e1c4ce9 -Author: Daniel-Constantin Mierla -Date: Tue Nov 29 09:33:24 2022 +0100 +commit d893f3af1444c8c4c5db6cd53fb577703007c90c +Author: Walter Schober +Date: Mon Jul 31 15:16:31 2023 +0200 - app_python3: Makefile - extend python3-config lookup + core: Add TCP_USER_TIMEOUT socket option on listening socket. + + Use tcp_send_timeout config option also on listening socket to timeout outbound messages sent on passive inbound connections. -commit 8be2b013b2cd2aa71e1c7e5618d7d4b079a4b5e5 -Author: Daniel-Constantin Mierla -Date: Tue Nov 29 08:45:07 2022 +0100 +commit 63445544d994d7876ff76eb66203400c5a3a4b91 +Author: Kamailio Dev +Date: Mon Aug 7 15:49:07 2023 +0200 - app_python: Makefile - look also for python2.7 if python2 is not found + modules: readme files regenerated - acc ... [skip ci] -commit 6e813fd8e0522f43f5c07b145834cd12dbd006f9 -Author: Daniel-Constantin Mierla -Date: Tue Nov 29 08:27:44 2022 +0100 +commit 6e9335ff2245596b74bc1c749d1e7805bf186f02 +Author: Дилян Палаузов +Date: Sat Jul 22 14:15:09 2023 +0200 - app_python3: removed extra semicolon + etc/ typos -commit 9dbf3aefa4de2e794fba12978a9640e803fb483e -Author: Daniel-Constantin Mierla -Date: Tue Nov 29 08:10:46 2022 +0100 +commit 9fba67792382b53ccd4851764505ee3b119531b1 +Author: Дилян Палаузов +Date: Sat Jul 22 14:13:05 2023 +0200 + + docs/ : typos - app_python: updates to use generic kemi function execution from core +commit e55a6ed0f24c9b81d8d3ad27ba25d4d88c474483 +Author: Victor Seva +Date: Thu Jul 20 14:04:30 2023 +0200 + + crypto: SHA1_Init deprecated at openssl 3.0 - - replaced code to retrieve the function parameters from python to be - more compact by walking the tuples list + From https://www.openssl.org/docs/man3.0/man7/migration_guide.html + + > Use of low-level digest functions such as SHA1_Init(3) have been informally + > discouraged from use for a long time. Applications should instead use the + > high level EVP APIs EVP_DigestInit_ex(3), EVP_DigestUpdate(3) and + > EVP_DigestFinal_ex(3), or the quick one-shot EVP_Q_digest(3). + + related to #3502 -commit 8531e4f50ec33f06562bd102e334532df2474102 -Author: Daniel-Constantin Mierla -Date: Mon Nov 28 14:25:37 2022 +0100 +commit bad420e9f72c237bbd608a9ff06ae3b63bce9625 +Author: Victor Seva +Date: Thu Jul 20 10:11:03 2023 +0200 - app_python3: updates to use generic kemi function execution from core + .devcontainer: Initial support for devcontainers [skip ci] - - replaced code to retrieve the function parameters from python to be - more compact by walking the tuples list + Allows to develop inside a container using vscode + + > https://code.visualstudio.com/docs/devcontainers/containers -commit d315eb26c1e4b9fcb4b9696f3b6492b2131ccf1b -Author: Daniel-Constantin Mierla -Date: Mon Nov 28 13:49:52 2022 +0100 +commit c2f12479debe7bd5f5819f3c3b332929dd5fe703 +Author: Victor Seva +Date: Thu Jul 20 10:05:18 2023 +0200 - nats: declare variable at beginning of function + .clang-format: add json settings [skip ci] -commit 305b13237cfbd11c45f19bc6a92b2fc829f05409 +commit 192b681ce7fcd868a4a47a7c26863c733321b8d4 Author: Victor Seva -Date: Mon Nov 28 11:54:49 2022 +0100 +Date: Wed Jul 26 15:00:38 2023 +0200 - pkg/kamailio/deb: version set 5.7.0~dev2 + sipcapture: make sure we null terminate the copy of the string + + bug introduced at cbd7810fff3d5145c1ce34c0e362b5590bb92a12 -commit afd781131248e4271c1ea9bc66dc5c76010838b7 -Author: Daniel-Constantin Mierla -Date: Mon Nov 28 09:55:39 2022 +0100 +commit 3c1700fb7693c05025be1058e856fe610f4be031 +Author: Victor Seva +Date: Wed Jul 26 14:53:26 2023 +0200 - Makefile.defs: version set to 5.7.0-dev2 + rtpproxy: make sure we null terminate the copy of the string. + + bug introduced at d00ceda2c04 -commit 977b56c70c26b8f07cfdc557e32fbebc267c67bb -Author: Daniel-Constantin Mierla -Date: Sat Nov 26 14:19:22 2022 +0100 +commit 2750e48b5445e9334cb7a062d7d53a1fb9a0a411 +Author: Maksym Sobolyev +Date: Tue Jul 25 12:29:02 2023 -0700 - app_ruby: updates to use generic kemi function execution from core + rtpproxy: make sure we null terminate the copy of the string. + + Broken in d00ceda2c04. -commit e93c935628a03adad22c76b2da3a8a111344c6dd -Author: Daniel-Constantin Mierla -Date: Fri Nov 25 12:10:49 2022 +0100 +commit 8b1139851d9f88add1fd7da0dbc0b2b56933cdd3 +Author: Stefan Mititelu +Date: Thu Jul 20 13:24:04 2023 +0300 - app_sqlang: updates to use generic kemi function execution from core + rtpengine: increase buf size to print mos llint range -commit ae1628ffbf5bfdae2d04f337d773391dac5d455c -Author: Daniel-Constantin Mierla -Date: Fri Nov 25 11:58:42 2022 +0100 +commit 6881faadec45dd16dd896b13db44862e7df70422 +Author: Stefan Mititelu +Date: Wed Jul 19 13:48:09 2023 +0300 - app_jsdt: updates to use generic kemi function execution from core + dialog: set cbs list to NULL after destroying -commit 6820b78c7e983b9b28efbc11f43b721709130e0f +commit 8a61b4607d6d079131bdbfff86c3e28167a12605 Author: Daniel-Constantin Mierla -Date: Fri Nov 25 11:44:28 2022 +0100 +Date: Wed Jul 19 11:06:11 2023 +0200 - app_lua: updates to use generic kemi function execution from core + geoip: reformat static export structures -commit 08c385ab20a87e4cd64ac278f56527d05a9115b8 +commit c35088bf31b3e3e828433bf03b6ce647a75ef8e2 Author: Daniel-Constantin Mierla -Date: Fri Nov 25 11:43:26 2022 +0100 +Date: Tue Jul 18 16:38:20 2023 +0200 + + geoip2: docs - section ids and formatting - misc/tools/kemi/kemi-code-gen.py: updates for generating generic execution function +commit f68a1e9c9f249faee38d29776d5831cbf9e3cce7 +Author: Nir Simionovich +Date: Mon Jul 17 11:26:18 2023 -0400 + + kamctl: add 2 new options to dispatcher management (#3512) + + *kamctl: add support for deleting a gateway or full setid in dispatcher. - - support to generate prototypes for functions returning xval + * kamctl: small style fix to help screen after previous change + + --------- + + Co-authored-by: Nir Simionovich -commit 74796c75c630211c1807424be36cf77634b7b2c0 -Author: Daniel-Constantin Mierla -Date: Fri Nov 25 11:29:42 2022 +0100 +commit 78c0275b9081d4ee18a89f702f3931e3c3f83489 +Author: joelbax <98022231+joelbax@users.noreply.github.com> +Date: Mon Jul 17 17:21:36 2023 +0200 - core: kemi - added generic function to execute a kemi export with any kind of parameters + rabbitmq: Adding amqps support (#3511) + + * rabbitmq: Adding amqps support + + Adding support for secure AMQP connections over TLS (amqps). + + * rabbitmq: Adding amqps support + + Adding support for secure AMQP connections over TLS (amqps). + + rabbitmq: Adding amqps support + + Adding support for secure AMQP connections over TLS (amqps). + + rabbitmq: Format fixes + + Some style format fixes + + * rabbitmq: Format fixes + + Fixing some missing spaces + + * rabbitmq: Typo fix + + Fixing inilialized by initialized -commit c38c1801d84f7b6049901e85c271f23dc63edb40 +commit 9f3356de1c769c610112df9dbcfdf6461de9f959 Author: Daniel-Constantin Mierla -Date: Fri Nov 25 11:27:52 2022 +0100 +Date: Mon Jul 17 08:37:04 2023 +0200 - core: kemi - added prototypes for various functions with 4+ params + htable: reformat initialized static structures -commit 11ffe722ae7530dff13da64a64122931b0758c7c -Author: Daniel-Constantin Mierla -Date: Fri Nov 25 09:05:09 2022 +0100 +commit 157119809f7ce08d568677342d1833ca64a78b01 +Author: Kamailio Dev +Date: Fri Jul 14 17:32:04 2023 +0200 - app_lua: updated handling function with (str,xval) params + modules: readme files regenerated - geoip2 ... [skip ci] -commit 360337fcf36cd91902af6d07e60782ae70f10911 +commit 956cb12f47befe860de87864c943c21347bf906f Author: Daniel-Constantin Mierla -Date: Fri Nov 25 09:02:29 2022 +0100 +Date: Fri Jul 14 17:21:41 2023 +0200 - core: kemi - changed prototypes with xval instead of long param + geoip2: docs - updated name from distance to geoip2_distance() -commit 63d0df60c84c81b8143d7e38a798f92b8a5a1744 +commit fcfa941320d4553545e5c8522d9668f309a1c10b Author: Daniel-Constantin Mierla -Date: Thu Nov 24 10:35:36 2022 +0100 +Date: Fri Jul 14 17:19:43 2023 +0200 - app_lua: support returning long value and functions with (str,long) params + geoip2: implemented distance fucntion for kemi -commit ccf74015e7f1bf60f56efa1f24a6370e0857c4c9 +commit 87be8a593ba32bd2205d14304c7084bc5788297a Author: Daniel-Constantin Mierla -Date: Thu Nov 24 10:32:29 2022 +0100 +Date: Fri Jul 14 17:10:17 2023 +0200 - core: kemi - prototypes for kemi functions with (str,long) params + geoip2: prefix distance with geoip2_ to reflect the module -commit 3406b9143a399a0445d09b83f40fe2fbe1781761 +commit 7a459481ebacf9aec4e7c61aa5a08de934a2edc5 Author: Daniel-Constantin Mierla -Date: Thu Nov 24 10:15:33 2022 +0100 +Date: Fri Jul 14 17:06:21 2023 +0200 - core: kemi - function to get/set pv with long value + geoip2: reformat module exports structures -commit 8b5531ad22fb324551ed27aa0beac2033df1afd8 +commit 40225a82ebbba4dd6fbdfb2f0d152b6178b4dafd Author: Daniel-Constantin Mierla -Date: Thu Nov 24 09:56:15 2022 +0100 +Date: Fri Jul 14 17:01:09 2023 +0200 - core: kemi - added long type and field to xval union + geoip2: use generic spve fixup functions -commit 6438573ce2d138d83cc1fa7cd88834c48d623ac6 -Author: Daniel-Constantin Mierla -Date: Wed Nov 23 10:51:04 2022 +0100 +commit 2b152b09adb9bbfefe24826e075f3f6dd525a23f +Author: Kamailio Dev +Date: Fri Jul 14 15:02:09 2023 +0200 - core: safety check for freeaddrinfo() param on log_init() - - - GH #3281 + modules: readme files regenerated - geoip2 ... [skip ci] -commit b4270a57ed10b9fcad56170bf808cc01aaeb7d7f +commit 84591b667e06ac8794d9f1050796a6273ce4532c Author: Kamailio Dev -Date: Wed Nov 23 10:46:56 2022 +0100 +Date: Fri Jul 14 14:47:36 2023 +0200 - modules: readme files regenerated - jwt ... [skip ci] + modules: readme files regenerated - mohqueue ... [skip ci] -commit 8d33363b5ec93ebd0068f270af23be9095950775 -Author: Daniel-Constantin Mierla -Date: Wed Nov 23 10:39:18 2022 +0100 +commit 60abf767988dba052d7e08c386a589c1aeb711ef +Author: Nikolay Ivanuschak +Date: Wed Jun 28 23:29:04 2023 +0300 - jwt: docs for jwt_verify_key(...) + geoip2: added distance function + + Added distance function which allows to calculate the distance + between the geocoordinates of the the IP-address passed as + incoming parameter (coordinates for the IP are determined inside + the function) and the geocoordinates passed as parameters for the function. -commit f264b3745a2e666f9bb617cb1d5cf9ac0e1a439e -Author: Daniel-Constantin Mierla -Date: Wed Nov 23 10:35:55 2022 +0100 +commit 1f1926f1e2feb4cd2eccc2ec5e216066f7bac036 +Author: Дилян Палаузов +Date: Wed Jun 21 21:39:55 2023 +0200 - jwt: added function to verify with key value given as parameter + textops: typos -commit 269455efb3827c9700f85715113b1757508b9767 -Author: Daniel-Constantin Mierla -Date: Wed Nov 23 10:32:40 2022 +0100 +commit 267a7ac1056979af800bb0818b87390bdc0a42d9 +Author: Дилян Палаузов +Date: Wed Jun 21 21:39:28 2023 +0200 - jwt: renamed parameter to indicate is a path to file + tcpops: typos -commit 929986648dcfefa1212cbfcc129b7bb3a44259d6 -Author: Kamailio Dev -Date: Wed Nov 23 09:16:28 2022 +0100 +commit b582e77086f9b8a93223979fa5bdcb40848c8fde +Author: Дилян Палаузов +Date: Wed Jun 21 21:38:52 2023 +0200 - modules: readme files regenerated - presence ... [skip ci] + statsd: typo -commit ced18c6f3c3a4632cb23510334466c236f08d26f -Author: Daniel-Constantin Mierla -Date: Wed Nov 23 09:07:44 2022 +0100 +commit 2ac0cf8c3e73af59480e54aaa483d197bb2adbc3 +Author: Дилян Палаузов +Date: Wed Jun 21 21:38:31 2023 +0200 - presence: docs - small typo + snmpstats: typos -commit 4a6b6e3f14318794405ba88a50f3d78971d60197 -Author: Daniel-Constantin Mierla -Date: Tue Nov 22 10:19:06 2022 +0100 +commit b6f84b7e5985bdd12122cc51f5a07cc764db3b57 +Author: Дилян Палаузов +Date: Wed Jun 21 21:38:11 2023 +0200 - auth_radius: updated to use xavp long value field + seas: typo -commit e37d9dbcfd199797a3514392e5a03f98a2c1151b -Author: Daniel-Constantin Mierla -Date: Tue Nov 22 10:18:04 2022 +0100 +commit ad81a4a258c0e70ce04bfef36dfbd5222740786b +Author: Дилян Палаузов +Date: Wed Jun 21 21:37:57 2023 +0200 - cnxcc: updated to use xavp long value field + sca: typos -commit d4251378c701a46803e24df607c0959a2975fa7b -Author: Daniel-Constantin Mierla -Date: Tue Nov 22 10:16:35 2022 +0100 +commit 286f0c764bcc4856ee3195119f929cbc29215874 +Author: Дилян Палаузов +Date: Wed Jun 21 21:37:33 2023 +0200 - memcached: updated to use xavp long value field + ruxc: typos -commit 68dcaf766c5c08ebb9ad08a9203f40dd77b74933 -Author: Daniel-Constantin Mierla -Date: Tue Nov 22 10:15:14 2022 +0100 +commit f6c5638e3ef5c5ff195fdf179e2cdaec23dea7e2 +Author: Дилян Палаузов +Date: Wed Jun 21 21:37:17 2023 +0200 - misc_radius: updated to use xavp long value field + rtp_media_server: typos -commit e14d2ee291f76cc4d1187ccbc1c88f6ccf36fe28 -Author: Daniel-Constantin Mierla -Date: Tue Nov 22 10:12:17 2022 +0100 +commit c741e8c7a04d77dec08d0b4953de812b57986296 +Author: Дилян Палаузов +Date: Wed Jun 21 21:36:49 2023 +0200 - peering: updated to use xavp long value field + rtimer: typo -commit 4b6328ce015bbdc0899dc948c0f981649039407c -Author: Daniel-Constantin Mierla -Date: Tue Nov 22 10:10:41 2022 +0100 +commit 86f0fd45e420874cef4f23f0a1c350e5d9e07a7f +Author: Дилян Палаузов +Date: Wed Jun 21 21:36:19 2023 +0200 - erlang: use proper name for the long field of xavp + rr: typo -commit 8860f244d2ad3587621b033374792a2daae7df22 -Author: Daniel-Constantin Mierla -Date: Tue Nov 22 09:56:12 2022 +0100 +commit 373fb98ef5e4f9a403d0e93080906cea02b41918 +Author: Дилян Палаузов +Date: Wed Jun 21 21:36:07 2023 +0200 - jwt: trim read value for the key - - - GH #3282 + rls: typos -commit f80c9a016bd3664cde3132f0f71064acdd3290f2 -Author: Daniel-Constantin Mierla -Date: Tue Nov 22 09:32:58 2022 +0100 +commit 44bbc54018375c6717adb78f8bffdd12fede292d +Author: Дилян Палаузов +Date: Wed Jun 21 21:35:38 2023 +0200 - usrloc: updated to use xavp long value field + registrar: typos and formatting -commit 44c018db84c846dbb2f1cb9551793b187449b450 -Author: Daniel-Constantin Mierla -Date: Tue Nov 22 09:32:58 2022 +0100 +commit 650b109dbcfe2c3083e09c987bae7ca39e4a19d2 +Author: Дилян Палаузов +Date: Wed Jun 21 21:34:21 2023 +0200 - tm: updated to use xavp long value field + regex: typos -commit c090b40c5d63458904349c3800101ac0429dc572 -Author: Daniel-Constantin Mierla -Date: Tue Nov 22 09:32:58 2022 +0100 +commit fcbde898093f3316e238baa19af50996cc9d087b +Author: Дилян Палаузов +Date: Wed Jun 21 21:33:50 2023 +0200 - sqlops: updated to use xavp long value field + ratelimit: typo -commit 2dd4a5902cb292948378ef4f25ac92cf2aa79614 -Author: Daniel-Constantin Mierla -Date: Tue Nov 22 09:32:58 2022 +0100 +commit 73a766a99a859f41ad796cb4282ac3f2675fb18f +Author: Дилян Палаузов +Date: Wed Jun 21 21:33:25 2023 +0200 - rtjson: updated to use xavp long value field + qos: typos -commit 9e7e3675c55122c7df83aef49fe3662a9374ee5b -Author: Daniel-Constantin Mierla -Date: Tue Nov 22 09:32:58 2022 +0100 +commit 2d26aa4193f2bf8c6598ca00fb8b03bd4adb73f8 +Author: Дилян Палаузов +Date: Wed Jun 21 21:32:30 2023 +0200 - registrar: updated to use xavp long value field + presence: typo -commit b958a486a4ac586cd04f13f32e0204d41dcb1418 -Author: Daniel-Constantin Mierla -Date: Tue Nov 22 09:32:58 2022 +0100 +commit 194cc306c445c8050da5dcd5ecc64b585727f28f +Author: Дилян Палаузов +Date: Wed Jun 21 21:31:59 2023 +0200 - pv_headers: updated to use xavp long value field + pike: typo -commit afbd2bf2db1d1ac6a1ee3bad6613e357f2a6a637 -Author: Daniel-Constantin Mierla -Date: Tue Nov 22 09:32:58 2022 +0100 +commit 26caea49d9d1834a3bf9ebe208a5b3ef3e52f88b +Author: Дилян Палаузов +Date: Wed Jun 21 21:31:40 2023 +0200 - pv: updated to use xavp long value field + permissions: typos -commit 642530f6541a39b386f6618b859e48d011873075 -Author: Daniel-Constantin Mierla -Date: Tue Nov 22 09:32:58 2022 +0100 +commit dfbc9aba5bf9a11545cbaee74393225ffcb0067a +Author: Дилян Палаузов +Date: Wed Jun 21 21:31:25 2023 +0200 - presence: updated to use xavp long value field + p_usrloc: typo -commit 24b3bf22546c7692e562eba35a8f57eb3147a1e9 -Author: Daniel-Constantin Mierla -Date: Tue Nov 22 09:32:58 2022 +0100 +commit c663fac898f6976ed96480bc924cc7ea1e50614a +Author: Дилян Палаузов +Date: Wed Jun 21 21:30:56 2023 +0200 - log_systemd: updated to use xavp long value field + osp: typos -commit e06fb0a84fa3db63d06cb764e89e8b7422848759 -Author: Daniel-Constantin Mierla -Date: Tue Nov 22 09:32:57 2022 +0100 +commit 0dcaaed5148cba775cebfd88d8e4a593f8c4297d +Author: Дилян Палаузов +Date: Wed Jun 21 21:29:41 2023 +0200 - jansson: updated to use xavp long value field + mohqueue: typo -commit 81232aba8a95f79647a5d6189bd9d3efcc580269 -Author: Daniel-Constantin Mierla -Date: Tue Nov 22 09:32:57 2022 +0100 +commit 1335e93a76d051cb724bc696ac857aa7c3a3f43e +Author: Kamailio Dev +Date: Thu Jul 13 17:46:27 2023 +0200 - erlang: updated to use xavp long value field + modules: readme files regenerated - imc ... [skip ci] -commit 619a65b94d6a7980cee11731248e2c22c3bba8b4 +commit 27a4fc543cb60636308e587523236b1ac4d56754 Author: Daniel-Constantin Mierla -Date: Tue Nov 22 09:32:57 2022 +0100 +Date: Thu Jul 13 17:40:48 2023 +0200 - dispatcher: updated to use xavp long value field + imc: docs for imc_room_member() -commit cfbe1e405948dfa873d49a36036ffcd03a95ac46 +commit daa88d8b287de5b40a478fd8291a45311fe738b2 Author: Daniel-Constantin Mierla -Date: Tue Nov 22 09:32:57 2022 +0100 +Date: Thu Jul 13 17:36:57 2023 +0200 - debugger: updated to use xavp long value field + imc: exported imc_room_member() to kemi -commit 96a174a4f4fe2cb3ba8ae3ba09a25190be85196b +commit 04bb88f988d4e99625efef3f3b575b5a2dc652c1 Author: Daniel-Constantin Mierla -Date: Tue Nov 22 09:32:57 2022 +0100 +Date: Thu Jul 13 17:25:47 2023 +0200 - cfgt: updated to use xavp long value field + imc: added function to check if a user is member of a chat room -commit 74f0c5414c3992d3790dc8195672607289e6c3d3 -Author: Daniel-Constantin Mierla -Date: Tue Nov 22 09:32:57 2022 +0100 +commit 508886c3054a8470fe4469e78e63aa37ae93922d +Author: MVONDO Eric OBS/OINIS +Date: Tue Jun 20 10:22:48 2023 +0100 - avpops: updated to use xavp long value field + siptrace: fix pseudo var direction attribute length -commit e97541cda7ad5342b3b9daaa29469d115102e429 -Author: Daniel-Constantin Mierla -Date: Tue Nov 22 09:32:57 2022 +0100 +commit 675f6c0224897544d30f5f863c503499b2e5f2fe +Author: Victor Seva +Date: Tue Jul 4 18:47:57 2023 +0200 - app_lua_sr: updated to use xavp long value field + core: modparam use strncpy() for setting boundaries + + * use strncat() + + > https://github.com/kamailio/kamailio/security/code-scanning/1836 + > https://github.com/kamailio/kamailio/security/code-scanning/1834 -commit 4c022cb9d6efbdd9d8a46353d8a9d9d1cb7411d9 -Author: Daniel-Constantin Mierla -Date: Tue Nov 22 09:18:47 2022 +0100 +commit 7e8a70e9bf3d0b52eae1b7933633095686f234b2 +Author: Victor Seva +Date: Tue Jun 27 14:20:59 2023 +0200 - core: xavp - number value is hold on long type field + jsonrcps: use strncpy() for setting boundaries + + * use strncat() - - removed the int field for type SR_XTYPE_INT + > https://github.com/kamailio/kamailio/security/code-scanning/2381 + > https://github.com/kamailio/kamailio/security/code-scanning/2380 + > https://github.com/kamailio/kamailio/security/code-scanning/1843 + > https://github.com/kamailio/kamailio/security/code-scanning/1841 -commit 228bdac63e53a39b048e055dbecd0c8ff09098d6 -Author: Daniel-Constantin Mierla -Date: Tue Nov 22 09:12:35 2022 +0100 +commit e347d89dba284f2d9635828b10b7ed49ad2244ad +Author: Victor Seva +Date: Tue Jun 27 10:27:47 2023 +0200 - core: pv - helper functions use long for value + core: socket_info use strncpy() for setting boundaries + + > https://github.com/kamailio/kamailio/security/code-scanning/2586 -commit d1db642736e9b573644f97a828dc7acd2f6abbfd -Author: Daniel-Constantin Mierla -Date: Mon Nov 21 11:30:35 2022 +0100 +commit 77ca2e93e945fe46783e953d58bc546d9d6d1b81 +Author: Victor Seva +Date: Tue Jun 27 10:20:57 2023 +0200 - core: avp - renamed structures to use num instead of int + permissions: use strncpy() for setting boundaries - - type of number is long + > https://github.com/kamailio/kamailio/security/code-scanning/2616 + > https://github.com/kamailio/kamailio/security/code-scanning/1845 -commit 7f258d97431a9a4bccf8155def52c9e9070c9f1d -Author: Daniel-Constantin Mierla -Date: Mon Nov 21 11:28:32 2022 +0100 +commit dd04bceb99ba69bd59c67ba103f3c55d47a31dd6 +Author: Victor Seva +Date: Tue Jun 27 09:49:35 2023 +0200 - sipcapture: debug message with header offset and address family + path: use snprintf() instead of sprintf() + + > https://github.com/kamailio/kamailio/security/code-scanning/2612 + > https://github.com/kamailio/kamailio/security/code-scanning/2613 + > https://github.com/kamailio/kamailio/security/code-scanning/2614 + > https://github.com/kamailio/kamailio/security/code-scanning/2615 -commit 5ff6404b4d5d63a3c0b573b485abfb1893288c67 -Author: Daniel-Constantin Mierla -Date: Mon Nov 21 11:09:35 2022 +0100 +commit d00ceda2c0428c6c02f3ed6d4c8c067e3f6ae94b +Author: Victor Seva +Date: Tue Jun 27 09:23:31 2023 +0200 - tm: updated for avp long value field + rtpproxy: use memcpy instead of strcpy for coherence + + > https://github.com/kamailio/kamailio/security/code-scanning/2617 + > https://github.com/kamailio/kamailio/security/code-scanning/2618 + > https://github.com/kamailio/kamailio/security/code-scanning/2620 -commit 6a22d4168a1614cf84df690ac6b56c0fa0857542 -Author: Daniel-Constantin Mierla -Date: Mon Nov 21 11:09:35 2022 +0100 +commit cbd7810fff3d5145c1ce34c0e362b5590bb92a12 +Author: Victor Seva +Date: Tue Jun 27 08:48:10 2023 +0200 - tls: updated for avp long value field + sipcapture: use memcpy instead of strncpy for coherence + + > https://github.com/kamailio/kamailio/security/code-scanning/2620 + > https://github.com/kamailio/kamailio/security/code-scanning/2621 -commit 6a5c4930976a9e2a6d52748524759f4b64d23d9f -Author: Daniel-Constantin Mierla -Date: Mon Nov 21 11:09:35 2022 +0100 +commit e17a3de2994e3237ea4a0916f60635f9f038d266 +Author: Emmanuel Schmidbauer +Date: Fri Jul 7 10:15:06 2023 -0400 - sdpops: updated for avp long value field + nats: nats_publish set reply parameter to be optional -commit 9911482bc6889107a1930239f4e2860ed080365c -Author: Daniel-Constantin Mierla -Date: Mon Nov 21 11:09:35 2022 +0100 +commit 9fd006e48469d86f68926418fc749cb798fdc9b7 +Author: Kamailio Dev +Date: Wed Jul 12 09:16:27 2023 +0200 - rtpproxy: updated for avp long value field + modules: readme files regenerated - imc ... [skip ci] -commit 39b71dcf637794ef95a1e218e9bb28540fd681a0 +commit 4d0459545ada92786d3d7ee1f9aeefd82c8527e7 Author: Daniel-Constantin Mierla -Date: Mon Nov 21 11:09:35 2022 +0100 +Date: Wed Jul 12 09:06:49 2023 +0200 - rtpengine: updated for avp long value field + imc: docs for imc_room_active() function -commit 6033dbf16a3f16292ef2dece95aba4e2004b4398 +commit ce3b16565a3375c4fcdabb39bfbd0c814f402da9 Author: Daniel-Constantin Mierla -Date: Mon Nov 21 11:09:35 2022 +0100 +Date: Wed Jul 12 09:00:56 2023 +0200 - pv: updated for avp long value field + imc: added function to check if a room is active -commit 25afad678b5753af6f3ad68fee44c7e948543a81 +commit 874351c0d4bc4e8fce5dd9f3ca617e8c3b61ef89 Author: Daniel-Constantin Mierla -Date: Mon Nov 21 11:09:35 2022 +0100 +Date: Wed Jul 12 08:28:41 2023 +0200 - mtree: updated for avp long value field + imc: reformat initialized structures -commit 179af99d46d176e07cfaff4057025b69402ba5cd -Author: Daniel-Constantin Mierla -Date: Mon Nov 21 11:09:34 2022 +0100 +commit 5da9ba4c12161ac864022b1624faef6c16777b4f +Author: Kamailio Dev +Date: Tue Jul 11 18:32:06 2023 +0200 - matrix: updated for avp long value field + modules: readme files regenerated - msilo ... [skip ci] -commit ce0d289824b5dac742355340703e7051ccd190d0 +commit 917b608f958e9a7a68388d8b53630cdf9cb2f3b1 Author: Daniel-Constantin Mierla -Date: Mon Nov 21 11:09:34 2022 +0100 +Date: Tue Jul 11 18:21:52 2023 +0200 - htable: updated for avp long value field + msilo: docs for use_mode parameter -commit d2f1e39d153fb0b6b83085f980cb6d83dcf45923 +commit 8ada99e8c686db639ee73a6584816c3fe0096b6d Author: Daniel-Constantin Mierla -Date: Mon Nov 21 11:09:34 2022 +0100 +Date: Tue Jul 11 18:17:40 2023 +0200 - group: updated for avp long value field + msilo: option to store call-id and reuse it on delivery -commit 34ec72e099eb51a81a32155fc7e50cb966232b45 +commit 38514a77aea446e36ba5ce2db32d0c4ae57571ed Author: Daniel-Constantin Mierla -Date: Mon Nov 21 11:09:34 2022 +0100 +Date: Tue Jul 11 17:42:17 2023 +0200 - domainpolicy: updated for avp long value field + msilo: docs for parms to set column names for callid and status -commit 59fb187c7706f9e59cdb69079127b5c6152b0811 +commit cdd6b960f4cfea2fa8a2f5f79750568d8c49d89f Author: Daniel-Constantin Mierla -Date: Mon Nov 21 11:09:34 2022 +0100 +Date: Tue Jul 11 17:37:27 2023 +0200 - domain: updated for avp long value field + msilo: exppose callid and status columns as params to match db schema -commit 46214133bf64b8c89872b9937cda54c74285d9b9 -Author: Daniel-Constantin Mierla -Date: Mon Nov 21 11:09:34 2022 +0100 +commit 7ca151a0479e4971980f4bbbc10cbd8f7deea1b6 +Author: Kamailio Dev +Date: Mon Jul 10 11:01:31 2023 +0200 - debugger: updated for avp long value field + modules: readme files regenerated - msilo ... [skip ci] -commit 8cdcb9b28c22b40099df3bab3a402eb3e1fc791c +commit 8da60f5a0a55fa2d5bb084b8215b96ec4c032161 Author: Daniel-Constantin Mierla -Date: Mon Nov 21 11:09:34 2022 +0100 +Date: Mon Jul 10 10:48:46 2023 +0200 - cfgt: updated for avp long value field + msilo: docs for m_store_addrs() -commit bbaafb0bc0b94a7b14c1ef17d7315210e3d0376f +commit 3542608f89dba934d943c3de8b66e178c0cecdc5 Author: Daniel-Constantin Mierla -Date: Mon Nov 21 11:09:34 2022 +0100 +Date: Mon Jul 10 10:42:15 2023 +0200 - carrierroute: updated for avp long value field + msilo: new function to allow specifying src/dst addresses -commit 132ffd7a48664c013aa3c095996e0c3d18c9f3f8 +commit 7827013c50121b5d085dc3352b44aad940460513 Author: Daniel-Constantin Mierla -Date: Mon Nov 21 11:09:34 2022 +0100 +Date: Mon Jul 10 10:15:49 2023 +0200 - avpops: updated for avp long value field + msilo: reformat exports structures for better alignment -commit 887903caa12a7cae785a8814ee9fa9a89f5d5c21 +commit b1356efd61e56eaa3426d8e2e813ea6730b4f2c9 Author: Daniel-Constantin Mierla -Date: Mon Nov 21 11:09:34 2022 +0100 +Date: Fri Jul 7 17:41:15 2023 +0200 - avp: updated for avp long value field + registrar: increase max size for user and domain building aor + + - renamed max aor lenght define to match the user and domain style -commit d536fb24bc265358924887877ce4395a41517e9a +commit 883f6b77211a76b35a9df570a8ddbbc344b05472 Author: Daniel-Constantin Mierla -Date: Mon Nov 21 10:32:21 2022 +0100 +Date: Thu Jul 6 21:26:28 2023 +0200 - core: avp - number field set to long + kex: safety checks when iterating stats list + + - GH #3186 -commit 00a8b6d765cdd8a1fc3b77416912f1163801a40e -Author: Daniel-Constantin Mierla -Date: Sun Nov 20 21:02:18 2022 +0100 +commit 498e9f7276459b3f3963544527d9bd2ae5d36e40 +Author: Henning Westerholt +Date: Wed Jul 5 10:08:57 2023 +0000 - lib/srdb1: cast pv value to long + ims_qos: remove not needed function name prefix from log message (related to GH #3503) -commit 8c4feb02e0e85771746b5c39af9fe65fbe54384e -Author: Daniel-Constantin Mierla -Date: Sat Nov 19 18:48:18 2022 +0100 +commit 2dbaa727a38e29da0f887fa5d0d8d20392839f9b +Author: Henning Westerholt +Date: Wed Jul 5 07:04:46 2023 +0000 - ims_dialog: cast pv value to long + tm: remove obselete comment, add clarification for reply_wait mode 2 -commit cbcad7a16173c2c436aabb70f848bcde5eb839b2 -Author: Daniel-Constantin Mierla -Date: Fri Nov 18 19:11:53 2022 +0100 +commit e5dc437808c4ecd81b61768d1d44c0de0ad16306 +Author: Kamailio Dev +Date: Tue Jul 4 18:47:16 2023 +0200 - core: updates to functions for cfg val int to long replacement + modules: readme files regenerated - xlog ... [skip ci] -commit d02732adef800b7a1107d106ac8e58730e256485 -Author: Daniel-Constantin Mierla -Date: Thu Nov 17 14:39:21 2022 +0100 +commit 1b291315b43da1148cee5f3821ddbe49b0c86b7f +Author: Stefan Mititelu +Date: Tue Jul 4 16:58:53 2023 +0300 - core: helper function to get mod param function in a string buffer + ims_qos: check and log for NULL sessionId -commit 1256392ab12ec1ada491f2fc5212bb99ba6fc14c -Author: Kamailio Dev -Date: Thu Nov 17 13:46:55 2022 +0100 +commit b5a37683e364f596b6c5b4ebbba1fff951d7be84 +Author: Norbert Koppány Legyes +Date: Tue Jul 4 17:27:17 2023 +0200 - modules: readme files regenerated - jansson ... [skip ci] + xlog: fix docs example for modparam methods_filter -commit d47d62f54c9115c765a1437ffc8c8e619e056f54 -Author: Daniel-Constantin Mierla -Date: Thu Nov 17 13:44:37 2022 +0100 +commit f9d6685c9ae01fa4cdda1ddb20f29f7e1239f981 +Author: Sergey Safarov +Date: Sun Jul 2 21:31:29 2023 +0300 - jansson: docs for jansson_pv_get() function + pkg/kamailio/obs: packaged geoip2 module -commit 3ce5c42c53dcf6f3f1da952d3b523876c7381913 +commit 7cd32bf9631a81c7c4382d45f498bdc9c7f9b34c Author: Daniel-Constantin Mierla -Date: Thu Nov 17 13:38:05 2022 +0100 +Date: Mon Jul 3 08:26:07 2023 +0200 - jansson: added jansson_pv_get(...) + http_client: use LIBCURL_VERSION_NUM instead of CURL_AT_LEAST_VERSION - - similar to jansson_geet(), but the input has to be a single variable - name, not a dynamic string + - older distros have compilers that don't cope with the later -commit a83e44b7a942afcf1770fa179cda8e530c74e28a +commit b8cae4fbcd026ffb81e8242500212582d9672ad5 Author: Daniel-Constantin Mierla -Date: Thu Nov 17 13:05:59 2022 +0100 +Date: Fri Jun 30 08:49:19 2023 +0200 - core: new global parameter return_mode - - - control the return code evaluation mode: - - 0 (default) - evaluation is like so far (negative is false, positive - is true) - - 1 - propagate return value and evaluation has to be done with >0 or - <0, otherwise value!=0 is evaluated to true no matter is negative - or positive + jansson: print unknown type in log message -commit 83b1ebb1ef7f6eb5a2fbc05f0da5a0e9a1109eca -Author: Henning Westerholt -Date: Wed Nov 16 15:46:31 2022 +0000 +commit 0e1aabd76cc59cd498e2e41ddff141bad793e0a7 +Author: Kamailio Dev +Date: Thu Jun 29 10:47:08 2023 +0200 - dialog: remove variable self-assignment that causes compilation warnings + modules: readme files regenerated - microhttpd ... [skip ci] -commit 17bc73c9dc35c0ec551e851bbff32f06ac4c32dd +commit 64086e607928fe458d6a32f384ef8449455d2679 Author: Daniel-Constantin Mierla -Date: Wed Nov 16 16:39:25 2022 +0100 +Date: Thu Jun 29 10:33:51 2023 +0200 - tls: switch to long pvar field + microhttpd: docs for listen_addr parameter -commit 6be9476b722e0496e8416acce691b8e5529a9882 +commit 94a3fbe46fc55d754cc499e3fbd4f6138ebe14e6 Author: Daniel-Constantin Mierla -Date: Wed Nov 16 16:18:41 2022 +0100 +Date: Thu Jun 29 10:28:00 2023 +0200 - debugger: switch to long pvar field + microhttpd: parameter to specify listen address -commit d1c13663538349282915ce7f861b337f8923fff6 -Author: Daniel-Constantin Mierla -Date: Wed Nov 16 16:12:03 2022 +0100 +commit f82fba83957c6ae62dd150914c80cb062af433f4 +Author: Victor Seva +Date: Wed Jun 28 15:04:28 2023 +0200 - lrkproxy: switch to long pvar field + pkg/kamailio/deb: version set 5.8.0~dev1 [skip ci] -commit 2aefad224788891f61b25e2ea683a9a6b35ac069 +commit 9de2d3e9661fe514ca0aa20a12771ca3e6dc70d6 Author: Daniel-Constantin Mierla -Date: Wed Nov 16 16:03:32 2022 +0100 +Date: Wed Jun 28 15:02:05 2023 +0200 - pv: switch to long pvar field + Makefile.defs: version set to 5.8.0-dev1 -commit d096290d7b9d27a5e817bc40eebd16e1e09be885 +commit d0aeacdc56f8b78477516e3a992e93b0f5219a60 Author: Daniel-Constantin Mierla -Date: Wed Nov 16 15:57:54 2022 +0100 +Date: Tue Jun 27 17:49:59 2023 +0200 - rtpengine: switch to long pvar field + microhttpd: set the content-type header in response -commit 721b728356fa31bd35721d9ba5d047121f535d5e -Author: Daniel-Constantin Mierla -Date: Wed Nov 16 15:56:14 2022 +0100 +commit 15348a754a398b830345e485926022a199c4fc00 +Author: Victor Seva +Date: Wed Jun 28 13:59:10 2023 +0200 - rtpproxy: switch to long pvar field + pkg/kamailio/deb: remove microhttpd from older versions + + > https://kamailio.sipwise.com/job/kamailiodev-nightly-binaries/2442/console -commit 0fccc0949ac682dc59a4a5e00f3ee895c244ee6a +commit 4baaba99fa729d4e5aae6f29c614c22cdaca452c Author: Daniel-Constantin Mierla -Date: Wed Nov 16 15:19:47 2022 +0100 +Date: Tue Jun 27 15:40:49 2023 +0200 - sdpops: switch to long pvar field + microhttpd: export send reply to kemi -commit 9ecbdce1a5ded2c5247a9a204b7841627f5e172a -Author: Daniel-Constantin Mierla -Date: Wed Nov 16 15:01:38 2022 +0100 +commit 3bc5a5775c490d0bfd43030f7eb437ead0d86d89 +Author: Kamailio Dev +Date: Tue Jun 27 13:32:05 2023 +0200 - call_control: switch to long pvar field + modules: readme files regenerated - microhttpd ... [skip ci] -commit 9055763381d56fb78384fd33589c7c2e768f0572 +commit 5ba80fdb5f549f26fad974965f5172834719e9ca Author: Daniel-Constantin Mierla -Date: Wed Nov 16 14:51:52 2022 +0100 +Date: Tue Jun 27 13:22:39 2023 +0200 - core: pv - field for int value switched to long + microhttpd: docs - updates with parameters, functions and event routes -commit b8d74973cffc504a76c543f65940a4810633efe5 +commit b22f3718d8fc23860eafb8d1fb17d7ff4ec532ec Author: Daniel-Constantin Mierla -Date: Wed Nov 16 14:20:38 2022 +0100 +Date: Tue Jun 27 13:05:52 2023 +0200 - core: rename RV_INT to RV_LONG and RVE_INT_OP to RVE_LONG_OP - -commit 9762c5f0d8268e76d55030203b5f0021509fffe6 -Author: Kamailio Dev -Date: Wed Nov 16 16:46:25 2022 +0100 - - modules: readme files regenerated - dialog ... [skip ci] + microhttpd: implemented request handler callback + + - execute event_route[microhttpd:request] when receiving an HTTP request -commit a6d9505b107204ffbe613d9f78beac22e09e8915 -Author: Henning Westerholt -Date: Wed Nov 16 15:33:06 2022 +0000 +commit 777ecf6bd8735538bf61f4f6e10d46ad7c39981b +Author: Victor Seva +Date: Tue Jun 27 10:00:26 2023 +0200 - dialog: deactivate print variable function which is only used for debugging + github: don't execute codeql for each push [skip ci] - - deactivate print variable function which is only used for debugging - - this function is not good for performance and might also cause race conditions + * set schedule cifuzz and codeql -commit 8c59f8e782381811b1afb6a75b8b8c9fa6959933 -Author: Kamailio Dev -Date: Tue Nov 15 17:31:21 2022 +0100 +commit 7e94c365359ca24ae7410121a5e4b4f7382b0b79 +Author: Victor Seva +Date: Tue Jun 27 08:34:25 2023 +0200 - modules: readme files regenerated - app_python3 ... [skip ci] + github: permissions for actions [skip ci] -commit 34d60608bea449ab7258a5d88894651303b80adf -Author: Daniel-Constantin Mierla -Date: Tue Nov 15 17:24:23 2022 +0100 +commit 02a066e95f6b58f04663dc21c4061883d568677b +Author: Victor Seva +Date: Tue Jun 27 08:22:46 2023 +0200 - app_python3: docs - added note about how Python modules used in script can be reloaded + pkg/kamailio/deb: kamailio-microhttpd-modules -commit 5ecae10fabb5da1911c7a7843ba3fb595bfb39e0 -Author: Kamailio Dev -Date: Thu Nov 10 12:01:36 2022 +0100 +commit 68998a16c94c8b14e31f5cc3c6d862ce37fde47c +Author: Daniel-Constantin Mierla +Date: Tue Jun 27 08:00:16 2023 +0200 - modules: readme files regenerated - dialog ... [skip ci] + Makefile.groups: group for microhttpd module -commit 91da5bd0c9d08d4a2979bab6053b417e16b51cf6 -Author: Victor Seva -Date: Mon Nov 7 11:20:24 2022 +0100 +commit 7c33160820c56c75c140bd4d84e0bacf3ca328fd +Author: Daniel-Constantin Mierla +Date: Tue Jun 27 07:05:43 2023 +0200 - dialog: add a note for early dialogs in dlg_set_var() + microhttpd: added local context structure -commit 966dab757d094b99c48431f7a22c2b557d53c4d1 -Author: Victor Seva -Date: Fri Nov 4 11:23:59 2022 +0100 +commit d215b5562e959db6a90bca65bea94fff9971ab74 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jun 26 23:36:35 2023 +0000 - dialog: dlg_set_var() support empty totag parameter + github: bump actions/upload-artifact from 1 to 3 + + Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 1 to 3. + - [Release notes](https://github.com/actions/upload-artifact/releases) + - [Commits](https://github.com/actions/upload-artifact/compare/v1...v3) - * support setting vars for non established dialogs + --- + updated-dependencies: + - dependency-name: actions/upload-artifact + dependency-type: direct:production + update-type: version-update:semver-major + ... + + Signed-off-by: dependabot[bot] -commit 4172faaaa60333595fe6444deefbaa2babe8e9e1 -Author: Kamailio Dev -Date: Wed Nov 9 21:31:29 2022 +0100 +commit 549cca07beef76f734e9eafe06a66b5509170b07 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jun 26 23:29:55 2023 +0000 - modules: readme files regenerated - ims_usrloc_pcscf ... [skip ci] + github: bump actions/checkout from 2 to 3 + + Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. + - [Release notes](https://github.com/actions/checkout/releases) + - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) + - [Commits](https://github.com/actions/checkout/compare/v2...v3) + + --- + updated-dependencies: + - dependency-name: actions/checkout + dependency-type: direct:production + update-type: version-update:semver-major + ... + + Signed-off-by: dependabot[bot] -commit c4afb8dab4f12a3a305894e4e260292b5bdca0d7 -Author: Henning Westerholt -Date: Wed Nov 9 20:28:45 2022 +0000 +commit b306bab6fb87033dadbf7b5eefbfbd233e3dc51a +Author: Victor Seva +Date: Tue Jun 27 01:34:01 2023 +0200 - ims_usrloc_pcscf: document expires_grace parameter + github: dependabot use prefix in commit [skip ci] -commit e7bd1570e3788e9d04047b4d1d00cb8bd8b172d3 -Author: Daniel-Constantin Mierla -Date: Mon Nov 7 21:11:56 2022 +0100 +commit 881bcd1094af3846fa0770d64a4f7c93b5835921 +Author: Victor Seva +Date: Tue Jun 27 01:28:41 2023 +0200 - websocket: more details on debig messages + github: remove updater.yaml [skip ci] + + * we are now using dependabot directly -commit a0d9deb9f852f887bed7c0809f3056b5f75379c8 -Author: Daniel-Constantin Mierla -Date: Fri Nov 4 09:55:22 2022 +0100 +commit f73484df4d75aa8a82f3b3ecece9431a79be88f1 +Author: Victor Seva +Date: Tue Jun 27 01:24:46 2023 +0200 - secsipid: ensure headers are parsed + github: create dependabot.yml -commit 0920aa1a27565bc52fd1ff9f4b9fc31dbd0d2a75 -Author: Daniel-Constantin Mierla -Date: Fri Nov 4 09:28:23 2022 +0100 +commit 006a6c2fc7039ccbd9d1230ecbdf7f774e1c0c54 +Author: Victor Seva +Date: Mon Jun 26 23:36:28 2023 +0200 - secsipid: debug message if identity header is not found + github: switch to bookworm for builds [skip ci] + + * codeql: add libmicrohttpd-dev dependency + build was failing due to missing dependency -commit e617ef84c3bbd3bbcb780991bc45216112056f94 -Author: Jose Luis Verdeguer -Date: Thu Nov 3 14:34:17 2022 +0100 +commit 1f3746cd020f5c6031cd157894d636f312132946 +Author: Victor Seva +Date: Mon Jun 26 23:24:53 2023 +0200 - secfilter: little fix in w_check_sqli + pkg/kamailio/deb: add libmicrohttpd-dev for microhttpd module -commit cd3b776649e652b5d27b2718c22f08736b1e9e84 +commit 2fa65883921be855710a3ab249c87980b4f42d60 Author: Daniel-Constantin Mierla -Date: Thu Nov 3 10:20:10 2022 +0100 - - secsipid: iterate through all Identity headers - -commit 065a83fbb1a8b9b1912aadecff039a485c2d46dd -Author: Kamailio Dev -Date: Sat Oct 29 09:31:37 2022 +0200 - - modules: readme files regenerated - dispatcher ... [skip ci] - -commit 0dc7d711c4c2d16d532862344f9ccd629de38e20 -Author: Henning Westerholt -Date: Sat Oct 29 07:17:10 2022 +0000 +Date: Mon Jun 26 16:50:19 2023 +0200 - dispatcher: small docs extensions regarding to ds_select_dst + microhttpd: new module implementing a http server using libmicrohttpd -commit 9b4d4d059e6222a64a9b9cadb0b867bea27ed0d8 -Author: Henning Westerholt -Date: Sat Oct 29 07:15:10 2022 +0000 +commit badc81cb427ba5aaf03ca26e4c2654d58ee08588 +Author: Victor Seva +Date: Fri Jun 23 09:06:43 2023 +0200 - dispatcher: small spelling fix in comment + utils/kamcmd: fix memory leak + + fixes #3478 -commit e7e2366634f7b56136b11d4b196150467a18b651 -Author: Henning Westerholt -Date: Sat Oct 29 07:14:32 2022 +0000 +commit 82f5fcbf88ee3058bd9da520b528c86393cc422a +Author: Victor Seva +Date: Thu Jun 22 17:29:48 2023 +0200 - core: small spelling fix in comment + tls: fix build for openssl < 1.1.1 + + OPENSSL_INIT_ATFORK was introduced in libssl 1.1.1 + error introduced at 9d6bfb96528c49e6aaa39aa47be877ca528c3537 -commit 77840e465e1e074ede44fbc262faa850e1c4f862 -Author: Kamailio Dev -Date: Thu Oct 27 10:16:43 2022 +0200 +commit 4d8263f9be97a541a24cbc6acc9855509640780b +Author: Daniel-Constantin Mierla +Date: Thu Jun 22 14:37:18 2023 +0200 - modules: readme files regenerated - app_python3 ... [skip ci] + http_client: fix depecration of CURLOPT_REDIR_PROTOCOLS + + - GH #3492 -commit 0d6d434a92ae69cf1e503f07ffa6f46a9948593e +commit 81be9e78c3731d45734480285d7afc17f8f9e87a Author: Daniel-Constantin Mierla -Date: Thu Oct 27 10:07:36 2022 +0200 +Date: Wed Jun 21 14:15:24 2023 +0200 - app_python3: note about kemi symbols and python reserved words + tls: enable locking for rand ctx if libssl version is 3.0+ -commit ad4faf03628db45d30f27358b81afd8e0bee03c0 +commit 3a4681c55eaca962344c0e451aa7e91770fb3dc5 Author: Daniel-Constantin Mierla -Date: Wed Oct 26 16:11:42 2022 +0200 +Date: Wed Jun 21 13:39:02 2023 +0200 - siputils: export add_uri_param() to kemi + rtpengine: use the long long macro to get the value from json -commit 3bcef382b810b4cd2a5a03b079086fee3bbbe187 +commit b7b3c67fc1205d114fadf360a594930ef69835a3 Author: Daniel-Constantin Mierla -Date: Tue Oct 25 18:45:33 2022 +0200 +Date: Wed Jun 21 09:27:28 2023 +0200 - rtp_media_server: init global variables + http_client: fix depecration of CURLOPT_PROTOCOLS and CURLINFO_SIZE_DOWNLOAD + + - GH #3484 -commit d5afbf0fb2f006d38fdfe32f6d2094638ad938b0 -Author: Daniel-Constantin Mierla -Date: Tue Oct 25 10:16:07 2022 +0200 +commit 4985bc9cc764699297235d4220ec9a07a9286988 +Author: Kamailio Dev +Date: Wed Jun 21 08:16:22 2023 +0200 - nats: formatted module exports structures + modules: readme files regenerated - rtpengine ... [skip ci] -commit 619ff95d760c9b98df515ddccc5aa1e39275beeb -Author: Daniel-Constantin Mierla -Date: Tue Oct 25 10:08:42 2022 +0200 +commit 4d51c674c5b9635b7f7d9ab39582752b856373d4 +Author: Joey Golan +Date: Tue Jun 13 20:10:58 2023 +0300 - nats: init global variables + rtpengine: release json document object -commit 51d2f707562f70749dd02727a34dc5e4fa20712e -Author: Daniel-Constantin Mierla -Date: Tue Oct 25 10:06:06 2022 +0200 +commit 75b41baad06bbd7f57fa8e1f71c608852df7494b +Author: Joey Golan +Date: Tue Jun 13 08:16:41 2023 +0300 - nats: safety check for nats_workers and nats_pub_workers on mod destroy + rtpengine: fix build failed on specific distribution + + Fix clang-format-checker errors -commit 51fc76737319f9b06ee4aa86e8c15c3fd5b62248 -Author: Daniel-Constantin Mierla -Date: Mon Oct 24 18:52:35 2022 +0200 +commit 17da2e8344fc5f010ae08277a89b4b122dd8c56b +Author: Joey Golan +Date: Mon Jun 12 20:44:01 2023 +0300 - pv: set str type for $hfl() + rtpengine: Fix rfuchs's PR comments -commit 9ffafd5d218eeec158081ae51c994ececab43944 -Author: Henning Westerholt -Date: Tue Oct 25 06:28:51 2022 +0000 +commit 26f6e57c8ffdf06e6837bb54396cd955bad8402a +Author: Joey Golan +Date: Mon Jun 12 16:34:42 2023 +0300 - db_postgres: use DBG loglevel for memory cleanup, we output an error already + Register a new worker process for dtmf event listener -commit baa961f60508f7bcc0564059eeb86981a79f6d42 -Author: Kamailio Dev -Date: Sat Oct 22 16:46:18 2022 +0200 +commit 44745cabfe78875dffa68f398402117f9a83be27 +Author: Joey Golan +Date: Wed May 31 17:39:34 2023 +0300 - modules: readme files regenerated - secfilter ... [skip ci] + rtpengine: support receiving dtmf events from rtpengine and raise an event -commit e7b3724d3fc514c8a541a6a7f7fb1a782f21f2e7 -Author: Jose Luis Verdeguer -Date: Sat Oct 22 16:41:05 2022 +0200 +commit c4b04696a6bfe31fdd65fa56529b0d46f2774067 +Author: Victor Seva +Date: Mon Jun 19 20:12:17 2023 +0200 - secfilter: Added information about two new params in the README file [skip ci] + tls: disable tls_rand for openssl >= 3.0 + + From https://www.openssl.org/docs/man3.0/man3/RAND_set_rand_method.html + + > All of the functions described on this page are deprecated. + > Applications should instead use RAND_set_DRBG_type(3), EVP_RAND(3) and + > EVP_RAND(7). -commit 518f874e7e177e5696b76c7148c1b4d2c9ab7af4 -Author: Jose Luis Verdeguer -Date: Sat Oct 22 16:30:53 2022 +0200 +commit a0a9373ccb3d3da3a1e9e1335d904fcf013d9ebd +Author: Victor Seva +Date: Mon Jun 19 13:36:53 2023 +0200 - secfilter: cleanup old data after a reload by timer function + tls: disable engine for openssl >= 3.0 + + From https://www.openssl.org/docs/man3.0/man7/migration_guide.html + + > The refactoring to support Providers conflicts internally with the APIs + > used to support engines, including the ENGINE API and any function that + > creates or modifies custom "METHODS" + + From https://www.openssl.org/docs/man3.0/man3/ENGINE_init.html: + + > All of the functions described on this page are deprecated. Applications + > should instead use the provider APIs. -commit 38f17e622e8539883a7213acce3aed0635b11aff -Author: Daniel-Constantin Mierla -Date: Wed Oct 19 17:24:17 2022 +0200 +commit 9d6bfb96528c49e6aaa39aa47be877ca528c3537 +Author: Victor Seva +Date: Tue Jun 13 12:37:21 2023 +0200 - rtp_media_server: removed lib bcunit linking + tls: OPENSSL_fork_[prepare|parent|child] deprecated at openssl 3.0 - - not required for the code - - tested on debian 11 + From https://www.openssl.org/docs/man3.0/man3/OPENSSL_fork_prepare.html: + + > OPENSSL_fork_prepare, OPENSSL_fork_parent, OPENSSL_fork_child have been + > deprecated since OpenSSL 3.0. + > + > These methods are currently unused, and as such, no replacement methods + > are required or planned. + > + > OpenSSL has state that should be reset when a process forks. For + > example, the entropy pool used to generate random numbers (and therefore + > encryption keys) should not be shared across multiple programs. The + > OPENSSL_fork_prepare(), OPENSSL_fork_parent(), and OPENSSL_fork_child() + > functions are used to reset this internal state. + > + > OPENSSL_init_crypto(3) will register these functions with the + > appropriate handler, when the OPENSSL_INIT_ATFORK flag is used -commit b411303502282b2f4d32ad299ed5bcfd0852e902 -Author: Daniel-Constantin Mierla -Date: Mon Oct 17 22:45:23 2022 +0200 +commit af976a989b2ed1bfd9090dd9ce09b0a7a8992965 +Author: Kamailio Dev +Date: Tue Jun 20 11:32:05 2023 +0200 - pv: check for contact address in pv_get_hfl() + modules: readme files regenerated - matrix ... [skip ci] -commit c6aec8b4e8e4840ae9b0359fbbb60188786647b8 -Author: Jose Luis Verdeguer -Date: Tue Oct 18 16:21:11 2022 +0200 +commit ba2e36551ff4f59afdc5f9d2b46bd9dff32e2f22 +Merge: d7ae9f1450 290f50eede +Author: Daniel-Constantin Mierla +Date: Tue Jun 20 11:23:26 2023 +0200 - secfilter: lock position changed + Merge branch 'dilyanpalauzov-typos' + + * dilyanpalauzov-typos: (35 commits) + modules: readme files regenerated - db_redis ... [skip ci] + ndb_redis: Makefile - updated find command for libhiredis_ssl + db_redis: Makefile - updated find command for libhiredis_ssl + ndb_redis: Fixing format + db_redis: Format fixes + ndb_redis: Searching SSL support in gcc search library path + db_redis: Searching SSL support in gcc search library path + ndb_redis: Missing uprotected redisSSLContext + ndb_redis: Fixing global variables names + db_redis: Fixing global variables + db_redis: Fixing Makefile + db_redis: Fixing build + ndb_redis: Format fixes + db_redis: Missing format fixes + db_redis: Fixing format + ndb_redis: Adding TLS support + db_redis: Adding TLS support + utils: typos + test/misc/code: typos + usrloc: typo + ... -commit bd78421dc16d1f2aa647976da5948ee0e750d918 -Author: Jose Luis Verdeguer -Date: Tue Oct 18 16:02:15 2022 +0200 +commit 290f50eede5f22a732e3ab9435682e6bf3d23825 +Author: Kamailio Dev +Date: Tue Jun 20 11:16:33 2023 +0200 - secfilter: added locks while check list values + modules: readme files regenerated - db_redis ... [skip ci] -commit 413efdd80bcffd11a17692d61f32efacf5d34c3d -Author: Sebastian Kemper -Date: Sun Oct 16 16:51:41 2022 +0200 +commit 50f592c63ae8e91b2ba33323a3b7641ad9967c92 +Author: Daniel-Constantin Mierla +Date: Tue Jun 20 11:04:30 2023 +0200 - siputils: fix time_t warning and a typo - - Fix the below warning one gets when compiling siputils for a 32 bit - target against a time64 libc (musl). - - Also fix a spelling mistake on the same line ("autdated" -> "outdated"). + ndb_redis: Makefile - updated find command for libhiredis_ssl - siputils.c: In function 'ki_hdr_date_check': - ../../core/parser/../dprint.h:321:73: warning: format '%ld' expects argument of type 'long int', but argument 11 has type 'time_t' {aka 'long long int'} [-Wformat=] - 321 | fprintf(stderr, "%2d(%d) %s: %.*s%s%s%s" fmt, \ - | ^~~~~~~~~~~~~~~~~~~~~~~~ - ../../core/parser/../dprint.h:345:25: note: in expansion of macro 'LOG_FX' - 345 | LOG_FX(facility, level, lname, prefix, _FUNC_NAME_, fmt, ## args) - | ^~~~~~ - ../../core/parser/../dprint.h:351:25: note: in expansion of macro 'LOG_FL' - 351 | LOG_FL(facility, level, NULL, prefix, fmt, ## args) - | ^~~~~~ - ../../core/parser/../dprint.h:354:25: note: in expansion of macro 'LOG_FP' - 354 | LOG_FP(DEFAULT_FACILITY, (level), LOC_INFO, fmt, ## args) - | ^~~~~~ - ../../core/parser/../dprint.h:392:37: note: in expansion of macro 'LOG' - 392 | # define ERR(fmt, args...) LOG(L_ERR, fmt , ## args) - | ^~~ - ../../core/parser/../dprint.h:418:16: note: in expansion of macro 'ERR' - 418 | #define LM_ERR ERR - | ^~~ - siputils.c:562:17: note: in expansion of macro 'LM_ERR' - 562 | LM_ERR("autdated date header value (%ld sec)\n", tnow - tmsg + tdiff); - | ^~~~~~ + - silent warnings about not existing directories + +commit e9cc9fc15b9ebb87d64478be93980e4c7766d941 +Author: Daniel-Constantin Mierla +Date: Tue Jun 20 11:03:04 2023 +0200 + + db_redis: Makefile - updated find command for libhiredis_ssl - Signed-off-by: Sebastian Kemper + - silent warnings about not existing directories -commit 0d363cf1c1f09b4920e137eac74e1593e7120531 -Author: korayvt -Date: Fri Oct 14 21:27:03 2022 +0300 +commit 279cf4e805838f897c2b71f2ea8c828de1725391 +Author: Joel Centelles +Date: Fri Jun 16 21:08:40 2023 +0200 - rtpengine: fixed set id value in log lines (#3265) + ndb_redis: Fixing format + + Fixing some spaces and indentations -commit 721ec276f2bfcc18236e0b9de1f5552f505f0cda -Author: Daniel-Constantin Mierla -Date: Fri Oct 14 11:17:25 2022 +0200 +commit 03ae83161307feeb95f36a60ef4f50d948a877b2 +Author: Joel Centelles +Date: Fri Jun 16 21:07:29 2023 +0200 - acc: init to 0 the arrays allocated for accounting + db_redis: Format fixes + + Fixing some spaces -commit 932062fc84048eaa38144cf0bbfa7a2cae95a258 -Author: Daniel-Constantin Mierla -Date: Fri Oct 14 11:15:38 2022 +0200 +commit 6c0bc1d276921fae02c06cadc0d96a8ff17b2a2f +Author: Joel Centelles +Date: Fri Jun 16 20:30:28 2023 +0200 - acc: free core attributes for cdrs sent to log file + ndb_redis: Searching SSL support in gcc search library path + + Checking libhiredis_ssl.so in gcc --print-search-dirs -commit 304bf9cab6d50231c9c948ed7d252d91631e7f30 -Author: Henning Westerholt -Date: Fri Oct 14 07:09:23 2022 +0000 +commit d0e84ab04921a01bfb980aa6ff5fb8df50ccd759 +Author: Joel Centelles +Date: Fri Jun 16 20:25:48 2023 +0200 - mqtt: add missing semicolon to #ifdef else case after 2bb8b568 + db_redis: Searching SSL support in gcc search library path + + Checking libhiredis_ssl.so in gcc --print-search-dirs -commit 0994754b9925dad3f306a3ecb9c62c41588390d1 -Author: Henning Westerholt -Date: Fri Oct 14 07:06:54 2022 +0000 +commit 1cde6d38a5d12950f5c405677ba652248881cd64 +Author: Joel Centelles +Date: Tue Jun 13 13:34:31 2023 +0200 - mqtt: use same coding style regarding whitespace/tabs after 2bb8b568 + ndb_redis: Missing uprotected redisSSLContext + + Fixing unprotected redisSSLContext reference in redis_client.h -commit 846ed0ab0d9ed11c9df2636d4061a64aca539a66 -Author: Henning Westerholt -Date: Fri Oct 14 07:05:10 2022 +0000 +commit 053c65d731ceca121a64f6c599f8b78911636c25 +Author: Joel Centelles +Date: Mon Jun 12 13:30:39 2023 +0200 - Revert "mqtt: fix double brackets introduced in 2bb8b568" + ndb_redis: Fixing global variables names - This reverts commit 96e28f8c1ce22042bd1f59dea7607aef51ac1f58. + Adding module name prefixing global variable names to prevent possible + conflicts. Also using ca_path info in SSL context creation. -commit 96e28f8c1ce22042bd1f59dea7607aef51ac1f58 -Author: Henning Westerholt -Date: Fri Oct 14 06:57:52 2022 +0000 +commit 89c9e4eb5df0ef2a8fe064eed961d9b838049cab +Author: Joel Centelles +Date: Mon Jun 12 13:24:31 2023 +0200 - mqtt: fix double brackets introduced in 2bb8b568 + db_redis: Fixing global variables + + Adding module name prefix to global variables to reduce possible conflicts. -commit 88667f7cbf8a41dd3951cdca74d203936ecb164a -Author: Kamailio Dev -Date: Thu Oct 13 17:46:30 2022 +0200 +commit 52d1959d6ed141ab7c2a96f1f79d8d6fd82cda00 +Author: Joel Centelles +Date: Fri Jun 9 13:34:15 2023 +0200 - modules: readme files regenerated - mqtt ... [skip ci] + db_redis: Fixing Makefile + + Removing unprotected references to libhiredis_ssl.so -commit 2bb8b5689c3064bd0ad1da80bdcfa36f29d2b8e3 -Author: Andreas Granig -Date: Thu Oct 13 08:42:14 2022 +0200 +commit 3162c80ee54eab842ddebef07c3c56792f30423b +Author: Joel Centelles +Date: Thu Jun 8 16:59:37 2023 +0200 - mqtt: Add tls_alpn module option + db_redis: Fixing build - This is used when a service (like AWS IoT Core) uses one TLS port - for multiple services (like https and mqtt), so you have to set - the ALPN to 'mqtt' to be able to connect kamailio. + Removing extra declaration outside from WITH_SSL block -commit ea7201d9c3b086fb79c093b4f127516befb08e25 -Author: Kamailio Dev -Date: Thu Oct 13 15:46:31 2022 +0200 +commit 93bcb36ee013e4ab02f71342fa2e2163dc380b8e +Author: Joel Centelles +Date: Thu Jun 8 16:57:04 2023 +0200 - modules: readme files regenerated - tsilo ... [skip ci] + ndb_redis: Format fixes + + Fixing C formatting issues -commit ef2ea73f044a1421b25734d4773bd2dacaab1165 -Author: Federico Cabiddu -Date: Thu Oct 13 15:42:56 2022 +0200 +commit 23a54de62daf07ace22569baf0a52ee851645200 +Author: Joel Centelles +Date: Thu Jun 8 16:48:21 2023 +0200 - tsilo: add new return code to ts_append and document it + db_redis: Missing format fixes + + Removing spaces from line ends. -commit aec01a7e10be54d2e2d9a91e54157a5bdda21e83 -Author: Maksim Nesterov -Date: Thu Sep 22 15:51:51 2022 +0300 +commit 6176c95a17f940c130f6219140593b6f08653e38 +Author: Joel Centelles +Date: Thu Jun 8 16:45:47 2023 +0200 - tm: proper fill of From/To URI/tag values using parsed structure in rpc_t_uac() + db_redis: Fixing format + + Fixing malformed C lines -commit c8bd10f791ef7aa48a16104472b039a8ca1a53c5 -Author: Daniel-Constantin Mierla -Date: Thu Oct 13 11:59:53 2022 +0200 +commit 5b4d1d9e6160ab7aec8e77ab1a3e53651f2d37cc +Author: Joel Centelles +Date: Fri Jun 2 18:44:09 2023 +0200 - kex: added fixup free functions to module exports + ndb_redis: Adding TLS support + + Checks for the tls parameter in the BD schema and, if it's enabled, creates a temporary TLS conext that is used to initialize the redis context. + Adds 1 new parameter: + * ca_path: For specifying a folder containing valid certification chains. -commit bc97b7adf77406dfc08b57b4a7df912a76d324e5 -Author: Daniel-Constantin Mierla -Date: Thu Oct 13 09:40:44 2022 +0200 +commit 8c934aa97890f288c7f06f4df9acad0f5853e03a +Author: Joel Centelles +Date: Fri Jun 2 18:42:16 2023 +0200 - nats: safety check on nats_workers inside mod destroy + db_redis: Adding TLS support + + Enhancing security options by enabling TLS connections and password definition. + Added 3 new parameters: + * opt_tls: For enabling TLS connections. + * ca_path: For specifying a folder containing valid certification chains. + * password: For providing DB access password. + + If opt_tls is provided a temporary SSL context is created to pass it to existing cluster or normal redis context. + TLS support is automatically enabled/disabled by checking libhiredis_ssl.so existence. -commit 6081ae45c21a50036d9b773d11b5c692767d6d1f +commit d7ae9f14502a90301455efbdf776eb785bcbbb50 Author: Kamailio Dev -Date: Wed Oct 12 16:16:30 2022 +0200 +Date: Tue Jun 20 11:16:33 2023 +0200 - modules: readme files regenerated - topoh ... [skip ci] + modules: readme files regenerated - db_redis ... [skip ci] -commit dc46d8eb102d4390a5cb257ee1ac9a0cc7528551 +commit d29d435cad3ec52f4171035446870ad2fe991858 Author: Daniel-Constantin Mierla -Date: Wed Oct 12 13:36:53 2022 +0200 +Date: Tue Jun 20 11:04:30 2023 +0200 - topoh: docs for mask_mode parameter + ndb_redis: Makefile - updated find command for libhiredis_ssl + + - silent warnings about not existing directories -commit 279de09111c0884f01fa002fabc8a200fcc26846 +commit d88d60a0f3d67f42e4201d6c871bbf993e6fa87b Author: Daniel-Constantin Mierla -Date: Wed Oct 12 13:20:19 2022 +0200 +Date: Tue Jun 20 11:03:04 2023 +0200 - topoh: modparam to control header masking + db_redis: Makefile - updated find command for libhiredis_ssl - - mask_mode - a new parameter - - if bit 1 is set, the masking of contact header in 3xx replies is - skipped - - GH #3256 + - silent warnings about not existing directories -commit 17ef6f22f24a77fba64d8076c8be771fac2ab00a -Author: Victor Seva -Date: Wed Oct 12 09:48:38 2022 +0200 +commit 043f31ea0314c5d1d60a6ce8ce81e626922223c4 +Author: Joel Centelles +Date: Fri Jun 16 21:08:40 2023 +0200 - src/Makefile: deb-stable is bullseye nowadays + ndb_redis: Fixing format - https://github.com/kamailio/pkg-kamailio-docker/issues/3 - -commit cbe6cef58da8de7efa18c4e34458a81176d23e42 -Author: Daniel-Constantin Mierla -Date: Tue Oct 11 10:17:34 2022 +0200 + Fixing some spaces and indentations - keepalive: removed redundant checks +commit cb96de742f1d729d01bf9c8c255a12aa089d6974 +Author: Joel Centelles +Date: Fri Jun 16 21:07:29 2023 +0200 -commit 611cfede181f4cd61f576068708975efe5f66ffc -Author: Daniel-Constantin Mierla -Date: Tue Oct 11 09:40:56 2022 +0200 - - core: dns cache - check pointer and small formatting - -commit 609962b49a79dc5650f72470f4b03746d2e6db46 -Author: Daniel-Constantin Mierla -Date: Mon Oct 10 13:01:21 2022 +0200 - - ims_registrar_pcscf: go to error to free variables on failure cases + db_redis: Format fixes + + Fixing some spaces -commit d39f12ced4c79f3b7d60b5477f5065d9589547e8 -Author: Daniel-Constantin Mierla -Date: Mon Oct 10 11:44:57 2022 +0200 +commit d41924862a1729de186a5d1f4adddcfeb7fb7b7d +Author: Joel Centelles +Date: Fri Jun 16 20:30:28 2023 +0200 - cdp: use empty string for debug messages when value is not set + ndb_redis: Searching SSL support in gcc search library path + + Checking libhiredis_ssl.so in gcc --print-search-dirs -commit d92a8a6d8d4c0d226f740a67c76ca742a3ffed2a -Author: Kamailio Dev -Date: Mon Oct 10 09:46:23 2022 +0200 +commit f7a712b36918bd9c01256fb2b283754ad9ed7422 +Author: Joel Centelles +Date: Fri Jun 16 20:25:48 2023 +0200 - modules: readme files regenerated - app_python ... [skip ci] + db_redis: Searching SSL support in gcc search library path + + Checking libhiredis_ssl.so in gcc --print-search-dirs -commit 7306e7683fd50420e93b44ec5593705194bf3616 -Author: Henning Westerholt -Date: Mon Oct 10 07:39:56 2022 +0000 +commit 77e74b974249b3c4e2e67cc074cc8ff26d50fde8 +Author: Joel Centelles +Date: Tue Jun 13 13:34:31 2023 +0200 - app_python: add a note that python2 is deprecated and app_python3 should be used + ndb_redis: Missing uprotected redisSSLContext + + Fixing unprotected redisSSLContext reference in redis_client.h -commit 25a060bb5d72cac5bafcd4e8e5960635bf848205 -Author: Daniel-Constantin Mierla -Date: Fri Oct 7 13:50:42 2022 +0200 +commit 90f977202af2d132fb63f20f76f9ad696a19656e +Author: Joel Centelles +Date: Mon Jun 12 13:30:39 2023 +0200 - core: snexpr - assign the lv to evaluated variable with number value + ndb_redis: Fixing global variables names + + Adding module name prefixing global variable names to prevent possible + conflicts. Also using ca_path info in SSL context creation. -commit 8d398d6a83153fc65acd49557b702879d2585dc8 -Author: Daniel-Constantin Mierla -Date: Thu Oct 6 11:24:51 2022 +0200 +commit 30eec549396899eae32e651ef58d65c4684ab296 +Author: Joel Centelles +Date: Mon Jun 12 13:24:31 2023 +0200 - ims_qos: use inter-module api release_dlg() instead of direct unref_dlg() + db_redis: Fixing global variables - - fix missing linker symbol + Adding module name prefix to global variables to reduce possible conflicts. -commit 598969df126af4ad4d2283e37078e1afe8773a32 -Author: Daniel-Constantin Mierla -Date: Wed Oct 5 10:41:38 2022 +0200 +commit 440e8cba9f9e8364e100a68283137da589e6f283 +Author: Joel Centelles +Date: Fri Jun 9 13:34:15 2023 +0200 - misctest: allow testing with larger message size than core accepts + db_redis: Fixing Makefile + + Removing unprotected references to libhiredis_ssl.so -commit 916ecb43e94fcc4662ae4212172b2b66488002de -Author: Daniel-Constantin Mierla -Date: Wed Oct 5 10:37:01 2022 +0200 +commit 4cca8c777020e5fea49e37940e3c521d766588f9 +Author: Joel Centelles +Date: Thu Jun 8 16:59:37 2023 +0200 - misc/fuzz/README.md: added link to OSS-Fuzz folder for Kamailio + db_redis: Fixing build + + Removing extra declaration outside from WITH_SSL block -commit 1cd2fc1977bfa5e362cef0199e4643085c66d3d1 -Author: Daniel-Constantin Mierla -Date: Wed Oct 5 10:34:43 2022 +0200 +commit dd6ee7a7499fce6ce33c59c0dd15af81a140ae4f +Author: Joel Centelles +Date: Thu Jun 8 16:57:04 2023 +0200 - misc/fuzz: add checks on input size + ndb_redis: Format fixes - - test with larger messages than core accepts + Fixing C formatting issues -commit 45c4c1b1851212bfc8e0c84d4e1a62cd89ad7b56 -Author: Daniel-Constantin Mierla -Date: Tue Oct 4 16:11:50 2022 +0200 +commit 077980a000c37320bfade650c680da55af92154e +Author: Joel Centelles +Date: Thu Jun 8 16:48:21 2023 +0200 - lrkproxy: init variable and check to fix compiler warnings + db_redis: Missing format fixes + + Removing spaces from line ends. -commit 640456bb13cd9da3ff84ca3542f9f28446062d7c -Author: Kamailio Dev -Date: Tue Oct 4 12:01:46 2022 +0200 +commit ba080b16353b53c29c147740f3541ceecbe31c1d +Author: Joel Centelles +Date: Thu Jun 8 16:45:47 2023 +0200 - modules: readme files regenerated - jsonrpcs ... [skip ci] + db_redis: Fixing format + + Fixing malformed C lines -commit 758ec768576cf4e380d6cd7f678f6270f79033af -Author: Henning Westerholt -Date: Tue Oct 4 09:50:08 2022 +0000 +commit 79d5ab3b86c0a1cc1b06efeee78ef5baa8d084f9 +Author: Joel Centelles +Date: Fri Jun 2 18:44:09 2023 +0200 - jsonrpcs: small spelling fix in docs + ndb_redis: Adding TLS support + + Checks for the tls parameter in the BD schema and, if it's enabled, creates a temporary TLS conext that is used to initialize the redis context. + Adds 1 new parameter: + * ca_path: For specifying a folder containing valid certification chains. -commit 6f400a8074fe60916867596431ca26dff00435d1 -Author: Kamailio Dev -Date: Fri Sep 30 11:46:18 2022 +0200 +commit 67c77289afb994178afc1fd7558833097eb2f5b9 +Author: Joel Centelles +Date: Fri Jun 2 18:42:16 2023 +0200 - modules: readme files regenerated - carrierroute ... [skip ci] + db_redis: Adding TLS support + + Enhancing security options by enabling TLS connections and password definition. + Added 3 new parameters: + * opt_tls: For enabling TLS connections. + * ca_path: For specifying a folder containing valid certification chains. + * password: For providing DB access password. + + If opt_tls is provided a temporary SSL context is created to pass it to existing cluster or normal redis context. + TLS support is automatically enabled/disabled by checking libhiredis_ssl.so existence. -commit 1e3f1886cef43fcbf6cdd6f1cefb5b72e5151abc +commit 453a973849cc6eaab2e07d445675a9a3d6b1d8c5 +Merge: 437b435c86 87959c23aa Author: Daniel-Constantin Mierla -Date: Fri Sep 30 11:35:53 2022 +0200 +Date: Tue Jun 20 09:31:59 2023 +0200 - carrierroute: exported cr_user_carrier() to kemi + Merge branch 'master' into typos -commit c32ce4d776d40fe2eccea9007fb842cd8c9c3af9 +commit 87959c23aacf4cfa7ed8acd214f70775939c8a01 Author: Daniel-Constantin Mierla -Date: Fri Sep 30 11:21:29 2022 +0200 +Date: Tue Jun 20 09:14:48 2023 +0200 - carrierroute: docs updated for cr_user_carrier() + Makefile.groups: added posops to extra group -commit e84c1947b3c9fa5dc07fbab0361758a9f87e9da2 -Author: Daniel-Constantin Mierla -Date: Fri Sep 30 11:16:48 2022 +0200 +commit 73fdf7a8eb1ca3e00ff4844e6c797114f17f3525 +Author: Дилян Палаузов +Date: Sun Jun 18 19:53:00 2023 +0200 - carrierroute: updated cr_load_user_carrier() to support any output variable + src/Makefile.defs: complete removal of VQ_MALLOC memory manager - - third parameter can be any writable - - added fixup-free function for it + … started in commit f92113d8e16d6e59c170dfa703d9db30980b6877. -commit d5ae9019dcdfe5b51ce87f6957902abbaa7fa071 +commit bfc5d4bdcdd1ce60359d1a2e6a097f312879799f Author: Daniel-Constantin Mierla -Date: Fri Sep 30 10:52:25 2022 +0200 +Date: Mon Jun 19 13:50:28 2023 +0200 - corex: added fixup free functions in module exports + dialplan: set right input/output pv references -commit ff7913f511f95a891fe870cb1fe88f586573af79 +commit f36744cf15c7fcddc7422f97a508cad600ca7d98 Author: Daniel-Constantin Mierla -Date: Fri Sep 30 09:17:36 2022 +0200 +Date: Mon Jun 19 13:18:59 2023 +0200 - core: snexpr - compile time options for formatting fload with full precission + core: kemi - propagate bool as a return value type + + - some scripting languages differentiate bool false|true vs int 0|1 values -commit d5df2e45cf6ae3c8fc61f565c9291b26ff255ede +commit 9580adf9a478f161605a0f663099f4d10c0c93eb Author: Daniel-Constantin Mierla -Date: Thu Sep 29 10:06:03 2022 +0200 +Date: Mon Jun 19 12:54:48 2023 +0200 - core: snexpr.h - custom function to format float value - - - use a precision of 4 decimals + core: kemi - reformat core exports for tool parsing -commit d5eebda3a09401478e6707bb03043d75b90fe1d3 -Author: Daniel-Constantin Mierla -Date: Thu Sep 29 09:27:09 2022 +0200 +commit 437b435c86c109bdda213998c6448ed255790018 +Author: Дилян Палаузов +Date: Sun Jun 18 19:08:12 2023 +0200 - core: snexpr.h - removed mistakenly placed string concat + utils: typos -commit 9a41fb5403a6bc4fd5ccee239ccdf725fe6f91df -Author: Richard Fuchs -Date: Wed Sep 28 09:33:56 2022 -0400 +commit e66c2c96908cb8c2169ace2c31c2a6cfae7201d3 +Author: Дилян Палаузов +Date: Sun Jun 18 19:06:42 2023 +0200 - rtpengine: allow to-tag usage for all commands + test/misc/code: typos -commit 28ce28f26ba069781ac6aee6c7ffcbd1281d7848 -Author: Kamailio Dev -Date: Wed Sep 28 13:01:21 2022 +0200 +commit 5888a402285b5edb2c8691a263530287968c9658 +Author: Дилян Палаузов +Date: Sun Jun 18 19:08:52 2023 +0200 - modules: readme files regenerated - lrkproxy ... [skip ci] + usrloc: typo -commit 6eb5bb67586bf91c5d42a5864d881a4fc82a6638 -Author: Mojtaba Esfandiari.S -Date: Wed Sep 28 14:25:26 2022 +0330 +commit c7471291950d24dceaf8b5db131afd37cde91c1f +Author: Дилян Палаузов +Date: Sun Jun 18 19:26:55 2023 +0200 - lrkproxy: Add new features : TURN support, behind_nat support, subset of range ports + ndb_mongodb: typo -commit a26eb52bf50e687251f994fd35b3afc5ff2a32ca -Author: Daniel-Constantin Mierla -Date: Wed Sep 28 09:19:58 2022 +0200 +commit 5f3c2fe040c8a9e19b3ea98dc343fa324c193be5 +Author: Дилян Палаузов +Date: Sun Jun 18 19:26:14 2023 +0200 - core: snexpr.h - declare iterators out of for() statements - - - support non-C99 compilers + ndb_cassandra: typos -commit 07424a6143c79037a3a6631bece9e536508d6d7d -Author: Kamailio Dev -Date: Tue Sep 27 16:16:21 2022 +0200 +commit c3919b68e947b6572eef8cd01486af4f28fed963 +Author: Дилян Палаузов +Date: Sun Jun 18 19:25:44 2023 +0200 - modules: readme files regenerated - presence_reginfo ... [skip ci] + nat_traversal: typo -commit 91cf0ce599b41fd6482e3206217fc9b6e7821a66 -Author: Matteo Brancaleoni -Date: Fri Sep 16 16:04:40 2022 +0200 +commit 3157cc16d409de71d692ec43441181327e1ebc9d +Author: Дилян Палаузов +Date: Sun Jun 18 19:25:26 2023 +0200 - presence_reginfo: Add option for aggregating presentities + msilo: typos -commit 1fbdc35c3d29da048cb06bfe0268c503c5015c3c -Author: Daniel-Constantin Mierla -Date: Mon Sep 26 20:37:31 2022 +0200 +commit c632c5fd6afb37704dde2de96c5a5a8d8e4cc44e +Author: Дилян Палаузов +Date: Sun Jun 18 19:24:16 2023 +0200 - pv: use the function for header name parsing that does not require the colon termination + mqtt: typo -commit 86a357c278c45a8d7b580e79ac074115871065fb -Author: Daniel-Constantin Mierla -Date: Mon Sep 26 15:58:15 2022 +0200 +commit 211ede8351683644d1829feb355ca4a2a6227bcd +Author: Дилян Палаузов +Date: Sun Jun 18 19:23:33 2023 +0200 - uac: use get_dlg_varstatus() to check if var exists + misctest: typos -commit 320af48dffaa3c9b2c266ad9f68233e3cf48f9f0 -Author: Daniel-Constantin Mierla -Date: Mon Sep 26 15:30:51 2022 +0200 +commit 91dd1ea66e735478d44906ee01a4d1d8898762d2 +Author: Дилян Палаузов +Date: Sun Jun 18 19:22:55 2023 +0200 - dialog: export new itermodule api functions - - - get duplicate var value and status + misc_radius: typos -commit abdb02d3d2eec9fb45646f68996da3526c92ef58 -Author: Daniel-Constantin Mierla -Date: Mon Sep 26 12:51:50 2022 +0200 +commit 854ccb898a586837c262a5d64515cf7a6820bccd +Author: Дилян Палаузов +Date: Sun Jun 18 19:22:11 2023 +0200 - dialog: updated ki_dlg_var_is_null() to use safer api function + memcached: typos -commit c2c3211cd31405188891abd16ef770c26a8ddd44 -Author: Daniel-Constantin Mierla -Date: Mon Sep 26 12:30:06 2022 +0200 +commit 55c5535c5fee881b16b95a2152d08aeca88f4b3f +Author: Дилян Палаузов +Date: Sun Jun 18 19:21:28 2023 +0200 - dialog: api function to get the status if dlg var is set or not + mediaproxy: typos -commit 8548aaa8a798b939e041821848b2f05b963451d8 -Author: Daniel-Constantin Mierla -Date: Mon Sep 26 12:04:29 2022 +0200 +commit 61b69b2d1b74234e5e78c0c50df6f65fe9273472 +Author: Дилян Палаузов +Date: Sun Jun 18 19:20:48 2023 +0200 - dialog: updated comments for api functions to get dlg var value + maxfwd: typo -commit 13512f48e03a2ef99847edf639582aaf3b4dfeb3 -Author: Daniel-Constantin Mierla -Date: Mon Sep 26 11:57:02 2022 +0200 +commit 7c97869cb944d6996a8bcf31bd50789b2e5afff3 +Author: Дилян Палаузов +Date: Sun Jun 18 19:20:26 2023 +0200 - dialog: api function get pkg-allocated duplicate of dlg var value + matrix: typo -commit a7571233bc7dee0381e8ed7e44408f63fa45c156 -Author: Daniel-Constantin Mierla -Date: Mon Sep 26 11:46:59 2022 +0200 +commit b682bedc8f33ac58297cfead05489e2c4c5204d3 +Author: Дилян Палаузов +Date: Sun Jun 18 19:19:56 2023 +0200 - dialog: update check on dialog var key length + mangler: typos -commit cc5216540f2240b7fc47adf66f380a00cf408aa0 -Author: Mojtaba Esfandiari.S -Date: Sat Sep 24 16:10:10 2022 +0330 +commit 854e69f9db966f11d92c630a4000fc214726ef9e +Author: Дилян Палаузов +Date: Sun Jun 18 19:18:04 2023 +0200 - Revert "lrkproxy: Add new features : TURN support, behind_nat support, subset of range ports" - - This reverts commit f2b07f2321980e74247cb0c968b98925172f6874. + lwsc: typos -commit f2b07f2321980e74247cb0c968b98925172f6874 -Author: Mojtaba Esfandiari.S -Date: Sat Sep 24 14:25:24 2022 +0330 +commit d61cd534f8ec10a232b8f446f277386b1abc2d66 +Author: Дилян Палаузов +Date: Sun Jun 18 19:14:26 2023 +0200 - lrkproxy: Add new features : TURN support, behind_nat support, subset of range ports + src/Makefile*: typos -commit a2d9a2f95e2212a9f5538ac25ac241206eff06a0 -Author: Daniel-Constantin Mierla -Date: Fri Sep 23 14:07:41 2022 +0200 +commit 9e4b47f75a572bb7732c90aac4a6b4346737ad37 +Author: Дилян Палаузов +Date: Sun Jun 18 19:10:46 2023 +0200 - pua_dialoginfo: use dlg api function get_dlg_varval() + core: typos -commit cd4e2259526bc4642259201ee96b00624f300437 +commit 087369c56e167995bf390d35651a68febd9c6c82 Author: Daniel-Constantin Mierla -Date: Fri Sep 23 13:59:36 2022 +0200 +Date: Fri Jun 16 17:24:29 2023 +0200 - uac: use dlg api functions get_dlg_varval() and get_dlg_varref() + cdp_avp: reformat code files with macros for code generation + + - clang format is not dealing nicely with such cases, disable formatting + for those snippets -commit fb7c497893f05587bda1c37e09d73a7ebb522715 +commit 3f7ccd57857c09cb76d6f21ba3b91b070e80fff8 Author: Daniel-Constantin Mierla -Date: Fri Sep 23 13:42:18 2022 +0200 +Date: Fri Jun 16 09:53:59 2023 +0200 - acc: use get_dlg_varval() to get values for dialog variables + cdp: check session pointer before use -commit ce3cd42631ac06a6a20892bd308901c6acd58f7a +commit ae1223e4236ce730448f32c262afec4c11e30eba Author: Daniel-Constantin Mierla -Date: Fri Sep 23 13:33:03 2022 +0200 +Date: Thu Jun 15 11:22:07 2023 +0200 - dialog: init output dlg var value param eariler + cdp: fix storage warning on time value -commit a7cecdcbc3c1d53fce22a33a3768da2a1907d64e +commit 631aab425e1f3908d9e1b044c2a0715f457655ac Author: Daniel-Constantin Mierla -Date: Fri Sep 23 13:17:02 2022 +0200 +Date: Thu Jun 15 10:35:49 2023 +0200 - dialog: internal api functions to get dlg variable reference or value + cdp: safety check closing fd for error cases -commit bcb3970d7a89ab27b43f86aee5b93a473a8b790b -Author: Daniel-Constantin Mierla -Date: Thu Sep 22 20:41:32 2022 +0200 +commit 41c4736367186f43e68361be0460bd590b7660bd +Author: Sipwise Development Team +Date: Wed May 12 11:53:43 2021 +0200 - acc_json: code formatting updates + db_redis: use sscan -commit 3e2b5d9ed6a0f18199359444c5ae33a1d6b94eb2 -Author: Daniel-Constantin Mierla -Date: Thu Sep 22 20:32:52 2022 +0200 +commit 3a8ebf5717eba0116cb71c7f953e9b7ff60d4b0e +Author: Sipwise Development Team +Date: Wed May 12 11:53:43 2021 +0200 - acc_json: use the variable for the time key + db_redis: graceful scan -commit 023af516f4ede3742f2e1836474978b596a4a3a8 -Author: Daniel-Constantin Mierla -Date: Thu Sep 22 20:30:52 2022 +0200 +commit c5a3c2cd8c6952356237c235c2ade159c030382b +Author: Sipwise Development Team +Date: Wed May 12 11:53:43 2021 +0200 - acc_json: moved global vars declaration to .c file - - - made them static + db_redis: skip empty keys -commit 41babc99c83c74ca3d1494698455394dd8458e87 -Author: Daniel-Constantin Mierla -Date: Thu Sep 22 09:34:05 2022 +0200 +commit 10a95d7c327a4bb83645723781d5885839f6fd0b +Author: Kamailio Dev +Date: Wed Jun 14 11:46:19 2023 +0200 - core: added #!defexps preprocessor directive - - - similar to #!defexp but the resulted value is enclosed in double - quotes + modules: readme files regenerated - cfgt ... [skip ci] -commit e241f7b8a07b24fba6d6ecf2c344a39d2b2b5859 -Author: Henning Westerholt -Date: Wed Sep 21 18:34:04 2022 +0000 +commit 60485701ea3c065e657206ebcb6dbfa212adf1d4 +Author: Victor Seva +Date: Mon Aug 29 13:59:38 2022 +0200 - kex: add additional safety checks for printing, based on PR #3250 from bensly-shanmugam + pv_headers: rework pvh_remove_header_param, take two + + * pvh_set_xavi changes/removes xavi, so we need the new value + * after pvh_remove_header, search for the header again -commit 8064a1d3cd35e76f0e563fa401c181632f33b43a -Author: Alex -Date: Tue Sep 20 17:12:22 2022 +0200 +commit 1ce15ab7094d3b13bf6db3cabb86bcdbab969d88 +Author: Victor Seva +Date: Wed Mar 29 12:12:54 2023 +0200 - build: harden pull_request.yml permissions - Signed-off-by: Alex + cfgt: route_log modparam + + If enabled, cfgt will log (WARN) the execution time of routes. -commit ddb39dd0f4fae470083006a7965d21512cd759b1 -Author: Alex -Date: Tue Sep 20 17:11:59 2022 +0200 +commit dd9c891bafe8de5dace630d676f9ea697152a4de +Author: Victor Seva +Date: Fri Mar 17 16:08:00 2023 +0100 - build: harden main.yml permissions - Signed-off-by: Alex + cfgt: don't dump same node -commit 411fb392fc3f2b399857dde2fb717ec2286e7fee -Author: Daniel-Constantin Mierla -Date: Tue Sep 20 17:41:36 2022 +0200 +commit b5ea290be4a5f92cd24dd39cbefe2987ed577d19 +Author: Victor Seva +Date: Wed Apr 27 15:49:30 2022 +0200 - core: added #!defexp ID STM preprocessor directive - - - abity to set a defined it to the result of snexpr statement - - example: + cfgt: skip_unknown modparam - #!define ADDR 127.0.0.1 - #!defexp SIPURI "sip:" + ADDR + ":5060" + If enabled, value different from 0, cfgt will not generate the report + of any message that doesn't match the callid_prefix. -commit 1fd075c4e7db180c61fcb2838e9e817ddd623003 -Author: Daniel-Constantin Mierla -Date: Tue Sep 20 11:01:56 2022 +0200 +commit c3f2ff656475d85b190f0a2f138b526d9a63e732 +Author: Victor Seva +Date: Wed Jun 14 10:53:34 2023 +0200 - core: clone values for defines + pua_dialoginfo: fix dlg_var store and retrieval + + * pubruri_calle[e|r]_avp can have more than one value. + Store values as comma separate strings at + pubruri_calle[e|r]_dlg_var + * be aware of possible multiple values when restoring + values from pubruri_calle[e|r]_dlg_var + * alloc string values always for str_list -commit b7a0d8a084a25a1b02e2c9845ef4e3b19f988c02 -Author: Daniel-Constantin Mierla -Date: Tue Sep 20 10:52:42 2022 +0200 +commit c064d5473dd679c1eb191ba012522de409b79420 +Author: Sergey Safarov +Date: Wed Jun 14 11:09:23 2023 +0300 - core: use defines for types of preprocessor defs + pkg/docker: submodule update [skip ci] -commit abe04ea06c68c7df180831bba1f4e73f53512db5 -Author: Daniel-Constantin Mierla -Date: Tue Sep 20 08:43:05 2022 +0200 +commit 768dd96da6f52e46bc227d9815f7225b33042295 +Author: Sergey Safarov +Date: Mon Jun 12 22:20:57 2023 +0300 - core: snexpr - updated to version supporting escaped chars in string values + pkg/kamailio/alpine: packaged lwsc -commit f7b35f05f31bd7cc01aea4572c79ba48d84d8123 +commit 88bcd44e07b43b723bb0ddc7b828f605179ae893 Author: Daniel-Constantin Mierla -Date: Mon Sep 19 08:40:19 2022 +0200 +Date: Wed Jun 14 08:44:35 2023 +0200 - acc_json: update to free cdr core attrs + cdp: log message when failing to set nonblock on socket -commit d616dc46b5373b1474bf855afde4c5687d2a2d09 +commit eaa4b177652259efda4e61aac9dd039ebde253c9 Author: Daniel-Constantin Mierla -Date: Mon Sep 19 08:15:53 2022 +0200 +Date: Wed Jun 14 08:33:23 2023 +0200 - acc: clone dlg core attributes - - - GH #3243 + cdp: safety check on diameter msg processing -commit c5f71a45c7c55af0cf4a6aa482d8a57018af7900 +commit 81ee6f7e9eb23c24fb06dd2c201f3246d6044c4d Author: Daniel-Constantin Mierla -Date: Sun Sep 18 21:33:25 2022 +0200 +Date: Wed Jun 14 08:28:58 2023 +0200 - acc: more meaningful array index names for building cdr attributes + cdp: dedicated log messages for timeout events -commit d56d65b8daac072a4726d9124072151d0d3fbb79 -Author: Julien Chavanton -Date: Tue Sep 6 10:45:12 2022 -0400 +commit f8bfc8d2c9f8b366e6a0d8d3b1790077ccca5b7e +Author: Daniel-Constantin Mierla +Date: Wed Jun 14 07:58:54 2023 +0200 - dispatcher: fix alog13 gateway selections + cdp: reworked same code execution in if branches -commit 518296523db0c1735c3234d77d6af312f5c9babb +commit 57182ddeaba6244a904f3c9d530e2aa8bc652fbd Author: Daniel-Constantin Mierla -Date: Sun Sep 18 20:09:53 2022 +0200 +Date: Tue Jun 13 14:27:02 2023 +0200 - dmq_usrloc: safety checks for sock field + cdp: changed function export macro for better list building - - GH #3243 + - more readable exports formatting -commit 9a15781f4804ef6620fad5a09ff2e9aacae871cb +commit 2f23b3ccc2288e5d146aeac807935af24f5923b3 Author: Daniel-Constantin Mierla -Date: Sat Sep 17 10:18:39 2022 +0200 +Date: Tue Jun 13 12:05:51 2023 +0200 - sipdump: use the right flag to parse ipv6 + cdp_avp: aligned exports structures -commit e49e5a52ded4bef36b5958a748b9556af52d2d33 -Author: Gustavo Almeida -Date: Fri Sep 16 21:06:53 2022 +0100 +commit 759d76819b7c8ab31d71ab8a77a3863c1861e374 +Author: Daniel-Constantin Mierla +Date: Tue Jun 13 09:43:00 2023 +0200 - pkg/kamailio/obs: added readline-devel build dependency (#3233) - - * pkg/kamailio/obs: added readline-devel build dependency + cdp: fix always true condition in peer_timer() - - Added a readline-devel dependency when generating rpm's. This ensures that when generating rpm's (mock context), kamcmd uses this library in its compilation and autocomplete is available in kamcmd's interactive mode. + - extended the log message -commit de6a35012669ad5892760c368cbd141e77bc91db +commit 1128df71dcba1cd97898c2970e7cd3221256adb1 Author: Daniel-Constantin Mierla -Date: Fri Sep 16 16:48:19 2022 +0200 +Date: Tue Jun 13 09:24:22 2023 +0200 - corex: print address family name for rpc corex.list_sockets + cdp: safety checks on error cleanup for diameter_peer_init_real() -commit a5d92da6370f6db15c1ccb69a0ad7b914163c1db +commit f1da698dd57b2cbe549f4b9083f66ebc336433c3 Author: Daniel-Constantin Mierla -Date: Fri Sep 16 16:45:21 2022 +0200 +Date: Tue Jun 13 09:17:44 2023 +0200 - core: print address family for rpc core.sockets_list + cdp: shortened log message for unkown type inside AAAConvertAVPToString() -commit 8bdee74fa6b68012919ddbb403da372187631bd9 +commit 10834bc77188a8cbcc174429fee8f99d6e94752f Author: Daniel-Constantin Mierla -Date: Fri Sep 16 16:42:16 2022 +0200 +Date: Tue Jun 13 08:48:57 2023 +0200 - core: helper function to get address family name + cdp: log message when cleaning up inside auth_client_statefull_sm_process() -commit 4434e83db1d4b668dabbe915fe36719ede165915 +commit db31ddb5d5af3d6add5c4aacb9da6cfede04bf04 Author: Daniel-Constantin Mierla -Date: Fri Sep 16 15:00:13 2022 +0200 +Date: Tue Jun 13 08:40:54 2023 +0200 - websocket: debug message for rpc command when finding no tcp connection + cdp: remove unnecessary checks inside Send_ASR() + + - updates to log messages -commit abe60832de46796a1395a75a67753c1a12a1ec0a -Author: Daniel-Constantin Mierla -Date: Fri Sep 16 14:51:31 2022 +0200 +commit 6a19434d4b93a8ec6e345b55ff1b83ff6bd38596 +Author: Kamailio Dev +Date: Mon Jun 12 18:16:32 2023 +0200 - websocket: clean up ws structures without an active tcp connection - - - GH #3236 + modules: readme files regenerated - mqueue ... [skip ci] -commit 0a61ec2f137414a7bfc2535dfe4df9b72e500cf8 -Author: Daniel-Constantin Mierla -Date: Fri Sep 16 14:31:44 2022 +0200 +commit 23d43645332451ec1ec6dab11da777f9c3bfe304 +Author: Ovidiu Sas +Date: Mon Jun 12 12:00:13 2023 -0400 - sipdump: make dest ipv6 addresses without square brackets + mqueue: fix documentation to match the code -commit ac711cffea91c44f4e13b5d75d6ae01ee4599099 +commit 39f09877e650d66e820ca7eb0d61416818d174fc Author: Daniel-Constantin Mierla -Date: Fri Sep 16 13:54:56 2022 +0200 +Date: Mon Jun 12 17:16:53 2023 +0200 - sipdump: make ipv6 addresses without square brackets + cdp: check setsockopt() return code -commit 95e0fe85ff9149c80249e848a437deb5dae2e463 -Author: Kamailio Dev -Date: Thu Sep 15 10:46:17 2022 +0200 +commit fb19f0ea4c656afe7b60788efb8804e552fd37f9 +Author: Daniel-Constantin Mierla +Date: Mon Jun 12 16:27:46 2023 +0200 - modules: readme files regenerated - dmq ... [skip ci] + auth_diameter: free req in some cases of errors -commit e683ee506d702e9edbe4ce74304170ca04c1d5ec +commit f99b116e876170709ad364ac2b8093969a939d4a Author: Daniel-Constantin Mierla -Date: Thu Sep 15 10:34:45 2022 +0200 +Date: Mon Jun 12 15:53:38 2023 +0200 - dmq: docs - reorganized the dmq request section + dialplan: restructured condition on input and output params -commit b7e6b0cc44b46a615dc23b6fae7f67e63296c913 +commit 060a96057309000592f126956cd343656a26ecba Author: Kamailio Dev -Date: Thu Sep 15 10:31:28 2022 +0200 +Date: Mon Jun 12 14:01:24 2023 +0200 - modules: readme files regenerated - dmq ... [skip ci] + modules: readme files regenerated - pdb ... [skip ci] -commit 1fd789246cc7c58237b9a903a198521cd5b3494d +commit 7d7e6dfcdaf21cae4b98ca5520e667b4f8f09145 Author: Daniel-Constantin Mierla -Date: Thu Sep 15 10:26:38 2022 +0200 +Date: Mon Jun 12 13:54:34 2023 +0200 - dmq: docs - note about using same Kamailio version + pdb: docs for ll_info mod param -commit e43083e32df03b629f0eab9d567bd41d6cb749ff +commit 88d8c46603f6e45ba90c51b7c8d80acae7fb400a Author: Daniel-Constantin Mierla -Date: Thu Sep 15 09:28:54 2022 +0200 +Date: Mon Jun 12 13:48:31 2023 +0200 - dialplan: prefixed some global variables to avoid naming conflicts + Makefile.modules: define MOD_NAMEID to module name without quotes -commit 220750f79737b13b6aad0c38d6dd8ea3e28d5ca5 +commit e818baa1b21249529c93990ef0340dd8b56b26cf Author: Daniel-Constantin Mierla -Date: Thu Sep 15 09:23:26 2022 +0200 +Date: Mon Jun 12 13:47:18 2023 +0200 - dialplan: removed unnecessary define + pdb: use local log level for an info log message + + - new mod param to allow remapping local log level for info + - related to GH #3296 -commit f89bab70ef9cc842f37799c7c414f40d8ac581ab +commit 03203d1baa5f185db8743a90f889e5483e90e911 Author: Daniel-Constantin Mierla -Date: Thu Sep 15 08:30:26 2022 +0200 +Date: Mon Jun 12 13:43:31 2023 +0200 - dialplan: rename exports to kemi + core: new log macros allowing to use local log levels per module - - function names have to be unique - -commit 2e8bfcef4f3f90214df0c1fe4d40d359265f060a -Author: Bastian Triller -Date: Wed Sep 14 19:30:22 2022 +0200 - - dialplan: Fix typos + - a variable has to be defined inside module like: + + ksr_loglevels_t _ksr_loglevels_MODNAME = KSR_LOGLEVELS_DEFAULTS; + + - for example, for pdb module: + + ksr_loglevels_t _ksr_loglevels_pdb = KSR_LOGLEVELS_DEFAULTS; - Fix typos in kemi exports + - then use LLM_XYZ() macro instead of LM_XYZ() - for example, use + LLM_INFO() instead of LM_INFO() -commit f68cbc16b7ac29cce143f7b77114eaef37312ab6 -Author: Daniel-Constantin Mierla -Date: Wed Sep 14 18:12:23 2022 +0200 +commit e55851ee7dfb7a60f0a9288d810b84cf3bcd0f19 +Author: Henning Westerholt +Date: Mon Jun 12 10:01:21 2023 +0000 - core: ppcfg - skip ending quite for exported defined values to snexpr + kamcmd: clang-format the source code for kamcmd tool -commit bb494b5d2dc4690c7389a3000ff8fda4ce3aeaa8 -Author: Daniel-Constantin Mierla -Date: Wed Sep 14 17:37:44 2022 +0200 +commit efa436bc228af99cfd1466b5ea1be2fc596f18b8 +Author: Kamailio Dev +Date: Mon Jun 12 12:01:34 2023 +0200 - core: ppcfg - debug messagee with result of snexpr evaluation + modules: readme files regenerated - jansson ... [skip ci] -commit 0406cba7db628a757572968269fd5d2f4426472e -Author: Daniel-Constantin Mierla -Date: Wed Sep 14 17:35:22 2022 +0200 +commit ebf1aa6dbfeca30d93c63291751417186f9100cd +Author: Jake Greene +Date: Mon May 22 21:01:01 2023 +0000 - core: ppcfg - remove enclosing quotes when exporting defined value to snexpr + presence: Add OK response to publish_cache_sync RPC command. -commit 2f67daa9ce945cb57b8429101569203d4b891d1c -Author: Stefan Mititelu -Date: Wed Sep 14 13:19:05 2022 +0300 +commit 07f86a52271920bc36db3a32c6ffa18434372ebf +Author: Jake Greene +Date: Fri May 19 18:02:51 2023 +0000 - dialplan: export dp_translate to kemi + Presence: semantical improvments to docs & rpc command name -commit a33b41ba804bc944b0e1c4ecf17fdc3ca68d4da0 -Author: Stefan Mititelu -Date: Tue Sep 13 11:41:04 2022 +0300 +commit 5197e7b41dd5d08451b7a7906177fc04e1c3ce8b +Author: Jake Greene +Date: Thu May 18 09:48:24 2023 -0500 - siputils: export is_gruu() to kemi + presence: Add htable_db_restore RPC command. + + - Introduced `htable_db_restore` RPC command to load updates from the 'presentity' table into the 'publ_cache' specifically for 'publ_cache' modes 1 or 2. + + - update docs for htable_db_restore RPC command -commit 678d93a742ba294bbe571c975814e01fdd795371 -Author: Stefan Mititelu -Date: Tue Sep 13 11:24:47 2022 +0300 +commit 90e172bad110c5a27da3908594b45f5bbe035d87 +Author: Дилян Палаузов +Date: Mon May 8 13:06:22 2023 +0200 - ratelimit: export functions to kemi + modules/utils: typo -commit a84e96f2e025a6befd4721ad3f67a104fd594190 -Author: Daniel-Constantin Mierla -Date: Wed Sep 14 08:17:30 2022 +0200 +commit 0e01e3afa4dcca66d1f879a09fe3fd70b5dc16e6 +Author: Дилян Палаузов +Date: Mon May 8 13:06:03 2023 +0200 - core: added preprocessor directive #!ifexp stm - - - conditional evaluation of the statement as an expression with strings - and numbers - - example: - - #!ifexp KAMAILIO_VERSION >= 5006000 - ... - #!else - ... - #!endif - - - defined IDs can be used inside the expression - - if not defined, value 0 is used - - if defined with value, the value is used - - if defined with no value, value 1 is used - - if expression is evaluated to !=0 or non-empty string, then it is considered true + userblocklist: typos -commit c19583117d120c3e350fca34f41daabc286f8c6e -Author: Daniel-Constantin Mierla -Date: Wed Sep 14 08:01:37 2022 +0200 +commit 9156897ce4784be45de5c80da0b4d6694acbca75 +Author: Дилян Палаузов +Date: Mon May 8 13:05:22 2023 +0200 - core: utils - added simple expression evaluations with strings and numbers - - - MIT license, import from github.com/miconda/snexpr + uri_db: typos -commit b7911b63d7a27a4f29acc4bca3101f7857930084 -Author: Matthias Urlichs -Date: Fri Sep 2 12:29:32 2022 +0200 +commit 4774bcff4822f5004472117d37787ed336196420 +Author: Дилян Палаузов +Date: Mon May 8 13:04:22 2023 +0200 - modules/python3: return NULL on error. - - - PyErr_SetString is a void function. It doesn't return NULL. + uid_avp_db: typos -commit d0e1827b2f8890da4fd30cc23f8bd090227d87f2 -Author: Kamailio Dev -Date: Thu Sep 8 10:31:31 2022 +0200 +commit cf1834c7bfd589d67b602cd0bd6feff56565dd94 +Author: Дилян Палаузов +Date: Mon May 8 13:01:47 2023 +0200 - modules: readme files regenerated - posops ... [skip ci] + uid_auth_db: typos -commit c3771966fa8470db91d04323a1e9c837a16a22cf -Author: Daniel-Constantin Mierla -Date: Thu Sep 8 10:09:14 2022 +0200 +commit 3c66eeb3cd09e4d4698a6d1a174fbf4c6a2d2485 +Author: Дилян Палаузов +Date: Mon May 8 13:04:53 2023 +0200 - posops: docs - updated pos_set_char() section - - - note that the change is done directly inside the sip message buffer + uid_domain: typos -commit 93e77d441112ce41042cfd904cc3e7fd8ae78b4a -Author: Kamailio Dev -Date: Wed Sep 7 23:46:23 2022 +0200 +commit 1a449c829a568bf16cf247fe5aa95eded3cebabd +Author: Дилян Палаузов +Date: Mon May 8 12:59:44 2023 +0200 - modules: readme files regenerated - rtpengine ... [skip ci] + uac_redirect: typos -commit 745010442f0a7298d8b4576cdebfe5f5b664c102 -Author: toharish -Date: Thu Sep 8 03:04:41 2022 +0530 +commit 46d4f8bd49cb27e9a1b0219543110a2b82860b01 +Author: Дилян Палаузов +Date: Mon May 8 12:55:51 2023 +0200 - rtpengine: added receive-from option (#3230) + uac: extend documentation - - Add receive-from option to flags - - receive-from=1.2.3.4 - - required for manageing rtpengine by a kamailio node behind a dispatcher kamailio node - - add received-from option in Document + This contains typos and some conclusions I made, while I tried to utilize + the uac module. -commit 2c622a6183dab5c5f50c8d46436bed014eae1146 -Author: Daniel-Constantin Mierla -Date: Tue Sep 6 09:16:53 2022 +0200 +commit e138e94bd3e222d0a8a7ef5e36c5dba66e73993b +Author: Дилян Палаузов +Date: Mon May 8 13:08:21 2023 +0200 - core: define OS_NAME at startup + tsilo: typos -commit 05694d88e3e697417be12e269511b0711404656b -Author: Daniel-Constantin Mierla -Date: Mon Sep 5 13:06:45 2022 +0200 +commit 20fa33e4c12ebc12ade4c70e4c91af8b8bff57aa +Author: Дилян Палаузов +Date: Mon May 8 13:09:09 2023 +0200 - core: define KAMAILIO_VERSION with VERSION number value + topos: typos -commit 3e94dd4bd3901d503c7be655d761f1d70453a451 -Author: Daniel-Constantin Mierla -Date: Mon Sep 5 10:24:06 2022 +0200 +commit 39701758116e2ffcc19d62df97b770df47faa0b4 +Author: Дилян Палаузов +Date: Mon May 8 13:11:50 2023 +0200 - core: use unsigned printing for version defines + tmx: update hyperlink to TM module -commit d4670ed58fb6e4325d5e3782f344237f8da5b70f -Author: Daniel-Constantin Mierla -Date: Sun Sep 4 20:31:51 2022 +0200 +commit 6625951ecce9ed84efafd8b07ff055fd49f9557b +Author: Дилян Палаузов +Date: Mon May 8 13:12:30 2023 +0200 - pua_dialoginfo: safety check for request pointer + tmrec: typos recurrence -commit f5c98a49c98aedcf6e1afec3c42dd862d0eeb9a3 -Author: Daniel-Constantin Mierla -Date: Fri Sep 2 13:15:35 2022 +0200 +commit d5501cfd654822df286f6916185c01fe4ac2bad7 +Author: Дилян Палаузов +Date: Mon May 8 13:18:16 2023 +0200 - core: support to specify options for load module - - - prototypes: - loadmodule("path", "options") - loadmodulex("path", "options") - - options is a string with characters: - - 'g' or 'G' - open the module shared object file with RTLD_GLOBAL set, - wich can be used for modules related to external scripting languages - to avoid reloading - - example: loadmodule("app_lua", "g") + rtpproxy: typos -commit 43f764cae870b15a96b8ca88f1eb195d4ceb8455 -Author: Daniel-Constantin Mierla -Date: Fri Sep 2 12:50:56 2022 +0200 +commit ac773d92e18243e441b5f2e5e8b797642bd0bc03 +Author: Дилян Палаузов +Date: Mon May 8 13:23:00 2023 +0200 - core: kemi - duplicate module name when registering the api exports + lrkproxy: typos -commit 69ba64e26e3876ce84053a691dee2f2ad9bb6185 -Author: Daniel-Constantin Mierla -Date: Fri Sep 2 12:06:20 2022 +0200 +commit d7700dd35725b35786dcc9da3dc938c236e845e5 +Author: Дилян Палаузов +Date: Mon May 8 13:21:10 2023 +0200 - core: support for loadmodule("path") and loadmodules("path") + lost: typos -commit 2cebd46f8f2dc3f87c9cfd2054976e347aa75ace -Author: Daniel-Constantin Mierla -Date: Thu Sep 1 10:53:54 2022 +0200 +commit 70a9ea2b1e5cceeaf050356e7baf00127a58567d +Author: Дилян Палаузов +Date: Mon May 8 13:13:49 2023 +0200 - dialog: remove strlen() checks when setting a variable - - - assumed key->s and val->s are 0-terminated, which may not be the case + lcr: typos -commit b7dc2ac6d66839b38ba8d6f36e9f28bc0a2d1425 -Author: Daniel-Constantin Mierla -Date: Thu Sep 1 10:50:30 2022 +0200 +commit 40d012d737dc5f59429b3bca2c0927412d2b4900 +Author: Дилян Палаузов +Date: Mon May 8 13:14:11 2023 +0200 - dialog: wrapper function to set a dlg var with unsigned integer parameter - - - use it to set cseq diff value + jansson: typo xavps's → xavp's -commit 30c628732092108e8d73856a5c9ec60b16d5ef99 +commit c285b16bc066ca4236ee00cf3e7fb24539fa9f2b Author: Daniel-Constantin Mierla -Date: Wed Aug 31 11:35:51 2022 +0200 +Date: Mon Jun 12 11:16:51 2023 +0200 - siptrace: use socket name for hep mirroring + Makefile: fixed paths for init.d scripts install on debian and centos - - GH #3174 + - GH #3476 -commit 1553a6c0efb2cec0b5962bba13bc0095211ee75d -Author: Daniel-Constantin Mierla -Date: Wed Aug 31 10:44:13 2022 +0200 +commit 7b1fe0483b684693c7baea9b62b471b64c6e22a9 +Author: Henning Westerholt +Date: Mon Jun 12 08:24:01 2023 +0000 - pua_dialoginfo: clone dlg var values + tools: use python3 for route_graph.py tool, for old systems with both python2/python3, fix file closing -commit 54905e6b02e36e72bb74a92c77b273cf57822f18 -Author: Daniel-Constantin Mierla -Date: Wed Aug 31 10:18:07 2022 +0200 +commit fa2a69e2ae919b7ba221e87e2001bde83113ce2a +Author: Akash Gupta +Date: Sat Jun 10 14:48:03 2023 +0530 - acc: duplicate dlg var values used in extra2strar_dlg_only() - - - avoid buffer index overlapping and be coherent with extra2strar() + tool: port the route_graph.py script to python version 3.x -commit 590d00f04ce714ad7ce3ae6a9ca7bd2853925cba +commit f867d2190853b9f21791d83573de3f96f4337242 Author: Daniel-Constantin Mierla -Date: Wed Aug 31 09:54:54 2022 +0200 +Date: Fri Jun 9 10:02:44 2023 +0200 - tm: exported t_exists() to kemi + kamzo: kemi exports formatted for kemidocs.py -commit 8cb948cc07e2d577cdd14efdfe38f3e9bbf11d79 +commit cabf1968bf75f2b85894e5cfda63e1cd3cb7bd82 Author: Daniel-Constantin Mierla -Date: Tue Aug 30 13:34:38 2022 +0200 +Date: Fri Jun 9 09:59:42 2023 +0200 - dialog: fetch directly the int value for dlg variable used in dlg_cseq_update() + ims_charging: kemi exports format for kemidocs.py -commit aded00bbfe75771cef8d0ee9ae8401772f7644a9 +commit d9f9e5c6be4d8d30bdccb0154e95a87982d5c736 Author: Daniel-Constantin Mierla -Date: Tue Aug 30 13:32:16 2022 +0200 +Date: Thu Jun 8 11:58:42 2023 +0200 - dialog: safer version for getting dlg variable value - - - clone to ensure that reference is not becoming invalid over the time + ratelimit: ending struct whitespace for kemi exports -commit a070f5c132a68111fade7212db6a2bc738e03193 +commit fd7ea1bac7c5a0bc7e79e5bb90072898c6652e9d Author: Daniel-Constantin Mierla -Date: Tue Aug 30 13:19:33 2022 +0200 - - dialog: updated to get the int value for cseq update operations - -commit 44103239ba5cc4c4582ccfacf4a3db3918e4431c -Author: Kamailio Dev -Date: Tue Aug 30 13:01:45 2022 +0200 +Date: Thu Jun 8 11:54:21 2023 +0200 - modules: readme files regenerated - tm ... [skip ci] + ratelimit: reformat kemi exports for kemidocs.py -commit c38b3585357a2200944cfd8e736f32093786350b +commit d9d4ef011c9ee4f9c664ad945b36197a98efa9cd Author: Daniel-Constantin Mierla -Date: Tue Aug 30 12:54:51 2022 +0200 +Date: Thu Jun 8 11:48:21 2023 +0200 - tm: docs for t_exists() + jansson: reformat kemi exports for kemdocs.py tool -commit f16e76e432f46d7fc62e8c1c0808149c7ffde0c1 -Author: Daniel-Constantin Mierla -Date: Tue Aug 30 12:49:54 2022 +0200 +commit 848d55388dda0c135820d9f24950561946249bbc +Author: Ovidiu Sas +Date: Mon Jun 12 00:24:15 2023 -0400 - tm: new function t_exists() - - - return true if the transaction exists for the current message without - setting the global references + mqueue: fix support for db_text + - db_operations are safe only after db mod_init() + - closes #3474 -commit 837d7eab397547a4a67158e4da719288e20a0bb4 +commit 79b82198075250420cb08d6b5fd5b100ff672606 Author: Daniel-Constantin Mierla -Date: Tue Aug 30 11:17:03 2022 +0200 +Date: Fri Jun 2 21:20:59 2023 +0200 - tsilo: restore also the global t branch index + pv: exported {val} transformation -commit 72234f9efbb5b299823b33dc4eda84a43d5f6384 -Author: Daniel-Constantin Mierla -Date: Tue Aug 30 10:58:39 2022 +0200 +commit bc82f8938a779dc5835079e0477b5970287c49e9 +Author: Kamailio Dev +Date: Thu Jun 1 13:46:22 2023 +0200 - pv_headers: use t_unset() based on vref instead of resetting global t always + modules: readme files regenerated - ims_usrloc_scscf ... [skip ci] -commit 294a00985b2cf4a397ffc81782f9ce6e4bc1ca15 +commit 1217c9098bc8790e659959a7df97e441e84b54ff Author: Daniel-Constantin Mierla -Date: Tue Aug 30 10:54:53 2022 +0200 +Date: Thu Jun 1 13:39:47 2023 +0200 - tmx: use t_unset() instead of t_unref() for pv_get_tm_reply_reason() + ims_usrloc_scscf: docs - type int for hash_size parameter -commit f69c13a587df53fb93999d81cd02dc99ab223187 +commit bc544daea2ee4bb568cf0314f6d32b8aa0c81ecc Author: Daniel-Constantin Mierla -Date: Tue Aug 30 10:53:15 2022 +0200 +Date: Wed May 31 11:53:14 2023 +0200 - tm: added t_unset() intermodule API function - - - reset global t and branch without releasing the transaction - - useful for cases when global t needs to be set in callbacks and then - reset before config execution is finished + async: use _async_timer_exec_last_slot = UINT_MAX for initial value -commit 07877fe6686139032d4d2f85b5f119b2cdf93cf6 +commit a059af04ac47fd31238ca4f22ad868529e035c43 Author: Daniel-Constantin Mierla -Date: Tue Aug 30 10:36:53 2022 +0200 +Date: Wed May 31 09:01:13 2023 +0200 - tmx: use t_find() for pv_get_tm_reply_reason() + sst: fix condition on sst_min_se for sst_check_min() -commit 887ea4420f2a11e9d26c031c8c75e897b0fd8072 +commit b2f99145fa7f4088c80dd3e759372445f93f5492 Author: Daniel-Constantin Mierla -Date: Tue Aug 30 09:07:58 2022 +0200 - - etc/kamailio.cfg: comment for route[NATMANAGE] made generic - -commit 836d122af8575c66651232f3ad25bad085bfb972 -Author: Victor Seva -Date: Sun Aug 28 22:59:44 2022 +0200 +Date: Tue May 30 17:00:27 2023 +0200 - pv_headers: use tm.t_find API + cfgt: reworked test on dest.s for freeing -commit 46d0356386bcf2a70671fd73979ef97bd5528d74 -Author: Victor Seva -Date: Sun Aug 28 22:42:40 2022 +0200 +commit cb6332982edff5fd2f10b6ee41c22388cc9a39b3 +Author: Daniel-Constantin Mierla +Date: Mon May 29 08:56:19 2023 +0200 - pkg/kamailio/deb: version set 5.7.0~dev1 [skip ci] + cdp: reworked switch for setting x->state = ACC_CC_ST_DISCON -commit 7a53ac8e8d92dbb375378b49562a7842055d7fb3 -Author: Victor Seva -Date: Sun Aug 28 22:40:42 2022 +0200 +commit 1205869ffd9c7e16a4f299b020f0bc90a2d4fcd7 +Author: Victor Seva +Date: Tue May 9 10:18:30 2023 +0200 - pkg/kamailio/deb: sync dirs contents [skip ci] + core: pv_cache_dump + + related to #3440 -commit c5d48f8ee3884934bd8b910a2dae1888fead3cf1 -Author: Kamailio Dev -Date: Fri Aug 26 12:16:27 2022 +0200 +commit 87ed3d9c3ae3ecfabe6d24f5fd3d656ef1182fac +Author: Дилян Палаузов +Date: Mon May 22 19:58:57 2023 +0200 - modules: readme files regenerated - dialog ... [skip ci] + src/Makefile.defs: recognize GCC 13 as recent ⇔ not too old compiler -commit 353aa1c821f2889c0a6dbadf9b1b1c1ed039deb6 +commit 423a818cf6e8f6d672630a0365e13877a173508f Author: Daniel-Constantin Mierla -Date: Fri Aug 26 12:11:08 2022 +0200 +Date: Wed May 24 21:06:45 2023 +0200 - dialog: docs for dlg_ctxiuid_mode params + siprepo: check if list is set on insert -commit a770c4957a31c143a29c68cb71e705c3f9cfcbad +commit 7971d825361bee29d65fcea69f2978d7af31eeaa Author: Daniel-Constantin Mierla -Date: Fri Aug 26 11:24:30 2022 +0200 +Date: Tue May 23 09:41:13 2023 +0200 - dialog: added modparam dlg_ctxiuid_mode to control when iuid is set + ipops: create container items if not found for srv and naptr functions + + - GH #3419 -commit d7e8ae72a0258aa6c3bcf850ea410a929da003cb +commit 9c125234cd5bb7ff580e875c82002a8dd69fff82 Author: Daniel-Constantin Mierla -Date: Fri Aug 26 10:15:58 2022 +0200 +Date: Tue May 23 09:35:07 2023 +0200 - core: dprint - simplified sip msg check + iopops: realign exported structures to highlight better the fields -commit 02b960d84d479b001cf94b2b53063deca1d7256d +commit 9ff464850c6ef23b37833b8c86efc1e973f744b1 Author: Daniel-Constantin Mierla -Date: Fri Aug 26 10:15:22 2022 +0200 +Date: Mon May 22 21:37:02 2023 +0200 - core: parse - added IS_SIP_MSG() macro to check if message type is SIP - - - defined also IS_SIP_REQUEST() same as IS_SIP() but with more explicit - name for detecting SIP requests + kamctl: version set to 5.8.0 -commit 654f22a03e874f86c4b2b2d29eb969a1be3bb25e -Author: David Escartin -Date: Thu Apr 28 14:19:53 2022 +0200 +commit a2209018fb03dda6d4b7df90f933c97bf4ae532b +Author: Victor Seva +Date: Fri May 19 01:39:40 2023 +0200 - dialog: set context iuid for CANCEL requests to let isflagset function return the right value in case a dialog flag was previously set on the call + core: clang-format for coherent indentation and coding style -commit a9cf4577c25d7933531b8969a1941bac4faf8d68 -Author: Daniel-Constantin Mierla -Date: Thu Aug 25 14:51:23 2022 +0200 +commit 339891e7da584abcc378aa2104f536841d615e57 +Author: Victor Seva +Date: Fri May 19 01:12:41 2023 +0200 - tm: new inter-module API function t_find(...) - - - combines get_t() with t_check_msg(...) to get the transaction, - returning also if it was referenced or not + pre-commit: add mixed-line-ending hook [skip ci] -commit 721daf5ca55a8fb366cff2821e249bfff64d8f87 -Author: Daniel-Constantin Mierla -Date: Thu Aug 25 10:48:16 2022 +0200 +commit e66a63a230e91461af0a82e3bbc54eabbf5195c7 +Author: Victor Seva +Date: Fri May 19 01:08:17 2023 +0200 - usrloc: adde random and pid to call-id for keepalive requests - - - GH #3225 + README: add pre-commit badge -commit 03dffaad07952568bd40e22d5b23aaa4bcfe613a -Author: Kamailio Dev -Date: Wed Aug 24 09:31:46 2022 +0200 +commit e15a57e0e027425827509277203341d55ace49fa +Author: Victor Seva +Date: Fri May 19 00:50:59 2023 +0200 - modules: readme files regenerated - pv ... [skip ci] + pre-commit: update pre-commit-hooks [skip ci] -commit 1a33c8b7c70e7f629868d926965ec456bf2eecae -Author: Daniel-Constantin Mierla -Date: Wed Aug 24 09:18:08 2022 +0200 +commit f781dc9ce914cc619abd9d53f987f1155557b720 +Author: Victor Seva +Date: Thu May 18 15:15:36 2023 +0200 - pv: updated docs for xavp_lshift() + pre-commit: tool to keep thing tidy [skip ci] -commit 4598f0a0df90ad81e192be55a89fbd5cca52a40e -Author: korayvt -Date: Tue Aug 23 14:05:45 2022 +0300 +commit 2cac52c68feeacc1dc90e4ff322b6109c32669e8 +Author: Victor Seva +Date: Fri May 19 00:24:53 2023 +0200 - core: added parser mode check + README: remove travis-ci info [skip ci] + + no longer used -commit 5d09caf029ed4271ac6dc856cb70cbf375b4c7f1 -Author: Matteo Brancaleoni -Date: Tue Jul 19 16:23:53 2022 +0200 +commit 08fbc4fa8d44c2c0ee596e1f30b95b5b4fcfc823 +Author: Henning Westerholt +Date: Thu May 18 11:37:44 2023 +0000 - pv: add monotonic clock to TimeVal pseudovariable - - - adds $TV(Sm) pseudovariable which returns the system monotonic clock - as a string - - on Linux, tries to use CLOCK_MONOTONIC_RAW which does not suffer from - ntp time adjustement + dispatcher: fix formatting after commit 1f53b159c311715b -commit 181bc683f6f0496b80c5997a4de30a21c04ce0bc -Author: Daniel-Constantin Mierla -Date: Tue Aug 23 09:57:43 2022 +0200 +commit 1f53b159c311715b993ee33d40fb35017626e89c +Author: Kamailio Dev +Date: Thu May 18 13:01:45 2023 +0200 - core: aliased dns_rev_via to rev_dns + modules: readme files regenerated - dispatcher ... [skip ci] -commit f71d984edc21c015fc4c81682b115b510169b713 -Author: Daniel-Constantin Mierla -Date: Tue Aug 23 09:50:28 2022 +0200 +commit 6183319381573e42b882d05ae1748539f7547d8c +Author: Henning Westerholt +Date: Thu May 18 10:52:52 2023 +0000 - core: aliased dns_use_failover to use_dns_failover + dispatcher: fix force send socket functionality, was not working in some TCP scenarios -commit 31ff79be68c262dc74ec4baaae8f9991ffbe7438 -Author: Daniel-Constantin Mierla -Date: Tue Aug 23 09:44:38 2022 +0200 +commit 704f589577f51bb85b76070ca5722d54590b2c09 +Author: Henning Westerholt +Date: Thu May 18 10:50:53 2023 +0000 - core: aliased dns_use_cache to use_dns_cache + dispatcher: clarification regarding xavp_dst_mode docs -commit a10da3a8802fd02bab9e8c655aa845d121370fd4 -Author: Daniel-Constantin Mierla -Date: Mon Aug 22 12:46:33 2022 +0200 +commit 83b092fea98cf6ba8b716fcfb574ad24db818ce3 +Author: Victor Seva +Date: Wed May 17 16:37:43 2023 +0200 - pv: parse header name given with variable to $hdr() and $hdrc() + xprint: clang-format for coherent indentation and coding style -commit b46afeca6c515f5baf1812ca821321117df6478b -Author: Henning Westerholt -Date: Tue Aug 23 07:29:23 2022 +0000 +commit 709163fa7e8ac3a1bf0a1f8ac5fdaa0ccce64d67 +Author: Victor Seva +Date: Wed May 17 16:37:43 2023 +0200 - etc/kamailio.cfg: corrected a typo ("endabled"), GH #3223 + xmpp: clang-format for coherent indentation and coding style -commit fb13cf364870895dec94fa1ddf6a1afd3c099715 -Author: Daniel-Constantin Mierla -Date: Mon Aug 22 12:38:14 2022 +0200 +commit 07044780f59b37e555e181a946658e841c66ca51 +Author: Victor Seva +Date: Wed May 17 16:37:43 2023 +0200 - pv: detect known headers provided with variable for $hfl(...) and $hflc(...) - - - GH #3194 + xmlrpc: clang-format for coherent indentation and coding style -commit 5dbee20d7d44bae21f3a225966808576285ef2eb -Author: Kamailio Dev -Date: Sun Aug 21 15:46:09 2022 +0200 +commit e748922b0f3c2346f633e1dbf2bfa97d11023697 +Author: Victor Seva +Date: Wed May 17 16:37:43 2023 +0200 - modules: readme files regenerated - topos ... [skip ci] + xmlops: clang-format for coherent indentation and coding style -commit 7dd3658e248a6c64b1606ebebac76869a006b911 -Author: Henning Westerholt -Date: Sun Aug 21 13:31:05 2022 +0000 +commit 0e0f42ae1e4e3aa39458e512125f00e52b65686e +Author: Victor Seva +Date: Wed May 17 16:37:43 2023 +0200 - topos: small doc improvements related to header_mode parameter + xlog: clang-format for coherent indentation and coding style -commit a5e805a555488e70116ee60d0d9e65ebf80c020e -Author: Kamailio Dev -Date: Sun Aug 21 15:31:12 2022 +0200 +commit 43b7f3bd64eb1075e7e567cb008bfbd8b60f1503 +Author: Victor Seva +Date: Wed May 17 16:37:42 2023 +0200 - modules: readme files regenerated - topos ... [skip ci] + xhttp_rpc: clang-format for coherent indentation and coding style -commit 54fe9d29d15bd15b60950035ad348baacbb868fe -Author: Mvondo Eric <106535097+emvondo@users.noreply.github.com> -Date: Sun Aug 21 14:19:51 2022 +0100 +commit d9d1e2469e63aa58e7154ec44777efec8695ef20 +Author: Victor Seva +Date: Wed May 17 16:37:42 2023 +0200 - topos: disable multiple comma separated values in One Single Via, Record-Route or Route header if needed (#3220) - - * topos: enable multiple Via values in separate via header - * topos: disable multiple comma separated values in One Single Via, Record-Route or Route header - * topos: disable multiple comma separated values in One Single Via, Record-Route or Route header - * topos: disable multiple comma separated values in One Single Via, Record-Route or Route header - * change parameter name for disabling compact form values + xhttp_prom: clang-format for coherent indentation and coding style -commit a022dbd6b30d8301053950756cd30a2b478433e0 -Author: Henning Westerholt -Date: Sun Aug 21 12:38:16 2022 +0000 +commit 0bc9de0dcdfbbceea45206cc5f9b4c7ab2a6f8ee +Author: Victor Seva +Date: Wed May 17 16:37:42 2023 +0200 - core: add pmtu_discovery=2 for IPv4 and IPv6 - set IP_PMTUDISC_WANT/IPV6_PMTUDISC_WANT (GH #3141) - - - add pmtu_discovery=2 for IPv4 and IPv6 - set IP_PMTUDISC_WANT/IPV6_PMTUDISC_WANT - - related to GH #3141 - - for IPv4: will fragment a datagram if needed according to the path MTU, - or will set the don't-fragment flag otherwise - - for IPv6: will fragment a datagram if needed according to the path MTU for IPv6 + xhttp_pi: clang-format for coherent indentation and coding style -commit 3cb1f8eaec344433fd94011ec28da464c5626c2a -Author: Henning Westerholt -Date: Fri Aug 19 16:31:56 2022 +0000 +commit d5a0735ee32685bfb070cb9288f6bbf4b699780c +Author: Victor Seva +Date: Wed May 17 16:37:42 2023 +0200 - utils: small whitespace fix for Makefile + xhttp: clang-format for coherent indentation and coding style -commit 99fde923448d251fb0e04d443d9a2bffce15d1b1 -Author: Henning Westerholt -Date: Fri Aug 19 14:39:01 2022 +0000 +commit 85ad2db0ced7c21e5f3e3871fc9cbdc0d637641a +Author: Victor Seva +Date: Wed May 17 16:37:42 2023 +0200 - tm: remove some commented out code in timer logic + xcap_server: clang-format for coherent indentation and coding style -commit ac4d7ce7bf153604e0e07d1003a1d078882c90f4 -Author: S-P Chan -Date: Fri Aug 19 22:18:39 2022 +0800 +commit ce9cd3132bf5834b5d6c3ecac42b0e4c002da71d +Author: Victor Seva +Date: Wed May 17 16:37:42 2023 +0200 - tls_wolfssl: add parser logic for previous commits related to TLSv1.3 + xcap_client: clang-format for coherent indentation and coding style -commit 2ba21dfaa5098c8a2dcf9185e1327c55a4e0e4bc -Author: S-P Chan -Date: Fri Aug 19 22:16:10 2022 +0800 +commit 90eea708c8ba661fa02ef5bb6bbbb5102ad6246c +Author: Victor Seva +Date: Wed May 17 16:37:41 2023 +0200 - tls_wolfssl: add support for configuration option TLSv1.3 and TLSv1.3+ + websocket: clang-format for coherent indentation and coding style -commit 377a23b8f0152d9c61ddf17e4b95d7fa08dd11d9 -Author: S-P Chan -Date: Fri Aug 19 22:01:08 2022 +0800 +commit 62db7b0e2b3f5ad40ca417e7d9c21518db448cb2 +Author: Victor Seva +Date: Wed May 17 16:37:41 2023 +0200 - tls_wolfssl: add timestamp and sni info for a session - - - ref: commit c0c1dcc100 for tls + uuid: clang-format for coherent indentation and coding style -commit 24cfce96a1e9e970ab7661a4e188dab2b3542fd0 -Author: Henning Westerholt -Date: Fri Aug 19 14:02:16 2022 +0000 +commit e0d162afb8c87b56a800ee5ddd395af27969be80 +Author: Victor Seva +Date: Wed May 17 16:37:41 2023 +0200 - tm: improve comment related to dns failover, add debug output in this case + utils: clang-format for coherent indentation and coding style -commit 399b34c6bd4e5cbfcf4dcb699755c393229fcb99 -Author: Henning Westerholt -Date: Fri Aug 19 13:17:46 2022 +0000 +commit 6e89f3e252dc6e8353ca3b7f2d7b29ab4173e8c8 +Author: Victor Seva +Date: Wed May 17 16:37:41 2023 +0200 - tm: backup and restore X/AVP values from initial transaction in DNS failover processing - - - restore X/AVP values from initial transaction in DNS failover processing - - the X/AVP context gets lost, so we need to re-create it from the transaction - - otherwise modules that depends on the X/AVPs, e.g. topology hiding will not work - - tested with one load-balancer and two proxy servers - - previous fix d6b1c20d3ad94 was reverted, we now properly backup and restore + usrloc: clang-format for coherent indentation and coding style -commit 9ceeabc299e08c944014c16ef54cd159b063be2e -Author: Henning Westerholt -Date: Fri Aug 19 13:15:53 2022 +0000 +commit af6b7b7034007dc51525732562853c402a6941a3 +Author: Victor Seva +Date: Wed May 17 16:37:41 2023 +0200 - Revert "tm: restore X/AVP values from initial transaction in DNS failover processing" - - This reverts commit d6b1c20d3ad94d9136cf247e67b7fc0d32b18d3b. + userblocklist: clang-format for coherent indentation and coding style -commit 3b0b03c921945000b2c0f97810061fee58faf77d -Author: Henning Westerholt -Date: Fri Aug 19 07:10:45 2022 +0000 +commit 8b3609542484c79cf09f3ee6fb57c1cc1a05138b +Author: Victor Seva +Date: Wed May 17 16:37:41 2023 +0200 - tls: exclude TLSv1.3 from OpenSSL > 1.1.0 < 1.1.1 for Debian stretch + uri_db: clang-format for coherent indentation and coding style -commit 60f25fc4b47222bac0eb09fbed93a1b63dcc54a4 -Author: Henning Westerholt -Date: Thu Aug 18 10:32:02 2022 +0000 +commit 57e22554272f30a51ec460fa18492a000fdb5e48 +Author: Victor Seva +Date: Wed May 17 16:37:40 2023 +0200 - tls: remove wrong TLSv1.3 statements from #ifdef block for openssl < 1.1.0 + uid_uri_db: clang-format for coherent indentation and coding style -commit 5f229a799b251e82431b4642e9bd8aa76c405d13 -Author: Daniel-Constantin Mierla -Date: Thu Aug 18 11:52:51 2022 +0200 +commit 18725c558c8437fa80e545eedc4eb26d48f7dad7 +Author: Victor Seva +Date: Wed May 17 16:37:40 2023 +0200 - registrar: use macro to init str value and more debug messages + uid_gflags: clang-format for coherent indentation and coding style -commit a88f805236ef0549ce8a8079142b202d569bf3f1 -Author: Daniel-Constantin Mierla -Date: Thu Aug 18 11:34:44 2022 +0200 +commit 488501c35eff7be60b87753e3c841b082aad305c +Author: Victor Seva +Date: Wed May 17 16:37:40 2023 +0200 - registrar: print number of contacts and max limit in logs and formatting updates + uid_domain: clang-format for coherent indentation and coding style -commit c73a4127dfab65f2c17ea9bf21c94b102f4ec1ea -Author: Henning Westerholt -Date: Wed Aug 17 16:07:58 2022 +0000 +commit c9ef2603b5b6c6979049c6c0f9521025afc7a731 +Author: Victor Seva +Date: Wed May 17 16:37:40 2023 +0200 - tls: add parser logic for previous commits related to TLSv1.3 + uid_avp_db: clang-format for coherent indentation and coding style -commit 988b999cbdf20a1c2056035cd4240d6147bf76a4 -Author: Kamailio Dev -Date: Wed Aug 17 16:01:35 2022 +0200 +commit db6b81a1a9995fec3720d01f32b517451ff2f077 +Author: Victor Seva +Date: Wed May 17 16:37:40 2023 +0200 - modules: readme files regenerated - tls ... [skip ci] + uid_auth_db: clang-format for coherent indentation and coding style -commit 105600b3b3385787e448955df49135c038095730 -Author: Henning Westerholt -Date: Wed Aug 17 13:55:59 2022 +0000 +commit f22200bfe135577bb4a71c01106ea7ba5c1b886a +Author: Victor Seva +Date: Wed May 17 16:37:40 2023 +0200 - tls: add support for configuration option TLSv1.3 and TLSv1.3+ + uac_redirect: clang-format for coherent indentation and coding style -commit 554d03a55f62b06802d4880f005806a0517da5fb -Author: Daniel-Constantin Mierla -Date: Wed Aug 17 11:21:54 2022 +0200 +commit f2c587938311398818b8c7c3e02fc3af3726bb53 +Author: Victor Seva +Date: Wed May 17 16:37:40 2023 +0200 - dialog: some formatting fixes and updates + uac: clang-format for coherent indentation and coding style -commit b5ae633242e5e34b1f6dc8f025e68872b47b461c -Author: Daniel-Constantin Mierla -Date: Wed Aug 17 11:07:55 2022 +0200 +commit 8187f195644ffd527f51d887dac34a1fb584edfd +Author: Victor Seva +Date: Wed May 17 16:37:39 2023 +0200 - usrloc: increased the size for keys2 array in ul_ka_db_records() - - - consequence of 06f933ad17aac3a3f0f81cf0e0ab04f38cf60993 + tsilo: clang-format for coherent indentation and coding style -commit 02a04a2b544d16ced3d6e59c4458605419880cfe -Author: Kamailio Dev -Date: Wed Aug 17 10:46:42 2022 +0200 +commit f57e9aa15b7b5fb9b1116406320487ea8845dcf7 +Author: Victor Seva +Date: Wed May 17 16:37:39 2023 +0200 - modules: readme files regenerated - usrloc ... [skip ci] + topos_redis: clang-format for coherent indentation and coding style -commit edde9cdb0c4d78f4e72da297c9f025d6367f6d8d -Author: Daniel-Constantin Mierla -Date: Wed Aug 17 10:34:46 2022 +0200 +commit f55112c0c5e442ce9e404940da583903420313ee +Author: Victor Seva +Date: Wed May 17 16:37:39 2023 +0200 - Makefile.defs: version set to 5.7.0-dev1 + topos: clang-format for coherent indentation and coding style -commit 06f933ad17aac3a3f0f81cf0e0ab04f38cf60993 -Author: Andy Brezinsky -Date: Tue Aug 16 11:20:20 2022 -0500 +commit 963f301a08ab6c3e15a20181b23e9177eb1e2232 +Author: Victor Seva +Date: Wed May 17 16:37:39 2023 +0200 - usrloc: re-use TCP connections for keepalive - - - Fixes GH #3178. Sets TCP connection id for keepalive based on the value in the database - If unset, tcpconn_id will remain 0 and keepalives will work the same as they do today - - Update documentation to clarify when it will use received vs AOR for keepalive + topoh: clang-format for coherent indentation and coding style -commit 8fb25f7cb6fa73dc37fe11df9b921c32009bd107 -Author: Shane Mitchell -Date: Tue Aug 16 23:17:17 2022 -0400 +commit b0b4d5d41b8ff0e6afb429a91d16c07f8e6efffb +Author: Victor Seva +Date: Wed May 17 16:37:39 2023 +0200 - dialog: dont reset dlg_db_mode in POSTCHILDINIT for DB_MODE_SHUTDOWN + tmx: clang-format for coherent indentation and coding style -commit c0c1dcc1008e74ed51987506d96bd8ebc88f3c9d -Author: Stefan Mititelu -Date: Thu Jul 14 12:02:37 2022 +0300 +commit 9c15771fd3b4ddf63928751e359b42b49559d8e5 +Author: Victor Seva +Date: Wed May 17 16:37:39 2023 +0200 - tls: add timestamp and sni info for a session + tmrec: clang-format for coherent indentation and coding style -commit 44b3ccd71467b78d9e9a7184c9fd25bc5f616ac4 -Author: Sergey Safarov -Date: Tue Aug 16 16:31:25 2022 +0300 +commit 77693248300a6cecb802950fad754bf933218163 +Author: Victor Seva +Date: Wed May 17 16:37:38 2023 +0200 - pkg/kamailio/obs: fixed rpm packaging on CentOS 8 and Fedora + tm: clang-format for coherent indentation and coding style -commit 4a6aa75dd1de4e33ba6ac3f1d770a1beed61e157 -Author: Sergey Safarov -Date: Tue Aug 16 12:30:56 2022 +0000 +commit 5a347dd24e0d60d9eef48f27b95df43a0eb3eb78 +Author: Victor Seva +Date: Wed May 17 16:37:38 2023 +0200 - pkg/kamailio/obs: fixed packaging for RHEL 7 and RHEL 6 based dists [skip ci] + tlsa: clang-format for coherent indentation and coding style -commit 1e4bf1dd7fbfc9d51f0e56e98472a42de781cdbd -Author: Daniel-Constantin Mierla -Date: Tue Aug 16 09:09:45 2022 +0200 +commit 7e36597b8f7797a0468a9d6d4a8070ba5603cf79 +Author: Victor Seva +Date: Wed May 17 16:37:38 2023 +0200 - msrp: proper cmap insert when last item has greater citemid - - - condition for last item was processed first, resulting in improper - order of items, GH #3215 + tls_wolfssl: clang-format for coherent indentation and coding style -commit f1dcb649cb779b2ccd14d18cad441d29653ffabd -Author: Kamailio Dev -Date: Mon Aug 15 20:46:09 2022 +0200 +commit d253dcd8b6c2f0111e2a09e1f10baa1f0733a41b +Author: Victor Seva +Date: Wed May 17 16:37:16 2023 +0200 - modules: readme files regenerated - secfilter ... [skip ci] + tls: clang-format for coherent indentation and coding style -commit 8f30f438f9ba6ab9a2d7bde1cfa4d186e2fe0d6f -Author: Jose Luis Verdeguer -Date: Mon Aug 15 20:27:34 2022 +0200 +commit 68fe076d4fa9233519a414cfddc9fb5bea5d73d4 +Author: Victor Seva +Date: Wed May 17 16:37:16 2023 +0200 - secfilter: fix examples [skip ci] + timer: clang-format for coherent indentation and coding style -commit 252562b8fce76cb01cde993b530509e89baae95a -Author: Kamailio Dev -Date: Mon Aug 15 20:31:14 2022 +0200 +commit cd9be5e55a6cd4d8ec53511abd7315546d806c90 +Author: Victor Seva +Date: Wed May 17 16:37:16 2023 +0200 - modules: readme files regenerated - xhttp ... [skip ci] + textopsx: clang-format for coherent indentation and coding style -commit 36b0da00b9fc08be9e855d5dd4cc878b6e3c88bf -Author: Daniel-Constantin Mierla -Date: Mon Aug 15 20:18:02 2022 +0200 +commit 507d4240b5a08fa874857c81b4b9411dffe9e0d3 +Author: Victor Seva +Date: Wed May 17 16:37:16 2023 +0200 - xhttp: docs - listed http_reply_parse core setting + textops: clang-format for coherent indentation and coding style -commit c09ede1ba7d600da37e7c0007f128a72b34250a4 -Author: Henning Westerholt -Date: Sun Aug 14 09:01:57 2022 +0000 +commit 76482e4df45ee350fb3f502a2be0f31b9b9af14e +Author: Victor Seva +Date: Wed May 17 16:37:16 2023 +0200 - core: different logging for IPv4 and IPv6 for socket option setting + tcpops: clang-format for coherent indentation and coding style -commit 990bdfe56b9d8e2d2d297b87998065e137d4e203 -Author: Henning Westerholt -Date: Sun Aug 14 08:56:12 2022 +0000 +commit de74852a83e7830749d74ab82becc16139956969 +Author: Victor Seva +Date: Wed May 17 16:37:16 2023 +0200 - core: also set pmtu_discovery core parameter for IPv6, GH #3141 - - - also set pmtu_discovery core parameter for IPv6 - - based on a patch from Rick van Rein - - probably to be extended further + systemdops: clang-format for coherent indentation and coding style -commit 43d927970f4be565284f53e986171eb3512c6b63 -Author: S-P Chan -Date: Thu Jul 14 09:11:30 2022 +0800 +commit d07141c699bf0e69b850f4100e83ad0b0354d4c0 +Author: Victor Seva +Date: Wed May 17 16:37:16 2023 +0200 - tls_wolfssl: wolfSSL — update to v5.4.0-stable - - - the upstream commit also fixes GCC warnings so - we don't have to workaround with -Wno-xxxxxx + sworker: clang-format for coherent indentation and coding style -commit 9a35ce57270d259f60a116322d17a411c58bcb4f -Author: Kamailio Dev -Date: Fri Aug 12 16:31:16 2022 +0200 +commit 4e3fb1666d7fe5b0c2973b842d065c1c7f9b8fbe +Author: Victor Seva +Date: Wed May 17 16:37:15 2023 +0200 - modules: readme files regenerated - secfilter ... [skip ci] + stun: clang-format for coherent indentation and coding style -commit d5ef682ebe98ca87021a8e2344bb94c75747f53e -Author: Jose Luis Verdeguer -Date: Fri Aug 12 14:01:53 2022 +0200 +commit 352a1f59d2e16501a1678f51705877f36b3edf65 +Author: Victor Seva +Date: Wed May 17 16:37:15 2023 +0200 - secfilter: updated samples [skip ci] + stirshaken: clang-format for coherent indentation and coding style -commit fe20e16bf1e1656ef794699db345eefd3d1b8ac8 -Author: Jose Luis Verdeguer -Date: Fri Aug 12 13:13:04 2022 +0200 +commit 30898dff28871ddf5a2054c46dee3e2007d144b8 +Author: Victor Seva +Date: Wed May 17 16:37:15 2023 +0200 - secfilter: machine-parsable data structure for RPC printing data + statsc: clang-format for coherent indentation and coding style -commit 26785f866eeadc6944af83ae1a57e8ff100f60f5 -Author: Daniel-Constantin Mierla -Date: Fri Aug 12 14:31:48 2022 +0200 +commit 972777a3555abeb5733629caeb0b0d9f674050e8 +Author: Victor Seva +Date: Wed May 17 16:37:15 2023 +0200 - core/cfg: cast pointer to long to silent compiler warning - - - GH #3208 + statistics: clang-format for coherent indentation and coding style -commit a8769af4c3a497d0f6a81cff17861e566ffa87bc -Author: drTr0jan -Date: Tue Jul 12 15:12:00 2022 +0300 +commit 578a17a5c608078d317066144256403fb79985cd +Author: Victor Seva +Date: Wed May 17 16:37:15 2023 +0200 - core: fix ksr_version_control() for FreeBSD build + sst: clang-format for coherent indentation and coding style -commit 3b1354e2fd26c06fa6bc5ddbee1a012507aa2ea5 -Author: Daniel-Constantin Mierla -Date: Fri Aug 12 09:16:24 2022 +0200 +commit e051bdc1315321824a366df97c671623b47843c7 +Author: Victor Seva +Date: Wed May 17 16:37:15 2023 +0200 - uac_redirect: check if reason parameter ifs provided for get_redirects() - - - cope properly with the common function used for the two function - variants - - GH #3197 + ss7ops: clang-format for coherent indentation and coding style -commit 939ceb3390b171b773eeb438b8fff72022e4f6f0 -Author: Daniel-Constantin Mierla -Date: Thu Aug 11 21:48:25 2022 +0200 +commit aeabdb6fa5bb7f3ab49d5af5e5e4d2b69596d786 +Author: Victor Seva +Date: Wed May 17 16:37:14 2023 +0200 - usrloc: do not send keepalives when destroying modules - - - GH #3207 + sqlops: clang-format for coherent indentation and coding style -commit 40d0c0ef19439ba03822c1a875ea0461f3f1106b -Author: Kamailio Dev -Date: Wed Aug 10 22:46:19 2022 +0200 +commit 1b5ab42c21c9b248f35d956ca3af53e193c81824 +Author: Victor Seva +Date: Wed May 17 16:37:14 2023 +0200 - modules: readme files regenerated - uac_redirect ... [skip ci] + speeddial: clang-format for coherent indentation and coding style -commit 7ef109e6cd1ce7ecbfa56c31ff7555275e59095f -Author: Daniel-Constantin Mierla -Date: Wed Aug 10 22:39:03 2022 +0200 +commit f2cca4f00625e25b60b14dbcbee407144b18744e +Author: Victor Seva +Date: Wed May 17 16:37:14 2023 +0200 - uac_redirect: clarifications for acc_function mod param + snmpstats: clang-format for coherent indentation and coding style -commit 9f3d1c274ad926e9640d0091c9702a34f8b2e539 -Author: russagit -Date: Wed Aug 10 09:23:13 2022 +0000 +commit 87766761e80656c37e967383708bec2ec66d0cac +Author: Victor Seva +Date: Wed May 17 16:37:14 2023 +0200 - sipt: Fix isup generic_number and generic_number_nai decoding (GH #3209) + smsops: clang-format for coherent indentation and coding style -commit d6ef0bf487e6246092683e0281f5323f056cdaf4 -Author: Kamailio Dev -Date: Wed Aug 10 09:31:18 2022 +0200 +commit 976486d2c365f0c58c8273a5b2cb62f226c74202 +Author: Victor Seva +Date: Wed May 17 16:37:14 2023 +0200 - modules: readme files regenerated - siptrace ... [skip ci] + sms: clang-format for coherent indentation and coding style -commit b4ab0fdcb9f49b2a3b3cac24b20a0f4e50283468 -Author: Stefan Mititelu -Date: Wed Aug 10 10:24:51 2022 +0300 +commit 698d642bb9ca309a2205b00d0ea10dbe74eda9c6 +Author: Victor Seva +Date: Wed May 17 16:37:14 2023 +0200 - siptrace: Update doc for the two new modparams + slack: clang-format for coherent indentation and coding style -commit da0178673f9a47600329fff2c3105e0fbfbd78f7 -Author: Henning Westerholt -Date: Tue Aug 9 14:15:04 2022 +0000 +commit be5c1b59547e9503391da615edcd73bf0e3dab0c +Author: Victor Seva +Date: Wed May 17 16:37:13 2023 +0200 + + sl: clang-format for coherent indentation and coding style - tm: add a comment to tm_xdata_swap +commit e569931dcd96087729eec1772a318e78ed505d14 +Author: Victor Seva +Date: Wed May 17 16:37:13 2023 +0200 -commit d6b1c20d3ad94d9136cf247e67b7fc0d32b18d3b -Author: Henning Westerholt -Date: Tue Aug 9 14:11:59 2022 +0000 + siputils: clang-format for coherent indentation and coding style - tm: restore X/AVP values from initial transaction in DNS failover processing - - - restore X/AVP values from initial transaction in DNS failover processing - - the X/AVP context gets lost, so we need to re-create it from the transaction - - otherwise modules that depends on the X/AVPs, e.g. topology hiding will not work - - tested with one load-balancer and two proxy servers +commit 6ea356e2ef09ce0c9e27e12ba63bc191d648a9bb +Author: Victor Seva +Date: Wed May 17 16:37:13 2023 +0200 -commit 25bec8eff91b332530095ada3997b92edbb5cce6 -Author: Henning Westerholt -Date: Tue Aug 9 14:05:00 2022 +0000 + siptrace: clang-format for coherent indentation and coding style - tm: use similar coding style for tm_xdata_replace as for tm_xdata_swap +commit b0633dd7bfc6c1802f5a098f1a3311e85b5d19b7 +Author: Victor Seva +Date: Wed May 17 16:37:13 2023 +0200 -commit 5ad003617bb79ea647fbfb1eb3c3ebfc4a44280d -Author: Henning Westerholt -Date: Tue Aug 9 14:03:22 2022 +0000 + sipt: clang-format for coherent indentation and coding style - tm: add some more debug messages to debug X/AVP and transaction handling +commit 2c17fbc22f84229d5f11c17bbb15696b0dcf9ed6 +Author: Victor Seva +Date: Wed May 17 16:37:13 2023 +0200 -commit 6b83bc4cd6da55582793321e6c1f36ff71c4233a -Author: Henning Westerholt -Date: Tue Aug 9 13:52:42 2022 +0000 + siprepo: clang-format for coherent indentation and coding style - tm: use internal function tm_xdata_swap instead of manually copy X/AVPs +commit 6b63f482deef965e347f1d746587cfaff21d8146 +Author: Victor Seva +Date: Wed May 17 16:37:13 2023 +0200 -commit 1f1297b407be0525e314b9d734d39a1a20ed886d -Author: Kamailio Dev -Date: Mon Aug 8 16:01:20 2022 +0200 + sipjson: clang-format for coherent indentation and coding style - modules: readme files regenerated - uac ... [skip ci] +commit 5b18c3415478e5f610199f63ba8d221d3e48f472 +Author: Victor Seva +Date: Wed May 17 16:37:13 2023 +0200 -commit a900fef06bbb71c722f29edfde130d618a784174 -Author: sznoname <342899761@qq.com> -Date: Mon Jul 25 11:03:44 2022 +0800 + sipdump: clang-format for coherent indentation and coding style - uac.reg_add +commit 7c36da9c0ca5faf98c7b66ee0678a36bd81c2d48 +Author: Victor Seva +Date: Wed May 17 16:37:12 2023 +0200 -commit cd1bf8302920b5fa08f6e79a334af175e8b520e1 -Author: Kamailio Dev -Date: Mon Aug 8 15:31:21 2022 +0200 + sipcapture: clang-format for coherent indentation and coding style - modules: readme files regenerated - siptrace ... [skip ci] +commit c726d55a19090f7da847171f27183e4f9db9457c +Author: Victor Seva +Date: Wed May 17 16:37:12 2023 +0200 -commit f5142e2059e1cf2d65f7fb0fe2ae6b5fdd0e3651 -Author: Henning Westerholt -Date: Mon Aug 8 13:18:59 2022 +0000 + secsipid_proc: clang-format for coherent indentation and coding style - siptrace: enable tracing of in-dialog ACKs and spiraled dialogs, analog to the setting of dialog module +commit 286c38522fdebdd4192126463725d4d9a2b83658 +Author: Victor Seva +Date: Wed May 17 16:37:12 2023 +0200 -commit 501421f42c17a411bde0fb2401437fa2ba1f5c66 -Author: Stefan Mititelu -Date: Tue Aug 2 16:01:55 2022 +0300 + secsipid: clang-format for coherent indentation and coding style - siptrace: Trace in-dialog ACK and dialog spirals - - Enable behavior via 2 new modparams. +commit 82100e1220e3ecd12afb986465957764f8743e3e +Author: Victor Seva +Date: Wed May 17 16:37:12 2023 +0200 -commit 13a4021914057ca66eaa91e2ea022e1827963b70 -Author: Daniel-Constantin Mierla -Date: Thu Aug 4 11:50:50 2022 +0200 + secfilter: clang-format for coherent indentation and coding style - dispatcher: check if packing address fails on removing via rpc - - - GH #3199 +commit ba2cbf2ba100bc3f06511302535c1bea2778a3c7 +Author: Victor Seva +Date: Wed May 17 16:37:12 2023 +0200 -commit bd40f0d08f5d0f14b301cb492d1082c71be91c50 -Author: Henning Westerholt -Date: Tue Aug 2 08:47:17 2022 +0000 + seas: clang-format for coherent indentation and coding style - usrloc: fix sending keepalive messages for IPv6, it was missing the brackets +commit 7c9415686ac1ae59c21141dc3013d288246ac445 +Author: Victor Seva +Date: Wed May 17 16:37:12 2023 +0200 -commit 8fa77cf95a1e985405d3471fc5655e2ec6a2e192 -Author: Kamailio Dev -Date: Wed Jul 27 09:31:30 2022 +0200 + sdpops: clang-format for coherent indentation and coding style - modules: readme files regenerated - acc ... [skip ci] +commit ed20f7f62b3504d207af542f0a99f8b22e0899d4 +Author: Victor Seva +Date: Wed May 17 16:37:11 2023 +0200 -commit 3ec40d792df5bcee838eee3e5e0e89a2ebdcc453 -Author: Henning Westerholt -Date: Wed Jul 27 07:26:57 2022 +0000 + sctp: clang-format for coherent indentation and coding style - acc: add some explanation that dialogs need to be tracked for CDR accounting +commit b48ac63551216b2afbf2d9d52c31cd390b181115 +Author: Victor Seva +Date: Wed May 17 16:37:11 2023 +0200 -commit 3a3003b42ce6eadbc9b12e45fd4668f12e783cfb -Author: Kamailio Dev -Date: Wed Jul 27 08:16:23 2022 +0200 + sanity: clang-format for coherent indentation and coding style + +commit 85c0ced80dd9c0253f24f8c1b62f07793d859ba5 +Author: Victor Seva +Date: Wed May 17 16:37:11 2023 +0200 - modules: readme files regenerated - nathelper ... [skip ci] + ruxc: clang-format for coherent indentation and coding style -commit c009f27578e8df9aa77ab852325dad8dc710d6c8 -Author: Daniel-Constantin Mierla -Date: Wed Jul 27 08:04:08 2022 +0200 +commit bbb3604d1704d8e24d9fbf4ed863121d6914ec19 +Author: Victor Seva +Date: Wed May 17 16:37:11 2023 +0200 - nathelper: docs - rephrased the remarks about set_contact_alias() + rtpproxy: clang-format for coherent indentation and coding style -commit 221c77314f755f1c6fa541b9ac83623b448dad9e -Author: Kamailio Dev -Date: Mon Jul 25 20:31:13 2022 +0200 +commit 37af6dfbe6756d6a3991fc757cd3e72c9e76f750 +Author: Victor Seva +Date: Wed May 17 16:37:11 2023 +0200 - modules: readme files regenerated - siputils ... [skip ci] + rtpengine: clang-format for coherent indentation and coding style -commit ac75a033132740b06d5afcdc17c25d3c354e7d89 -Author: Henning Westerholt -Date: Mon Jul 25 18:28:19 2022 +0000 +commit 5f48f91efd3b5d3ed76fadc3604cd308eefdd8d9 +Author: Victor Seva +Date: Wed May 17 16:37:11 2023 +0200 - siputils: fix typo for is_first_hope, related to gh #3200 + rtp_media_server: clang-format for coherent indentation and coding style -commit 913761d503284952c4f64e9fef31be2d82e06f74 -Author: Kamailio Dev -Date: Mon Jul 25 16:01:50 2022 +0200 +commit 135d55131dbcc0d8e8a99913629d930b567f5e41 +Author: Victor Seva +Date: Wed May 17 16:37:10 2023 +0200 - modules: readme files regenerated - ratelimit ... [skip ci] + rtjson: clang-format for coherent indentation and coding style -commit cae9d78a6c8d33f6c4ec780901a55c27260c2000 -Author: Henning Westerholt -Date: Mon Jul 25 13:55:39 2022 +0000 +commit eca9b97ead0a22490461a326aac4a0b4b1e7bc36 +Author: Victor Seva +Date: Wed May 17 16:37:10 2023 +0200 - ratelimit: fix docs to actual values in the code for queue and pipe limits + rtimer: clang-format for coherent indentation and coding style -commit b8bf86eb11a17c853450e5c7f81d2446cf719fbc -Author: Daniel-Constantin Mierla -Date: Thu Jul 21 20:15:29 2022 +0200 +commit 4b120452ebfbd7bf935c3c9345d0ce1623e33812 +Author: Victor Seva +Date: Wed May 17 16:37:10 2023 +0200 - app_python3: use new Python 3.10+ API functions for tracking execution - - - GH #3187 + rr: clang-format for coherent indentation and coding style -commit 45c38614cbdc9bde2fa4b1836ae5aef5793b51d4 -Author: Alessio Garzi -Date: Thu Jul 14 09:54:24 2022 +0200 +commit 4f2523f2feb8042feacf9cfbd2ff73c2f8933ebf +Author: Victor Seva +Date: Wed May 17 16:37:10 2023 +0200 - kamctl: regenerated db schema files - - - regenerated db schema files for table watchers - after addition of index time_status_idx + rls: clang-format for coherent indentation and coding style -commit 3e916b2ddf8a2a4a4db5ecbf6e64f7e4e23dc246 -Author: Alessio Garzi -Date: Thu Jul 14 09:53:23 2022 +0200 +commit 42d357e5c1400f60f138b2d604e1f6bfb8d8b65e +Author: Victor Seva +Date: Wed May 17 16:37:10 2023 +0200 - lib/srdb1: Index "inserted_time"+"status" in watchers - - - New index for watchers table for columns "inserted_time" and "status". - This is a little performance boost since the function - ps_watchers_db_timer_clean() cleans pending subscriptions - using this columns inside the "where" clause. - New index has been added to both Postgres and Mysql/MariaDB backends. + registrar: clang-format for coherent indentation and coding style -commit 9b9052960ab190157744a429e4961d0d9d456f3a -Author: Daniel-Constantin Mierla -Date: Wed Jul 20 08:28:20 2022 +0200 +commit fb7c59cafceb35628d40c727dbfa2990335b922a +Author: Victor Seva +Date: Wed May 17 16:37:10 2023 +0200 - dialog: formatting and logs adjustments + regex: clang-format for coherent indentation and coding style -commit 6380cab25f429104062fd417fc8045ff10b0e658 -Author: Daniel-Constantin Mierla -Date: Tue Jul 19 22:27:59 2022 +0200 +commit 79301505e26f55f2830d21dd960a130810f0b99d +Author: Victor Seva +Date: Wed May 17 16:37:10 2023 +0200 - pua_dialoginfo: cast to unsigned for compile warnings on bitwise shifting + ratelimit: clang-format for coherent indentation and coding style -commit e21df35840c7a85cf26a3005f718e5e37edeac8e -Author: Daniel-Constantin Mierla -Date: Mon Jul 18 08:37:48 2022 +0200 +commit cf1978231edcad1611df9d88e670ac7b5cc7aab5 +Author: Victor Seva +Date: Wed May 17 16:37:09 2023 +0200 - uac_redirect: test if the acc function is set before binding to acc module - - - GH #3188 + rabbitmq: clang-format for coherent indentation and coding style -commit 6c40d950e9060d91df6a2df60051d627a0c73ede -Author: Kamailio Dev -Date: Thu Jul 14 08:46:21 2022 +0200 +commit 08b5cbc2e6639b744728c47df8373e506d972623 +Author: Victor Seva +Date: Wed May 17 16:37:09 2023 +0200 - modules: readme files regenerated - app_perl ... [skip ci] + qos: clang-format for coherent indentation and coding style -commit 5828d8252c18df13b4a37321168c88687f9fc3b3 -Author: Daniel-Constantin Mierla -Date: Thu Jul 14 08:42:34 2022 +0200 +commit d56093d37d65105b5550639df88c6b5902603f7e +Author: Victor Seva +Date: Wed May 17 16:37:09 2023 +0200 - topos: parse the corresponding param for initial methods + pv_headers: clang-format for coherent indentation and coding style -commit ded477354676cd6238534001a0dfa6abe1198ba3 -Author: Daniel-Constantin Mierla -Date: Wed Jul 13 18:27:42 2022 +0200 +commit f5c0077f65ca50940fc53776c2b964e45ebec8f5 +Author: Victor Seva +Date: Wed May 17 16:37:09 2023 +0200 - app_perl: docs - updates for warn_mode + pv: clang-format for coherent indentation and coding style -commit e53db29378b452c79654b220353fa794081597f7 -Author: Daniel-Constantin Mierla -Date: Wed Jul 13 18:24:50 2022 +0200 +commit c140c3acd69409b9f99c4986d84c5c9d5cb77b65 +Author: Victor Seva +Date: Wed May 17 16:37:09 2023 +0200 - app_perl: if warn_mode is 2, set -W for perl_parse() + pua_xmpp: clang-format for coherent indentation and coding style -commit c80cccd996dcc3b91d4f0f68a2de51104a16d1a5 -Author: Alessio Garzi -Date: Thu Jul 7 15:22:12 2022 +0200 +commit cb22d7e9c3e1fa5fffa7f7a22b179f96e6ef327e +Author: Victor Seva +Date: Wed May 17 16:37:09 2023 +0200 - presence: No autocommit+rollback if no active watchers - - - In case the active_watcher query returns no elements there - is a weird situation where kamailio first runs the select for - active_watcher then rollbacks. - This can happen a lot of times for each second since function - process_dialogs() runs repeatedly. - For this reason trying to avoid the rollback can result - in a quite good performance boost. + pua_usrloc: clang-format for coherent indentation and coding style -commit 805b921c0d6958db1620b0712450ef7a128cb5ce -Author: S-P Chan -Date: Thu Jul 7 10:31:00 2022 +0800 +commit c4e589ab9dd52ad769d04edd1f0598405df42418 +Author: Victor Seva +Date: Wed May 17 16:37:08 2023 +0200 - core: crypto add support for SHA-512/256 for RFCs 8760/7616 + pua_rpc: clang-format for coherent indentation and coding style -commit 0080e06d36bc0263795fa7ff716fe0b2d218f5c1 -Author: Daniel-Constantin Mierla -Date: Mon Jul 11 10:15:32 2022 +0200 +commit 3e79c970aa5fa1e028d82985b47645524d824dd4 +Author: Victor Seva +Date: Wed May 17 16:37:08 2023 +0200 - app_perl: Makefile - option to set the path to perl binary + pua_reginfo: clang-format for coherent indentation and coding style -commit 7856251f372688cf6835a3468d2a4277f7575f87 -Author: Kamailio Dev -Date: Mon Jul 11 10:01:28 2022 +0200 +commit 7a836358872d765aa0412eed380b96398a6f488b +Author: Victor Seva +Date: Wed May 17 16:37:08 2023 +0200 - modules: readme files regenerated - app_perl ... [skip ci] + pua_json: clang-format for coherent indentation and coding style -commit e038a2122d9ed5858bbafc088f3cfc18666b95fd -Author: Daniel-Constantin Mierla -Date: Mon Jul 11 09:50:13 2022 +0200 +commit 8966ab98d30d6278bdd9c282f3c666827000ad1e +Author: Victor Seva +Date: Wed May 17 16:37:08 2023 +0200 - app_perl: docs for warn_mode parameter + pua_dialoginfo: clang-format for coherent indentation and coding style -commit ec78caf6e0efffcc8f4f78954ae88d083734c442 -Author: Daniel-Constantin Mierla -Date: Mon Jul 11 08:55:30 2022 +0200 +commit db1dfee3c76681e14b80a45a77b931d4748858cb +Author: Victor Seva +Date: Wed May 17 16:37:08 2023 +0200 - app_perl: new parameter to set warn flag for perl parse + pua: clang-format for coherent indentation and coding style -commit a466d0b73a66b18419555eca437136f1bcaebff9 -Author: Daniel-Constantin Mierla -Date: Fri Jul 8 13:37:33 2022 +0200 +commit 6391b15598af3567df8e60408cd3eb94258af0b5 +Author: Victor Seva +Date: Wed May 17 16:37:08 2023 +0200 - app_perl: more debug messages to catch per execution errors + print_lib: clang-format for coherent indentation and coding style -commit 8c910452cf6090f87156d7c0e14477ef5956b59d -Author: Daniel-Constantin Mierla -Date: Fri Jul 8 13:19:14 2022 +0200 +commit fc027184353d0e03c5c8790d3eaca8e93d8fcb81 +Author: Victor Seva +Date: Wed May 17 16:37:07 2023 +0200 - app_perl: print the error string if execution of perl script sets it + print: clang-format for coherent indentation and coding style -commit eb052e85ea4efe29eeb4181f49a14a3fd64e9bda -Author: Daniel-Constantin Mierla -Date: Fri Jul 8 12:26:11 2022 +0200 +commit 194a8d4d38367548845cf2076015bac17aff8a51 +Author: Victor Seva +Date: Wed May 17 16:37:07 2023 +0200 - app_perl: work only with my_perl global variable - - - some macros link to it + presence_xml: clang-format for coherent indentation and coding style -commit 5cd4e817a24308b82fc3f631fb18f354dadf2b7e -Author: Daniel-Constantin Mierla -Date: Fri Jul 8 11:14:27 2022 +0200 +commit bffc6c4f69dac25e70505775bd017f6d4d3526ca +Author: Victor Seva +Date: Wed May 17 16:37:07 2023 +0200 - core: use memcpy and set end of string + presence_reginfo: clang-format for coherent indentation and coding style -commit b12335579437d12a5de12aa415477a832d6224cd -Author: Daniel-Constantin Mierla -Date: Fri Jul 8 10:19:03 2022 +0200 +commit 7c729f6c6cf2c8771b43f35fd91d66f54193b258 +Author: Victor Seva +Date: Wed May 17 16:37:07 2023 +0200 - app_perl: log the perl function name when not found + presence_profile: clang-format for coherent indentation and coding style -commit 840b4f9054fe9f8a29cb41deeb421b0ebe75e4b8 -Author: Kamailio Dev -Date: Thu Jul 7 09:31:19 2022 +0200 +commit 5152e2790722257ca75771a000140c96b5afc981 +Author: Victor Seva +Date: Wed May 17 16:37:07 2023 +0200 - modules: readme files regenerated - app_perl ... [skip ci] + presence_mwi: clang-format for coherent indentation and coding style -commit 42f42baf7753402e9506c45d4e53d548978c168a -Author: Daniel-Constantin Mierla -Date: Thu Jul 7 09:15:12 2022 +0200 +commit 953ef0c751ab1ec95c999547681c2373a90fef25 +Author: Victor Seva +Date: Wed May 17 16:37:07 2023 +0200 - app_perl: docs for parse_mode parameter + presence_dialoginfo: clang-format for coherent indentation and coding style -commit c2ad115ec1b96e99bc956f0f8e83cacc214da6b6 -Author: Daniel-Constantin Mierla -Date: Thu Jul 7 09:04:37 2022 +0200 +commit 33a2c8ccc5a257b3114d6e46b67a94bfe9afcef0 +Author: Victor Seva +Date: Wed May 17 16:37:06 2023 +0200 - app_perl: added modparam to control behaviour on perl_parse() code + presence_conference: clang-format for coherent indentation and coding style -commit d90d15ddaf937222e8634a18b61de779c87a3c90 -Author: Daniel-Constantin Mierla -Date: Thu Jul 7 08:55:21 2022 +0200 +commit 197f64ff273e7eb62f341ff668036cca2f442fe2 +Author: Victor Seva +Date: Wed May 17 16:37:06 2023 +0200 - app_perl: continue on perl_parse() non-0 return code - - - it is application return code on some perl versions + presence: clang-format for coherent indentation and coding style -commit 22b405e12631a33d02823bf2816538b5f2102259 -Author: Daniel-Constantin Mierla -Date: Thu Jul 7 08:12:33 2022 +0200 +commit c38af2267479bf4dfd4a44101e2c87a6ddd8de98 +Author: Victor Seva +Date: Wed May 17 16:37:06 2023 +0200 - app_perl: check returned my_perl value on reload - - - related to GH #3134 + prefix_route: clang-format for coherent indentation and coding style -commit c67bbca95b861f735889f14467c0192896298e84 -Author: Daniel-Constantin Mierla -Date: Wed Jul 6 09:37:07 2022 +0200 +commit 442f266bd3ce1d020375a1d5f9804e39da29c217 +Author: Victor Seva +Date: Wed May 17 16:37:06 2023 +0200 - tm: enable debug message to log putting transaction on wait + posops: clang-format for coherent indentation and coding style -commit dedd7ee2ddcb92b020ea40a074008a317a9553f5 -Author: Victor Seva -Date: Mon Jul 4 15:49:20 2022 +0200 +commit 1e3674afd25bd5fcaecd99e2d734d4973eae800e +Author: Victor Seva +Date: Wed May 17 16:37:06 2023 +0200 - tm: check T just in case before UNREF - - Related #3156 + pipelimit: clang-format for coherent indentation and coding style -commit 504695defe5510774aa37e658d016570f99c2e4f -Author: Kamailio Dev -Date: Tue Jul 5 20:46:19 2022 +0200 +commit 448caabdc1c9ec1de6f08139df4a663977caa604 +Author: Victor Seva +Date: Wed May 17 16:37:06 2023 +0200 - modules: readme files regenerated - topos ... [skip ci] + pike: clang-format for coherent indentation and coding style -commit 8c2eb726dfb235a721a9721a17714e2c90bd0120 -Author: Daniel-Constantin Mierla -Date: Tue Jul 5 20:41:14 2022 +0200 +commit 15605096ffdb540ce34f160bd8da601266bbc3a5 +Author: Victor Seva +Date: Wed May 17 16:37:06 2023 +0200 - topos: docs for methods_noinitial parameter + phonenum: clang-format for coherent indentation and coding style -commit da4e4a7aed16d3ced57a6154ac85974823ad9695 -Author: Daniel-Constantin Mierla -Date: Tue Jul 5 20:36:24 2022 +0200 +commit 71571d66c400aa2f80d866551b564208b29cc807 +Author: Victor Seva +Date: Wed May 17 16:37:05 2023 +0200 - topos: new parameter to allow specifying initial request methods to skip topos + permissions: clang-format for coherent indentation and coding style -commit b7f4a7a040717cd03fdeb6d04aac653034cc759e +commit 4bf8282e3bfcc16094d03fe1774268388dfa9c89 Author: Victor Seva -Date: Tue Jul 5 08:15:13 2022 +0200 +Date: Wed May 17 16:37:05 2023 +0200 - pkg/kamailio/deb: lintian overwrite [skip ci] + peering: clang-format for coherent indentation and coding style -commit 2bd6985b8a6f87cfe8238a095e5d63a1bebf82d4 -Author: Kamailio Dev -Date: Mon Jul 4 16:01:16 2022 +0200 +commit ca324931833cda3377acf451138cc39be2d49482 +Author: Victor Seva +Date: Wed May 17 16:37:05 2023 +0200 - modules: readme files regenerated - tm ... [skip ci] + pdt: clang-format for coherent indentation and coding style -commit c4f5b88b1861c73bc96904eef00b0048c9550240 -Author: Daniel-Constantin Mierla -Date: Mon Jul 4 15:51:32 2022 +0200 +commit d8cd464075247e16dc9c142d350c575e3db52f53 +Author: Victor Seva +Date: Wed May 17 16:37:05 2023 +0200 - tm: docs - fixed section for rpc.t_uac_wait_block + pdb: clang-format for coherent indentation and coding style -commit ebbe6268de3aff6ba830f1722942c2f10c6de2f3 -Author: Kamailio Dev -Date: Mon Jul 4 15:46:14 2022 +0200 +commit f2220160e4cc233816af18de63e2e323e7ca9f24 +Author: Victor Seva +Date: Wed May 17 16:37:05 2023 +0200 - modules: readme files regenerated - ndb_redis ... [skip ci] + path: clang-format for coherent indentation and coding style -commit b8fc507c9dee07f1a0b7af01d24142240bcd8fa4 -Author: Daniel-Constantin Mierla -Date: Mon Jul 4 15:34:47 2022 +0200 +commit 878a2c8044531b529bd399b62a8045922a423d73 +Author: Victor Seva +Date: Wed May 17 16:37:05 2023 +0200 - topos: docs - small updates to module description + p_usrloc: clang-format for coherent indentation and coding style -commit fdb7c2f635bf7145730444cafb129c4df37a1b7a -Author: Daniel-Constantin Mierla -Date: Mon Jul 4 15:30:09 2022 +0200 +commit 3b770d392754fe4f9421f21afa230096e839e4d8 +Author: Victor Seva +Date: Wed May 17 16:37:04 2023 +0200 - ndb_redis: docs for debug parameter + outbound: clang-format for coherent indentation and coding style -commit f171428374ecabb16e4f7621f2fcc7840bd22100 -Author: Daniel-Constantin Mierla -Date: Mon Jul 4 15:20:30 2022 +0200 +commit eb8c5c4283753793576a52831b2da50b1cab242f +Author: Victor Seva +Date: Wed May 17 16:37:04 2023 +0200 - ndb_redis: new param to control the verbosity of some log messages + osp: clang-format for coherent indentation and coding style -commit ef00062fb3feb051e3e11c62ce3c529579d23f5b -Author: Daniel-Constantin Mierla -Date: Mon Jul 4 14:08:27 2022 +0200 +commit 34f4c5a39cf4167e4667398dff26922441a7c5a0 +Author: Victor Seva +Date: Wed May 17 16:37:04 2023 +0200 - ndb_redis: clean up response on moved reply with cluster mode on + nsq: clang-format for coherent indentation and coding style -commit 5f26491e288092629fcd508b9acefe6edf175845 -Author: S-P Chan -Date: Thu Jun 30 09:44:42 2022 +0800 +commit 28049ecee8a6407b7e1bc792498762dac9c922ae +Author: Victor Seva +Date: Wed May 17 16:37:04 2023 +0200 - tls_wolfssl: cert serial number can exceed uint64 - - - GH #3168 + nosip: clang-format for coherent indentation and coding style -commit 06e2363a961a1f7f866faee81aeac737db2359fc -Author: S-P Chan -Date: Mon Jul 4 19:28:54 2022 +0800 +commit d8ca55e0bc8ebb62b94e9236e67ecf30a8f78a63 +Author: Victor Seva +Date: Wed May 17 16:37:04 2023 +0200 - tls_wolfssl: move git submodule to misc/external/wolfssl - - - GH #3164 + ndb_redis: clang-format for coherent indentation and coding style -commit 996bf4cad1d5645761fb80e66e435cedf29fa749 -Author: S-P Chan -Date: Thu Jun 30 07:19:18 2022 +0800 +commit 8d402c220dd88b0622f68715a12c473907808d67 +Author: Victor Seva +Date: Wed May 17 16:37:04 2023 +0200 - tls: cert serial number can exceed uint64 - - - GH #3168 + ndb_mongodb: clang-format for coherent indentation and coding style -commit 444adb0b27d62fbd2af25e4f555b6aab5ca7bc96 -Author: Victor Seva -Date: Wed Jun 29 09:03:14 2022 +0200 +commit b49392ebcdf1f9af536742a0107720cfb6380f36 +Author: Victor Seva +Date: Wed May 17 16:36:58 2023 +0200 - presence: be more resilient doing clean up of presentity values - - previously if an error was found we were bailing out and the value - was kept so at next round the value will be there and no more values - where removed + ndb_cassandra: clang-format for coherent indentation and coding style -commit 267d4ad48ac8426b3d5c53724281605a74d07999 -Author: Daniel-Constantin Mierla -Date: Sun Jul 3 12:20:05 2022 +0200 +commit 55ed36e45baf11abd4c67f17be8d3eaf313cd133 +Author: Victor Seva +Date: Wed May 17 16:36:58 2023 +0200 - auth: coherent log message content with header parsing + nats: clang-format for coherent indentation and coding style -commit bb1a80695825a607bfc713dab22b6edb369e8351 +commit d952b84c85d72e59d88e8a77507bf4274954e090 Author: Victor Seva -Date: Mon Jul 4 09:25:38 2022 +0200 +Date: Wed May 17 16:36:58 2023 +0200 - github: use different file to define PR checks [skip ci] + nathelper: clang-format for coherent indentation and coding style -commit 584ef26d685f381ddb627866400cfde1b0239f06 +commit 5d1fbcab0817a41a3afbe609238bb1bf5cb3adc9 Author: Victor Seva -Date: Fri Jul 1 20:52:20 2022 +0200 +Date: Wed May 17 16:36:58 2023 +0200 - github: enable 5.5 and 5.6 branches [skip ci] + nat_traversal: clang-format for coherent indentation and coding style -commit 66f175f40e6145e895fa22952b40b372e4eff381 -Author: Daniel-Constantin Mierla -Date: Fri Jul 1 19:19:14 2022 +0200 +commit 777c1cb6b4d28138a8b8fc085fdc5655e5565d88 +Author: Victor Seva +Date: Wed May 17 16:36:58 2023 +0200 - siptrace: lookup socket by name if not set for hep - - - GH #3174 + mtree: clang-format for coherent indentation and coding style -commit 510013c67df999e5637b6f289c02b3387691ce89 +commit cd9f807580082205565ab1ff9ef8a62272ec194a Author: Victor Seva -Date: Fri Jul 1 15:26:47 2022 +0200 +Date: Wed May 17 16:36:57 2023 +0200 - core: fix build warning - - > In file included from /usr/include/string.h:519, - > from core/socket_info.c:34: - > In function 'strncpy', - > inlined from 'fix_hostname' at core/socket_info.c:1741:2: - > Warning: /usr/include/x86_64-linux-gnu/bits/string_fortified.h:95:10: warning: '__builtin_strncpy' specified bound depends on the length of the source argument [-Wstringop-truncation] - > 95 | return __builtin___strncpy_chk (__dest, __src, __len, - > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - > 96 | __glibc_objsize (__dest)); - > | ~~~~~~~~~~~~~~~~~~~~~~~~~ - > core/socket_info.c: In function 'fix_hostname': - > core/socket_info.c:1741:38: note: length computed here - > 1741 | strncpy(address_str->s, tmp, strlen(tmp)+1); - > | ^~~~~~~~~~~ - > In file included from /usr/include/string.h:519, - > from core/socket_info.c:34: - > In function 'strncpy', - > inlined from 'build_iface_list' at core/socket_info.c:1554:5: - > Warning: /usr/include/x86_64-linux-gnu/bits/string_fortified.h:95:10: warning: '__builtin_strncpy' output may be truncated copying 63 bytes from a string of length 63 [-Wstringop-truncation] - > 95 | return __builtin___strncpy_chk (__dest, __src, __len, - > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - > 96 | __glibc_objsize (__dest)); - > | ~~~~~~~~~~~~~~~~~~~~~~~~~ - - > In file included from /usr/include/string.h:519, - > from core/cfg.y:40: - > In function 'strncpy', - > inlined from 'yyparse' at core/cfg.y:708:6: - > Warning: /usr/include/x86_64-linux-gnu/bits/string_fortified.h:95:10: warning: '__builtin_strncpy' specified bound depends on the length of the source argument [-Wstringop-truncation] - > 95 | return __builtin___strncpy_chk (__dest, __src, __len, - > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - > 96 | __glibc_objsize (__dest)); - > | ~~~~~~~~~~~~~~~~~~~~~~~~~ - > core/cfg.tab.c: In function 'yyparse': - > core/cfg.y:708:84: note: length computed here - > 708 | strncpy($$, $1, strlen($1)+1); - > | ^ - > In file included from /usr/include/string.h:519, - > from core/cfg.y:40: - > In function 'strncpy', - > inlined from 'yyparse' at core/cfg.y:699:5: - > Warning: /usr/include/x86_64-linux-gnu/bits/string_fortified.h:95:10: warning: '__builtin_strncpy' specified bound depends on the length of the source argument [-Wstringop-truncation] - > 95 | return __builtin___strncpy_chk (__dest, __src, __len, - > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - > 96 | __glibc_objsize (__dest)); - > | ~~~~~~~~~~~~~~~~~~~~~~~~~ - > core/cfg.tab.c: In function 'yyparse': - > core/cfg.y:699:76: note: length computed here - > 699 | strncpy($$, $1, strlen($1)+1); - > | ^ - > In file included from /usr/include/string.h:519, - > from core/cfg.y:40: - > In function 'strncpy', - > inlined from 'yyparse' at core/cfg.y:689:6: - > Warning: /usr/include/x86_64-linux-gnu/bits/string_fortified.h:95:10: warning: '__builtin_strncpy' specified bound depends on the length of the source argument [-Wstringop-truncation] - > 95 | return __builtin___strncpy_chk (__dest, __src, __len, - > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - > 96 | __glibc_objsize (__dest)); - > | ~~~~~~~~~~~~~~~~~~~~~~~~~ - > core/cfg.tab.c: In function 'yyparse': - > core/cfg.y:689:70: note: length computed here - > 689 | strncpy($$, tmp, strlen(tmp)+1); - > | + msrp: clang-format for coherent indentation and coding style -commit 5c3a00871a73f73843fe83b5c16dd9eecb1207e0 +commit 44e5ec3910054bb3b1fe70c54f174d72ec82eb92 Author: Victor Seva -Date: Fri Jul 1 15:10:55 2022 +0200 +Date: Wed May 17 16:36:57 2023 +0200 - kazoo: fix build warning - - > Warning: kz_amqp.c:2271:6: warning: variable 'num_headers' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized] - > if(idx == -1) { - > ^~~~~~~~~ - > kz_amqp.c:2327:6: note: uninitialized use occurs here - > if (num_headers > 0) { - > ^~~~~~~~~~~ - > kz_amqp.c:2271:3: note: remove the 'if' if its condition is always false - > if(idx == -1) { - > ^~~~~~~~~~~~~~~ - > kz_amqp.c:2281:5: note: variable 'num_headers' is declared here - > int num_headers = 0; - > ^ - > 1 warning generated. + msilo: clang-format for coherent indentation and coding style -commit 1f6ec9022f2358441233e8b139e13cbdcf0947aa -Author: Daniel-Constantin Mierla -Date: Thu Jun 30 19:33:45 2022 +0200 +commit 31af21a1022d39b2426a9c4cad658a9b92659a8a +Author: Victor Seva +Date: Wed May 17 16:36:57 2023 +0200 - kamctl: propagate DB_PATH to DBTEXT_PATH - - - GH #3170 + mqueue: clang-format for coherent indentation and coding style -commit ecbe90524165cf2fd8081ec5fe81d674f7a3334a +commit 5afc71465aa7a3ef3e398e9a107fcb9fa1e73df4 Author: Victor Seva -Date: Thu Jun 30 07:46:48 2022 +0200 +Date: Wed May 17 16:36:57 2023 +0200 - pkg/kamailio/deb: add initial support for jammy + mqtt: clang-format for coherent indentation and coding style -commit a78adb5340ae6cb57f756189d070c32c49bfa426 -Author: Daniel-Constantin Mierla -Date: Tue Jun 28 18:41:50 2022 +0200 +commit 14759133db64489dc0c9f8e38682f6f64c0f9874 +Author: Victor Seva +Date: Wed May 17 16:36:57 2023 +0200 - core: init pv buffers earlier to be avaialble for cli params - - - GH #3152 + mohqueue: clang-format for coherent indentation and coding style -commit d9626dc9f341718ad7d78e62042695124ba52c32 -Author: Victor Seva -Date: Wed Jun 22 15:12:33 2022 +0200 +commit a8eaac568a1dd2cfc9e6f87c8bdb76553c063d40 +Author: Victor Seva +Date: Wed May 17 16:36:57 2023 +0200 - pv_headers: rework pvh_remove_header_param - - * fix KEMI interface, this is suppose to be called - like pvh_remove_header_param(header_name, string_to_remove) - * use pv buffer for temporal value - * use xavi interface to set the new value + misctest: clang-format for coherent indentation and coding style -commit 03a489addb248bd7e4820dc281ade4f4f3deda3c +commit e90ab1267bb4d42e1b2f64f0654aaa42fffea1be Author: Victor Seva -Date: Tue Jun 28 09:37:59 2022 +0200 +Date: Wed May 17 16:36:56 2023 +0200 - pkg/kamailio/deb: update lintian overrides [skip ci] + misc_radius: clang-format for coherent indentation and coding style -commit c170cc811b9a03383c07578f4b4c88e15b96b637 -Author: S-P Chan -Date: Fri Jun 24 15:58:14 2022 +0800 +commit da7d1962c7f05cdaebd4f57f818abda95dba1e82 +Author: Victor Seva +Date: Wed May 17 16:36:56 2023 +0200 - tls_wolfssl: make - use kamailio make infra vars + memcached: clang-format for coherent indentation and coding style -commit fa6a2d79aca3bc4733276ce99a53efd8fe63ffd5 -Author: Daniel-Constantin Mierla -Date: Sat Jun 25 14:48:35 2022 +0200 +commit da6bb37ce2a7c99c1bfb567ef883e3a1bccb03c4 +Author: Victor Seva +Date: Wed May 17 16:36:56 2023 +0200 - ipops: added fixup free functions and use of ANY_ROUTE + mediaproxy: clang-format for coherent indentation and coding style -commit 87b698f7deca1794019f98167ba49d3e4737ba71 -Author: Kamailio Dev -Date: Fri Jun 24 16:01:17 2022 +0200 +commit d6f57ba321c81bfbde8cdac5bdd6b0979d377450 +Author: Victor Seva +Date: Wed May 17 16:36:56 2023 +0200 - modules: readme files regenerated - textops ... [skip ci] + matrix: clang-format for coherent indentation and coding style -commit 4570b3ebc6da35efc3cc55b1f4418446b9071688 -Author: Akash Gupta -Date: Fri Jun 24 18:43:54 2022 +0530 +commit e20a865d4791d7cd113182133a45e1e92785a8aa +Author: Victor Seva +Date: Wed May 17 16:36:56 2023 +0200 - tls: Fix typo + math: clang-format for coherent indentation and coding style -commit c5cd400287e27fce6fcf6272a4efe9a9fa8aa419 -Author: Akash Gupta -Date: Fri Jun 24 18:43:20 2022 +0530 +commit 3d4c0d745ee1ec4af91ac45c1131ad0799611f23 +Author: Victor Seva +Date: Wed May 17 16:36:56 2023 +0200 - textops: Fix typos + mangler: clang-format for coherent indentation and coding style -commit 65a484dffa3c854bc17068175cee3dc37fd09d18 -Author: Kamailio Dev -Date: Fri Jun 24 12:46:16 2022 +0200 +commit d2e04212ab7bbb9bdaa443ef752f0d14019c520f +Author: Victor Seva +Date: Wed May 17 16:36:56 2023 +0200 - modules: readme files regenerated - nats ... [skip ci] + lwsc: clang-format for coherent indentation and coding style -commit 25d42b7e69cc6242c66887a2816499d841e3ba89 -Author: Seven Du -Date: Fri Jun 24 18:44:28 2022 +0800 +commit 0459451ed633d71988e312472b5c18980e3edeed +Author: Victor Seva +Date: Wed May 17 16:36:55 2023 +0200 - nats: add KEMI publish function and event_callback param (#3154) + lrkproxy: clang-format for coherent indentation and coding style -commit 06679174fc3d9cc6a18bc3edc7f2fb985c50d27b -Author: Daniel-Constantin Mierla -Date: Fri Jun 24 10:50:08 2022 +0200 +commit bae6239c6e3d56a4f5417646090cdbf34fe78b48 +Author: Victor Seva +Date: Wed May 17 16:36:55 2023 +0200 - topos_redis: use tag based on direction for early dialog transaction record loading - - - GH #3112 + lost: clang-format for coherent indentation and coding style -commit 6aa1a84c6e37e0d6d5a725d43636debeaf5fa3b4 -Author: Daniel-Constantin Mierla -Date: Fri Jun 24 08:18:42 2022 +0200 +commit 73972a702a63d7209d303dbe4b3530aa8f9ffda2 +Author: Victor Seva +Date: Wed May 17 16:36:55 2023 +0200 - kamctl/dbtextdb: solve TypeError: a bytes-like object is required, not 'str' - - - GH #2469 + log_systemd: clang-format for coherent indentation and coding style -commit 4fcb2e5e41f45dc7fb049141678d91ae9525a76b -Author: Kamailio Dev -Date: Fri Jun 24 08:16:15 2022 +0200 +commit a1a2f82e0cf1c30c044a951750f0fc6553d5223a +Author: Victor Seva +Date: Wed May 17 16:36:55 2023 +0200 - modules: readme files regenerated - dialog ... [skip ci] + log_custom: clang-format for coherent indentation and coding style -commit 03dc76428f4cbd1c023289851ceb6218ea535f29 -Author: Daniel-Constantin Mierla -Date: Fri Jun 24 08:11:02 2022 +0200 +commit 3ad039d5f0b8bf851e484d917863bafbbef8e6ad +Author: Victor Seva +Date: Wed May 17 16:36:55 2023 +0200 - Revert "Revert "dialog: Terminate dialogs in Early stage and add functionality to send messages within a dialog"" - - This reverts commit 1465a9b6e9fda36617b7b198ae051f0957803550. + ldap: clang-format for coherent indentation and coding style -commit d695c9cca02d584e295d12fe574e99085c7adecd -Author: S-P Chan -Date: Fri Jun 24 11:08:11 2022 +0800 +commit ecc2c9e54fa8f24c1e96860c1f59b43f2e1e8b7a +Author: Victor Seva +Date: Wed May 17 16:36:55 2023 +0200 - tls_wolfssl: less verbose during build + lcr: clang-format for coherent indentation and coding style -commit 19edea067f890814c767581fef65713046c768c6 -Author: Sergey Safarov -Date: Wed Jun 22 18:16:41 2022 +0000 +commit 65daf0988f44953c218f401d6027682822fff9da +Author: Victor Seva +Date: Wed May 17 16:36:54 2023 +0200 - pkg/kamailio/obs: added CentOS 9 support + kex: clang-format for coherent indentation and coding style -commit 38d2a6a16179cb72e97dd6eec600405e57f4be12 -Author: S-P Chan -Date: Thu Jun 23 15:15:11 2022 +0800 +commit ae2ad67fa04066ff3baa1196ac6074d054474628 +Author: Victor Seva +Date: Wed May 17 16:36:54 2023 +0200 - tls_wolfssl: add wolfssl@e722c15be8 as a submodule + kemix: clang-format for coherent indentation and coding style -commit 85a2523db649009332af059f6260ab4467b30360 -Author: S-P Chan -Date: Thu Jun 23 10:22:31 2022 +0800 +commit 567384c7f7f2b914b5cbbea65d9ab6936c713d25 +Author: Victor Seva +Date: Wed May 17 16:36:54 2023 +0200 - tls_wolfssl: reduce overhead per fragment to maintain 16 byte alignment + keepalive: clang-format for coherent indentation and coding style -commit 4484a5eb9e0dd6e6723390cb96c378f88f1fd074 -Author: S-P Chan -Date: Thu Jun 23 10:10:11 2022 +0800 +commit b33f7a2a21978b1b624258e01c9cd988357c92f6 +Author: Victor Seva +Date: Wed May 17 16:36:54 2023 +0200 - tls_wolfssl: ser_realloc realign memory correctly to 16-bytes - - If shm_realloc returns a different 8/16 byte alignment we - need to memmove the correct amount. + kazoo: clang-format for coherent indentation and coding style -commit e74cb2371ab879874a8981818139024f1c2beb9e -Author: Frits Wiersma -Date: Wed Jun 22 21:50:44 2022 +0200 +commit 296caa2d6c9fd9eb86a17fa6719cccefd023f409 +Author: Victor Seva +Date: Wed May 17 16:36:54 2023 +0200 - acc: Fix reason code for locally generated replies. (#3137) - - * acc: Fix reason code for locally generated replies. - - - Use heap memory for the reason code instead of the stack memory. - - See issue #2981 - - * acc: Remove code which was commented out. - - - Code was commented out in the previous pull request. (#3137). - - This has now been corrected. + kafka: clang-format for coherent indentation and coding style -commit f49f14a87606314e98a253ee29b1624ae814dccf -Author: Victor Seva -Date: Wed Oct 7 15:35:50 2020 +0200 +commit e5bff977cf4e59aab006297a7a91520356f0a39f +Author: Victor Seva +Date: Wed May 17 16:36:54 2023 +0200 - topos: don't insert contact header for 4xx replies - - unless original msg has contact + jwt: clang-format for coherent indentation and coding style -commit 71502d2bb733340db310bf4e0c47e4b194f49113 -Author: Victor Seva -Date: Wed Jun 22 12:26:46 2022 +0200 +commit 728ed60909173fd9ce513a136d4c9ea6d5e0b00b +Author: Victor Seva +Date: Wed May 17 16:36:54 2023 +0200 - core: fix freeaddrinfo coredump - - > #0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50 - > #1 0x00007fbb5e515537 in __GI_abort () at abort.c:79 - > #2 0x00007fbb5e56e768 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7fbb5e67ce2d "%s\n") at ../sysdeps/posix/libc_fatal.c:155 - > #3 0x00007fbb5e575a5a in malloc_printerr (str=str@entry=0x7fbb5e67b05a "free(): invalid pointer") at malloc.c:5347 - > #4 0x00007fbb5e576c14 in _int_free (av=, p=, have_lock=0) at malloc.c:4173 - > #5 0x00007fbb5e5d8da0 in __GI_freeaddrinfo (ai=ai@entry=0x7fbb5e83ba10) at ../sysdeps/posix/getaddrinfo.c:2520 - > #6 0x000055ba099dcd0b in log_init () at core/dprint.c:482 - > #7 0x000055ba09970d7a in main (argc=10, argv=0x7ffde85a1788) at main.c:2055 + jsonrpcs: clang-format for coherent indentation and coding style -commit 322562a354887dec18e7df2d90a328fe32fc122e -Author: Kamailio Dev -Date: Tue Jun 21 09:01:17 2022 +0200 +commit 566db03019e8aca34d282938deee727ad8b4c4ac +Author: Victor Seva +Date: Wed May 17 16:36:53 2023 +0200 - modules: readme files regenerated - topos ... [skip ci] + jsonrpcc: clang-format for coherent indentation and coding style -commit 1ba5080ee484b5785ae17d38e7108be9d505924a -Author: Daniel-Constantin Mierla -Date: Tue Jun 21 08:56:51 2022 +0200 +commit c4e39b7c836c9cfd87f44e49104c04612e7ebe7a +Author: Victor Seva +Date: Wed May 17 16:36:53 2023 +0200 - topos: docs for methods_nocontact parameter + json: clang-format for coherent indentation and coding style -commit ab714eb386060df994875cfd1c8cf2b61fe7fa8f -Author: Daniel-Constantin Mierla -Date: Tue Jun 21 08:52:41 2022 +0200 +commit 393548de8effe4c1daff4100104c2c642962615e +Author: Victor Seva +Date: Wed May 17 16:36:10 2023 +0200 - topos: added methods_nocontact parameter - - - specify the list of methods to skip adding contact header for + janssonrpcc: clang-format for coherent indentation and coding style -commit 414c7dd608584df18f871b42e05f401e21ba775d -Author: Daniel-Constantin Mierla -Date: Tue Jun 21 08:41:53 2022 +0200 +commit 1f42d3fcfa6ca2cdf2bfa674dae075c85e90be2a +Author: Victor Seva +Date: Wed May 17 16:36:10 2023 +0200 - topos: skip adding contact header for BYE, CANCEL, PRACK - - - GH #3149 + jansson: clang-format for coherent indentation and coding style -commit 6790185478ba96ebb0626846386b28aea15dcce8 -Author: Seven Du -Date: Sun Jun 19 18:13:29 2022 +0800 +commit f8c6f3dc1b61b045c796d91b77f4afcc58576ca2 +Author: Victor Seva +Date: Wed May 17 16:36:10 2023 +0200 - ppcfg: add values to log to better tell the problem + ipops: clang-format for coherent indentation and coding style -commit 20d0b2211ef6023149c4dd1cdcaf23d0edf42846 -Author: S-P Chan -Date: Sat Jun 18 11:11:36 2022 +0800 +commit 874e9150a5dbce5bc5219962d169a1acad487bd6 +Author: Victor Seva +Date: Wed May 17 16:36:10 2023 +0200 - tls_wolfssl: memory handling cleanup - - Set memory allocators to align up to 16-bytes + ims_usrloc_scscf: clang-format for coherent indentation and coding style -commit 1affa052deb00885156c33538d081647d44e53d5 -Author: Henning Westerholt -Date: Mon Jun 20 17:22:38 2022 +0000 +commit 8598f4e099a30e94af1fb526afc39170af53ee0d +Author: Victor Seva +Date: Wed May 17 16:36:10 2023 +0200 - benchmark: use common error logging defines for memory allocation problems + ims_usrloc_pcscf: clang-format for coherent indentation and coding style -commit 0b2942e1dfe6cd84f97d62f6b4fccc86e5802eff -Author: Henning Westerholt -Date: Mon Jun 20 17:19:55 2022 +0000 +commit a8403652f033c8dc9bc7f1667fb1e33acfb371dd +Author: Victor Seva +Date: Wed May 17 16:36:09 2023 +0200 - benchmark: use INFO log level for timer registration (related to GH #3150) + ims_registrar_scscf: clang-format for coherent indentation and coding style -commit b3c8329cfbfa19613dfbadaea7f220443dbb7f55 -Author: Seven Du -Date: Sun Jun 19 19:42:18 2022 +0800 +commit d0d11e9f71636a49bc279930d00569c4d33931f1 +Author: Victor Seva +Date: Wed May 17 16:36:09 2023 +0200 - nats: fix the nats:connected event_route not being triggered on a successful connect + ims_registrar_pcscf: clang-format for coherent indentation and coding style -commit 1c0a87d107ebb3adc3b09ff5489422a67d897eb3 -Author: Kamailio Dev -Date: Mon Jun 20 11:46:26 2022 +0200 +commit d1a5dc6de5c4965236ead644342eac3e798d1df3 +Author: Victor Seva +Date: Wed May 17 16:36:09 2023 +0200 - modules: readme files regenerated - ims_registrar_scscf ... [skip ci] + ims_qos: clang-format for coherent indentation and coding style -commit d772f47ba196633c53504677103626ecc1904d54 -Merge: f2549f5b38 afed750ea1 -Author: alexyosifov <47529095+alexyosifov@users.noreply.github.com> -Date: Mon Jun 20 12:42:56 2022 +0300 +commit fa2f17f0d697b45b98b4422bdc037adc6218c0fa +Author: Victor Seva +Date: Wed May 17 16:36:09 2023 +0200 - Merge pull request #3146 from alexyosifov/skip_multiple_bindings_on_reg_resp - - ims_registrar_scscf: 200OK changes according to RFC3261 + ims_ocs: clang-format for coherent indentation and coding style -commit f2549f5b38b7ea9bf01e8528cc13ce8fd7a5853c +commit 4a5bb1088c684dc15b70318eb655a39052aef807 Author: Victor Seva -Date: Sun Jun 19 01:41:54 2022 +0200 +Date: Wed May 17 16:36:09 2023 +0200 - Revert "pkg/kamailio/deb: fix tlsa build" - - This reverts commit 6f162fc63d0503637c4c3c96ab4b13189239250f. + ims_isc: clang-format for coherent indentation and coding style -commit dae400d384e1073d4d998d83e69b68e88765a642 +commit a3b7d9989a5fe68937f6ea15a3a1b7a5804e97ad Author: Victor Seva -Date: Sun Jun 19 01:41:39 2022 +0200 +Date: Wed May 17 16:36:09 2023 +0200 - Revert "Makefile.group: add tlsa to ktls" - - This reverts commit 8141e4454c5e6eba08d7ff5d5213948c248f7a03. + ims_ipsec_pcscf: clang-format for coherent indentation and coding style -commit 6f162fc63d0503637c4c3c96ab4b13189239250f +commit 7d29322056da699f09060884ee28e64dff885de7 Author: Victor Seva -Date: Sun Jun 19 00:38:03 2022 +0200 +Date: Wed May 17 16:36:08 2023 +0200 - pkg/kamailio/deb: fix tlsa build - - * remove unused mod_name definition + ims_icscf: clang-format for coherent indentation and coding style -commit 8141e4454c5e6eba08d7ff5d5213948c248f7a03 +commit 57b636787d87ce922342d40df8424511711135da Author: Victor Seva -Date: Fri Jun 17 21:16:29 2022 +0200 +Date: Wed May 17 16:36:08 2023 +0200 - Makefile.group: add tlsa to ktls + ims_diameter_server: clang-format for coherent indentation and coding style -commit 398e808719520b054fce25a722b9b794ebab2744 +commit eccfa6bffeeb93d22a0c049af8d362023c9ca396 Author: Victor Seva -Date: Fri Jun 17 11:33:47 2022 +0200 +Date: Wed May 17 16:36:08 2023 +0200 - pkg/kamailio/deb: rework rules [skip ci] - - * define list elements per line. It helps to remove/add them in - backports scripts - * remove unused definitions - * include dpkg-dev helper makefile files with definitions - * rework backports scripts + ims_dialog: clang-format for coherent indentation and coding style -commit 41ab78edff1677fc1a575b84e275bfc525978efa -Author: Daniel-Constantin Mierla -Date: Fri Jun 17 09:53:01 2022 +0200 +commit 12f3e8f600bd160075d081a9208e3e40aa149643 +Author: Victor Seva +Date: Wed May 17 16:36:08 2023 +0200 - core: added domain and auto_domains as variants for alias and auto_aliases + ims_charging: clang-format for coherent indentation and coding style -commit 2620a22d8793f7e40b10765d46dba952adb677bf -Author: Daniel-Constantin Mierla -Date: Fri Jun 17 09:15:27 2022 +0200 +commit 7048217eb06e3d7a8eb5af48383f7f975f7af624 +Author: Victor Seva +Date: Wed May 17 16:36:08 2023 +0200 - etc/kamailio.cfg: use of htable guarded by own ifdef - - - allows independent loading for extending (e.g., store items to fix - in-dialog routing) + ims_auth: clang-format for coherent indentation and coding style -commit a21bf23c1299a15a538de9883082e1d075b7f7e0 -Author: Kamailio Dev -Date: Thu Jun 16 12:31:15 2022 +0200 +commit 9f351785ff9b9c65370f7e576fdb51f4a247ed49 +Author: Victor Seva +Date: Wed May 17 16:36:08 2023 +0200 - modules: readme files regenerated - pua_dialoginfo ... [skip ci] + imc: clang-format for coherent indentation and coding style -commit 8ac3137057d07f42eb8845ae4fb29cd9c4021165 -Author: Victor Seva -Date: Fri Feb 28 11:39:24 2020 +0100 +commit b6fd0eeec3807d043f7a18be7ac3586defaf5063 +Author: Victor Seva +Date: Wed May 17 16:36:07 2023 +0200 - pua_dialoginfo: local_identity_dlg_var + http_client: clang-format for coherent indentation and coding style -commit bd7261a5f656a8e723bb6999633c55864b46f1b6 -Author: Victor Seva -Date: Tue Jun 30 09:27:58 2020 +0200 +commit 66d99f277c8f0ba71c2d86ff6039924cd5c4ddaf +Author: Victor Seva +Date: Wed May 17 16:36:07 2023 +0200 - pua_dialoginfo: use lock when use_puburi_avps is set + http_async_client: clang-format for coherent indentation and coding style -commit a5c0d5fe890a243e648d0de7463da63b910c2a81 -Author: Victor Seva -Date: Thu Feb 20 18:50:14 2020 +0100 +commit e3a31a046f7032d8a797a51751679c6b4163109a +Author: Victor Seva +Date: Wed May 17 16:36:07 2023 +0200 - pua_dialoginfo: refresh_pubruri_avps_flag + htable: clang-format for coherent indentation and coding style -commit 38c0469fd804e79a6f9f69efb063a7e29c14485a -Author: Kamailio Dev -Date: Thu Jun 16 09:46:18 2022 +0200 +commit 003cfd2abf71217ad936c6dc0781ae7374f1e3bb +Author: Victor Seva +Date: Wed May 17 16:36:07 2023 +0200 - modules: readme files regenerated - tls_wolfssl ... [skip ci] + h350: clang-format for coherent indentation and coding style -commit 20f37638e0457a029648785bb206f3fafdff0427 -Author: S-P Chan -Date: Thu Jun 16 15:36:17 2022 +0800 +commit 2209444f837ace72d44f92cedabdf72f2011ab9e +Author: Victor Seva +Date: Wed May 17 16:36:07 2023 +0200 - tls_wolfssl: initial docs + gzcompress: clang-format for coherent indentation and coding style -commit a1398511036983471f4fd1d1e33099dee8a565bf -Author: S-P Chan -Date: Thu Jun 16 14:42:00 2022 +0800 +commit feb9b6d140e7ab4dd14c4427c2937c5ed9460747 +Author: Victor Seva +Date: Wed May 17 16:36:07 2023 +0200 - tls_wolfssl: Miscellaneous cleanup - - Cleanup of OpenSSL symbols and OpenSSL-related memory warnings. + group: clang-format for coherent indentation and coding style -commit 585ee60394db1c0ea1143a95523131fc212aca38 -Author: Daniel-Constantin Mierla -Date: Thu Jun 16 09:17:06 2022 +0200 +commit 3560b72188b2ce13247dc66e6b3f7768be2a48e5 +Author: Victor Seva +Date: Wed May 17 16:36:07 2023 +0200 - tls_wolfssl: renamed tls_mod.{c,h} to tls_wolfssl_mod.{c,h} - - - main files of the module to match module name + geoip2: clang-format for coherent indentation and coding style -commit 5080208f445b4f4b4c01530fe485fca6f38541f0 -Author: Daniel-Constantin Mierla -Date: Thu Jun 16 09:00:16 2022 +0200 +commit 0b273cebbe6fa533e57f177fd403d057d43388f3 +Author: Victor Seva +Date: Wed May 17 16:36:06 2023 +0200 - Makefile.groups: added group for tls_wolfssl module + geoip: clang-format for coherent indentation and coding style -commit c08a7cbdfc34f19b8abe8a92d8d75dab8a05d729 -Merge: 9529730c47 7c1326aa14 -Author: Daniel-Constantin Mierla -Date: Thu Jun 16 08:39:02 2022 +0200 +commit 41cd7a2e3e99efd1b06e8d5694fada267da78811 +Author: Victor Seva +Date: Wed May 17 16:36:06 2023 +0200 - Merge pull request #3144 from space88man/wolfssl - - tls_wolfssl: new module TLS stack based on wolfSSL + exec: clang-format for coherent indentation and coding style -commit 7c1326aa14ad651ff916b8ef35fa08d2dc90a3a7 -Author: S-P Chan -Date: Tue Jun 14 14:47:32 2022 +0800 +commit f45726eb8fa27ade3bc22929e7b40363b8959d7d +Author: Victor Seva +Date: Wed May 17 16:36:06 2023 +0200 - tls_wolfssl: new module TLS stack based on wolfSSL - - Initial support. Use OpenSSL-compatiblity layer to achieve - compilation. + evrexec: clang-format for coherent indentation and coding style -commit 9529730c478aef83c9b84c98242bf8af4bf152ad -Author: Daniel-Constantin Mierla -Date: Wed Jun 15 11:36:30 2022 +0200 +commit 1fd07cc888a704a6cc1fa138a7c3bba5ff77152a +Author: Victor Seva +Date: Wed May 17 16:36:06 2023 +0200 - tls: Makefile - link libdl dynamically - - - libcrypto uses dlopen() and dlclose() - - GH #3115 + evapi: clang-format for coherent indentation and coding style -commit b08b9d9038e0f90a9475a209c8941b930f7a12a1 -Author: Kamailio Dev -Date: Wed Jun 15 11:31:26 2022 +0200 +commit 4d856d4be25c29030c1a38efbc72d04e73550fb2 +Author: Victor Seva +Date: Wed May 17 16:36:06 2023 +0200 - modules: readme files regenerated - db_cluster ... [skip ci] + erlang: clang-format for coherent indentation and coding style -commit 9b1a3a6b9a3e6a24d646e62ba74811cfdf553dae -Author: Daniel-Constantin Mierla -Date: Wed Jun 15 11:29:33 2022 +0200 +commit 5886f6130fdb422e4c00786caaf48c0544c12b84 +Author: Victor Seva +Date: Wed May 17 16:36:06 2023 +0200 - db_cluster: docs - more suggestive db url examples + enum: clang-format for coherent indentation and coding style -commit afed750ea14890966f9c06955cc8b985844769ba -Author: Aleksandar Yosifov -Date: Wed Jun 15 10:14:24 2022 +0300 +commit f52dd528c488c9b0c6f55bd4720f9a53868d2f7e +Author: Victor Seva +Date: Wed May 17 16:36:05 2023 +0200 - ims_registrar_scscf: 200OK changes according to RFC3261 - - Added corrections for 200OK reply on Re-Registration - according to RFC3261 - registrar respond with multiple bindings in case - of multiple bindings. - Added a new parameter skip_multiple_bindings_on_reg_resp - for 200OK reply used for Re-Registration. Default value is 0. - If set to 1 - registrar replies only with current contact, not with - multiple bindings. + drouting: clang-format for coherent indentation and coding style -commit f0cea1a7c03e400b4398795c2d8b0f7e45d1dfb5 -Author: Daniel-Constantin Mierla -Date: Tue Jun 14 11:44:24 2022 +0200 +commit b16014efa351fe52d3342795bbe7fb6e2d94d4ca +Author: Victor Seva +Date: Wed May 17 16:36:05 2023 +0200 - core: stop at the first config error on startup - - - continuing to look for more errors to print them on one check can end - up in crashing because some internal interpreter structure may not be - filled properly - - new cli option --all-errors that can be used to enable printing - details for more detected config errors + domainpolicy: clang-format for coherent indentation and coding style -commit 649b421cf6b8b9dbec5bf632b612214d3918899b -Author: Kamailio Dev -Date: Tue Jun 14 10:31:17 2022 +0200 +commit 8eb3ae270e7ee6f7508254255530939c5bb1880c +Author: Victor Seva +Date: Wed May 17 16:36:05 2023 +0200 - modules: readme files regenerated - siputils ... [skip ci] + domain: clang-format for coherent indentation and coding style -commit 96c49c5adc22bd80eca465cea619c20f926bb3ef -Author: Daniel-Constantin Mierla -Date: Tue Jun 14 10:27:06 2022 +0200 +commit d97cebf4a71c3a83ef7545fc5927fe9625207daa +Author: Victor Seva +Date: Wed May 17 16:36:05 2023 +0200 - siputils: docs - proper module name in examples + dnssec: clang-format for coherent indentation and coding style -commit badb945afc11cde49b3c5d26be7c63f8d64d4dcd -Author: Daniel-Constantin Mierla -Date: Tue Jun 14 10:25:15 2022 +0200 +commit 12aea06c9ee18268ea7186600f2177996cf26aa5 +Author: Victor Seva +Date: Wed May 17 16:36:05 2023 +0200 - siputils: docs for e164_max_len param + dmq_usrloc: clang-format for coherent indentation and coding style -commit 0b629dfc66ec7a2f5620ba253f8a932e3f164b07 -Author: Daniel-Constantin Mierla -Date: Tue Jun 14 10:20:59 2022 +0200 +commit 85783de49890c4f678bad7561ea8eba99673355c +Author: Victor Seva +Date: Wed May 17 16:36:05 2023 +0200 - siputils: added e164_max_len modparam - - - specify the max length for e164 number check, includting the leading - '+' - - GH #3117 + dmq: clang-format for coherent indentation and coding style -commit 93dccff9391e1336e1a37add1d07b4058b7593e8 -Author: Kamailio Dev -Date: Tue Jun 14 10:01:27 2022 +0200 +commit a288219cd1194b127def679c745260c0154d6749 +Author: Victor Seva +Date: Wed May 17 16:36:04 2023 +0200 - modules: readme files regenerated - auth ... [skip ci] + dlgs: clang-format for coherent indentation and coding style -commit 8d7583b82a1ffff78fb61b2de7b51deb77ba30a4 -Merge: c938619e45 a82e5657b6 -Author: Daniel-Constantin Mierla -Date: Tue Jun 14 09:49:14 2022 +0200 +commit d663b437f1642d4da41a953ab38083efbf2f2474 +Author: Victor Seva +Date: Wed May 17 16:36:04 2023 +0200 - Merge pull request #3133 from sn4kebite/auth-dont-invalidate-nc - - auth: Add flag for not invalidating nc on auth failure + diversion: clang-format for coherent indentation and coding style -commit c938619e458e0efa0676e7e60c2b1a6fc7e947db -Author: Anthony Alba -Date: Sat Jun 11 09:05:26 2022 +0800 +commit 6f45af36ef9d4fdd525a2c817c7800eff4136278 +Author: Victor Seva +Date: Wed May 17 16:36:04 2023 +0200 - packaging: on EL8 package with Python 3.9 + dispatcher: clang-format for coherent indentation and coding style -commit 8683deb20a3f69c3b6d2c8370d23d1451f823a6b -Author: Anthony Alba -Date: Fri Jun 10 22:13:39 2022 +0800 +commit 01d0d1de2c82db189c288a157932f4a3ba98970a +Author: Victor Seva +Date: Wed May 17 16:36:04 2023 +0200 - app_python3: use _ksr_is_main to detect child process + dialplan: clang-format for coherent indentation and coding style -commit 64ae9ed7212c1db352ab583b8d319358da23775f -Author: Daniel-Constantin Mierla -Date: Fri Jun 10 14:05:09 2022 +0200 +commit 783a416f1a542a3e195660f13eff30b86304dabd +Author: Victor Seva +Date: Wed May 17 16:36:04 2023 +0200 - siputils: removed duplicated function for e164 check + dialog: clang-format for coherent indentation and coding style -commit da4f786b0c0275a6e4c8324f9b4c347351b5a48a -Author: Kamailio Dev -Date: Fri Jun 10 09:16:30 2022 +0200 +commit 656e147c47088b8147d48948c482491f35fa4482 +Author: Victor Seva +Date: Wed May 17 16:36:04 2023 +0200 - modules: readme files regenerated - dispatcher ... [skip ci] + debugger: clang-format for coherent indentation and coding style -commit e052fd8507115065b566912a6146dce329b19408 -Author: Henning Westerholt -Date: Fri Jun 10 07:08:24 2022 +0000 +commit 2b597d8c2a5316286929d13623c6b77c9600338a +Author: Victor Seva +Date: Wed May 17 16:36:03 2023 +0200 - dispatcher: extend documentation about default behaviour with missing match mode + db_unixodbc: clang-format for coherent indentation and coding style -commit 251bb74535594629499dfd2bb2cebfb4d728a260 -Author: Anthony Alba -Date: Thu Jun 9 23:02:18 2022 +0800 +commit 2a660612138dd212de748c65da89189681cfbbfc +Author: Victor Seva +Date: Wed May 17 16:36:03 2023 +0200 - app_python3: call PyOS_AfterFork_Child() only in child processes - - - GH #3125: we should not call PyOS_AfterFork_Child() in the main - process. + db_text: clang-format for coherent indentation and coding style -commit 73db408a4a1d58d8fd4c7950ede7ac3a18f3355c -Author: Anthony Alba -Date: Thu Jun 9 21:24:44 2022 +0800 +commit 3d7a3769d03a0c036a7e2514f972af4bd5c36055 +Author: Victor Seva +Date: Wed May 17 16:36:03 2023 +0200 - app_python3: workaround for abort in Python 3.8+ + db_sqlite: clang-format for coherent indentation and coding style -commit 75bdb84c8eff081f74cee383307769861c8e4500 -Author: Kamailio Dev -Date: Wed Jun 8 23:31:21 2022 +0200 +commit 65b7724ae196ff9da346a486721de53d280cfff1 +Author: Victor Seva +Date: Wed May 17 16:36:03 2023 +0200 - modules: readme files regenerated - sipdump ... [skip ci] + db_redis: clang-format for coherent indentation and coding style -commit 2a744a58c57542520e4ff4c73b1419a083b17076 -Author: Daniel-Constantin Mierla -Date: Wed Jun 8 23:23:09 2022 +0200 +commit 368c2dffd8e4f4d8335d0cbf73a68afe333ff0fa +Author: Victor Seva +Date: Wed May 17 16:36:03 2023 +0200 - sipdump: docs - sync example with description + db_postgres: clang-format for coherent indentation and coding style -commit 0eeb4cc61f4a340ef5f8d4acf1d4ea20eb711f73 -Author: Daniel-Constantin Mierla -Date: Tue Jun 7 09:12:40 2022 +0200 +commit 2c45e429bf745541238aab727955dc6267a385ef +Author: Victor Seva +Date: Wed May 17 16:36:03 2023 +0200 - uac: check new callid value for setting $uac_req() field - - - GH #3135 + db_perlvdb: clang-format for coherent indentation and coding style -commit a82e5657b66272c0833c1d1d6a55ee29acc315a5 -Author: Jon Bergli Heier -Date: Fri Jun 3 15:43:39 2022 +0200 +commit ff47e83bb4b646a857c3646f93227521ee4ed692 +Author: Victor Seva +Date: Wed May 17 16:36:02 2023 +0200 - auth: Add flag for not invalidating nc on auth failure - - If flag 32 is set then we skip updating nc in pre_auth. On success we - call check_nonce once more to do the update. This can be used to chain - calls to eg. pv_auth_check to authenticate against multiple passwords. + db_oracle: clang-format for coherent indentation and coding style -commit 1225d7fda1d8c3eb82c403dcd0cd38d57fc4ad2a +commit 1e0cf1fb6b6348ea759d6bd44624bd1b51a6b36a Author: Victor Seva -Date: Fri Jun 3 11:40:46 2022 +0200 +Date: Wed May 17 16:36:02 2023 +0200 - pkg/kamailio/deb: update Maintainer and Vcs fields [skip ci] - - In order to be more clear of who is the origin of the packages + db_mysql: clang-format for coherent indentation and coding style -commit 3b136547467b5e9fa6b39da9b078946b07fb94cc -Author: Kamailio Dev -Date: Fri Jun 3 11:31:28 2022 +0200 +commit 71b9235e3be8ad12666c05f3fb5bab18ea6fdeb1 +Author: Victor Seva +Date: Wed May 17 16:36:02 2023 +0200 - modules: readme files regenerated - tm ... [skip ci] + db_mongodb: clang-format for coherent indentation and coding style -commit 062e6daa0f149e01674667f77608afb35b6e099a -Author: emvondo -Date: Fri Jun 3 11:28:16 2022 +0200 +commit f8d371315ba6e951cc2c1c564603ee4718844ea3 +Author: Victor Seva +Date: Wed May 17 16:36:02 2023 +0200 - tm: new param to specify reply codes for dns srv failover + db_flatstore: clang-format for coherent indentation and coding style -commit 1ac02d9f0b436602cfc8bf72037ca7f84be3d67f -Author: Daniel-Constantin Mierla -Date: Fri Jun 3 11:21:14 2022 +0200 +commit 81078ba7fb9bb084cde36228bbdee2e249198a03 +Author: Victor Seva +Date: Wed May 17 16:36:02 2023 +0200 - dispatcher: fix for checking reply code class rule + db_cluster: clang-format for coherent indentation and coding style -commit 0550a3d44b2addc160b6a20bd2c9bf2831187400 -Merge: 72901b7822 bd4cc48687 -Author: Daniel-Constantin Mierla -Date: Thu Jun 2 21:17:11 2022 +0200 +commit 8ab3075e036fb15a6218bed302d8d2bf18d752fd +Author: Victor Seva +Date: Wed May 17 16:36:02 2023 +0200 - Merge pull request #3127 from atanasdb/ims_qos_fix - - ims_qos: fix module loading crash + db_cassandra: clang-format for coherent indentation and coding style -commit 72901b7822c5684f8a10faa91118f3fd6de6c01a -Author: Daniel-Constantin Mierla -Date: Thu Jun 2 12:48:38 2022 +0200 +commit 1dc0bbbe9d15782ca5bf807aef0cd3babc83c7af +Author: Victor Seva +Date: Wed May 17 16:36:01 2023 +0200 - ctl: skip checking end tag for BINRPC_T_DOUBLE values - - - related to GH #3123 + db_berkeley: clang-format for coherent indentation and coding style -commit a81266d38d500dfc7f7fda4c3903d375fabe8d24 -Author: Kamailio Dev -Date: Wed Jun 1 18:16:21 2022 +0200 +commit 8e9863e0a269c5daf81f2dfc88ae3e76d782c678 +Author: Victor Seva +Date: Wed May 17 16:36:01 2023 +0200 - modules: readme files regenerated - ims_ipsec_pcscf ... [skip ci] + db2_ops: clang-format for coherent indentation and coding style -commit f3bdccdf08acde773aaa5731bcf47b8ec7fa798b -Author: Daniel-Constantin Mierla -Date: Wed Jun 1 18:15:26 2022 +0200 +commit 4f10a615df63bda84aa4a95893e453a79a0eb1b4 +Author: Victor Seva +Date: Wed May 17 16:36:01 2023 +0200 - ims_ipsec_pcscf: docs for the ipsec_forward() flag to set tcp transport parameter + db2_ldap: clang-format for coherent indentation and coding style -commit a6a3bd088368fbf65c283ae27e999d315db0844b -Author: Daniel-Constantin Mierla -Date: Wed Jun 1 18:11:22 2022 +0200 +commit 4940fd2e0a13ef3438dbf93c981d9e8e4f475c56 +Author: Victor Seva +Date: Wed May 17 16:36:01 2023 +0200 - ims_ipsec_pcscf: new option for ipsec_forward() to set trasport for tcp dst uri + ctl: clang-format for coherent indentation and coding style -commit 881e3e1e195858d36d863a32f3c40f1cb83c8d9d -Author: drTr0jan -Date: Wed Jun 1 10:07:26 2022 +0300 +commit 913ef5b0f94237acea1ec851cfe9b7d05ae414f0 +Author: Victor Seva +Date: Wed May 17 16:36:01 2023 +0200 - lost: Makefile - support for FreeBSD build - - - added libcurl deps. + crypto: clang-format for coherent indentation and coding style -commit f1634883e64587e28df629fa902c7f4116338f2c -Author: Kamailio Dev -Date: Wed Jun 1 14:16:40 2022 +0200 +commit 00168efc53ff75d153894709fc172e29f83687dc +Author: Victor Seva +Date: Wed May 17 16:36:01 2023 +0200 - modules: readme files regenerated - ims_ipsec_pcscf ... [skip ci] + cplc: clang-format for coherent indentation and coding style -commit 9ce0f4ae1aca95380729b1717c6b7658270034bc -Author: Daniel-Constantin Mierla -Date: Wed Jun 1 14:10:10 2022 +0200 +commit 35454ba09732a6d08e0cdf172af22cb0f59fb427 +Author: Victor Seva +Date: Wed May 17 16:36:00 2023 +0200 - ims_ipsec_pcscf: removed shadowing (sub-scope) variables + counters: clang-format for coherent indentation and coding style -commit 3c885a2a1052373b5998ada2793e31362cd64818 -Author: Daniel-Constantin Mierla -Date: Wed Jun 1 13:52:15 2022 +0200 +commit 70625d0ba322ad23bbcf29c809aad4c15f566aa0 +Author: Victor Seva +Date: Wed May 17 16:36:00 2023 +0200 - ims_ipsec_pcscf: docs for the ipsec_forward() flag to use UE client port for TCP requests + corex: clang-format for coherent indentation and coding style -commit 762fc6068a23e7afd3251be58732d054a9dadab0 -Author: Daniel-Constantin Mierla -Date: Wed Jun 1 13:11:37 2022 +0200 +commit bd5ffa18a75f30293e454a2ece5e5447ce90c12f +Author: Victor Seva +Date: Wed May 17 16:36:00 2023 +0200 - ims_ipsec_pcscf: ipsec_forward() option to use UE client port for requests over TCP + cnxcc: clang-format for coherent indentation and coding style -commit 21f3b485a4fa5cadd84962020a54a63db742e667 -Author: Daniel-Constantin Mierla -Date: Wed Jun 1 13:00:42 2022 +0200 +commit 388fa4f5874317de09ce2215512447d357a260bd +Author: Victor Seva +Date: Wed May 17 16:36:00 2023 +0200 - ims_ipsec_pcscf: docs for flag to not reset dst uri + cfgutils: clang-format for coherent indentation and coding style -commit 0bc56bd13b343057a62177b1b77e9aa82ae00155 -Author: Daniel-Constantin Mierla -Date: Wed Jun 1 12:58:07 2022 +0200 +commit f719c8be69e33998f1953c896425fa1f69aadaec +Author: Victor Seva +Date: Wed May 17 16:36:00 2023 +0200 - ims_ipsec_pcscf: new option to skip resetting the dst uri in ipsec_forward() + cfgt: clang-format for coherent indentation and coding style -commit 2234a18e9031a634ba43655779c644ce549af505 -Author: Daniel-Constantin Mierla -Date: Wed Jun 1 08:24:50 2022 +0200 +commit d488407ececc207993d483c4d48a060579df4b1a +Author: Victor Seva +Date: Wed May 17 16:36:00 2023 +0200 - core: new socket global parameter to set listen attributes with a structure style - - - alternative to listen when a usual bind address is provided - - example: - - socket = { - bind = udp:127.0.0.1:5060; - advertise = 1.2.3.4:5080; - name = "udp0"; - } + cfg_db: clang-format for coherent indentation and coding style -commit afcab24d999fa999fbc99cda607423cde9fa8714 -Merge: 80c941bd08 36baa8cda6 -Author: Daniel-Constantin Mierla -Date: Tue May 31 18:43:31 2022 +0200 +commit 5c4d2431153c00d0726ba4daa843a2a85d264a1c +Author: Victor Seva +Date: Wed May 17 16:36:00 2023 +0200 - Merge pull request #3130 from drTr0jan/fix-freebsd - - Fix Makefile.groups and SLACK for build on FreeBSD + cdp_avp: clang-format for coherent indentation and coding style -commit 36baa8cda606e107308303c33c5b98cbb513c653 -Author: drTr0jan -Date: Tue May 31 19:07:59 2022 +0300 +commit bda0a6b3b0403949fdbfa0468cc1341a5357101a +Author: Victor Seva +Date: Wed May 17 16:35:59 2023 +0200 - slack: Makefile - support for FreeBSD build - - - added LIBS and DEFS variables, making them consistent with - the rest of modules. + cdp: clang-format for coherent indentation and coding style -commit 5910c8184f42e9564711a07959d410aa2d483b43 -Author: drTr0jan -Date: Tue May 31 19:02:04 2022 +0300 +commit 403fc1d99d11d74bd5bcc839c2a2a685f0a8921f +Author: Victor Seva +Date: Wed May 17 16:35:59 2023 +0200 - Makefile.groups: renamed malloc_test to misctest - - - building module_group_standard fail due to rename of malloc_test module. + carrierroute: clang-format for coherent indentation and coding style -commit bd4cc486879616d502362dd464b04d7d3c2865c4 -Author: Atanas Bakalov -Date: Tue May 31 12:52:38 2022 +0200 +commit 5b56026ba1fdfa328b112750ad9616d5a6a18e7c +Author: Victor Seva +Date: Wed May 17 16:35:59 2023 +0200 - ims_qos: fix compilation warning + call_obj: clang-format for coherent indentation and coding style -commit 80c941bd083854c4b55bd4af218cb65d06040d94 -Author: Kamailio Dev -Date: Tue May 31 10:16:16 2022 +0200 +commit ec844ccbce439051b8c2cf69a89d3ef4dc5942e6 +Author: Victor Seva +Date: Wed May 17 16:35:59 2023 +0200 - modules: readme files regenerated - ims_ipsec_pcscf ... [skip ci] + call_control: clang-format for coherent indentation and coding style -commit 6ab5fd2192b9151e5ecc8423d189c730cd225689 -Author: Daniel-Constantin Mierla -Date: Tue May 31 10:08:27 2022 +0200 +commit 2e6436351d694c335ef31b6c6278b071bd2f7e6b +Author: Victor Seva +Date: Wed May 17 16:35:59 2023 +0200 - ims_usrloc_pcscf: more debug messages in get_pcontact() + blst: clang-format for coherent indentation and coding style -commit 07d9a77272ee0b8b3e25ee5ddb443cd3adb01890 -Author: Daniel-Constantin Mierla -Date: Tue May 31 10:06:13 2022 +0200 +commit 90e13c2386e5d3812a03c48708cf6bce5ca99c25 +Author: Victor Seva +Date: Wed May 17 16:35:58 2023 +0200 - ims_ipsec_pcscf: docs for new flag for no alias use + benchmark: clang-format for coherent indentation and coding style -commit f71e8e66da1e4c611a7b00bb6a264ab59f279ac7 -Author: Daniel-Constantin Mierla -Date: Tue May 31 09:42:49 2022 +0200 +commit f8f4fcdb48a48452f999e746bc23a02a1802e686 +Author: Victor Seva +Date: Wed May 17 16:35:58 2023 +0200 - ims_ipsec_pcscf: option to skip use of alias for pcontact received details + avpops: clang-format for coherent indentation and coding style -commit c22c89d8d72dccb7c7eaca7a84cb9c186784ca80 -Author: Kamailio Dev -Date: Tue May 31 08:46:20 2022 +0200 +commit 349b93a2ddbadf62fb47600c062abf5620259c77 +Author: Victor Seva +Date: Wed May 17 16:35:58 2023 +0200 - modules: readme files regenerated - ims_ipsec_pcscf ... [skip ci] + avp: clang-format for coherent indentation and coding style -commit 4ee3a788bf60b9e2191766b7cf153a6d7d23bfbb -Author: Daniel-Constantin Mierla -Date: Tue May 31 08:32:12 2022 +0200 +commit dff2f1a5d033ffaf252bd80a004f06346ff21169 +Author: Victor Seva +Date: Wed May 17 16:35:58 2023 +0200 - ims_ipsec_pcscf: docs updated for ipsec_forward() + auth_xkeys: clang-format for coherent indentation and coding style -commit 13dbfe9da2df3bd0ae21a3f1cbee90f2f47e470b -Author: Daniel-Constantin Mierla -Date: Tue May 31 08:30:04 2022 +0200 +commit 08e243030c190b57eec9bdefd9bd869263209923 +Author: Victor Seva +Date: Wed May 17 16:35:58 2023 +0200 - ims_ipsec_pcscf: added option to search ipsec tunel by new r-uri + auth_radius: clang-format for coherent indentation and coding style -commit 39c44dd769104c2cc3af6c3a11ec44287134894b -Author: Kamailio Dev -Date: Mon May 30 15:31:17 2022 +0200 +commit 552c5b148ee8d9d7cf9c9e971f0c1327bea95019 +Author: Victor Seva +Date: Wed May 17 16:35:58 2023 +0200 - modules: readme files regenerated - ims_ipsec_pcscf ... [skip ci] + auth_identity: clang-format for coherent indentation and coding style -commit 4ce48efbb7022dbb060173816577aed404689bb9 -Author: Daniel-Constantin Mierla -Date: Mon May 30 15:24:38 2022 +0200 +commit d889afa8189d79510bdbfc006ef0ca4781898f15 +Author: Victor Seva +Date: Wed May 17 16:35:57 2023 +0200 - ims_ipsec_pcscf: simplified parsing target uri for contact filling + auth_ephemeral: clang-format for coherent indentation and coding style -commit c0628e4e13bd95412e5f43dfe9a3e1d23aeebaaf -Author: Daniel-Constantin Mierla -Date: Mon May 30 15:17:37 2022 +0200 +commit 63b19282d967ceb2dfa8e2d8a4beadbdfe9cffca +Author: Victor Seva +Date: Wed May 17 16:35:57 2023 +0200 - ims_ipsec_pcscf: docs for new flag to use dst uri for ipsec tunnel search + auth_diameter: clang-format for coherent indentation and coding style -commit a851acca1c06daf847dc27ad31b0eb0ba7e93f4d -Author: Daniel-Constantin Mierla -Date: Mon May 30 15:10:38 2022 +0200 +commit 5eed2433c43d1f15adcf09bc971c398d4be67f40 +Author: Victor Seva +Date: Wed May 17 16:35:57 2023 +0200 - ims_ipsec_pcscf: option to use dst address for tunnel search + auth_db: clang-format for coherent indentation and coding style -commit a812e490d3ba4245c2dba4f08d081a957fb5679b -Author: Sergey Safarov -Date: Mon May 30 15:21:23 2022 +0300 +commit 1083f1fe43c43c312afaa1c8cbc9ad754db0795c +Author: Victor Seva +Date: Wed May 17 16:35:57 2023 +0200 - pkg/kamailio/obs: packaged siprepo module into RPM files + async: clang-format for coherent indentation and coding style -commit 61b175bcffed9492d6cc718c9ac70c4378712807 -Author: Daniel-Constantin Mierla -Date: Mon May 30 13:19:40 2022 +0200 +commit 9f247443eb0e69f1a0b9980e711f752c24623acc +Author: Victor Seva +Date: Wed May 17 16:34:53 2023 +0200 - ims_usrloc_scscf: same type for init flag variable - - - it was defined as int but the extern declaration was unsigned - - added ims_ulp_ prefix to avoid global scope conflict with other modules + app_sqlang: clang-format for coherent indentation and coding style -commit 44b465350faa5f640262b693dfbb7959921b4cea -Author: Daniel-Constantin Mierla -Date: Mon May 30 13:16:07 2022 +0200 +commit 93879bb507f75cc93b8ff002facb30ef2d9b7009 +Author: Victor Seva +Date: Wed May 17 16:34:53 2023 +0200 - ims_usrloc_pcscf: same type for init flag variable - - - it was defined as int but the extern declaration was unsigned - - added ims_ulp_ prefix to avoid global scope conflict with other modules + app_ruby_proc: clang-format for coherent indentation and coding style -commit 3ba676e9776b8fea8e64eeb8ea7520ab83b8702c -Author: Daniel-Constantin Mierla -Date: Mon May 30 13:09:18 2022 +0200 +commit 8f8a45ff3cc66839b0a714f88ab2bef17b4abb61 +Author: Victor Seva +Date: Wed May 17 16:34:53 2023 +0200 - ims_ipsec_pcscf: same type for init flag variable - - - it was defined as int but the extern declaration was unsigned - - added ipsec_ prefix to avoid global scope conflict with other modules + app_ruby: clang-format for coherent indentation and coding style -commit a4cba5eea619a62d722170ff92f4324c3e4e90cb -Author: Daniel-Constantin Mierla -Date: Mon May 30 12:58:18 2022 +0200 +commit ef556363a5b8e983ed302ff7a8b7eac2b5431de3 +Author: Victor Seva +Date: Wed May 17 16:34:52 2023 +0200 - ims_ipsec_pcscf: clang-format for coherent indentation and coding style + app_python3s: clang-format for coherent indentation and coding style -commit ab8cb43c83f8c9528e45a5b57fbb1440360f201e -Author: Atanas Bakalov -Date: Mon May 30 10:46:38 2022 +0200 +commit a449857542ecb24b718acfd632447a97a3821042 +Author: Victor Seva +Date: Wed May 17 16:34:52 2023 +0200 - rx_aar: unreference dialog in case of aar update (#3104) - - - release the dialog reference even for aar updates as the dialog was - already referenced when issuing the aar request - - Co-authored-by: Atanas Bakalov + app_python3: clang-format for coherent indentation and coding style -commit 0a494043b70b3c5e47397f03802fe8fa79ed1fb6 -Author: riccardv <70984967+riccardv@users.noreply.github.com> -Date: Mon May 30 10:45:26 2022 +0200 +commit d9bfe53033379f202de38fe9e8eb5e6290a644ae +Author: Victor Seva +Date: Wed May 17 16:34:52 2023 +0200 - ims_ipsec_pcscf: ik and ck keys expansion fixes (#3121) - - - input ik,ck keys for add_sa() are not zero terminated. - - des3_ede encryption key expansion possible buffer overflow, - - sha1 authentication key expansion correction. - - Co-authored-by: riccardv + app_python: clang-format for coherent indentation and coding style -commit 9b8a4fd17e8819395043f54d43dab07a226d8490 -Author: Wolfgang Kampichler -Date: Sat May 28 22:42:02 2022 +0200 +commit 1d347efddd7ff0e77ad1558dae27ed4bd31a25b4 +Author: Victor Seva +Date: Wed May 17 16:34:52 2023 +0200 - lost: URI list support in LoST response (filter for sip/sips scheme) + app_perl: clang-format for coherent indentation and coding style -commit a0d89214cf8296d30bacdf10a8732bc8826b2418 +commit 2ed8ff55b11df3f2b92755e804c7306bd1b9ae65 Author: Victor Seva -Date: Fri May 27 17:18:01 2022 +0200 +Date: Wed May 17 16:34:52 2023 +0200 - dialog: w_dlg_get_var, fix incompatible pointer - - > CC (gcc) [M dialog.so] dialog.o - > dialog.c: In function 'w_dlg_get_var': dialog.c:1608:6: warning: assignment to 'str *' {aka 'struct _str *'} from incompatible pointer type 'sr_kemi_xval_t *' {aka 'struct sr_kemi_xval *'} [-Wincompatible-pointer-types] - > 1608 | val = ki_dlg_get_var(msg, &sc, &sf, &st, &k); - > | ^ + app_mono: clang-format for coherent indentation and coding style -commit de70fdc58a011bb8189f83bad99e064a8a0111da +commit 285c0e8ca7ec89bd9ff57c43e59ec729d966a9b2 Author: Victor Seva -Date: Fri May 27 16:58:28 2022 +0200 +Date: Wed May 17 16:34:52 2023 +0200 - dialog: dlg_get_var assure return null on error + app_lua_sr: clang-format for coherent indentation and coding style -commit 0d9380c8812d4e57b0c92f5f68b6c20001b28819 -Author: Kamailio Dev -Date: Tue May 24 12:31:17 2022 +0200 +commit fc61e9ab5123abd90600f342de6ec3d470e7e4a5 +Author: Victor Seva +Date: Wed May 17 16:34:51 2023 +0200 - modules: readme files regenerated - auth_identity ... [skip ci] + app_lua: clang-format for coherent indentation and coding style -commit 6e7b6cfabba6774627f942d7f02e1adf62bf7797 -Author: Daniel-Constantin Mierla -Date: Tue May 24 12:21:53 2022 +0200 +commit 3b7e80c3c5572cfda5770087d99e10b2a53c2a9a +Author: Victor Seva +Date: Wed May 17 16:34:51 2023 +0200 - auth_identity: docs - type for accept_pem_certs param + app_jsdt: clang-format for coherent indentation and coding style -commit 9155a53bccd090e51b274802d140f363aca6d4b7 -Author: Daniel-Constantin Mierla -Date: Tue May 24 12:19:38 2022 +0200 +commit 70ac94f3df4f6cd06fc53404f6867eb326077da5 +Author: Victor Seva +Date: Wed May 17 16:34:51 2023 +0200 - auth_identity: removed auth_identity.xml from source folder - - - there is one in doc/ subfolder + app_java: clang-format for coherent indentation and coding style -commit d001dc00e4f5cc5925727757e3517eebc164c7f8 -Author: Kamailio Dev -Date: Tue May 24 10:46:28 2022 +0200 +commit 64a2e2dda7d0e1a78942ebadff7e60a2d26bb286 +Author: Victor Seva +Date: Wed May 17 16:34:51 2023 +0200 - modules: readme files regenerated - ims_ipsec_pcscf ... [skip ci] + acc_json: clang-format for coherent indentation and coding style -commit 59fd5cd7053df2941aa6df7270ed7a021ce1f62d -Author: Kristiyan Peychev <97663519+kristiyan-peychev-flolive@users.noreply.github.com> -Date: Tue May 24 11:39:47 2022 +0300 +commit 5666ee0ffc2b7e794563821afbfff0ef883d2a6a +Author: Victor Seva +Date: Wed May 17 16:34:51 2023 +0200 - IMS, P-CSCF: fix issues with UEs and ipsec tunnel (#3094) - - * ims_ipsec_pcscf: fix issues with UEs and ipsec tunnel - - UEs were not sending certain replies through the ipsec tunnel - - * ims_ipsec_pcscf: fix issues pointed out in code review - - Remove error logs which were not errors at all. - Fix issue in clean_spi_list where the free SPI list would get completely wiped. - - * ims_ipsec_pcscf: lower log severity from error to info - - Co-authored-by: Teodor Mihov + acc_diameter: clang-format for coherent indentation and coding style -commit 8718fb447b0d5d53a0eeb5b21ed6f8d1766cb21b -Author: Daniel-Constantin Mierla -Date: Mon May 23 08:18:04 2022 +0200 +commit b41657fb5597423e443e561812b1ed8d42106900 +Author: Victor Seva +Date: Wed May 17 16:03:18 2023 +0200 - INSTALL, README: updated version and links + acc: clang-format for coherent indentation and coding style -commit bed6bba77a16ec1a840544d674d03d692869c68e -Author: Daniel-Constantin Mierla -Date: Sat May 21 08:21:49 2022 +0200 +commit afdf66528d695994152ec67138643af0deac8741 +Author: Victor Seva +Date: Wed May 17 15:44:30 2023 +0200 - dialog: fix ki_dlg_get_var() introduced previously + auth: clang-format for coherent indentation and coding style -commit 130ce1bf871cfb4a89bcf0cc74d898f84eeaa981 -Author: Liviu Andron -Date: Fri May 20 12:30:46 2022 +0200 +commit 5c075f8982bdf282f03d9e74f9663509a432474b +Author: Victor Seva +Date: Wed May 17 12:43:36 2023 +0200 - core: const correctness - - benign const qualifiers in inline functions + github: define proper target-ref in clang-format-checker [skip ci] -commit 7c347e244cf761d04d5aff906e88571cd68217f3 -Author: Daniel-Constantin Mierla -Date: Fri May 20 16:07:56 2022 +0200 +commit e18adca6d62ab327cb8b8c23291eef8ab4543d53 +Author: Victor Seva +Date: Wed May 17 12:40:32 2023 +0200 - dialog: reworked kemi export for dlg_get_var() + github: add checkout before clang-format-checker [skip ci] - - return SR_KEMIP_XVAL type + > https://github.com/WolleTD/clang-format-checker/issues/15 -commit 3efc0c1093ed3c9b5a11e40e4ccc65c93f4627a4 -Author: Kamailio Dev -Date: Fri May 20 13:31:17 2022 +0200 +commit 2c36d50ac56663c92bc007c85b18199a1fdff363 +Author: Victor Seva +Date: Wed May 17 12:34:47 2023 +0200 - modules: readme files regenerated - registrar ... [skip ci] + github: update clang-format-checker action to v1.10 [skip ci] -commit f0bf4cebef916887cd5196dce0521d4784904ab8 -Author: Daniel-Constantin Mierla -Date: Fri May 20 13:26:00 2022 +0200 +commit 2b4cceb35bf49fc581fdb7af10c080f927a93a4a +Author: Victor Seva +Date: Wed May 17 12:16:49 2023 +0200 - registrar: docs for reg_from_user() function + github: add clang-format-checker for pull-request [skip ci] -commit 005e8afeb6a9297bd9c752c6daaa0d99f6b4eaad +commit 5e0fb402a7755ea22c41c0b8fcefbdf9694442b8 Author: Daniel-Constantin Mierla -Date: Fri May 20 13:17:24 2022 +0200 +Date: Wed May 17 11:21:08 2023 +0200 - registrar: added function reg_from_user(ultable, uri, mode) + Makefile.defs: set LIBSSL_SET_MUTEX_SHARED by default to 1 - - return true if the message came from the user identified uri parameter - by matching agains its location records - -commit 5e4576a54e7783b1ee8fde6af7919232a5e207c4 -Author: Daniel-Constantin Mierla -Date: Fri May 20 13:15:43 2022 +0200 - - core: mod fixup helpers for params sequence str, str, int + - one can set LIBSSL_SET_MUTEX_SHARED=0 in make command line to switch + to detection mode if it is need to set it or not based on libssl + version + - GH #3458, GH #3384 -commit 18972def7a21506088988c1011b8aa6f13e1b8a9 -Author: Daniel-Constantin Mierla -Date: Fri May 20 09:51:44 2022 +0200 +commit 2eb17e9ccfa3963813215e6ddf2fdadeb588f485 +Author: Victor Seva +Date: Wed May 17 10:07:56 2023 +0200 - seas: proper print formater %.*s instead of %*.s + github: GitHub Actions Version Updater + + > https://github.com/marketplace/actions/github-actions-version-updater + + * PAT created using kamailio-sync + * organization secret WORKFLOW_SECRET created -commit fce806b5715286fa15148bbb8117ff3b9b4d0897 +commit 4c524547e1fdd4aa6dfa0ed0ada57b002296a258 Author: Daniel-Constantin Mierla -Date: Fri May 20 09:50:27 2022 +0200 +Date: Wed May 17 09:57:20 2023 +0200 - kazoo: proper print formater %.*s instead of %*.s + topoh: don't set 0 twice at the end of masked/unmasked call-id + + - fomatting updates -commit 81265e41b52cfda9a284233c93683522a98f0a64 +commit 991de5e51e799a0110b7aa489eb27f4f01f5dfd2 Author: Daniel-Constantin Mierla -Date: Wed May 18 09:18:23 2022 +0200 +Date: Wed May 17 09:52:37 2023 +0200 - siprepo: set name for timer function + topos: small formatting fixes -commit 9051033ac04fc94a0f19f8fbec6ec507fa6ab8d1 -Author: Kamailio Dev -Date: Tue May 17 12:46:29 2022 +0200 +commit 85b62cefa8d33bc736f1ab16e7c40646c903c812 +Author: harish +Date: Wed May 17 00:21:21 2023 +0530 - modules: readme files regenerated - dialog ... [skip ci] + topoh: memory leak fix for API call + + th_mask_callid_str & th_unmask_callid_str funtions used for API call to + encode/decode call-ID uses static array declaration for callid_mbuf was + unable to free callid data lump after use and leads to memory leak. + when these futions was used through API call for topos memory leak bug + as reported + qm_free(): BUG: bad pointer 0x7faec4a7xxxx (out of memory block!) called + from core: core/data_lump.c: free_lump(470) -commit 6d7d1281b250e9eb73a686b323e06a2b5b81013c -Author: Victor Seva -Date: Wed May 11 15:50:14 2022 +0200 +commit fe4c47bb47e466af2eddc0a8987c13cb976e5a3b +Author: Victor Seva +Date: Wed May 17 09:22:10 2023 +0200 - dialog: dlg_set_var(callid, ft, tt, key, value) + siptrace: fix destination target parameter on ki_sip_trace_msg + + fixes #3457 -commit 79e1052ccb764c3a1af52dc902fb3f606be5fd4b -Author: Victor Seva -Date: Fri May 6 13:30:01 2022 +0200 +commit bafefbc841eb7a6929baeff0b3fbe185860f4290 +Author: Sergey Safarov +Date: Wed May 17 09:23:07 2023 +0300 - dialog: dlg_get_var(ci, ft, tt, key, dst_var) + pkg/kamailio/obs: packaged math module -commit 1f7e894f5b293f97dc99e1b7e5d06159f91a96f7 +commit ba9d663c5d382edef3c98b31aa4341b21c307a34 Author: Daniel-Constantin Mierla -Date: Tue May 17 12:30:24 2022 +0200 +Date: Tue May 16 17:28:02 2023 +0200 - tm: fix kemi t_relay_to_proto() variants for tls + htable: set dbload filed on empty db result -commit c6ecf1d18a41167e54dbcfca566ebf7eb8fa5b74 -Author: Daniel-Constantin Mierla -Date: Mon May 16 18:51:51 2022 +0200 +commit 3823056e55db45831abc584a7df2b8998c18cf10 +Author: Kamailio Dev +Date: Tue May 16 14:16:33 2023 +0200 - xlog: docs - updated section ids + modules: readme files regenerated - usrloc ... [skip ci] -commit 8caf4ece54623fb3b85cc5c98315d9e53ae56fbf +commit f4deff8d064e9931fd4ee4fe1bbe166901e7c617 Author: Daniel-Constantin Mierla -Date: Mon May 16 18:51:25 2022 +0200 +Date: Tue May 16 14:07:22 2023 +0200 - kazoo: docs - removed unnecessary xinclude entity + usrloc: docs updated for ul.flush to indicate it depends on db mode -commit d32f8f52198d04a90f53a221a1797faa1a0f39af +commit f4dc688548aa7753af93ce6e9089b53e9fc4c7ec Author: Daniel-Constantin Mierla -Date: Mon May 16 13:48:28 2022 +0200 +Date: Tue May 16 13:32:35 2023 +0200 - core: tcp main - check setsockopt() result for SO_LINGER + topos: formatting and debug cleanup after last commit with callid masking -commit 2538ddd36245c86424ef4911c7bc8bf65f99eefb +commit f5f681c43a4736e4ec3ce5f16e11e61305384d79 Author: Kamailio Dev -Date: Mon May 16 09:16:18 2022 +0200 - - modules: readme files regenerated - dialog ... [skip ci] - -commit b498a0ad470a83f1e21c45a585926509827dda50 -Author: Daniel-Constantin Mierla -Date: Mon May 16 09:09:42 2022 +0200 +Date: Tue May 16 13:31:19 2023 +0200 - dialog: docs -remark wabout to-tag parameter for dlg_get() + modules: readme files regenerated - topos ... [skip ci] -commit e46c90c5ca98a9fba08382686c25c707efd57bf3 -Author: Rick Barenthin -Date: Tue May 3 19:42:31 2022 +0200 +commit 14d4b2422c0fed27fecf01665197f9d0669aa24e +Author: harish +Date: Fri Jan 27 01:20:59 2023 +0530 - core: add an option to trigger also an RST on tcp connection close + Topos: Added CallID Mask Document for Topos - - This gives an option to also send RST in case kamailio closes the - connection. There are cases where a FIN,ACK back forth leaves - the connection in the host in TIME_WAIT state, but the ports on both - sides are fixed. This leads to no request can send until - the TIME_WAIT state is gone. + Added document for Call-ID Mask in Topos Module -commit 2d24221e3b409a13f3724267860d8f8411ae063e -Author: Dennis Yurasov -Date: Sun May 15 21:49:18 2022 +0300 +commit d98ff2aab3d3e379fa27da187fbd069c23fb0fe9 +Author: harish +Date: Fri Jan 27 01:15:46 2023 +0530 - siptrace: fix hardcoded PROTO_UDP in duplicate_uri module parameter + Topos: Added Call ID mask when sending to Downstream - - possibility to switch to other then UDP transport protocol in diplicate_uri - -commit a1ea2c0d49f56154af5ba1028d7340ea3ed1ae42 -Author: Kamailio Dev -Date: Fri May 13 16:16:25 2022 +0200 - - modules: readme files regenerated - pv ... [skip ci] - -commit 1144c2e9bfa99e817acff378967d689d356c216b -Author: Daniel-Constantin Mierla -Date: Fri May 13 16:07:04 2022 +0200 - - pv: allow xavp_push_dst() in request/branch/failure_rotue + Added Call-ID mask while sending the request to Downstream and unmasking + when receiveing from downstream -commit 33c3f35544489ca367290dbf95d4c5ab11e5adc4 +commit c8893cc05b0cabf7bde1b1a8db49bf46266632aa Author: Daniel-Constantin Mierla -Date: Fri May 13 16:03:40 2022 +0200 +Date: Tue May 16 13:03:05 2023 +0200 - pv: docs for xavp_push_dst() + usrloc: check if database handle is initialized for db_update_ucontact_ruid() -commit 8cb05b21a6683a569563c72eeba92f3054b4d31e +commit 94dd64a5238b4bf60ca21e09e216c01166f4a93f Author: Daniel-Constantin Mierla -Date: Fri May 13 15:52:26 2022 +0200 +Date: Tue May 16 12:45:57 2023 +0200 - pv: xavp_push_dst(xname) function + core: use unsigned long (j) for rpc core.shmmem - - push a destination from XAVP attributes + - GH #3450 -commit ae40acf61a5c666db5ff9c55f2ff9b0770418a52 +commit 1d5722e18e04e8935b342d303fe265c5d8f06e8e Author: Daniel-Constantin Mierla -Date: Fri May 13 15:51:51 2022 +0200 - - core: socket info - function to get socket by listen or advertise - -commit 490eb07a75567c91f20beaa4833f1df10a9cab1f -Author: Kamailio Dev -Date: Thu May 12 19:31:15 2022 +0200 +Date: Tue May 16 12:20:36 2023 +0200 - modules: readme files regenerated - registrar ... [skip ci] + jsonrpcs: give spath parameter for storing result -commit 38365c43c2b627587d9aff470f371a0ec76bbba2 +commit 640b8c5dac458b3c45fac1a09ae04ef4574bf621 Author: Daniel-Constantin Mierla -Date: Thu May 12 19:23:06 2022 +0200 +Date: Tue May 16 08:47:39 2023 +0200 - registrar: docs - removed extra closing tag + README: version updated to 5.8 -commit 4d94b9e0fa7dfeb425f15c2e92e906425c96d810 +commit 7f2d55ce62783536f4c5c28a5935d9c3b20da311 Author: Kamailio Dev -Date: Thu May 12 19:01:19 2022 +0200 - - modules: readme files regenerated - registrar ... [skip ci] - -commit 45d7500ace163660047e241df9a7b178638e3329 -Author: Daniel-Constantin Mierla -Date: Thu May 12 18:49:06 2022 +0200 +Date: Mon May 15 23:01:09 2023 +0200 - registrar: proper attribute name for contact record xavp + modules: readme files regenerated - tls_wolfssl ... [skip ci] -commit 4d478b741e8a21365d1e7c0342476f2e77cca34c -Author: Daniel-Constantin Mierla -Date: Thu May 12 18:41:32 2022 +0200 +commit df286e7aee90cb206a821fe7e50d55f2c1c2583f +Author: Victor Seva +Date: Mon May 15 22:47:25 2023 +0200 - registrar: docs for lookup_xavp(...) + tls_wolfssl: add note about the current state of affairs -commit 194962260c4e880a199797fa0d9faf8e766c8d76 -Author: Daniel-Constantin Mierla -Date: Thu May 12 18:18:14 2022 +0200 +commit 2a79d77faa107b73e22717649776430524d9e597 +Author: Victor Seva +Date: Mon May 15 22:34:59 2023 +0200 - registrar: added lookup_xavp("ultable", "uri", "rxname", "cxname") + Revert "tls_wolfssl: use wolfssl lib from system if available" - - lookup of uri and store record and contact attributes in xavps + This reverts commit 14b1f79c29f317c74bbcbba75853ce45c353a865. -commit 9100baa7e3762b49a339933b2790a9d9cb1128c5 -Author: Daniel-Constantin Mierla -Date: Thu May 12 13:51:52 2022 +0200 +commit d8a244c6286ea0b96f5466c281aeca37d86bb17f +Author: Victor Seva +Date: Mon May 15 22:34:47 2023 +0200 - core: str - helerp macros to set str variable with char* value + Revert "pkg/kamailio/deb: introduce wolftls package" + + This reverts commit 13430c2e8b9fccf7565ddcf38dcab8e516cebef0. -commit 67f6a2890a38d81dae934e01a2ca536a45625c42 -Author: Daniel-Constantin Mierla -Date: Thu May 12 13:20:50 2022 +0200 +commit 091dc9a76bcec5c8a4bc73e863ed10b1b9d76c92 +Author: Henning Westerholt +Date: Mon May 15 13:22:09 2023 +0000 - pv: declare pv wrapper function with two parameters + topos: fix early-dialog b-side UPDATE requests routing (GH #3437) -commit 69f33615874cf3505a6ce9ea9e74be2797bbe433 -Author: Daniel-Constantin Mierla -Date: Thu May 12 11:21:46 2022 +0200 +commit 14b1f79c29f317c74bbcbba75853ce45c353a865 +Author: Victor Seva +Date: Mon May 15 13:35:48 2023 +0200 - registrar: kemi functions to get $ulc(...) attributes + tls_wolfssl: use wolfssl lib from system if available -commit 9f9fd6ff153fe72aa4bb07f81aa4fbcf67cd9491 -Author: Daniel-Constantin Mierla -Date: Wed May 11 16:42:19 2022 +0200 +commit d858378b722da6a44d937250e0985eddd31663b3 +Author: Victor Seva +Date: Mon May 15 12:18:49 2023 +0200 - pv: kemi function to get $shvinc(name) value + github: refresh branches [skip ci] -commit 6770afc5329c18371fb5149eaf5ef2a95f286eff -Author: Daniel-Constantin Mierla -Date: Wed May 11 16:16:47 2022 +0200 +commit 13430c2e8b9fccf7565ddcf38dcab8e516cebef0 +Author: Victor Seva +Date: Mon May 15 11:19:42 2023 +0200 - pv: use fixup get int value to evaluate the index parameter + pkg/kamailio/deb: introduce wolftls package -commit eebdabe4850d99ff937171d4b723122726c0aa43 +commit 4a20e2fdb2f0c0fa7366f7646ed35b80df87fa07 Author: Daniel-Constantin Mierla -Date: Wed May 11 16:11:42 2022 +0200 +Date: Mon May 15 11:24:04 2023 +0200 - pv: added $shvinc(name) - return incremented value of $shv(inc) - - - leverage internal mutex to avoid config locks + kamctl/xhttp_pi: regenerated content from db xml schema -commit 85d1881b665fd4e380538996b1eb6280af46d31a +commit 8f7c0893f0c53b9f399cfa0989fecd9bd15b344d Author: Kamailio Dev -Date: Tue May 10 19:46:22 2022 +0200 - - modules: readme files regenerated - pv ... [skip ci] - -commit 426787068bab1dbeb07ca7b973ac90a91a980628 -Author: Daniel-Constantin Mierla -Date: Tue May 10 19:42:48 2022 +0200 +Date: Fri May 12 17:31:24 2023 +0200 - pv: docs for xavp_lshift() function + modules: readme files regenerated - tls ... [skip ci] -commit 72c361fd80ba0f3d017591e4bb3fb883f7dec490 -Author: Daniel-Constantin Mierla -Date: Tue May 10 19:35:52 2022 +0200 +commit 1fd57e57255cb7f6d76326a255a3a91d107cba89 +Author: Florian Floimair +Date: Fri May 12 16:51:39 2023 +0200 - pv: config function to shift xavps to left with rotation + tls: update documentation (TLS v1.0 & 1.1 deprecation) -commit 4b377f07128a5322e7647bd9d492b50e81c5f278 +commit e6dcc14646f00aa71fc08368b268e7356d3343c7 Author: Daniel-Constantin Mierla -Date: Tue May 10 19:35:02 2022 +0200 +Date: Thu May 11 08:16:09 2023 +0200 - core: xavp - helper function to shift xavps to left with rotation + auth_radius: print radius config path on failure to load -commit 7e88c988a4843ee35172809c6955eac870229ff1 +commit 6d26825f1e147713694fdb74d25e506b0626b249 Author: Kamailio Dev -Date: Mon May 9 18:46:15 2022 +0200 +Date: Thu May 11 00:01:21 2023 +0200 - modules: readme files regenerated - geoip2 ... [skip ci] + modules: readme files regenerated - pipelimit ... [skip ci] -commit 0c16d6824fda729bf481e300992fb6bad057c89d -Author: Henning Westerholt -Date: Mon May 9 16:43:22 2022 +0000 +commit 7438bfd8405ab98f48a96138183675cf799c7386 +Author: Victor Seva +Date: Wed May 10 23:48:23 2023 +0200 - geoip2: log errors for cases where the container could not evaluated and add docs + pipelimit: fix documentation on default value of plp_limit_column [skip ci] - - log errors for cases where the container could not evaluated due to missing - initialization of the pvc container because no actual access is done in the cfg - - add documentation describing that at least one access to the container is necessary - for the match function to work correctly - -commit 2e38d1a5a1178ca437d5256d7619fee251b06d6f -Author: Daniel-Constantin Mierla -Date: Mon May 9 11:19:16 2022 +0200 + fixes #3449 - mtree: remove single-used small function - -commit 1ff86ffceede46c7a67fec92c8319c34c916a545 +commit eca3bf7570290854561ecd4ef71dc093941e2d72 Author: Daniel-Constantin Mierla -Date: Mon May 9 09:16:49 2022 +0200 +Date: Wed May 10 13:38:23 2023 +0200 - dialog: open db connection in POSTCHILDINIT callback for DB_MODE_SHUTDOWN + registrar: do not walk xavp list twice to get tcp connection id -commit 4780d46976a7a392f23af0d89f05855d473bcb30 +commit 9326cff7f67604a27049ee1cae0c9a5b965efd9d Author: Daniel-Constantin Mierla -Date: Mon May 9 09:05:18 2022 +0200 +Date: Wed May 10 13:34:32 2023 +0200 - usrloc: connect to db for main process in PROC_POSTCHILDINIT child init + htable: use long types for expires operations -commit c5da175fd79ecd17752bb2fd8af2b5a65739e58e +commit 35e279603f37aec4e8cba6a321726dfee958fc94 Author: Daniel-Constantin Mierla -Date: Sun May 8 21:35:07 2022 +0200 +Date: Wed May 10 12:04:08 2023 +0200 - app_squirrel: updated squirrel interpreter to latest git version (3.2+) + cplc: use time_t field for proper storage size -commit 3bd6eb0d7322b9f4654656b3f0b5080cd44c6e5b +commit 88a1340f0a9ec3408a61625e3621be82a4975940 Author: Daniel-Constantin Mierla -Date: Sat May 7 20:20:42 2022 +0200 - - app_jsdt: duktape interpreter upgraded to v2.7.0 - -commit a21c929a389c6e5f85e9166d01adb0d474c6ebaf -Author: Henning Westerholt -Date: Sun May 8 15:33:56 2022 +0000 +Date: Wed May 10 11:48:39 2023 +0200 - userblocklist: fix function comment, related to gh #3102 + cnxcc: cast time_t to get rid of newer compiler warnings -commit 778374aba27d81058869dba18b5dd0833893056a -Author: Stefan Mititelu -Date: Thu May 5 15:14:01 2022 +0300 - - userblocklist: fix restart errors - -commit 97efd6a64380025f3b4ef45372180f7e61448c1c +commit 6b4e3b4b227381bfe896b23af5c4ce996c95f6e8 Author: Kamailio Dev -Date: Sun May 8 17:31:17 2022 +0200 - - modules: readme files regenerated - acc ... [skip ci] - -commit c282b5812c9e9badb4c99fe8ce3bd5cce927044f -Author: Bastian Triller -Date: Thu May 5 18:28:28 2022 +0200 +Date: Wed May 10 09:46:21 2023 +0200 - utils: Fix typos + modules: readme files regenerated - p_usrloc ... [skip ci] -commit f72c574372abf4c0286799137896a247ed6269b6 -Author: Bastian Triller -Date: Thu May 5 18:27:33 2022 +0200 +commit 81d33005df808699a7e8068883ab76e30a299d0f +Author: Stefan Mititelu +Date: Fri Apr 28 10:22:13 2023 +0300 - uid_auth_db: Fix typos + p_usrloc: Add use_domain_crc32 modparam -commit ff9b030be39f82d0e952301ddd0b61a0de5a8041 -Author: Bastian Triller -Date: Thu May 5 18:26:57 2022 +0200 +commit ab0a2be6b522c1b48a2442447c24e7ab156e3d4e +Author: Victor Seva +Date: Tue May 9 23:28:04 2023 +0200 - tls: Fix typos + dialplan: fix ki_dp_translate() checks for input/output parameters + + fixes #3447 -commit c5ff6d9638b1033d2536ed46a7d254c016d8b103 -Author: Bastian Triller -Date: Thu May 5 18:25:59 2022 +0200 +commit 84dbcdb812fce70d6d470050793125698c06d0fd +Author: Kamailio Dev +Date: Tue May 9 20:31:14 2023 +0200 - sanity: Fix typos + modules: readme files regenerated - registrar ... [skip ci] -commit b94f8da598ef99d06a0db8f9bb2f9ca29a198740 -Author: Bastian Triller -Date: Thu May 5 18:25:31 2022 +0200 +commit ad8c6688d43d3d5913efa12ae1a85ef6ee3e162f +Author: Stefan Mititelu +Date: Fri Apr 28 11:15:36 2023 +0300 - pike: Fix typos + tls: Add rpc function to kill session by id + + Note that it may take few seconds for session to be killed. -commit f6da37aa7dec1cdc5a737ed354a68ae15cfc7a43 -Author: Bastian Triller -Date: Thu May 5 18:24:53 2022 +0200 +commit 439a1c7471c562b14d482c691107e88aaf694162 +Author: Daniel-Constantin Mierla +Date: Tue May 9 16:07:41 2023 +0200 - ldap: Fix typos + registrar: use xavp->val.v.l for tcp connection id + + Co-authored-by: Bastian Triller -commit 4caf7e70c09a5b61f5c28b89fa1ea5c951e4cbc0 -Author: Bastian Triller -Date: Thu May 5 18:24:21 2022 +0200 +commit 404ccb00ad294b39da58132772881143bc15fa04 +Author: Julien Chavanton +Date: Thu Apr 27 12:43:13 2023 -0400 - ctl: Fix typos + registrar: adding tcpconn_id to xavp_cfg -commit ba3f7d5157819d55a67a054de1b7d0f8fc521140 -Author: Bastian Triller -Date: Thu May 5 18:24:00 2022 +0200 +commit 43ac6b27d7ca7bc522f362c25ebb3c22ab918280 +Author: Richard Fuchs +Date: Tue May 9 15:05:39 2023 +0200 - auth: Fix typos + rtpengine: fix unaligned memory access + + Make sure the pointers we return from our continuous memory buffer is + always 64-bit aligned as it's used not only for strings, but also for + structs/objects, and such unaligned memory access is undefined on some + archs and flagged as such by ASAN. + + From https://github.com/sipwise/rtpengine/commit/ade8100d3b10308f1ff63f8cb06fdf292618edca + + fixes #3444 -commit 5e71d0100ff93e345d31b7210e93be92cde88111 -Author: Bastian Triller -Date: Thu May 5 18:22:28 2022 +0200 +commit c75e4a087f73a0976e343789593a888524aa752b +Author: Daniel-Constantin Mierla +Date: Tue May 9 08:35:15 2023 +0200 - acc: Fix typos + siptrace: exported sip_trace_msg() to kemi -commit 4b2b8925c2c8f195f135ff262f7b45601b111b0d -Author: Bastian Triller -Date: Thu May 5 18:22:00 2022 +0200 +commit d42497e112659c2f0ba60fe959793315cf98a02b +Author: Kamailio Dev +Date: Mon May 8 15:01:37 2023 +0200 - lib: Fix typos + modules: readme files regenerated - siptrace ... [skip ci] -commit 5dd8f0a6ff30fd3aa917a98b006106bef61506e5 -Author: Bastian Triller -Date: Thu May 5 18:21:23 2022 +0200 +commit b21362807d86aa1e84c32b24f36f5138cf22c51b +Author: Daniel-Constantin Mierla +Date: Mon May 8 14:48:29 2023 +0200 - core: Fix typos + siptrace: docs for sip_trace_msg() -commit e8bdf2b99de1ecfe8f276e2d9bed54e01588210b -Author: Bastian Triller -Date: Thu May 5 18:20:11 2022 +0200 +commit 5ec8c403e0a49ec752d5b10f330f53a97d625822 +Author: Daniel-Constantin Mierla +Date: Mon Apr 24 20:28:48 2023 +0200 - pkg: Fix typos + siptrace: reworked sip_trace_msg() to specify source and target addresses + + - implemented for hep mirroring only + - prototype: sip_trace_msg(data, saddr, taddr, duri, corrid) -commit 5497d15766d25625b4704a3bd3e884ef2f1149da -Author: Bastian Triller -Date: Thu May 5 18:19:21 2022 +0200 +commit 43e76ead36e9d09d462ebc0ba2fc88d06c4d9ac4 +Author: Daniel-Constantin Mierla +Date: Mon Apr 24 12:11:26 2023 +0200 - doc: Fix typos + siptrace: sip_trace_msg() exported with 3 parameters -commit 543cd8f897bc43d5fe1eb4c562d8351b32778209 +commit 7532e92bc45f35348a34f9e7bd39fc00db4118dd Author: Daniel-Constantin Mierla -Date: Fri May 6 13:50:13 2022 +0200 +Date: Fri Apr 21 21:55:02 2023 +0200 - ipops: add dns container in dns_update_pv() if not created before - - - dns context creation relied on using the dns variable in some way, the - main purpose of dns_update_pv() being to fill the variable, but one may - want to use it for testing only + siptrace; fix parameter inside sip_trace_msg() -commit 0f9a833fcc7cbc306a5d47413f6449ccc5a37f59 +commit b6d03564570839553bd0eeed28c06102bfa9fc46 Author: Daniel-Constantin Mierla -Date: Fri May 6 12:46:28 2022 +0200 +Date: Fri Apr 21 21:51:47 2023 +0200 - ipops: warning when too many dns containers are created + siptrace: added sip_trace_msg(dst, corlid, vmsg) + + - send sip trace with the message provided as parmameter -commit 33228bba33a6ea2e2d9a7acd9a240929223b9d39 -Author: Daniel-Constantin Mierla -Date: Thu May 5 19:52:11 2022 +0200 +commit f9cbe7ad01331e97852872c29b612409bf571c8d +Author: Victor Seva +Date: Thu May 4 21:46:22 2023 +0200 - db_berkeley: reset lkey to avoid double free + pkg/kamailio/deb: version set 5.8.0~dev0 [skip ci] -commit e310166a5c0c7d419e036315c1d105278db51e58 +commit c88e506fe6a1ba0f588c5866a63ffb18fa25478a Author: Victor Seva -Date: Thu May 5 12:50:11 2022 +0200 +Date: Thu May 4 20:12:32 2023 +0200 - pkg/kamailio/deb: version set 5.7.0~dev0 [skip ci] + lcr: fix crash be calling load_gw* via KEMI + + move the check of lcr_id to the helper + + fixes #3435 -commit 39431b8fd94f49e2ae5ee61109bf8e329a1c7c60 +commit 1c924f9bc9d880f9c32fe5cb4d23722f27107be6 Author: Daniel-Constantin Mierla -Date: Thu May 5 12:11:31 2022 +0200 +Date: Thu May 4 20:45:00 2023 +0200 - Makefile.defs: version set to 5.7.0-dev0 + Makefile.defs: version set to 5.8.0-dev0 - master branch is open for new features to be part of future release - series 5.7.x + series 5.8.x -===================== 2022-05-23 Version 5.6.0 Released ===================== + +===================== 2023-05-17 Version 5.7.0 Released ===================== diff --git a/INSTALL b/INSTALL index 5aeccba6d..6fd7dbfda 100644 --- a/INSTALL +++ b/INSTALL @@ -155,7 +155,7 @@ OS Notes: Solaris 10 ---------- - As above; you can use Solaris's yacc instead of bison. You might also + As above; you can use Solaris' yacc instead of bison. You might also need gtar and ginstall. If you don't have ginstall you can use Solaris install, just make sure it's in the PATH (it's usually in /usr/sbin) and add INSTALL=install either to the environment or to the make command line diff --git a/README b/README index a2e80a281..d6c537dac 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ -Kamailio v5.7 +Kamailio v5.8 ============= https://www.kamailio.org diff --git a/README.md b/README.md index f0a904a08..d06dd7a78 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![Build Status](https://github.com/kamailio/kamailio/actions/workflows/main.yml/badge.svg)](https://github.com/kamailio/kamailio/actions) [![Code Triage Badge](https://www.codetriage.com/kamailio/kamailio/badges/users.svg)](https://www.codetriage.com/kamailio/kamailio) +[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit) Project Website: @@ -100,13 +101,6 @@ For more information about the mailing lists, please see: * https://www.kamailio.org/w/mailing-lists/ -### IRC Channel - -An open IRC discussion channel is managed by the community: - - * irc server: irc.freenode.net - * irc channel: #kamailio - ### Matrix Channel An open Matrix discussion channel is managed by the community: @@ -121,9 +115,4 @@ News: * https://www.kamailio.org/w/category/news/ * Twitter @kamailio -## Travis-CI - Testing Build Environment - - * [travis-ci](https://travis-ci.org/kamailio/kamailio/builds/) - * [docker build](/test/travis/README.md) - **Thank you for flying Kamailio!** diff --git a/doc/docbook/catalog.xml b/doc/docbook/catalog.xml index 50f4fff69..fb18a5668 100644 --- a/doc/docbook/catalog.xml +++ b/doc/docbook/catalog.xml @@ -20,7 +20,7 @@ + documents being processed (they usually contain HTTP URIs). --> diff --git a/doc/docbook/dep.xsl b/doc/docbook/dep.xsl index f65480ddc..af4b5ab03 100644 --- a/doc/docbook/dep.xsl +++ b/doc/docbook/dep.xsl @@ -66,7 +66,7 @@ in this step. --> - + diff --git a/doc/docbook/entities.xml b/doc/docbook/entities.xml index c91f4dd56..5734b4c31 100644 --- a/doc/docbook/entities.xml +++ b/doc/docbook/entities.xml @@ -19,9 +19,9 @@ - - - + + + &kamailiohome;"> @@ -54,8 +54,8 @@ - - + + &serhome;"> &serbugs;"> diff --git a/doc/docbook/html.chunked.xsl b/doc/docbook/html.chunked.xsl index c80e73433..4f291e5d8 100644 --- a/doc/docbook/html.chunked.xsl +++ b/doc/docbook/html.chunked.xsl @@ -5,7 +5,7 @@ - + diff --git a/doc/doxygen/main.dox b/doc/doxygen/main.dox index 5bf7286c9..c509f724e 100644 --- a/doc/doxygen/main.dox +++ b/doc/doxygen/main.dox @@ -16,7 +16,7 @@ * The documentation can be generated using doxygen by running "make doxygen" * * \section Other information - * If you want other informaiton about Kamailio, please visit http://www.kamailio.org + * If you want other information about Kamailio, please visit https://www.kamailio.org * * \section License Kamailio license * Kamailio is free software; you can redistribute it and/or modify diff --git a/doc/man/kamailio.cfg.5 b/doc/man/kamailio.cfg.5 index 25e0bf305..6a25829fd 100644 --- a/doc/man/kamailio.cfg.5 +++ b/doc/man/kamailio.cfg.5 @@ -36,7 +36,7 @@ see .PP Full documentation on kamailio, including configuration guidelines, FAQs and licensing conditions, is available at -.I http://kamailio.org. +.I https://kamailio.org. .PP For reporting bugs see .I diff --git a/doc/misc/HISTORY b/doc/misc/HISTORY index 464aceba7..398d438aa 100644 --- a/doc/misc/HISTORY +++ b/doc/misc/HISTORY @@ -6,7 +6,7 @@ This is a short ser history based mainly on my memory and my old mail archive. I've tried to mention only the important events. I'm sure I have missed a lot of things and/or people. If this is your case, please don't feel offended, send me an email and I will straighten things up. -Three years ago on 4 September 2001 I committed the first working ser version on a private cvs. In fact I started writting ser 2 days before, on 2nd September. +Three years ago on 4 September 2001 I committed the first working ser version on a private cvs. In fact I started writing ser 2 days before, on 2nd September. I was supposed to write some kind of sip glue for a Cisco PSTN gateway in 1 week, but of course I did it in the last 2 days :-) At that time the config looked like: @@ -20,7 +20,7 @@ At that time the config looked like: A short time after this Jiri began testing the code and requesting new features.2 weeks later I completely changed the config format bringing it pretty close to what we have today. At the time Jiri stronlgy disagreed with the ideea arguing that the new config would increase code complexity too much and would severely impact performance. The final argument was: I already wrote the code and it works :-) -In Octomber 2001 I made some changes to ser routing language bringing it to what we still use today. +In October 2001 I made some changes to ser routing language bringing it to what we still use today. In the next months I've created the module interface, the first two modules (print and textops) and I've added the shared memory support (this involved the creation of ser's own malloc library which proved to be much faster for ser's memory usage patterns than standards malloc implementations). During the same period Bogdan and Jan joined me and Jiri also began writing code. In December 2001 Bogdan announced that tm was up and running (after a sleepless night). @@ -28,12 +28,12 @@ At the beginning of 2002 we were joined by Daniel. Jan introduced the mysql, usr Ser first public appearance was at the April 2002 Sipit. We ran it on a pda an still managed to be faster than the testing tools that were used against us :-) In May 2002 ser got ipv6 support. -In August 2002 Nils commited sipsak to berlios (very useful testing tool). +In August 2002 Nils committed sipsak to berlios (very useful testing tool). In September 2002 ser went public: it was GPL'ed and the cvs tree was moved to berlios. During the same month Jiri introduced the FIFO interface, Karel committed serweb and we had the first GPL'ed release: ser 0.8.8. In December 2002 ser got its first big external contribution: the enum module, written by Juha Heinanen. -In January 2003 Raphael commited sems on berlios. +In January 2003 Raphael committed sems on berlios. In February 2003 ser got tcp support. Sometime during the 2003 spring ser got the permissions module from Miklos Tirpak and nathelper from Maxim Sobolev. -In August 2003, Uli commited isdngw to sems. +In August 2003, Uli committed isdngw to sems. All the rest is too new to be in the history :-) diff --git a/doc/misc/NEWS b/doc/misc/NEWS index 755d4c861..9627916dd 100644 --- a/doc/misc/NEWS +++ b/doc/misc/NEWS @@ -69,7 +69,7 @@ new config variables: udp4_raw can be used on Linux and FreeBSD. For other BSDs and Darwin one must compile with -DUSE_RAW_SOCKS. On Linux one should also set udp4_raw_mtu if the MTU on any network - interface that could be used for sending is smaller then 1500. + interface that could be used for sending is smaller than 1500. Can be set at runtime as long as sr was started with enough privileges (core.udp4_raw). - udp4_raw_mtu - MTU value used for UDP IPv4 packets when udp4_raw is @@ -215,7 +215,7 @@ core: defined expr - returns true if expr is defined, and false if not. Note: only a standalone avp or pvar can be undefined, everything else is defined. - strlen(expr) - returns the lenght of expr evaluated as string. + strlen(expr) - returns the length of expr evaluated as string. strempty(expr) - returns true if expr evaluates to the empty string (equivalent to expr==""). e.g.: if (defined $v && !strempty($v)) $len=strlen($v); @@ -374,7 +374,7 @@ modules: - t_relay_to renamed to t_relay_to_avp (undocumented function) - t_relay() can now also take host and port parameters (e.g. t_relay(host, port)), behaving like a statefull - forwad(host, port) version (forward to host:port using the same + forward(host, port) version (forward to host:port using the same protocol on which the message was received) - t_relay_to_udp(), t_relay_to_tcp() and t_relay_to_tls() work now even with no parameters: in this case the message is @@ -400,7 +400,7 @@ modules: reply arrives on such a branch - noisy_ctimer is now 1 (on) by default - added maximum transaction lifetime - a transaction is not - allowed to be active longer then this interval. See + allowed to be active longer than this interval. See t_set_max_lifetime(), max_inv_lifetime and max_noninv_lifetime. - support for changing the retransmission intervals on the fly, on a per transaction basis (it is enabled if tm is compiled @@ -497,7 +497,7 @@ core: (can be changed at runtime, e.g. sercmd cfg.set_now_int tcp connection_lifetime 180 ) - fallback to tcp or other congestion controlled transport - protocol if a forwarded udp sip request is greater then + protocol if a forwarded udp sip request is greater than udp_mtu (config). Default off. See udp_mtu and udp_mtu_try_proto. - sctp support (one-to-many, work in progress, for now linux @@ -528,7 +528,7 @@ new config variables: maximum datagram size that can be received over tcp. Default: 4096, can be changed at runtime. tcp_wq_blk_size = block size used for tcp async writes. It should be big - enough to hold a few datagrams. If it's smaller then a + enough to hold a few datagrams. If it's smaller than a datagram (in fact a tcp write()) size, it will be rounded up. It has no influenced on the number of datagrams queued (for that see tcp_conn_wq_max or tcp_wq_max). @@ -539,7 +539,7 @@ new config variables: Default: no, can be changed at runtime. udp_mtu = number - fallback to another protocol (udp_mtu_try_proto must be set also either globally or per packet) if the constructed - request size is greater then udp_mtu. + request size is greater than udp_mtu. Recommended size: 1300. Default: 0 (off). udp_mtu_try_proto = TCP|TLS|SCTP|UDP - if udp_mtu !=0 and udp forwarded request size (after adding all the "local" headers) > @@ -618,17 +618,17 @@ new config variables: associations. sctp_srto_max = milliseconds - maximum value of the retransmission timeout (RTO) (default: OS specific). - WARNING: values lower then the sctp sack_delay will cause lots of + WARNING: values lower than the sctp sack_delay will cause lots of retransmissions and connection instability (see sctp_srto_min for more details). Can be changed at runtime (sctp srto_max) but it will affect only new associations. sctp_srto_min = milliseconds - minimum value of the retransmission timeout (RTO) (default: OS specific). - WARNING: values lower then the sctp sack_delay of any peer might cause + WARNING: values lower than the sctp sack_delay of any peer might cause retransmissions and possible interoperability problems. According to the standard the sack_delay should be between 200 and 500 ms, so avoid trying - values lower then 500 ms unless you control all the possible sctp peers + values lower than 500 ms unless you control all the possible sctp peers and you do make sure their sack_delay is higher or their sack_freq is 1. Can be changed at runtime (sctp srto_min) but it will affect only new associations. @@ -653,8 +653,8 @@ new config variables: associations. sctp_sack_delay = milliseconds - delay until an ACK is generated after receiving a packet. Default: OS specific. - WARNING: a value higher then srto_min can cause a lot of retransmissions - (and strange problems). A value higher then srto_max will result in very + WARNING: a value higher than srto_min can cause a lot of retransmissions + (and strange problems). A value higher than srto_max will result in very high connections instability. According to the standard the sack_delay value should be between 200 and 500 ms. Can be changed at runtime (sctp sack_delay) but it will affect only new @@ -891,7 +891,7 @@ core: - default log level switched to 0 (only messages < L_WARN will be printed by default) - separate memdbg log level which controls the memory/malloc related - debug messages (to see them ser must be compiled with malloc debuging: + debug messages (to see them ser must be compiled with malloc debugging: -DDBG_QM_MALLOC or -DDBG_FM_MALLOC and memdbg must be <= debug ) - added named routes: names can be used instead of numbers in all the route commads or route declarations. route(number) is equivalent to @@ -915,7 +915,7 @@ core: a route reaches its end without executing a return statement, it returns 1. If return is used in the top level route is equivalent with exit [val]. - drop /exit [n] now will end the script execution - exit n will exit with code n (usefull in onreply/onsend routes where + exit n will exit with code n (useful in onreply/onsend routes where if script code !=0 a reply is generated/the message is sent or to force script errors) - added $? which can be used to check the return code of the last executed @@ -956,14 +956,14 @@ core: (see below dns_* and man resolv.conf(6)). The maximum time a dns request can take (before failing) is: (dns_retr_time*dns_retr_no)*(search_list_domains) - If dns_try_ipv6 is yes, mutliply it again by 2. + If dns_try_ipv6 is yes, multiply it again by 2. The fastest possible dns config (max 1s): dns_try_ipv6=no dns_retr_time=1 dns_retr_no=1 dns_use_search_list=no - default on reply route added: onreply_route {.. } will add a default - onreply route that will be executed for any reply (usefull to catch + onreply route that will be executed for any reply (useful to catch replies without using tm) - branch_routes added (tm triggered), only a very limited number of commands are available (see tm docs) @@ -1013,7 +1013,7 @@ new config variables: fact search "" (so even if the search list is empty/missing there will still be 2 dns queries, eg. foo+'.' and foo+""+'.') tcp_connection_lifetime = value (s) - how long the lifetime of a - tcp connection will be exteneded after an IO event (accept, connect, + tcp connection will be extended after an IO event (accept, connect, read, write). Default: 120 s. tcp_poll_method = poll|select|sigio_rt|epoll_et|epoll-lt|kqueue|devpoll - poll method used (by default the best one for the current OS is selected) @@ -1040,7 +1040,7 @@ WARNING: - older 0.10.99-dev version (< 0.10.99-dev46) returned a 480 reply general: - gcc 4.0 support - - mutlicast options are set for all the sockets + - multicast options are set for all the sockets - mediaproxy: memory leak, unchecked memory allocations - postgress: some bugs and cleanups (compiles cleanly now) - tm: shm cloned lumps (SER-55) @@ -1084,7 +1084,7 @@ modules: - TM has a new parameter: restart_fr_on_each_reply. If set (default) fr_inv timer will be restarted for each provisional reply, if not set it will be restarted only for the first reply and for replies >=180 - (but only if increasing, eg.: 180, 181 ...). Usefull when dealing with bad + (but only if increasing, eg.: 180, 181 ...). Useful when dealing with bad UAs that re-transmit 180s. - TM saves the avp list into transactions, and make it available into callbacks, failure and reply routes. @@ -1096,7 +1096,7 @@ modules: email value from DB (as VM), TM looks for the "email" attribute to get the value. vm() function was replaced with t_write_req() - vm_reply() fifo functions was replcated by TM with t_reply() fifo function + vm_reply() fifo functions was replaced by TM with t_reply() fifo function NOTE!! because current version of SEMS/AA try to send reply via vm_reply, it will not work with the TM version. - xlog - printing the body of any header by specifying the name; new @@ -1106,7 +1106,7 @@ modules: new modules: - avp / avp_db / avp_radius - load and check avps per caller or callee - avpops - flexible module for operations with avps and database, introducing - a pseudo-varible support in SER configuration file + a pseudo-variable support in SER configuration file - cpl-c - implementation of Call Processing Language - dispatcher - implements a dispatcher for incoming requests using hashes over parts of the request to select the destination @@ -1143,7 +1143,7 @@ core: - avp (Attribute-Value Pair) support added - avp alias support added - multicast support added (see mcast_loopback & mcast_ttl) - - saving of procces group id enabled, if the -G option is specified + - saving of process group id enabled, if the -G option is specified (a safe way to quickly kill all ser processes) - core dump-ing is enabled by default, see also disable_core_dump - protocol and port can be specified in the alias and listen lines, e.g.: @@ -1196,7 +1196,7 @@ core: log_facility = LOG_LOCAL0 if ser logs to syslog, you can control the facility for logging. Very useful when you want to divert all ser logs to a different log file. - See man page syslog(3) for more detailes. + See man page syslog(3) for more details. unix_sock = "/tmp/ser.sock" The name of the socket the unixsock server should listen on. unix_sock_children = 1 @@ -1212,7 +1212,7 @@ core: force_tcp_alias() force_tcp_alias(port) adds a tcp port alias for the current connection (if tcp). - Usefull if you want to send all the trafic to port_alias through + Useful if you want to send all the traffic to port_alias through the same connection this request came from [it could help for firewall or nat traversal]. With no parameters adds the port from the message via as the alias. @@ -1288,7 +1288,7 @@ auth_db: Bug fixes ========= - memory leak in digest credentials parser fixed -- authenticathion ha1 didn't include domain if username was of the form +- authentication ha1 didn't include domain if username was of the form user@domain and calculate_ha1 was set to yes (modules/auth_db) - tm reply processing race condition (modules/tm), special thanks go to Dong Liu @@ -1355,7 +1355,7 @@ Changes to use of ser scripts About Multiple Transport Support -------------------------------- -SER now suports multiple transport protocols: UDP and TCP. As there +SER now supports multiple transport protocols: UDP and TCP. As there may be UAs which support only either protocol and cannot speak to each other directly, we recommend to alway record-route SIP requests, to keep the transport-translating SER in path. Also, if a destination @@ -1390,7 +1390,7 @@ auth module: authentication - auth_radius contains functions needed for radius authentication - group module contains group membership checking functions -- group_radius contains radius group membeship checking functions +- group_radius contains radius group membership checking functions - is_in_group has been renamed to is_user_in and places to groups module - check_to and check_from have been moved to the uri module @@ -1404,7 +1404,7 @@ exec module: ------------ - exec_uri and exec_user have been obsoleted by exec_dset; exec_dset is identical to exec_uri in capabilities; it - additionaly passes content of request elements (header + additionally passes content of request elements (header fields and URI parts) in environment variables; users of exec_user can use exec_dset now and use the "URI_USER" variable to learn user part of URI @@ -1444,7 +1444,7 @@ rr module: - a new option, "enable_full_lr" can be set to make life with misimplemented UAs easier and put LR in from "lr=on" - rr module can insert two Record-Route header fields when - necesarry (disconnected networks, UDP->TCP and so on) + necessary (disconnected networks, UDP->TCP and so on) tm module: ---------- diff --git a/doc/misc/TODO b/doc/misc/TODO index 9f5c6beb7..ba6ab6868 100644 --- a/doc/misc/TODO +++ b/doc/misc/TODO @@ -21,7 +21,7 @@ x [mem] investigate: keep an used/unused flag per fragment, on free check if neighboring frags were not used and if so defragment - [timer] multiple timers? at least ticks should no be affected by the amount of work done in the timer handlers -- [tcp] ser intiated tcp connections use INADDR_ANY (they should be bound first +- [tcp] ser initiated tcp connections use INADDR_ANY (they should be bound first to some ip/port ?function of the dest?) - [tcp] need to confirm fd receipt after send_fd, before closing it (this might happen in tcp_send new conn.) (see FreeBSD send BUGS for more info) @@ -65,7 +65,7 @@ x extend listen and alias to include port numbers and protocol: tcp foo.bar:5063, udp foo.bar:5062, foo2.bar x added set_advertised_{address,port} -- was: add force_via, force_srcip a.s.o (the advertised addresses should be overwritable from the script). -x ? add force_outbound_socket(ip)? (choose an apropriate socket from the +x ? add force_outbound_socket(ip)? (choose an appropriate socket from the listen list for sending the msg; works on udp only) release: @@ -102,7 +102,7 @@ not so critical: x replace remaining mallocs/frees at least in msg_translator.c - add $(INCLUDES) to the Makefiles x make ser suncc ready -- fix parse_cseq!!! (it doesnt parse 1234\n INVITE a.s.o) +- fix parse_cseq!!! (it doesn't parse 1234\n INVITE a.s.o) x fix 0 parameter module f. call x better Via parsing (handle ' ' in uri, eg: foo.bar : 1234 ; received=) and ipv6 addresses ([fec0:aa::01]). @@ -148,7 +148,7 @@ x command line switch for checking the config file syntax - config file version (a la sendmail) 0 loop detection - cfg. file reload -- flags for using names or ip adresses in Via ? +- flags for using names or ip addresses in Via ? - escape char injection/printing fix (verify all log/printed messages for terminal escapes and remove them) @@ -202,7 +202,7 @@ tm optimizations: - inline/macro/drop for: get_tm_table, set_kr, lock_hash, unlock_hash, set_t, get_t - replace snprintfs int build_uac_request, *_dlg -- fix the huge param no. in this functions (use structs if neccessary): +- fix the huge param no. in this functions (use structs if necessary): build_uac_request, build_uac_request_dlg, t_uac, t_uac_dlg - uri2proxy - t_uac_dlg => extra malloc/free (no roxy needed here) diff --git a/doc/misc/cvs-commit-rules.txt b/doc/misc/cvs-commit-rules.txt index b5153e40c..b13738550 100644 --- a/doc/misc/cvs-commit-rules.txt +++ b/doc/misc/cvs-commit-rules.txt @@ -3,8 +3,8 @@ Kamailio git commit rules 1. Changing other people's code: -------------------------------- - - send a patch to the code/module mantainer and/or sr-dev - (don't commit changes to code you don't own if you don't have the mantainer's approval) + - send a patch to the code/module maintainer and/or sr-dev + (don't commit changes to code you don't own if you don't have the maintainer's approval) Exceptions: a. compilation (this includes warning) fixes b. bug fixes @@ -25,4 +25,4 @@ Exceptions: linux, freebsd, netbsd, openbsd, solaris >= 8; x86, ultrasparc, strongarm; gcc 4.x, icc, sun cc >=5.3). It should also compile on gcc 2.95 and 3.x. - the code must be tested or the change trivial enough - - the code should compile without warnings on all the arhitectures (with some exceptions) + - the code should compile without warnings on all the architectures (with some exceptions) diff --git a/doc/scripts/cdefs2doc/dump_cfg_defs.pl b/doc/scripts/cdefs2doc/dump_cfg_defs.pl index b1517dca1..a95dda326 100755 --- a/doc/scripts/cdefs2doc/dump_cfg_defs.pl +++ b/doc/scripts/cdefs2doc/dump_cfg_defs.pl @@ -49,7 +49,7 @@ my $patch_required="$0 requires a patched GCC:TranslationUnit, see the " . # gcc name my $gcc="gcc"; # default defines -my $c_defs="DNAME='\"kamailio\"' -DVERSION='\"5.1.0-dev3\"' -DARCH='\"x86_64\"' -DOS='linux_' -DOS_QUOTED='\"linux\"' -DCOMPILER='\"gcc 4.9.2\"' -D__CPU_x86_64 -D__OS_linux -DSER_VER=5001000 -DCFG_DIR='\"/usr/local/etc/kamailio/\"' -DRUN_DIR='\"/run/kamailio/\"' -DPKG_MALLOC -DSHM_MEM -DSHM_MMAP -DDNS_IP_HACK -DUSE_MCAST -DUSE_TCP -DDISABLE_NAGLE -DHAVE_RESOLV_RES -DUSE_DNS_CACHE -DUSE_DNS_FAILOVER -DUSE_DST_BLOCKLIST -DUSE_NAPTR -DWITH_XAVP -DMEM_JOIN_FREE -DF_MALLOC -DQ_MALLOC -DTLSF_MALLOC -DDBG_SR_MEMORY -DUSE_TLS -DTLS_HOOKS -DUSE_CORE_STATS -DSTATISTICS -DMALLOC_STATS -DWITH_AS_SUPPORT -DUSE_SCTP -DFAST_LOCK -DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=1024 -DCC_GCC_LIKE_ASM -DHAVE_GETHOSTBYNAME2 -DHAVE_UNION_SEMUN -DHAVE_SCHED_YIELD -DHAVE_MSG_NOSIGNAL -DHAVE_MSGHDR_MSG_CONTROL -DHAVE_ALLOCA_H -DHAVE_TIMEGM -DHAVE_SCHED_SETSCHEDULER -DHAVE_IP_MREQN -DHAVE_EPOLL -DHAVE_SIGIO_RT -DSIGINFO64_WORKAROUND -DUSE_FUTEX -DHAVE_SELECT"; +my $c_defs="DNAME='\"kamailio\"' -DVERSION='\"5.1.0-dev3\"' -DARCH='\"x86_64\"' -DOS='linux_' -DOS_QUOTED='\"linux\"' -DCOMPILER='\"gcc 4.9.2\"' -D__CPU_x86_64 -D__OS_linux -DSER_VER=5001000 -DCFG_DIR='\"/usr/local/etc/kamailio/\"' -DRUN_DIR='\"/run/kamailio/\"' -DPKG_MALLOC -DSHM_MEM -DSHM_MMAP -DDNS_IP_HACK -DUSE_MCAST -DUSE_TCP -DDISABLE_NAGLE -DHAVE_RESOLV_RES -DUSE_DNS_CACHE -DUSE_DNS_FAILOVER -DUSE_DST_BLOCKLIST -DUSE_NAPT -DMEM_JOIN_FREE -DF_MALLOC -DQ_MALLOC -DTLSF_MALLOC -DDBG_SR_MEMORY -DUSE_TLS -DTLS_HOOKS -DUSE_CORE_STATS -DSTATISTICS -DMALLOC_STATS -DWITH_AS_SUPPORT -DUSE_SCTP -DFAST_LOCK -DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=1024 -DCC_GCC_LIKE_ASM -DHAVE_GETHOSTBYNAME2 -DHAVE_UNION_SEMUN -DHAVE_SCHED_YIELD -DHAVE_MSG_NOSIGNAL -DHAVE_MSGHDR_MSG_CONTROL -DHAVE_ALLOCA_H -DHAVE_TIMEGM -DHAVE_SCHED_SETSCHEDULER -DHAVE_IP_MREQN -DHAVE_EPOLL -DHAVE_SIGIO_RT -DSIGINFO64_WORKAROUND -DUSE_FUTEX -DHAVE_SELECT"; # file with gcc syntax tree my $file; #"tcp_options.c.001t.tu" ; diff --git a/doc/scripts/cdefs2doc/dump_counters.pl b/doc/scripts/cdefs2doc/dump_counters.pl index 1ddfa29e7..fc2ae9b08 100755 --- a/doc/scripts/cdefs2doc/dump_counters.pl +++ b/doc/scripts/cdefs2doc/dump_counters.pl @@ -39,7 +39,7 @@ my $patch_required="$0 requires a patched GCC:TranslationUnit, see the " . # gcc name my $gcc="gcc"; # default defines -my $c_defs="DNAME='\"kamailio\"' -DVERSION='\"5.1.0-dev3\"' -DARCH='\"x86_64\"' -DOS='linux_' -DOS_QUOTED='\"linux\"' -DCOMPILER='\"gcc 4.9.2\"' -D__CPU_x86_64 -D__OS_linux -DSER_VER=5001000 -DCFG_DIR='\"/usr/local/etc/kamailio/\"' -DRUN_DIR='\"/run/kamailio/\"' -DPKG_MALLOC -DSHM_MEM -DSHM_MMAP -DDNS_IP_HACK -DUSE_MCAST -DUSE_TCP -DDISABLE_NAGLE -DHAVE_RESOLV_RES -DUSE_DNS_CACHE -DUSE_DNS_FAILOVER -DUSE_DST_BLOCKLIST -DUSE_NAPTR -DWITH_XAVP -DMEM_JOIN_FREE -DF_MALLOC -DQ_MALLOC -DTLSF_MALLOC -DDBG_SR_MEMORY -DUSE_TLS -DTLS_HOOKS -DUSE_CORE_STATS -DSTATISTICS -DMALLOC_STATS -DWITH_AS_SUPPORT -DUSE_SCTP -DFAST_LOCK -DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=1024 -DCC_GCC_LIKE_ASM -DHAVE_GETHOSTBYNAME2 -DHAVE_UNION_SEMUN -DHAVE_SCHED_YIELD -DHAVE_MSG_NOSIGNAL -DHAVE_MSGHDR_MSG_CONTROL -DHAVE_ALLOCA_H -DHAVE_TIMEGM -DHAVE_SCHED_SETSCHEDULER -DHAVE_IP_MREQN -DHAVE_EPOLL -DHAVE_SIGIO_RT -DSIGINFO64_WORKAROUND -DUSE_FUTEX -DHAVE_SELECT"; +my $c_defs="DNAME='\"kamailio\"' -DVERSION='\"5.1.0-dev3\"' -DARCH='\"x86_64\"' -DOS='linux_' -DOS_QUOTED='\"linux\"' -DCOMPILER='\"gcc 4.9.2\"' -D__CPU_x86_64 -D__OS_linux -DSER_VER=5001000 -DCFG_DIR='\"/usr/local/etc/kamailio/\"' -DRUN_DIR='\"/run/kamailio/\"' -DPKG_MALLOC -DSHM_MEM -DSHM_MMAP -DDNS_IP_HACK -DUSE_MCAST -DUSE_TCP -DDISABLE_NAGLE -DHAVE_RESOLV_RES -DUSE_DNS_CACHE -DUSE_DNS_FAILOVER -DUSE_DST_BLOCKLIST -DUSE_NAPT -DMEM_JOIN_FREE -DF_MALLOC -DQ_MALLOC -DTLSF_MALLOC -DDBG_SR_MEMORY -DUSE_TLS -DTLS_HOOKS -DUSE_CORE_STATS -DSTATISTICS -DMALLOC_STATS -DWITH_AS_SUPPORT -DUSE_SCTP -DFAST_LOCK -DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=1024 -DCC_GCC_LIKE_ASM -DHAVE_GETHOSTBYNAME2 -DHAVE_UNION_SEMUN -DHAVE_SCHED_YIELD -DHAVE_MSG_NOSIGNAL -DHAVE_MSGHDR_MSG_CONTROL -DHAVE_ALLOCA_H -DHAVE_TIMEGM -DHAVE_SCHED_SETSCHEDULER -DHAVE_IP_MREQN -DHAVE_EPOLL -DHAVE_SIGIO_RT -DSIGINFO64_WORKAROUND -DUSE_FUTEX -DHAVE_SELECT"; # file with gcc syntax tree my $file; #"tcp_options.c.001t.tu" ; diff --git a/doc/scripts/cdefs2doc/dump_rpcs.pl b/doc/scripts/cdefs2doc/dump_rpcs.pl index 80cfe807d..8081cbca4 100755 --- a/doc/scripts/cdefs2doc/dump_rpcs.pl +++ b/doc/scripts/cdefs2doc/dump_rpcs.pl @@ -43,7 +43,7 @@ my $patch_required="$0 requires a patched GCC:TranslationUnit, see the " . # gcc name my $gcc="gcc"; # default defines -my $c_defs="DNAME='\"kamailio\"' -DVERSION='\"5.1.0-dev3\"' -DARCH='\"x86_64\"' -DOS='linux_' -DOS_QUOTED='\"linux\"' -DCOMPILER='\"gcc 4.9.2\"' -D__CPU_x86_64 -D__OS_linux -DSER_VER=5001000 -DCFG_DIR='\"/usr/local/etc/kamailio/\"' -DRUN_DIR='\"/run/kamailio/\"' -DPKG_MALLOC -DSHM_MEM -DSHM_MMAP -DDNS_IP_HACK -DUSE_MCAST -DUSE_TCP -DDISABLE_NAGLE -DHAVE_RESOLV_RES -DUSE_DNS_CACHE -DUSE_DNS_FAILOVER -DUSE_DST_BLOCKLIST -DUSE_NAPTR -DWITH_XAVP -DMEM_JOIN_FREE -DF_MALLOC -DQ_MALLOC -DTLSF_MALLOC -DDBG_SR_MEMORY -DUSE_TLS -DTLS_HOOKS -DUSE_CORE_STATS -DSTATISTICS -DMALLOC_STATS -DWITH_AS_SUPPORT -DUSE_SCTP -DFAST_LOCK -DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=1024 -DCC_GCC_LIKE_ASM -DHAVE_GETHOSTBYNAME2 -DHAVE_UNION_SEMUN -DHAVE_SCHED_YIELD -DHAVE_MSG_NOSIGNAL -DHAVE_MSGHDR_MSG_CONTROL -DHAVE_ALLOCA_H -DHAVE_TIMEGM -DHAVE_SCHED_SETSCHEDULER -DHAVE_IP_MREQN -DHAVE_EPOLL -DHAVE_SIGIO_RT -DSIGINFO64_WORKAROUND -DUSE_FUTEX -DHAVE_SELECT"; +my $c_defs="DNAME='\"kamailio\"' -DVERSION='\"5.1.0-dev3\"' -DARCH='\"x86_64\"' -DOS='linux_' -DOS_QUOTED='\"linux\"' -DCOMPILER='\"gcc 4.9.2\"' -D__CPU_x86_64 -D__OS_linux -DSER_VER=5001000 -DCFG_DIR='\"/usr/local/etc/kamailio/\"' -DRUN_DIR='\"/run/kamailio/\"' -DPKG_MALLOC -DSHM_MEM -DSHM_MMAP -DDNS_IP_HACK -DUSE_MCAST -DUSE_TCP -DDISABLE_NAGLE -DHAVE_RESOLV_RES -DUSE_DNS_CACHE -DUSE_DNS_FAILOVER -DUSE_DST_BLOCKLIST -DUSE_NAPTR -DMEM_JOIN_FREE -DF_MALLOC -DQ_MALLOC -DTLSF_MALLOC -DDBG_SR_MEMORY -DUSE_TLS -DTLS_HOOKS -DUSE_CORE_STATS -DSTATISTICS -DMALLOC_STATS -DWITH_AS_SUPPORT -DUSE_SCTP -DFAST_LOCK -DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=1024 -DCC_GCC_LIKE_ASM -DHAVE_GETHOSTBYNAME2 -DHAVE_UNION_SEMUN -DHAVE_SCHED_YIELD -DHAVE_MSG_NOSIGNAL -DHAVE_MSGHDR_MSG_CONTROL -DHAVE_ALLOCA_H -DHAVE_TIMEGM -DHAVE_SCHED_SETSCHEDULER -DHAVE_IP_MREQN -DHAVE_EPOLL -DHAVE_SIGIO_RT -DSIGINFO64_WORKAROUND -DUSE_FUTEX -DHAVE_SELECT"; # file with gcc syntax tree my $file; diff --git a/doc/scripts/cdefs2doc/dump_selects.pl b/doc/scripts/cdefs2doc/dump_selects.pl index b48f76bbb..c7dbaa186 100755 --- a/doc/scripts/cdefs2doc/dump_selects.pl +++ b/doc/scripts/cdefs2doc/dump_selects.pl @@ -40,7 +40,7 @@ my $patch_required="$0 requires a patched GCC:TranslationUnit, see the " . # gcc name my $gcc="gcc"; # default defines -my $c_defs="DNAME='\"kamailio\"' -DVERSION='\"5.1.0-dev3\"' -DARCH='\"x86_64\"' -DOS='linux_' -DOS_QUOTED='\"linux\"' -DCOMPILER='\"gcc 4.9.2\"' -D__CPU_x86_64 -D__OS_linux -DSER_VER=5001000 -DCFG_DIR='\"/usr/local/etc/kamailio/\"' -DRUN_DIR='\"/run/kamailio/\"' -DPKG_MALLOC -DSHM_MEM -DSHM_MMAP -DDNS_IP_HACK -DUSE_MCAST -DUSE_TCP -DDISABLE_NAGLE -DHAVE_RESOLV_RES -DUSE_DNS_CACHE -DUSE_DNS_FAILOVER -DUSE_DST_BLOCKLIST -DUSE_NAPTR -DWITH_XAVP -DMEM_JOIN_FREE -DF_MALLOC -DQ_MALLOC -DTLSF_MALLOC -DDBG_SR_MEMORY -DUSE_TLS -DTLS_HOOKS -DUSE_CORE_STATS -DSTATISTICS -DMALLOC_STATS -DWITH_AS_SUPPORT -DUSE_SCTP -DFAST_LOCK -DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=1024 -DCC_GCC_LIKE_ASM -DHAVE_GETHOSTBYNAME2 -DHAVE_UNION_SEMUN -DHAVE_SCHED_YIELD -DHAVE_MSG_NOSIGNAL -DHAVE_MSGHDR_MSG_CONTROL -DHAVE_ALLOCA_H -DHAVE_TIMEGM -DHAVE_SCHED_SETSCHEDULER -DHAVE_IP_MREQN -DHAVE_EPOLL -DHAVE_SIGIO_RT -DSIGINFO64_WORKAROUND -DUSE_FUTEX -DHAVE_SELECT"; +my $c_defs="DNAME='\"kamailio\"' -DVERSION='\"5.1.0-dev3\"' -DARCH='\"x86_64\"' -DOS='linux_' -DOS_QUOTED='\"linux\"' -DCOMPILER='\"gcc 4.9.2\"' -D__CPU_x86_64 -D__OS_linux -DSER_VER=5001000 -DCFG_DIR='\"/usr/local/etc/kamailio/\"' -DRUN_DIR='\"/run/kamailio/\"' -DPKG_MALLOC -DSHM_MEM -DSHM_MMAP -DDNS_IP_HACK -DUSE_MCAST -DUSE_TCP -DDISABLE_NAGLE -DHAVE_RESOLV_RES -DUSE_DNS_CACHE -DUSE_DNS_FAILOVER -DUSE_DST_BLOCKLIST -DUSE_NAPT -DMEM_JOIN_FREE -DF_MALLOC -DQ_MALLOC -DTLSF_MALLOC -DDBG_SR_MEMORY -DUSE_TLS -DTLS_HOOKS -DUSE_CORE_STATS -DSTATISTICS -DMALLOC_STATS -DWITH_AS_SUPPORT -DUSE_SCTP -DFAST_LOCK -DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=1024 -DCC_GCC_LIKE_ASM -DHAVE_GETHOSTBYNAME2 -DHAVE_UNION_SEMUN -DHAVE_SCHED_YIELD -DHAVE_MSG_NOSIGNAL -DHAVE_MSGHDR_MSG_CONTROL -DHAVE_ALLOCA_H -DHAVE_TIMEGM -DHAVE_SCHED_SETSCHEDULER -DHAVE_IP_MREQN -DHAVE_EPOLL -DHAVE_SIGIO_RT -DSIGINFO64_WORKAROUND -DUSE_FUTEX -DHAVE_SELECT"; # file with gcc syntax tree my $file; diff --git a/doc/stylesheets/dbschema_k/catalog.xml b/doc/stylesheets/dbschema_k/catalog.xml index 636d69d2f..f95a2ea0f 100644 --- a/doc/stylesheets/dbschema_k/catalog.xml +++ b/doc/stylesheets/dbschema_k/catalog.xml @@ -64,7 +64,7 @@ diff --git a/doc/stylesheets/dbschema_k/xsl/db_berkeley.xsl b/doc/stylesheets/dbschema_k/xsl/db_berkeley.xsl index b7a1a7f46..ce140021f 100644 --- a/doc/stylesheets/dbschema_k/xsl/db_berkeley.xsl +++ b/doc/stylesheets/dbschema_k/xsl/db_berkeley.xsl @@ -114,8 +114,8 @@ + But it is not possible (at least with XSL 1.0, AFAIK) to append data to a + file. So it's much easier to do this in the Makefile --> diff --git a/doc/stylesheets/dbschema_k/xsl/db_redis.xsl b/doc/stylesheets/dbschema_k/xsl/db_redis.xsl index 0c202b0dc..1fe347a0a 100644 --- a/doc/stylesheets/dbschema_k/xsl/db_redis.xsl +++ b/doc/stylesheets/dbschema_k/xsl/db_redis.xsl @@ -46,8 +46,8 @@ + But it is not possible (at least with XSL 1.0, AFAIK) to append data to a + file. So it's much easier to do this in the Makefile --> diff --git a/doc/stylesheets/dbschema_k/xsl/dbtext.xsl b/doc/stylesheets/dbschema_k/xsl/dbtext.xsl index 29c4b4da7..66d17e957 100644 --- a/doc/stylesheets/dbschema_k/xsl/dbtext.xsl +++ b/doc/stylesheets/dbschema_k/xsl/dbtext.xsl @@ -46,8 +46,8 @@ + But it is not possible (at least with XSL 1.0, AFAIK) to append data to a + file. So it's much easier to do this in the Makefile --> diff --git a/doc/stylesheets/dbschema_k/xsl/mysql.xsl b/doc/stylesheets/dbschema_k/xsl/mysql.xsl index 0694ef375..2fb4a1cf9 100644 --- a/doc/stylesheets/dbschema_k/xsl/mysql.xsl +++ b/doc/stylesheets/dbschema_k/xsl/mysql.xsl @@ -138,7 +138,7 @@ AUTO_INCREMENT - + PRIMARY KEY diff --git a/doc/stylesheets/dbschema_k/xsl/pi_framework_mod.xsl b/doc/stylesheets/dbschema_k/xsl/pi_framework_mod.xsl index 58c592c90..84b203d45 100644 --- a/doc/stylesheets/dbschema_k/xsl/pi_framework_mod.xsl +++ b/doc/stylesheets/dbschema_k/xsl/pi_framework_mod.xsl @@ -39,7 +39,7 @@ <!-- - provisionning --> + provisioning --> <mod><mod_name> </mod_name> diff --git a/doc/tutorials/cfg_list/Makefile b/doc/tutorials/cfg_list/Makefile index cda24264d..66aa377d5 100644 --- a/doc/tutorials/cfg_list/Makefile +++ b/doc/tutorials/cfg_list/Makefile @@ -72,7 +72,7 @@ c_defs=-DNAME='\"kamailio\"' -DVERSION='\"5.1.0-dev3\"' -DARCH='\"x86_64\"' \ -DRUN_DIR='\"/run/kamailio/\"' -DPKG_MALLOC -DSHM_MEM -DSHM_MMAP \ -DDNS_IP_HACK -DUSE_MCAST -DUSE_TCP -DDISABLE_NAGLE -DHAVE_RESOLV_RES \ -DUSE_DNS_CACHE -DUSE_DNS_FAILOVER -DUSE_DST_BLOCKLIST -DUSE_NAPTR \ - -DWITH_XAVP -DMEM_JOIN_FREE -DF_MALLOC -DQ_MALLOC -DTLSF_MALLOC \ + -DMEM_JOIN_FREE -DF_MALLOC -DQ_MALLOC -DTLSF_MALLOC \ -DDBG_SR_MEMORY -DUSE_TLS -DTLS_HOOKS -DUSE_CORE_STATS -DSTATISTICS \ -DMALLOC_STATS -DWITH_AS_SUPPORT -DUSE_SCTP -DFAST_LOCK -DADAPTIVE_WAIT \ -DADAPTIVE_WAIT_LOOPS=1024 -DCC_GCC_LIKE_ASM -DHAVE_GETHOSTBYNAME2 \ diff --git a/doc/tutorials/counter_list/Makefile b/doc/tutorials/counter_list/Makefile index 0ef48b236..7cef0f721 100644 --- a/doc/tutorials/counter_list/Makefile +++ b/doc/tutorials/counter_list/Makefile @@ -66,7 +66,7 @@ c_defs=-DNAME='\"kamailio\"' -DVERSION='\"5.1.0-dev3\"' -DARCH='\"x86_64\"' \ -DRUN_DIR='\"/run/kamailio/\"' -DPKG_MALLOC -DSHM_MEM -DSHM_MMAP \ -DDNS_IP_HACK -DUSE_MCAST -DUSE_TCP -DDISABLE_NAGLE -DHAVE_RESOLV_RES \ -DUSE_DNS_CACHE -DUSE_DNS_FAILOVER -DUSE_DST_BLOCKLIST -DUSE_NAPTR \ - -DWITH_XAVP -DMEM_JOIN_FREE -DF_MALLOC -DQ_MALLOC -DTLSF_MALLOC \ + -DMEM_JOIN_FREE -DF_MALLOC -DQ_MALLOC -DTLSF_MALLOC \ -DDBG_SR_MEMORY -DUSE_TLS -DTLS_HOOKS -DUSE_CORE_STATS -DSTATISTICS \ -DMALLOC_STATS -DWITH_AS_SUPPORT -DUSE_SCTP -DFAST_LOCK -DADAPTIVE_WAIT \ -DADAPTIVE_WAIT_LOOPS=1024 -DCC_GCC_LIKE_ASM -DHAVE_GETHOSTBYNAME2 \ diff --git a/doc/tutorials/presence/cfg/ps.cfg b/doc/tutorials/presence/cfg/ps.cfg index 05fad8140..1d6d2ebb2 100644 --- a/doc/tutorials/presence/cfg/ps.cfg +++ b/doc/tutorials/presence/cfg/ps.cfg @@ -283,7 +283,7 @@ route[RR] # use different transport protocol # if the initial INVITE got the ACC flag store this in - # an RR AVP cookie. this is more for demonstration purpose + # an RR AVP cookie. This is more for demonstration purpose if (isflagset(FLAG_ACC)) { $account = "yes"; setavpflag($account, "dialog_cookie"); diff --git a/doc/tutorials/presence/install.xml b/doc/tutorials/presence/install.xml index 76ac767f1..ebd0e99fc 100644 --- a/doc/tutorials/presence/install.xml +++ b/doc/tutorials/presence/install.xml @@ -18,7 +18,7 @@ more information see .
Dependencies -Presence module dependecies may be found in sections Presence module dependencies may be found in sections PA module dependencies and RLS module dependencies. These modules depend on common libraries which have their own dependencies as mentioned below. diff --git a/doc/tutorials/presence/intro.xml b/doc/tutorials/presence/intro.xml index f02c44341..ecb0345fa 100644 --- a/doc/tutorials/presence/intro.xml +++ b/doc/tutorials/presence/intro.xml @@ -65,7 +65,7 @@ libraries. Their interface is described in standalone documents.
Persistence Modules can store their status (working data) into database. This data is automatically reloaded on startup, so it is possible to restart SIP-router and -clients don't note it. Established SIP dialogs are stored in a database too. +clients don't notice it. Established SIP dialogs are stored in a database too. Details about database storage are described for each module separately in module documentation. @@ -85,7 +85,7 @@ rules may be found in and Only XCAP storage of authorization rules is supported at this moment. It is not fully implemented now - only basic rule conditions, no sphere and time conditions. Transformations defined in are -ignored. Maybe, that in the +ignored. Maybe, in the future it will be possible to use other variants like webdav or storing authorization rules in SIP-router's own database. diff --git a/doc/tutorials/rpc_list/Makefile b/doc/tutorials/rpc_list/Makefile index ac838ef7d..c620793f8 100644 --- a/doc/tutorials/rpc_list/Makefile +++ b/doc/tutorials/rpc_list/Makefile @@ -139,7 +139,7 @@ c_defsX=-DNAME='\"kamailio\"' -DVERSION='\"5.1.0-dev3\"' -DARCH='\"x86_64\"' \ -DRUN_DIR='\"/run/kamailio/\"' -DPKG_MALLOC -DSHM_MEM -DSHM_MMAP \ -DDNS_IP_HACK -DUSE_MCAST -DUSE_TCP -DDISABLE_NAGLE -DHAVE_RESOLV_RES \ -DUSE_DNS_CACHE -DUSE_DNS_FAILOVER -DUSE_DST_BLOCKLIST -DUSE_NAPTR \ - -DWITH_XAVP -DMEM_JOIN_FREE -DF_MALLOC -DQ_MALLOC -DTLSF_MALLOC \ + -DMEM_JOIN_FREE -DF_MALLOC -DQ_MALLOC -DTLSF_MALLOC \ -DDBG_SR_MEMORY -DUSE_TLS -DTLS_HOOKS -DUSE_CORE_STATS -DSTATISTICS \ -DMALLOC_STATS -DWITH_AS_SUPPORT -DUSE_SCTP -DFAST_LOCK -DADAPTIVE_WAIT \ -DADAPTIVE_WAIT_LOOPS=1024 -DCC_GCC_LIKE_ASM -DHAVE_GETHOSTBYNAME2 \ diff --git a/doc/tutorials/select_list/Makefile b/doc/tutorials/select_list/Makefile index 50be57d3a..5f3a32822 100644 --- a/doc/tutorials/select_list/Makefile +++ b/doc/tutorials/select_list/Makefile @@ -68,7 +68,7 @@ c_defs=-DNAME='\"kamailio\"' -DVERSION='\"5.1.0-dev3\"' -DARCH='\"x86_64\"' \ -DRUN_DIR='\"/run/kamailio/\"' -DPKG_MALLOC -DSHM_MEM -DSHM_MMAP \ -DDNS_IP_HACK -DUSE_MCAST -DUSE_TCP -DDISABLE_NAGLE -DHAVE_RESOLV_RES \ -DUSE_DNS_CACHE -DUSE_DNS_FAILOVER -DUSE_DST_BLOCKLIST -DUSE_NAPTR \ - -DWITH_XAVP -DMEM_JOIN_FREE -DF_MALLOC -DQ_MALLOC -DTLSF_MALLOC \ + -DMEM_JOIN_FREE -DF_MALLOC -DQ_MALLOC -DTLSF_MALLOC \ -DDBG_SR_MEMORY -DUSE_TLS -DTLS_HOOKS -DUSE_CORE_STATS -DSTATISTICS \ -DMALLOC_STATS -DWITH_AS_SUPPORT -DUSE_SCTP -DFAST_LOCK -DADAPTIVE_WAIT \ -DADAPTIVE_WAIT_LOOPS=1024 -DCC_GCC_LIKE_ASM -DHAVE_GETHOSTBYNAME2 \ diff --git a/doc/tutorials/serdev/routing_engine.xml b/doc/tutorials/serdev/routing_engine.xml index a3c417f2b..6ea403c2b 100644 --- a/doc/tutorials/serdev/routing_engine.xml +++ b/doc/tutorials/serdev/routing_engine.xml @@ -259,7 +259,7 @@ route statement. - As we have mentioned already, there can be more that one + As we have mentioned already, there can be more than one route statement in the config file. One of them is main (without number), the other are additional. This command makes it possible to execute an additional route statement. diff --git a/doc/tutorials/seruser/otherapps.xml b/doc/tutorials/seruser/otherapps.xml index dbcd1407d..1c44d405b 100644 --- a/doc/tutorials/seruser/otherapps.xml +++ b/doc/tutorials/seruser/otherapps.xml @@ -32,7 +32,7 @@ usage: serctl mail <username> .................... send an email to a user serctl alias show [<alias>] ............... show aliases serctl alias rm <alias> ................... remove an alias - serctl alias add <alias> <uri> ............ add an aliases + serctl alias add <alias> <uri> ............ add an alias * access control lists * serctl acl show [<username>] .............. show user membership diff --git a/etc/kamailio.cfg b/etc/kamailio.cfg old mode 100644 new mode 100755 index fe7b111a0..3f9a5fe79 --- a/etc/kamailio.cfg +++ b/etc/kamailio.cfg @@ -1,6 +1,6 @@ #!KAMAILIO # -# Kamailio SIP Server v5.7 - default configuration script +# Kamailio SIP Server v5.8 - default configuration script # - web: https://www.kamailio.org # - git: https://github.com/kamailio/kamailio # @@ -220,6 +220,14 @@ enable_tls=yes /* upper limit for TLS connections */ tls_max_connections=2048 + +/* For OpenSSL 3 integration + * functions calling libssl3 can be invoked in a transient thread + * 0: disable threaded calls + * 1: use thread executors for process#0 only + * 2: no thread executors, but use atfork handler to reset thread-locals to NULL + * 3: use thread executors for all processes */ +tls_threads_mode=1 #!endif /* set it to yes to enable sctp and load sctp.so module */ @@ -257,6 +265,12 @@ voicemail.srv_port = "5060" desc "VoiceMail Port" /* set paths to location of modules */ # mpath="/usr/local/lib/kamailio/modules/" +# when using TLS with OpenSSL it is recommended to load this module +# first so that OpenSSL is initialized correctly +#!ifdef WITH_TLS +loadmodule "tls.so" +#!endif + #!ifdef WITH_MYSQL loadmodule "db_mysql.so" #!endif @@ -319,10 +333,6 @@ loadmodule "rtpproxy.so" #!endif #!endif -#!ifdef WITH_TLS -loadmodule "tls.so" -#!endif - #!ifdef WITH_HTABLE loadmodule "htable.so" #!endif diff --git a/misc/examples/exec/exec_s5b.cfg b/misc/examples/exec/exec_s5b.cfg index 302a7f7b2..4773a88b2 100644 --- a/misc/examples/exec/exec_s5b.cfg +++ b/misc/examples/exec/exec_s5b.cfg @@ -33,7 +33,7 @@ route{ }; }; # user found, forward to his current uri now; if any - # forwarding error occurs (e.g., busy or cancelled recevied + # forwarding error occurs (e.g., busy or cancelled received # from downstream), proceed to failure_route[1] t_on_failure("1"); if (!t_relay()) { diff --git a/misc/examples/ims/icscf/README.md b/misc/examples/ims/icscf/README.md index 85cb411cb..982cc4665 100644 --- a/misc/examples/ims/icscf/README.md +++ b/misc/examples/ims/icscf/README.md @@ -2,7 +2,7 @@ Project Website: - * http://www.kamailio.org + * https://www.kamailio.org ## Database Structure diff --git a/misc/examples/ims/icscf/kamailio.cfg b/misc/examples/ims/icscf/kamailio.cfg index 5bbfc22f5..4434e6a25 100644 --- a/misc/examples/ims/icscf/kamailio.cfg +++ b/misc/examples/ims/icscf/kamailio.cfg @@ -1,10 +1,10 @@ #!KAMAILIO # # This config file implements the basic I-CSCF functionality -# - web: http://www.kamailio.org +# - web: https://www.kamailio.org # - git: http://sip-router.org # -# Refer to the Core CookBook at http://www.kamailio.org/dokuwiki/doku.php +# Refer to the Core CookBook at https://www.kamailio.org/w/documentation/ # for an explanation of possible statements, functions and parameters. # # Direct your questions about this file to: . diff --git a/misc/examples/ims/pcscf/README.md b/misc/examples/ims/pcscf/README.md index 5a1bb30ed..ddca44733 100644 --- a/misc/examples/ims/pcscf/README.md +++ b/misc/examples/ims/pcscf/README.md @@ -2,7 +2,7 @@ Project Website: - * http://www.kamailio.org + * https://www.kamailio.org ## Database Structure diff --git a/misc/examples/ims/pcscf/kamailio.cfg b/misc/examples/ims/pcscf/kamailio.cfg index af8ca1aa8..9e52ab015 100644 --- a/misc/examples/ims/pcscf/kamailio.cfg +++ b/misc/examples/ims/pcscf/kamailio.cfg @@ -2,10 +2,10 @@ # TelcoSuite (V3) Proxy-CSCF # # Kamailio SIP Server -# - web: http://www.kamailio.org +# - web: https://www.kamailio.org # - git: http://sip-router.org # -# Refer to the Core CookBook at http://www.kamailio.org/dokuwiki/doku.php +# Refer to the Core CookBook at https://www.kamailio.org/w/documentation/ # for an explanation of possible statements, functions and parameters. # diff --git a/misc/examples/ims/pcscf/pcscf.cfg.sample b/misc/examples/ims/pcscf/pcscf.cfg.sample index 4d2635776..2b2269493 100644 --- a/misc/examples/ims/pcscf/pcscf.cfg.sample +++ b/misc/examples/ims/pcscf/pcscf.cfg.sample @@ -1,4 +1,4 @@ -# IP-Adress for incoming SIP-Traffic, in the following format: +# IP-Address for incoming SIP-Traffic, in the following format: # SIP / UDP listen=udp:0.0.0.0:5060 diff --git a/misc/examples/ims/pcscf/route/mo.cfg b/misc/examples/ims/pcscf/route/mo.cfg index fdd3ac2ea..230f24dfe 100644 --- a/misc/examples/ims/pcscf/route/mo.cfg +++ b/misc/examples/ims/pcscf/route/mo.cfg @@ -1,5 +1,5 @@ ###################################################################### -# Originating, Intial Requests +# Originating, Initial Requests ###################################################################### route[MO] { diff --git a/misc/examples/ims/pcscf/sems/sems.conf b/misc/examples/ims/pcscf/sems/sems.conf index ecae29e6c..9f15d86af 100644 --- a/misc/examples/ims/pcscf/sems/sems.conf +++ b/misc/examples/ims/pcscf/sems/sems.conf @@ -446,7 +446,7 @@ use_default_signature=yes # optional parameter: unhandled_reply_loglevel={error|warn|info|debug|no} # # the default application logic implemented in the applications is to stop -# the session right after sending BYE, without waiting for a reply. this +# the session right after sending BYE, without waiting for a reply. This # leads to many log entries of the form # ERROR: [b6fa6bb0] handleSipMsg (AmSipDispatcher.cpp:48): unhandled # reply: [code:200;phrase:[OK];... ] diff --git a/misc/examples/ims/scscf/README.md b/misc/examples/ims/scscf/README.md index 34b7d6dbe..d28328cb4 100644 --- a/misc/examples/ims/scscf/README.md +++ b/misc/examples/ims/scscf/README.md @@ -2,7 +2,7 @@ Project Website: - * http://www.kamailio.org + * https://www.kamailio.org ## Database Structure diff --git a/misc/examples/ims/scscf/kamailio.cfg b/misc/examples/ims/scscf/kamailio.cfg index 0f3244443..70e2614cb 100644 --- a/misc/examples/ims/scscf/kamailio.cfg +++ b/misc/examples/ims/scscf/kamailio.cfg @@ -1,10 +1,10 @@ #!KAMAILIO # # This config file implements the basic P-CSCF functionality -# - web: http://www.kamailio.org +# - web: https://www.kamailio.org # - git: http://sip-router.org # -# Refer to the Core CookBook at http://www.kamailio.org/dokuwiki/doku.php +# Refer to the Core CookBook at https://www.kamailio.org/w/documentation/ # for an explanation of possible statements, functions and parameters. # # Direct your questions about this file to: . @@ -799,7 +799,7 @@ route[apply_privacy] } ###################################################################### -# Originating, Intial Requests +# Originating, Initial Requests ###################################################################### route[orig] { diff --git a/misc/examples/ims/scscf/scscf.cfg.sample b/misc/examples/ims/scscf/scscf.cfg.sample index 835a830f7..c3e1765c3 100644 --- a/misc/examples/ims/scscf/scscf.cfg.sample +++ b/misc/examples/ims/scscf/scscf.cfg.sample @@ -25,7 +25,7 @@ alias=scscf.mnc001.mcc001.3gppnetwork.org ##!define DB_URL "con1=>mysql://scscf:heslo@127.0.0.1/scscf" ##!define DB_URL2 "con2=>mysql://scscf:heslo@127.0.0.1/scscf" -# Select Authorization Algorhithm: +# Select Authorization Algorithm: ##!define REG_AUTH_DEFAULT_ALG "AKAv1-MD5" ##!define REG_AUTH_DEFAULT_ALG "AKAv2-MD5" ##!define REG_AUTH_DEFAULT_ALG "MD5" diff --git a/misc/examples/kamailio/acc-mysql.cfg b/misc/examples/kamailio/acc-mysql.cfg index 53cc9df40..ed13f6970 100644 --- a/misc/examples/kamailio/acc-mysql.cfg +++ b/misc/examples/kamailio/acc-mysql.cfg @@ -1,6 +1,6 @@ # $Id$ # -# Sample config for MySQL accouting with Kamailio 1.2.0 +# Sample config for MySQL accounting with Kamailio 1.2.0 # # - mysql module must be compiled and installed # diff --git a/misc/examples/kamailio/acc.cfg b/misc/examples/kamailio/acc.cfg index 831d701aa..71e2f02fc 100644 --- a/misc/examples/kamailio/acc.cfg +++ b/misc/examples/kamailio/acc.cfg @@ -1,7 +1,7 @@ # # $Id$ # -# example: accounting calls to nummerical destinations +# example: accounting calls to numerical destinations # # ------------------ module loading ---------------------------------- diff --git a/misc/examples/kamailio/ctd.sh b/misc/examples/kamailio/ctd.sh index f792aac82..a1f5f04ce 100644 --- a/misc/examples/kamailio/ctd.sh +++ b/misc/examples/kamailio/ctd.sh @@ -28,7 +28,7 @@ # with Cisco 7960, Mitel 5055, Grandstream and Pingtel; Windows # Messenger does not support REFER. Never tested on solaris. # Some cisco 7960 images don't work (in particular, POS30202 -# doesnt, POS3-03-8-21 does) +# doesn't, POS3-03-8-21 does) # # History: # -------- @@ -132,7 +132,7 @@ fifo_job="$!" # initiate dummy INVITE with pre-3261 "on-hold" # (note the dots -- they mean in order of appearance: -# outbound uri, end of headers, end of body; eventualy +# outbound uri, end of headers, end of body; eventually # the FIFO request must be terminated with an empty line) #cat < $FIFO <0 then @@ -354,7 +354,19 @@ function ksr_route_natmanage() return 1; end - KSR.rtpproxy.rtpproxy_manage("co"); + if KSR.kx.ifdef('WITH_RTPENGINE') then + if KSR.nathelper.nat_uac_test(8)>0 then + KSR.rtpengine.rtpengine_manage("replace-origin replace-session-connection SIP-source-address"); + else + KSR.rtpengine.rtpengine_manage("replace-origin replace-session-connection"); + end + else + if KSR.nathelper.nat_uac_test(8)>0 then + KSR.rtpproxy.rtpproxy_manage("co"); + else + KSR.rtpproxy.rtpproxy_manage("cor"); + end + end if KSR.siputils.is_request()>0 then if KSR.siputils.has_totag()<0 then diff --git a/misc/examples/kemi/kamailio-basic-kemi-ruby.rb b/misc/examples/kemi/kamailio-basic-kemi-ruby.rb index 85316d41c..e97f19db0 100644 --- a/misc/examples/kemi/kamailio-basic-kemi-ruby.rb +++ b/misc/examples/kemi/kamailio-basic-kemi-ruby.rb @@ -176,7 +176,7 @@ def ksr_route_withindlg() exit end -# IP authorization and user authenticaton +# IP authorization and user authentication def ksr_route_auth() if !KSR.is_REGISTER() then # source IP allowed @@ -225,7 +225,7 @@ def ksr_route_natmanage() end end end - #KSR.info("Natmange - returning if NAT flags set") + #KSR.info("Natmanage - returning if NAT flags set") return if !KSR.isflagset($FLT_NATS) and !KSR.isbflagset($FLB_NATB) #KSR.info("Natmanage - RTPPROXY from here on") KSR::RTPPROXY::RTPPROXY_manage("co"); diff --git a/misc/examples/kemi/kamailio-basic-kemi.cfg b/misc/examples/kemi/kamailio-basic-kemi.cfg index b6bdfbb93..d1fb05d35 100644 --- a/misc/examples/kemi/kamailio-basic-kemi.cfg +++ b/misc/examples/kemi/kamailio-basic-kemi.cfg @@ -1,7 +1,7 @@ #!KAMAILIO # # Kamailio SIP Server v5.0 - default configuration script -# - web: http://www.kamailio.org +# - web: https://www.kamailio.org # - git: http://sip-router.org # # Direct your questions about this file to: @@ -39,6 +39,12 @@ # rtpproxy -l _your_public_ip_ -s udp:localhost:7722 # - option for NAT SIP OPTIONS keepalives: WITH_NATSIPPING # +# *** To use RTPEngine (instead of RTPProxy) for nat traversal execute: +# - define WITH_RTPENGINE +# - install RTPEngine: https://github.com/sipwise/rtpengine +# - start RTPEngine: +# rtpengine --listen-ng=127.0.0.1:2223 ... +# # *** To enable TLS support execute: # - adjust CFGDIR/tls.cfg as needed # - define WITH_TLS @@ -237,8 +243,12 @@ loadmodule "permissions.so" #!ifdef WITH_NAT loadmodule "nathelper.so" +#!ifdef WITH_RTPENGINE +loadmodule "rtpengine.so" +#!else loadmodule "rtpproxy.so" #!endif +#!endif #!ifdef WITH_TLS loadmodule "tls.so" @@ -352,8 +362,13 @@ modparam("permissions", "db_mode", 1) #!ifdef WITH_NAT +#!ifdef WITH_RTPENGINE +# ----- rtpengine params ----- +modparam("rtpengine", "rtpengine_sock", "udp:127.0.0.1:2223") +#!else # ----- rtpproxy params ----- modparam("rtpproxy", "rtpproxy_sock", "udp:127.0.0.1:7722") +#!endif # ----- nathelper params ----- modparam("nathelper", "natping_interval", 30) diff --git a/misc/examples/mixed/acc.cfg b/misc/examples/mixed/acc.cfg index 8f2854346..fd64e02f0 100644 --- a/misc/examples/mixed/acc.cfg +++ b/misc/examples/mixed/acc.cfg @@ -1,7 +1,7 @@ # # $Id$ # -# example: accounting calls to nummerical destinations +# example: accounting calls to numerical destinations # # ------------------ module loading ---------------------------------- diff --git a/misc/examples/mixed/kamailio-minimal-anycast.cfg b/misc/examples/mixed/kamailio-minimal-anycast.cfg index 40d4788f6..da4067cf1 100644 --- a/misc/examples/mixed/kamailio-minimal-anycast.cfg +++ b/misc/examples/mixed/kamailio-minimal-anycast.cfg @@ -82,7 +82,7 @@ listen=udp:IPADDR_THISNODE:5060 ####### Custom Parameters ######### -/* These parameters can be modified runtime via RPC interface +/* These parameters can be modified at runtime via RPC interface * - see the documentation of 'cfg_rpc' module. * * Format: group.id = value 'desc' description @@ -142,7 +142,7 @@ modparam("rr", "append_fromtag", 0) modparam("acc", "early_media", 0) modparam("acc", "report_ack", 0) modparam("acc", "report_cancels", 0) -/* by default ww do not adjust the direct of the sequential requests. +/* by default we do not adjust the direct of the sequential requests. * if you enable this parameter, be sure the enable "append_fromtag" * in "rr" module */ modparam("acc", "detect_direction", 0) diff --git a/misc/examples/mixed/kamailio-minimal-proxy.cfg b/misc/examples/mixed/kamailio-minimal-proxy.cfg index a332c1240..32830f9fe 100644 --- a/misc/examples/mixed/kamailio-minimal-proxy.cfg +++ b/misc/examples/mixed/kamailio-minimal-proxy.cfg @@ -56,7 +56,7 @@ children=2 ####### Custom Parameters ######### -/* These parameters can be modified runtime via RPC interface +/* These parameters can be modified at runtime via RPC interface * - see the documentation of 'cfg_rpc' module. * * Format: group.id = value 'desc' description @@ -116,7 +116,7 @@ modparam("rr", "append_fromtag", 0) modparam("acc", "early_media", 0) modparam("acc", "report_ack", 0) modparam("acc", "report_cancels", 0) -/* by default ww do not adjust the direct of the sequential requests. +/* by default we do not adjust the direct of the sequential requests. * if you enable this parameter, be sure the enable "append_fromtag" * in "rr" module */ modparam("acc", "detect_direction", 0) diff --git a/misc/examples/mixed/nathelper.cfg b/misc/examples/mixed/nathelper.cfg index b1e36aab5..18a8c339f 100644 --- a/misc/examples/mixed/nathelper.cfg +++ b/misc/examples/mixed/nathelper.cfg @@ -7,7 +7,7 @@ # you will also have to install Maxim's RTP proxy. The proxy is enforced # if one of the parties is behind a NAT. # -# If you have an endpoing in the public internet which is known to +# If you have an endpoint in the public internet which is known to # support symmetric RTP (Cisco PSTN gateway or voicemail, for example), # then you don't have to force RTP proxy. If you don't want to enforce # RTP proxy for some destinations than simply use t_relay() instead of diff --git a/misc/examples/mixed/onr.cfg b/misc/examples/mixed/onr.cfg index c5fcc3286..282ccd4ca 100644 --- a/misc/examples/mixed/onr.cfg +++ b/misc/examples/mixed/onr.cfg @@ -4,7 +4,7 @@ # example script showing both types of forking; # incoming message is forked in parallel to # 'nobody' and 'parallel', if no positive reply -# appears with final_response timer, nonsense +# appears within final_response timer, nonsense # is retried (serial forking); than, destination # 'foo' is given last chance @@ -57,7 +57,7 @@ failure_route[2] { # try out the last resort destination append_branch("sip:foo@iptel.org"); log(1, "second redirection\n"); - # we no more call t_on_negative here; if this destination + # we no more call t_on_failure here; if this destination # fails too, transaction will complete t_relay(); } diff --git a/misc/examples/mixed/replicate.cfg b/misc/examples/mixed/replicate.cfg index e54276e48..3c0b1a576 100644 --- a/misc/examples/mixed/replicate.cfg +++ b/misc/examples/mixed/replicate.cfg @@ -34,7 +34,7 @@ modparam("auth", "secret", "alsdkhglaksdhfkloiwr") route{ # initial sanity checks -- messages with - # max_forwars==0, or excessively long requests + # max_forwards==0, or excessively long requests if (!mf_process_maxfwd_header("10")) { sl_send_reply("483", "Too Many Hops"); break; diff --git a/misc/examples/mixed/sip-router.cfg.m4 b/misc/examples/mixed/sip-router.cfg.m4 index 0dc5eba89..6f81968b4 100644 --- a/misc/examples/mixed/sip-router.cfg.m4 +++ b/misc/examples/mixed/sip-router.cfg.m4 @@ -76,7 +76,7 @@ loadmodule "/usr/local/lib/sip-router/modules/domain.so" modparam("usrloc|acc|auth_db|group|msilo", "db_url", "sql://sip-router:heslo@localhost/sip-router") # -- usrloc params -- -/* 0 -- dont use mysql, 1 -- write_through, 2--write_back */ +/* 0 -- don't use mysql, 1 -- write_through, 2 -- write_back */ modparam("usrloc", "db_mode", 2) modparam("usrloc", "timer_interval", 10) @@ -187,7 +187,7 @@ route { # anti-spam -- if somene claims to belong to our domain in From, - # challenge him (skip REGISTERs -- we will chalenge them later) + # challenge him (skip REGISTERs -- we will challenge them later) if (search("(From|F):.*@SER_HOST_REGEX")) { # invites forwarded to other domains, like FWD may cause subsequent # request to come from there but have iptel in From -> verify @@ -297,8 +297,8 @@ route { break; }; - # some UACs might be fooled by Contacts our UACs generate to make MSN - # happy (web-im, e.g.) -- tell its urneachable + # some UACs might be fooled by Contacts our UACs generated to make MSN + # happy (web-im, e.g.) -- tell it is unreachable if (uri =~ "sip:daemon@") { sl_send_reply("410", "Daemon is gone"); break; @@ -317,7 +317,7 @@ route { break; }; - # Remove leading + if it is a number begining with + + # Remove leading + if it is a number beginning with + if (uri =~ "^[a-zA-Z]+:\+[0-9]+@") { strip(1); prefix("00"); @@ -372,7 +372,7 @@ route { } # -# Forcing media relay if necesarry +# Forcing media relay if necessary # route[NAT_ROUTE] { if (uri=~"[@:](192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.)" && !search("^Route:")) { @@ -384,7 +384,7 @@ route[NAT_ROUTE] { force_rtp_proxy(); append_hf("P-RTP-Proxy: YES\r\n"); }; - append_hf("P-NATed-Calee: Yes\r\n"); + append_hf("P-NATed-Callee: Yes\r\n"); }; # nat processing of replies; apply to all transactions (for example, diff --git a/misc/examples/mixed/voicemail.cfg b/misc/examples/mixed/voicemail.cfg index 8ccbc36ab..f0d8f54f0 100644 --- a/misc/examples/mixed/voicemail.cfg +++ b/misc/examples/mixed/voicemail.cfg @@ -41,7 +41,7 @@ route{ # initial sanity checks -- messages with - # max_forwars==0, or excessively long requests + # max_forwards==0, or excessively long requests if (!mf_process_maxfwd_header("10")) { sl_send_reply("483", "Too Many Hops"); break; diff --git a/misc/examples/obsoleted/imgw.cfg b/misc/examples/obsoleted/imgw.cfg index 92db9ebc1..086ac3327 100644 --- a/misc/examples/obsoleted/imgw.cfg +++ b/misc/examples/obsoleted/imgw.cfg @@ -77,7 +77,7 @@ route{ if (! t_newtran()) { # retransmit whatever we have - # it's useless to do any retransmision, because we haven't + # it's useless to do any retransmission, because we haven't # sent any statefull reply. (bogdan) #t_retransmit_reply(); break; @@ -142,7 +142,7 @@ route{ if (! t_newtran()) { # retransmit whatever we have - # it's useless to do any retransmision, because we haven't + # it's useless to do any retransmission, because we haven't # sent any statefull reply. (bogdan) #t_retransmit_reply(); break; diff --git a/misc/examples/obsoleted/secondary.cfg b/misc/examples/obsoleted/secondary.cfg index 97736af06..cf6bf0b04 100644 --- a/misc/examples/obsoleted/secondary.cfg +++ b/misc/examples/obsoleted/secondary.cfg @@ -197,7 +197,7 @@ route{ /* added by Bogdan for cpl demo - Dorgham request*/ if (uri=~"sip:test@.*" && method=="INVITE") { - log("SER : runing CPL!! :)\n"); + log("SER : running CPL!! :)\n"); if ( !cpl_run_script() ) { log("SER : Error during running CPL script!\n"); diff --git a/misc/examples/obsoleted/sms.cfg b/misc/examples/obsoleted/sms.cfg index abe6dc83a..6fd925438 100644 --- a/misc/examples/obsoleted/sms.cfg +++ b/misc/examples/obsoleted/sms.cfg @@ -60,7 +60,7 @@ route{ # UAS script implementation # if that is not a new transaction... (t_newtran is a new - # function which atomicaly adds a transaction if there is + # function which atomically adds a transaction if there is # none) if (! t_newtran()) { # retransmit whatever we have diff --git a/misc/examples/obsoleted/smsgw.cfg b/misc/examples/obsoleted/smsgw.cfg index 619d11169..998a54e3b 100644 --- a/misc/examples/obsoleted/smsgw.cfg +++ b/misc/examples/obsoleted/smsgw.cfg @@ -99,7 +99,7 @@ route{ if (! t_newtran()) { # retransmit whatever we have - # it's useless to do any retransmision, because we haven't + # it's useless to do any retransmission, because we haven't # sent any statefull reply. (bogdan) #t_retransmit_reply(); break; diff --git a/misc/examples/obsoleted/test.cfg b/misc/examples/obsoleted/test.cfg index 6911c0e8e..9e40b024f 100644 --- a/misc/examples/obsoleted/test.cfg +++ b/misc/examples/obsoleted/test.cfg @@ -180,7 +180,7 @@ route{ /* added by Bogdan for cpl demo - Dorgham request*/ if (uri=~"sip:test@.*" && method=="INVITE") { - log("SER : runing CPL!! :)\n"); + log("SER : running CPL!! :)\n"); if ( !cpl_run_script() ) { log("SER : Error during running CPL script!\n"); diff --git a/misc/examples/obsoleted/tmtest.cfg b/misc/examples/obsoleted/tmtest.cfg index 0cb9179be..6d8e9f1da 100644 --- a/misc/examples/obsoleted/tmtest.cfg +++ b/misc/examples/obsoleted/tmtest.cfg @@ -100,7 +100,7 @@ route{ # - we need it for calls from gateways (otherwise, subsequent # requests from the other # party will attempt to contact gateway # directly through blocked ports) - # - we need it for Windows Messanger's IM sessions to cross + # - we need it for Windows Messenger's IM sessions to cross # firewalls -- we force all MESSAGEs to go via our server # to avoid blocking port numbers (some firewalls can do # standard SIP but are puzzled by Microsoft's proprietary @@ -135,7 +135,7 @@ route{ log("LOG Request is REGISTER\n"); # prohibit attempts to grab someone else's To address # using valid credentials; the only exception is the user - # 'replciator' permitted to generate 3-rd party registrations + # 'replicator' permitted to generate 3-rd party registrations # update Contact database log("LOG: REGISTER is authorized, saving location\n"); diff --git a/misc/examples/pkg/kamailio-basic.cfg b/misc/examples/pkg/kamailio-basic.cfg index 4c2a01442..102784f44 100644 --- a/misc/examples/pkg/kamailio-basic.cfg +++ b/misc/examples/pkg/kamailio-basic.cfg @@ -1,7 +1,7 @@ #!KAMAILIO # # Kamailio SIP Server v5.1 - default basic configuration script -# - web: http://www.kamailio.org +# - web: https://www.kamailio.org # - git: http://sip-router.org # # Direct your questions about this file to: diff --git a/misc/examples/pkg/kamailio-oob.cfg b/misc/examples/pkg/kamailio-oob.cfg index 075f1a65b..5bfe217ca 100644 --- a/misc/examples/pkg/kamailio-oob.cfg +++ b/misc/examples/pkg/kamailio-oob.cfg @@ -1,7 +1,7 @@ #!KAMAILIO # # Kamailio SIP Server v5.1 - default advanced configuration script -# - web: http://www.kamailio.org +# - web: https://www.kamailio.org # - git: http://sip-router.org # # Direct your questions about this file to: @@ -194,7 +194,7 @@ tcp_accept_no_cl=yes ####### Custom Parameters ######### -# These parameters can be modified runtime via RPC interface +# These parameters can be modified at runtime via RPC interface # - see the documentation of 'cfg_rpc' module. # # Format: group.id = value 'desc' description @@ -360,7 +360,7 @@ modparam("registrar", "gruu_enabled", 0) modparam("acc", "early_media", 0) modparam("acc", "report_ack", 0) modparam("acc", "report_cancels", 0) -/* by default ww do not adjust the direct of the sequential requests. +/* by default we do not adjust the direct of the sequential requests. if you enable this parameter, be sure the enable "append_fromtag" in "rr" module */ modparam("acc", "detect_direction", 0) @@ -862,7 +862,7 @@ route[PSTN] { #!ifdef WITH_PSTN # check if PSTN GW IP is defined if (strempty($sel(cfg_get.pstn.gw_ip))) { - xlog("SCRIPT: PSTN rotuing enabled but pstn.gw_ip not defined\n"); + xlog("SCRIPT: PSTN routing enabled but pstn.gw_ip not defined\n"); return; } @@ -919,7 +919,7 @@ route[TOVOICEMAIL] { # check if VoiceMail server IP is defined if (strempty($sel(cfg_get.voicemail.srv_ip))) { - xlog("SCRIPT: VoiceMail rotuing enabled but IP not defined\n"); + xlog("SCRIPT: VoiceMail routing enabled but IP not defined\n"); return; } if($avp(oexten)==$null) diff --git a/misc/examples/pkg/sip-router-basic.cfg b/misc/examples/pkg/sip-router-basic.cfg index c67ad5bb1..e5fdad922 100644 --- a/misc/examples/pkg/sip-router-basic.cfg +++ b/misc/examples/pkg/sip-router-basic.cfg @@ -50,7 +50,7 @@ rev_dns=no # (cmd. line: -R) #group=sip-router #disable_core=yes #disables core dumping #open_fd_limit=1024 # sets the open file descriptors limit -#mhomed=yes # usefull for multihomed hosts, small performance penalty +#mhomed=yes # useful for multihomed hosts, small performance penalty #disable_tcp=yes #tcp_accept_aliases=yes # accepts the tcp alias via option (see NEWS) sip_warning=yes diff --git a/misc/examples/pkg/sip-router-oob.cfg b/misc/examples/pkg/sip-router-oob.cfg index 8325ce197..ccee20afa 100644 --- a/misc/examples/pkg/sip-router-oob.cfg +++ b/misc/examples/pkg/sip-router-oob.cfg @@ -91,7 +91,7 @@ # from untrusted sources, such as the user agents or foreign proxy # servers # * refined DB use (e.g., flatstore for acc) -# * miscellanous: +# * miscellaneous: # - dialog module for monitoring purposes # - more extensive logging using xlog (controlled by gflags/gAVPs) # * leveraging 2.1 features: @@ -181,7 +181,7 @@ rev_dns=no # (cmd. line: -R) #group=sip-router #disable_core=yes # disables core dumping #open_files_limit=20480 # sets the open file descriptors limit -#mhomed=yes # usefull for multihomed hosts, small performance +#mhomed=yes # useful for multihomed hosts, small performance # penalty disable_tcp=no # be conservative about enabling TCP -- it can # degrade performance a lot @@ -268,7 +268,7 @@ tls_enable=yes #!endif # -------------------- Custom Parameters ------------------------------------ -# These parameters can be modified runtime via RPC interface, +# These parameters can be modified at runtime via RPC interface, # read the documentation of cfg_rpc module. # Session Timer parameters, RFC 4028 @@ -521,7 +521,7 @@ modparam("tm", "restart_fr_on_each_reply", 0) # -- xmlrpc -- #!ifdef WITH_XMLRPC -# Use a sub-route. This is a lot safer then relying on the request method +# Use a sub-route. This is a lot safer than relying on the request method # to distinguish HTTP from SIP modparam("xmlrpc", "route", "XMLRPC"); #!endif @@ -596,7 +596,7 @@ route # to PSTN. If email-like URIs are used, having a URI alias for # processing incoming PSTN-to-ip requests may be useful, too. # Important: the script is assuming one global pstn-gw for all - # domains! Failure to allow gw_ip to be a domain-specic attribute + # domains! Failure to allow gw_ip to be a domain-specific attribute # would result in security gaps (onsend_route checks only for one # gateway). @@ -642,12 +642,12 @@ route route(INBOUND); # There is SIP user for the called address. Before trying PSTN, - # you may have to convert the adress, for instance by using + # you may have to convert the address, for instance by using # ENUM. #route(ENUM); # Last resort: if none of the previous route has found - # the recepient, try PSTN. + # the recipient, try PSTN. route(PSTN); # nothing matched @@ -807,14 +807,14 @@ route[UAC_NAT_DETECTION] # - mismatch of transport IP and IP in Via # - mismatch of transport port and port in Via # in all other cases we skip the port test, because lots of clients - # do not correctly advertise their emphemeral port number in their Via + # do not correctly advertise their ephemeral port number in their Via # header in case of reliable transports (although they are not behind # a NAT). # Warning: if you are dealing with SIP implementations which are - # running on public IP and do as-symmertic signaling for whatever + # running on public IP and do as-symmetric signaling for whatever # reason the following check will make their signaling symmetric. - # If you need to support as-symmertic signaling reduce the following + # If you need to support as-symmetric signaling reduce the following # nat_uac_test for UDP to "3" or even "1". if ((proto == UDP && nat_uac_test("19")) || (nat_uac_test("3")) || @@ -881,9 +881,9 @@ route[UAS_NAT_DETECTION] # IP address into the Contact header, but "forget" about the port. # Warning: if you are dealing with SIP implementations which are - # running on public IP and do as-symmertic signaling for whatever + # running on public IP and do as-symmetric signaling for whatever # reason the following check will make their signaling symmetric. - # If you need to support as-symmertic signaling reduce the following + # If you need to support as-symmetric signaling reduce the following # nat_uac_test for UDP to just "1". if ( (proto == UDP && nat_uac_test("33")) || (nat_uac_test("1") || @@ -982,7 +982,7 @@ route[PROCESS_ROUTES] route(SESSION_TIMER); } - # Some broken devices overide the dialog route set with the + # Some broken devices override the dialog route set with the # Record-Route headers from each in-dialog request. So, we # better add Record-Route headers again. If we call # record_route() after loose_route(), the AVP cookies are @@ -1348,7 +1348,7 @@ route[INBOUND] if (isflagset(FLAG_NAT_REG)) { setflag(FLAG_NAT); /* client was behind NAT when made registration */ } - # We set the tm module timers according to the prefences + # We set the tm module timers according to the preferences # of the callee (avoid too long ringing of his phones). # Note1: Timer values have to be in ms now! # Note2: This makes even more sense if you switch to a @@ -1363,7 +1363,7 @@ route[INBOUND] } # This enables session timer support as long as one side - # supports it. If you want to have session timmer support + # supports it. If you want to have session timer support # only for calls from your PSTN gateway but not between pure # VoIP calls you can remove the comment marks from the if # clause in the next line and closing bracket below. @@ -1496,7 +1496,7 @@ route[SESSION_TIMER] eval_oper("(int)", -1); eval_oper(">=", -2); - # Let's check for the Suported header. + # Let's check for the Supported header. if (hf_value_exists("Supported", "timer")) { # The UAC supports Session-Timer, so we # only need to take a look at the values diff --git a/misc/examples/presence/full-no-failover.cfg b/misc/examples/presence/full-no-failover.cfg index 2120971e2..5060518a6 100644 --- a/misc/examples/presence/full-no-failover.cfg +++ b/misc/examples/presence/full-no-failover.cfg @@ -14,7 +14,7 @@ alias="test-domain.com" #user=ser #group=ser #open_fd_limit=1024 # sets the open file descriptors limit -mhomed=yes # usefull for multihomed hosts, small performance penalty +mhomed=yes # useful for multihomed hosts, small performance penalty #disable_tcp=yes #tcp_accept_aliases=yes # accepts the tcp alias via option (see NEWS) @@ -108,7 +108,7 @@ modparam("pa", "timer_interval", 10) # route for generated SUBSCRIBE requests for presence modparam("presence_b2b", "presence_route", "") -# waiting time from error to new attepmt about SUBSCRIBE +# waiting time from error to new attempt about SUBSCRIBE modparam("presence_b2b", "on_error_retry_time", 60) # how long wait for NOTIFY with Subscription-Status=terminated after unsubscribe modparam("presence_b2b", "wait_for_term_notify", 33) @@ -229,7 +229,7 @@ route{ if (!have_flat_list()) { # query_resource_list failed or was not called - # do standard RLS query acording to To/AOR + # do standard RLS query according to To/AOR if (!query_rls_services()) { log(1, "XCAP query failed\n"); t_reply("404", "No such list URI"); diff --git a/misc/examples/presence/no-db.cfg b/misc/examples/presence/no-db.cfg index 47eb8d71a..d165fed25 100644 --- a/misc/examples/presence/no-db.cfg +++ b/misc/examples/presence/no-db.cfg @@ -7,7 +7,7 @@ port=5060 children=2 alias="test-domain.com" -mhomed=yes # usefull for multihomed hosts, small performance penalty +mhomed=yes # useful for multihomed hosts, small performance penalty #tcp_accept_aliases=yes # accepts the tcp alias via option (see NEWS) #tcp_poll_method="sigio_rt" @@ -142,7 +142,7 @@ route{ if (!have_flat_list()) { # query_resource_list failed or was not called - # do standard RLS query acording to To/AOR + # do standard RLS query according to To/AOR query_rls_services(); } diff --git a/misc/examples/scripts/ctd.sh b/misc/examples/scripts/ctd.sh index a08615b86..dd3a7de93 100755 --- a/misc/examples/scripts/ctd.sh +++ b/misc/examples/scripts/ctd.sh @@ -28,7 +28,7 @@ # with Cisco 7960, Mitel 5055, Grandstream and Pingtel; Windows # Messenger does not support REFER. Never tested on solaris. # Some cisco 7960 images don't work (in particular, POS30202 -# doesnt, POS3-03-8-21 does) +# doesn't, POS3-03-8-21 does) # # History: # -------- @@ -129,7 +129,7 @@ fifo_job="$!" # initiate dummy INVITE with pre-3261 "on-hold" # (note the dots -- they mean in order of appearance: -# outbound uri, end of headers, end of body; eventualy +# outbound uri, end of headers, end of body; eventually # the FIFO request must be terminated with an empty line) cat > $FIFO < $TMP echo "The lockfile $LOCKF" >> $TMP - echo "was just removed because ist was older then $LOCK_TIMEOUT minutes." >> $TMP + echo "was just removed because it was older than $LOCK_TIMEOUT minutes." >> $TMP echo "But if you receive this mail the cause of this error still exists or respawned." >> $TMP SERR_SUBJECT="serresponse reminder" fi @@ -124,7 +124,7 @@ if [ ! -e $LOCKF ] ; then done else echo "unconfigured serresponse executed on ${HOSTN}." > $TMP - echo "Warning: This script if configured for the iptel.org enviroment." + echo "Warning: This script is configured for the iptel.org environment." echo " Please configure it to your local settings first." echo echo "If you do not press CTRL-C within 2 seconds an informational message" diff --git a/misc/examples/scripts/web_im/README b/misc/examples/scripts/web_im/README index 216f45d2a..978c1ba9d 100644 --- a/misc/examples/scripts/web_im/README +++ b/misc/examples/scripts/web_im/README @@ -2,7 +2,7 @@ # $Id$ # -This examle illustrate how to use ser's FIFO interface +This example illustrates how to use ser's FIFO interface to initate sending an instant message from a webpage. To enable this example, you need diff --git a/misc/examples/webrtc/kamailio-default-websocket.cfg b/misc/examples/webrtc/kamailio-default-websocket.cfg index 8005605ff..3b9402d05 100644 --- a/misc/examples/webrtc/kamailio-default-websocket.cfg +++ b/misc/examples/webrtc/kamailio-default-websocket.cfg @@ -198,7 +198,7 @@ tcp_rd_buf_size=16384 ####### Custom Parameters ######### -/* These parameters can be modified runtime via RPC interface +/* These parameters can be modified at runtime via RPC interface * - see the documentation of 'cfg_rpc' module. * * Format: group.id = value 'desc' description @@ -350,7 +350,7 @@ modparam("registrar", "gruu_enabled", 0) modparam("acc", "early_media", 0) modparam("acc", "report_ack", 0) modparam("acc", "report_cancels", 0) -/* by default ww do not adjust the direct of the sequential requests. +/* by default we do not adjust the direct of the sequential requests. * if you enable this parameter, be sure the enable "append_fromtag" * in "rr" module */ modparam("acc", "detect_direction", 0) diff --git a/misc/fuzz/fuzz_parse_msg.c b/misc/fuzz/fuzz_parse_msg.c index c96462bab..80fe75a22 100644 --- a/misc/fuzz/fuzz_parse_msg.c +++ b/misc/fuzz/fuzz_parse_msg.c @@ -13,65 +13,64 @@ #include "../parser/parse_identityinfo.h" #include "../parser/parse_disposition.h" -int LLVMFuzzerInitialize(int *argc, char ***argv) -{ - ksr_hname_init_index(); - return 0; +int LLVMFuzzerInitialize(int *argc, char ***argv) { + ksr_hname_init_index(); + return 0; } -int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) -{ - sip_msg_t orig_inv = {}; - orig_inv.buf = (char *)data; - orig_inv.len = size; +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + sip_msg_t orig_inv = { }; + orig_inv.buf = (char*)data; + orig_inv.len = size; - if(size >= 4 * BUF_SIZE) { - /* test with larger message than core accepts, but not indefinitely large */ - return 0; - } + if(size >= 4*BUF_SIZE) { + /* test with larger message than core accepts, but not indefinitely large */ + return 0; + } - if(parse_msg(orig_inv.buf, orig_inv.len, &orig_inv) < 0) { - goto cleanup; - } + if (parse_msg(orig_inv.buf, orig_inv.len, &orig_inv) < 0) { + goto cleanup; + } - parse_headers(&orig_inv, HDR_EOH_F, 0); + parse_headers(&orig_inv, HDR_EOH_F, 0); - parse_sdp(&orig_inv); + parse_sdp(&orig_inv); - parse_from_header(&orig_inv); + parse_from_header(&orig_inv); - parse_from_uri(&orig_inv); + parse_from_uri(&orig_inv); - parse_to_header(&orig_inv); + parse_to_header(&orig_inv); - parse_to_uri(&orig_inv); + parse_to_uri(&orig_inv); - parse_contact_headers(&orig_inv); + parse_contact_headers(&orig_inv); - parse_refer_to_header(&orig_inv); + parse_refer_to_header(&orig_inv); - parse_pai_header(&orig_inv); + parse_pai_header(&orig_inv); - parse_diversion_header(&orig_inv); + parse_diversion_header(&orig_inv); - parse_privacy(&orig_inv); + parse_privacy(&orig_inv); - parse_content_disposition(&orig_inv); + parse_content_disposition(&orig_inv); - parse_identityinfo_header(&orig_inv); + parse_identityinfo_header(&orig_inv); - parse_record_route_headers(&orig_inv); + parse_record_route_headers(&orig_inv); - parse_route_headers(&orig_inv); + parse_route_headers(&orig_inv); - str uri; - get_src_uri(&orig_inv, 0, &uri); + str uri; + get_src_uri(&orig_inv, 0, &uri); - str ssock; - get_src_address_socket(&orig_inv, &ssock); + str ssock; + get_src_address_socket(&orig_inv, &ssock); cleanup: - free_sip_msg(&orig_inv); + free_sip_msg(&orig_inv); - return 0; + return 0; } diff --git a/misc/fuzz/fuzz_uri.c b/misc/fuzz/fuzz_uri.c index 0636ce24b..3cc6dec06 100644 --- a/misc/fuzz/fuzz_uri.c +++ b/misc/fuzz/fuzz_uri.c @@ -2,13 +2,13 @@ #include "../config.h" #include "../parser/parse_uri.c" -int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) -{ - struct sip_uri uri; - if(size >= BUF_SIZE) { - /* test with larger message than core accepts, but not indefinitely large */ - return 0; - } - parse_uri(data, size, &uri); - return 0; +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + struct sip_uri uri; + if(size >= BUF_SIZE) { + /* test with larger message than core accepts, but not indefinitely large */ + return 0; + } + parse_uri(data, size, &uri); + return 0; } diff --git a/misc/scripts/dbtext/ser_dbtext.sh b/misc/scripts/dbtext/ser_dbtext.sh index d572dca06..52dc74009 100755 --- a/misc/scripts/dbtext/ser_dbtext.sh +++ b/misc/scripts/dbtext/ser_dbtext.sh @@ -38,7 +38,7 @@ DESCRIPTION actions. The database template for SER dbtext database is stored in dbtext_template - directory which can usualy be found in /var/lib/ser (depending on + directory which can usually be found in /var/lib/ser (depending on installation). You can use the template to create SER database manually if you cannot or do not want to use this shell wrapper. diff --git a/misc/scripts/mysql/sip-router_mysql.sh b/misc/scripts/mysql/sip-router_mysql.sh index aba468c7a..4190b9806 100755 --- a/misc/scripts/mysql/sip-router_mysql.sh +++ b/misc/scripts/mysql/sip-router_mysql.sh @@ -52,7 +52,7 @@ DESCRIPTION section COMMANDS for brief overview of supported actions. The SQL definition of tables and initial data within SER database is stored - in a separate files which can be usualy found under /usr/local/share/ser + in a separate files which can be usually found under /usr/local/share/ser (depending on installation). You can use those files to create SER database manually if you cannot or do not want to use this shell wrapper. @@ -97,7 +97,7 @@ COMMANDS that the tables are empty. update-data - Update initial data in the database. This command deletes vendor-controled + Update initial data in the database. This command deletes vendor-controlled rows from the database and replaces them with new data. diff --git a/misc/scripts/postgres/ser_postgres.sh b/misc/scripts/postgres/ser_postgres.sh index cca43e1ee..a689b5716 100755 --- a/misc/scripts/postgres/ser_postgres.sh +++ b/misc/scripts/postgres/ser_postgres.sh @@ -33,7 +33,7 @@ Usage: $COMMAND create [database] for SER and SERWeb. In addition to that two users are created, one with read/write permissions and one with read-only permissions. - Commmand 'drop' deletes database named '${DBNAME}' and associated users. + Command 'drop' deletes database named '${DBNAME}' and associated users. Command 'backup' Dumps the contents of the database in . If no database name is provided on the command line then the default '${DBNAME}' @@ -84,7 +84,7 @@ db_load() #pars: # Drop SER database db_drop() { - # Drop dabase + # Drop database # Revoke user permissions echo "Dropping database $1" diff --git a/misc/scripts/serconf.sh b/misc/scripts/serconf.sh index 9f04481be..478075c83 100755 --- a/misc/scripts/serconf.sh +++ b/misc/scripts/serconf.sh @@ -230,7 +230,7 @@ modparam("usrloc|acc|auth_db|group|msilo|uri", "db_url", "$SER_SQL_URI") # -- usrloc params -- -/* 0 -- dont use mysql, 1 -- write_through, 2--write_back */ +/* 0 -- don't use mysql, 1 -- write_through, 2 -- write_back */ modparam("usrloc", "db_mode", 2) modparam("usrloc", "timer_interval", 10) @@ -283,7 +283,7 @@ route{ }; - # Make sure that requests dont advertise addresses + # Make sure that requests don't advertise addresses # from private IP space (RFC1918) in Contact HF # (note: does not match with folded lines) if (search("^(Contact|m): .*@(192\.168\.|10\.|172\.16)")) { @@ -294,13 +294,13 @@ route{ && !( src_ip==192.168.0.0/16 || src_ip==10.0.0.0/8 || src_ip==172.16.0.0/12 )) { log("LOG: Someone trying to register from private IP again\n"); - sl_send_reply("479", "We dont accept private IP contacts" ); + sl_send_reply("479", "We don't accept private IP contacts" ); break; }; }; # anti-spam -- if somene claims to belong to our domain in From, - # challenge him (skip REGISTERs -- we will chalenge them later) + # challenge him (skip REGISTERs -- we will challenge them later) if (search("(From|F):.*$SER_DOMAIN_TEST_RE")) { # invites forwarded to other domains, like FWD may cause subsequent # request to come from there but have iptel in From -> verify @@ -374,7 +374,7 @@ route{ # avoid stealing incoming calls if (method=="REGISTER") { - # Make sure that user's dont register infinite loops + # Make sure that users don't register infinite loops # (note: does not match with folded lines) if (search("^(Contact|m): .*@$SER_DOMAIN_TEST_RE")) { log(1, "LOG: alert: someone trying to set aor==contact\n"); @@ -407,8 +407,8 @@ route{ break; }; - # some UACs might be fooled by Contacts our UACs generate to make MSN - # happy (web-im, e.g.) -- tell its urneachable + # some UACs might be fooled by Contacts our UACs generated to make MSN + # happy (web-im, e.g.) -- tell it is unreachable if (uri=~"sip:daemon@" ) { sl_send_reply("410", "daemon is gone"); break; @@ -422,7 +422,7 @@ route{ }; } else { # aliases (take precedences over PSTN number; provisioning interface - # is set up to assinge aliases beginning with 8) + # is set up to assign aliases beginning with 8) lookup("aliases"); }; @@ -471,7 +471,7 @@ route[2] { # routing logic for inbound requests aliased outbound; unlike # with real outbound requests we do not force authentication # as these calls are server by our server and we do not want -# to disqualify unathenticated request originatiors from other +# to disqualify unauthenticated request originatiors from other # domains route[5] { append_hf("P-hint: ALIASED-OUTBOUND\r\n"); diff --git a/misc/tools/kemi/python_mock/README.md b/misc/tools/kemi/python_mock/README.md index fdb3322c9..5e72e738c 100644 --- a/misc/tools/kemi/python_mock/README.md +++ b/misc/tools/kemi/python_mock/README.md @@ -19,10 +19,10 @@ Return values can be injected through the dictionary \_mock\_data ```python -#set retun value for all calls to the function +#set return value for all calls to the function _mock_data[module][function] = value -#set retun value for specific parameters being passed +#set return value for specific parameters being passed _mock_data[module][function][param_value] = value #call the function myFunc when func is passed, return of myFunc will diff --git a/misc/tools/kemi/python_mock/kemi_mock.py b/misc/tools/kemi/python_mock/kemi_mock.py index 6cb453c32..48a73efa2 100755 --- a/misc/tools/kemi/python_mock/kemi_mock.py +++ b/misc/tools/kemi/python_mock/kemi_mock.py @@ -14,15 +14,18 @@ from collections import defaultdict #python 3.2 doesnt support types.Union noUnion = False +reserved_keywords = {"async"} + + def printMocReturn(module_name, func, indent): param_names = [] param_list = [] param_signature = "" - if (func['params'] != 'none'): + if func['params'] is not None and func['params'] != 'none': param_list = func['params'].split(", ") i = 0 - for param in param_list: + for _ in param_list: param_names.append("param"+str(i)) i = i + 1 @@ -56,13 +59,13 @@ def printDefaultReturn(func, indent): for i in range(indent): prefix = prefix+"\t" - if(func['ret'] == "bool"): + if func['ret'] == "bool": print(prefix + "return True") - elif(func['ret'] == "int"): + elif func['ret'] == "int": print(prefix + "return 1") - elif (func['ret'] == "str"): + elif func['ret'] == "str": print(prefix + "return \"\"") - elif (func['ret'] == "xval"): + elif func['ret'] == "xval": print(prefix + "return None") else: print(prefix + "return") @@ -78,38 +81,39 @@ def printFunction(module_name, func, indent): log_format_params = "%s" - if indent > 0: - params = "self" - param_list = [] - if(func['params']!="none"): + if func['params'] is not None and func['params'] != "none": param_list = func['params'].split(", ") i = 0 - for param in param_list: + for _ in param_list: if params != "": params = params + ", " params = params + "param" + str(i) + ": " + param_list[i] log_params = log_params + ", param" + str(i) log_format_params = log_format_params + ", %s" i = i+1 + if len(param_list) > 0: + log_params = "(" + log_params + ")" prefix = "" for i in range(indent): prefix = prefix+"\t" - if(func['ret'] == "bool"): + if indent > 0: + print(prefix + "@staticmethod") + if func['ret'] == "bool": print(prefix + "def " + func['name'] +"("+params+") -> bool:") - elif(func['ret'] == "int"): + elif func['ret'] == "int": print(prefix + "def " + func['name'] +"("+params+") -> int:") - elif (func['ret'] == "str"): + elif func['ret'] == "str": print(prefix + "def " + func['name'] + "(" + params + ") -> int:") - elif(func['ret'] == "xval"): + elif func['ret'] == "xval": if noUnion: print(prefix + "def " + func['name'] + "(" + params + "):") else: - print(prefix + "def " + func['name'] +"("+params+") -> Union[int,str]:") + print(prefix + "def " + func['name'] +"("+params+") -> Union[int, str, None]:") else: print(prefix + "def " + func['name'] +"("+params+"):") - print(prefix + "\tprint(\"Calling " + log_format_params + "\" % ("+log_params+"))") + print(prefix + "\tprint(\"Calling " + log_format_params + "\" % "+log_params+")") printMocReturn(module_name, func, indent+1) print("") @@ -128,8 +132,10 @@ if len(sys.argv) > 2: if not noUnion: print("from typing import Union") +print("import sys") print("import types") -print("_mock_data={}") +print("_mock_data = {}") +print("") with open(sys.argv[1]) as f: data = json.load(f) @@ -177,6 +183,7 @@ if "pv" not in classes: for module_name, module in classes.items(): if module_name != "": + print("") print("class " + module_name.capitalize() + ":") for func in module: @@ -188,7 +195,10 @@ for func in classes['']: for module_name in classes.keys(): if module_name != "": - print(module_name + " = "+module_name.capitalize()+"()") + if module_name in reserved_keywords: + print("setattr(sys.modules[__name__], '" + module_name + "', " + module_name.capitalize() + "())") + else: + print(module_name + " = "+module_name.capitalize()+"()") print("") diff --git a/misc/tools/kemi/python_mock/test.py b/misc/tools/kemi/python_mock/test.py index cb1a0d676..04272bba0 100755 --- a/misc/tools/kemi/python_mock/test.py +++ b/misc/tools/kemi/python_mock/test.py @@ -2,6 +2,13 @@ import KSR +# this assumes you have your mock KSR.py in the local directory e.g. /test/ +# and your kemi code is in ../conf/kamailio.py + +sys.path.insert(0, "../conf/") +import kamailio as kamailio + + #return sip:hello@world only if $ru is passed to pv.get KSR._mock_data['pv']['get'] = {} KSR._mock_data['pv']['get']['$ru'] = "sip:hello@world" @@ -22,6 +29,11 @@ def appendHeader(param0: str): KSR._mock_data['hdr']['append'] = appendHeader KSR.hdr.append("X-HDR: my-header") + +k = kamailio.kamailio() +k.ksr_request_route(None) # Call the kemi script, the mock implementations will be called + +# Validate the results if appendCalled: print("hdr.append successfully called!") else: diff --git a/misc/tools/pike_top/pike_top.c b/misc/tools/pike_top/pike_top.c index 2c146d6a6..9abfd7be2 100644 --- a/misc/tools/pike_top/pike_top.c +++ b/misc/tools/pike_top/pike_top.c @@ -41,89 +41,87 @@ // XML elements in result // they MUST NOT have a number on the tail // because pike uses it for "row" numbering -static const char *const MAX_HITS = "max_hits"; -static const char *const IP_ADDR = "ip_addr"; -static const char *const LEAF_HITS_PREV = "leaf_hits_prev"; -static const char *const LEAF_HITS_CURR = "leaf_hits_curr"; -static const char *const EXPIRES = "expires"; -static const char *const STATUS = "status"; -static const char *const NUMBER_OF_ROWS = "number_of_rows"; +static const char * const MAX_HITS = "max_hits"; +static const char * const IP_ADDR = "ip_addr"; +static const char * const LEAF_HITS_PREV = "leaf_hits_prev"; +static const char * const LEAF_HITS_CURR = "leaf_hits_curr"; +static const char * const EXPIRES = "expires"; +static const char * const STATUS = "status"; +static const char * const NUMBER_OF_ROWS = "number_of_rows"; #define IP_ADDR_MAX_LENGTH 40 -#define STATUS_MAX_LENGTH 10 -typedef struct TopItem -{ - char ip_addr[IP_ADDR_MAX_LENGTH]; - in_addr_t ipv4_addr; /* uint32_t */ - struct in6_addr ipv6_addr; - unsigned short leaf_hits[2]; - unsigned int expires; +#define STATUS_MAX_LENGTH 10 +typedef struct TopItem { + char ip_addr[IP_ADDR_MAX_LENGTH]; + in_addr_t ipv4_addr; /* uint32_t */ + struct in6_addr ipv6_addr; + unsigned short leaf_hits[2]; + unsigned int expires; char status[STATUS_MAX_LENGTH]; - int num_of_ips; /* number of IP addresses in aggregated result */ + int num_of_ips; /* number of IP addresses in aggregated result */ } TopItem; -int compare_TopItem_hits(const void *left, const void *right) +int compare_TopItem_hits(const void* left, const void *right) { TopItem *li = (TopItem *)left; TopItem *ri = (TopItem *)right; - return li->leaf_hits[0] + li->leaf_hits[1] - ri->leaf_hits[0] - - ri->leaf_hits[1]; + return li->leaf_hits[0] + li->leaf_hits[1] - ri->leaf_hits[0] - ri->leaf_hits[1]; } -/** Compare function to qsort array in reverse order (biger first) */ -int compare_TopItem_hits_reverse(const void *left, const void *right) +/** Compare function to qsort array in reverse order (bigger first) */ +int compare_TopItem_hits_reverse(const void* left, const void *right) { return compare_TopItem_hits(right, left); } int compare_TopItem_ipv4_addr(const void *item1, const void *item2) { - return ((TopItem *)item1)->ipv4_addr - ((TopItem *)item2)->ipv4_addr; + return ((TopItem*)item1)->ipv4_addr - ((TopItem*)item2)->ipv4_addr; } /** * @return concatenated string in newly allocated memory */ -static char *concat(const char *name, int index) +static char *concat( const char *name, int index ) { char *ptr; int rv; rv = asprintf(&ptr, "%s%d", name, index); - if(rv == -1) + if ( rv == -1 ) return 0; return ptr; } -static void strfree(char *ptr) +static void strfree( char *ptr ) { - if(ptr) + if (ptr) free(ptr); } -static void die_if_fault_occurred(xmlrpc_env *env) +static void die_if_fault_occurred (xmlrpc_env *env) { - if(env->fault_occurred) { - fprintf(stderr, "XML-RPC Fault: %s (%d)\n", env->fault_string, - env->fault_code); + if (env->fault_occurred) { + fprintf(stderr, "XML-RPC Fault: %s (%d)\n", + env->fault_string, env->fault_code); exit(1); } } /** @return 0 if everything is OK, 1 otherwise */ -static int fault_occurred(xmlrpc_env *env) +static int fault_occurred (xmlrpc_env *env) { - if(env->fault_occurred) { - fprintf(stderr, "XML-RPC Fault: %s (%d)\n", env->fault_string, - env->fault_code); + if (env->fault_occurred) { + fprintf(stderr, "XML-RPC Fault: %s (%d)\n", + env->fault_string, env->fault_code); return 1; } return 0; } -static void die_if_fault_occurred_line(xmlrpc_env *env, int line) +static void die_if_fault_occurred_line (xmlrpc_env *env, int line) { - if(env->fault_occurred) + if (env->fault_occurred) fprintf(stderr, "LINE: %d\n", line); die_if_fault_occurred(env); } @@ -131,26 +129,23 @@ static void die_if_fault_occurred_line(xmlrpc_env *env, int line) void print_help() { printf("\n"); - if(isatty(1)) - printf("usage: \033[1mpike_top : [--hot|--warm|--all] " - "[--mask]\033[0m\n"); + if ( isatty(1) ) + printf("usage: \033[1mpike_top : [--hot|--warm|--all] [--mask]\033[0m\n"); else - printf("usage: pike_top : [--hot|--warm|--all] " - "[--mask] [--ipleaf|--inner]\n"); + printf("usage: pike_top : [--hot|--warm|--all] [--mask] [--ipleaf|--inner]\n"); printf("\n"); printf("\toptions:\n" - "\t\t--hot ... show hot IP leaves\n" - "\t\t--all ... show all IP leaves\n" - "\t\t--mask ... aggregate results regarding IP mask length\n" - "\t\t (default 32, i.e. not aggregate)\n" - "\t\t IPv4 only at this time\n\n" - "\t\t\tdefault is to show HOT nodes\n\n"); - if(isatty(1)) - printf("You can use \033[1mwatch\033[0m(1) utility for periodical " - "output.\n\n"); + "\t\t--hot ... show hot IP leaves\n" + "\t\t--all ... show all IP leaves\n" + "\t\t--mask ... aggregate results regarding IP mask length\n" + "\t\t (default 32, i.e. not aggregate)\n" + "\t\t IPv4 only at this time\n\n" + "\t\t\tdefault is to show HOT nodes\n\n"); + if ( isatty(1) ) + printf("You can use \033[1mwatch\033[0m(1) utility for periodical output.\n\n"); else printf("You can use watch(1) utility for periodical output.\n\n"); - /* +/* printf("Note:\n" "It is a question if reporting warm nodes is useful and if yes, how to report\n" "them. I feel that should be more welcome to report parents of warm nodes,\n" @@ -159,36 +154,39 @@ void print_help() } /* Following options are conforming to definition of node status defined in pike/ip_tree.h */ -#define OPT_WARM 1 -#define OPT_HOT 2 -#define OPT_ALL 3 +#define OPT_WARM 1 +#define OPT_HOT 2 +#define OPT_ALL 3 /** * @param options ORed cmdline options * @return position of first non option parameter */ int process_options(int argc, char *argv[], int *options, int *mask_length) { - static struct option long_options[] = {{"hot", 0, 0, 'h'}, - /* {"warm", 0, 0, 'w'}, */ - {"all", 0, 0, 'a'}, {"mask", 0, 0, 'm'}, {"help", 0, 0, '?'}, - {0, 0, 0, 0}}; + static struct option long_options[] = { + {"hot", 0, 0, 'h'}, +/* {"warm", 0, 0, 'w'}, */ + {"all", 0, 0, 'a'}, + {"mask", 0, 0, 'm'}, + {"help", 0, 0, '?'}, + {0,0,0,0} + }; int c, index, counter; *options = 0; counter = 0; - while((c = getopt_long(argc, argv, "hwam:", long_options, &index)) != -1) { - switch(c) { + while ( (c=getopt_long(argc, argv, "hwam:", long_options, &index)) != -1 ) { + switch (c) { case 'h': *options = OPT_HOT; ++counter; break; - /* case 'w': +/* case 'w': *options = OPT_WARM; ++counter; break; -*/ - case 'a': +*/ case 'a': *options = OPT_ALL; ++counter; break; @@ -203,13 +201,13 @@ int process_options(int argc, char *argv[], int *options, int *mask_length) break; } } - if(counter > 1) { - fprintf(stderr, "ERROR: Node type selectors are exlusive, only one of " + if ( counter > 1 ) { + fprintf(stderr, "ERROR: Node type selectors are exclusive, only one of " "them can be used\n"); print_help(); exit(1); } - if(*options == 0) + if ( *options == 0 ) *options = OPT_HOT; return optind; @@ -222,19 +220,18 @@ int process_options(int argc, char *argv[], int *options, int *mask_length) * @param rv returned value * @return 1 if succeed and 0 otherwise */ -int get_int_from_struct_by_name( - xmlrpc_value *structP, const char *element_name, int *rv) +int get_int_from_struct_by_name(xmlrpc_value *structP, const char *element_name, int *rv) { xmlrpc_env env; xmlrpc_env_init(&env); xmlrpc_value *valueP; xmlrpc_struct_find_value(&env, structP, element_name, &valueP); - if(env.fault_occurred) + if ( env.fault_occurred ) goto error; xmlrpc_read_int(&env, valueP, rv); - if(env.fault_occurred) + if ( env.fault_occurred ) goto error1; xmlrpc_DECREF(valueP); @@ -251,9 +248,8 @@ error: * @param rv contains newly allocated string or NULL if fails * @return 1 if succeed and 0 otherwise */ -/* FIXME terminates the programm if it fails */ -int get_string_from_struct_by_name( - xmlrpc_value *structP, const char *element_name, char **rv) +/* FIXME terminates the programme if it fails */ +int get_string_from_struct_by_name(xmlrpc_value *structP, const char *element_name, char **rv) { xmlrpc_env env; xmlrpc_env_init(&env); @@ -281,8 +277,7 @@ int get_int_from_struct_by_idx(xmlrpc_value *structP, int index, int *rv) xmlrpc_value *keyP; xmlrpc_value *valueP; - xmlrpc_struct_read_member(&env, structP, index, &keyP, - &valueP); /* increment refcount of returned values */ + xmlrpc_struct_read_member(&env, structP, index, &keyP, &valueP); /* increment refcount of returned values */ die_if_fault_occurred_line(&env, __LINE__); xmlrpc_read_int(&env, valueP, rv); die_if_fault_occurred_line(&env, __LINE__); @@ -290,20 +285,17 @@ int get_int_from_struct_by_idx(xmlrpc_value *structP, int index, int *rv) return 1; } -enum _value_type -{ +enum _value_type { TYPE_NOT_DEF = 0, TYPE_INTEGER = 1, - TYPE_STRING = 2 + TYPE_STRING = 2 }; typedef enum _value_type value_type; -struct _key_value_pair -{ +struct _key_value_pair { char *key; value_type type; - union value - { + union value { int integer; char *string; void *value; @@ -312,10 +304,10 @@ struct _key_value_pair typedef struct _key_value_pair key_value_pair; void key_value_pair_cleanup(key_value_pair *kvp) { - if(kvp && kvp->key) { + if (kvp && kvp->key) { free(kvp->key); } - if(kvp && kvp->type == TYPE_STRING && kvp->value.string) { + if (kvp && kvp->type == TYPE_STRING && kvp->value.string) { free(kvp->value.string); } kvp->key = 0; @@ -329,7 +321,7 @@ void key_value_pair_cleanup(key_value_pair *kvp) * @param rv pointer to key_value_pair * @return 1 if succeed and 0 otherwise */ -/* FIXME terminates the programm if it fails */ +/* FIXME terminates the programme if it fails */ int get_struct_item_by_idx(xmlrpc_value *structP, int index, key_value_pair *rv) { xmlrpc_env env; @@ -339,12 +331,11 @@ int get_struct_item_by_idx(xmlrpc_value *structP, int index, key_value_pair *rv) int length; const char *string; - xmlrpc_struct_read_member(&env, structP, index, &keyP, - &valueP); /* increment refcount of returned values */ + xmlrpc_struct_read_member(&env, structP, index, &keyP, &valueP); /* increment refcount of returned values */ die_if_fault_occurred_line(&env, __LINE__); xmlrpc_read_string(&env, keyP, (const char **)&rv->key); /* handle value type */ - switch(xmlrpc_value_type(valueP)) { + switch ( xmlrpc_value_type(valueP) ) { case XMLRPC_TYPE_INT: xmlrpc_read_int(&env, valueP, &rv->value.integer); die_if_fault_occurred_line(&env, __LINE__); @@ -352,19 +343,16 @@ int get_struct_item_by_idx(xmlrpc_value *structP, int index, key_value_pair *rv) break; case XMLRPC_TYPE_STRING: xmlrpc_read_string(&env, valueP, &string); - printf("get_struct_item_by_idx: ptr = %p, string value = '%s'\n", - string, string); + printf("get_struct_item_by_idx: ptr = %p, string value = '%s'\n", string, string); die_if_fault_occurred_line(&env, __LINE__); rv->value.string = (char *)string; rv->type = TYPE_STRING; break; default: - fprintf(stderr, - "Wrong type of return value in key: '%s', exiting...\n", - rv->key); + fprintf(stderr, "Wrong type of return value in key: '%s', exiting...\n", rv->key); exit(1); } - xmlrpc_DECREF(keyP); /* decrement refcount */ + xmlrpc_DECREF(keyP); /* decrement refcount */ xmlrpc_DECREF(valueP); die_if_fault_occurred_line(&env, __LINE__); /* FIXME add error handling */ @@ -384,7 +372,7 @@ int read_row(xmlrpc_value *structP, int index, TopItem *top_item) char *string = 0; elem = concat(IP_ADDR, index); - if(!get_string_from_struct_by_name(structP, elem, &string)) + if ( ! get_string_from_struct_by_name(structP, elem, &string) ) goto error; strncpy(top_item->ip_addr, string, sizeof(top_item->ip_addr)); free(string); @@ -392,25 +380,22 @@ int read_row(xmlrpc_value *structP, int index, TopItem *top_item) free(elem); elem = concat(LEAF_HITS_PREV, index); - if(!get_int_from_struct_by_name( - structP, elem, (unsigned int *)&top_item->leaf_hits[0])) + if ( ! get_int_from_struct_by_name(structP, elem, (unsigned int *)&top_item->leaf_hits[0]) ) goto error; free(elem); elem = concat(LEAF_HITS_CURR, index); - if(!get_int_from_struct_by_name( - structP, elem, (unsigned int *)&top_item->leaf_hits[1])) + if ( ! get_int_from_struct_by_name(structP, elem, (unsigned int *)&top_item->leaf_hits[1]) ) goto error; free(elem); elem = concat(EXPIRES, index); - if(!get_int_from_struct_by_name( - structP, elem, (unsigned int *)&top_item->expires)) + if ( ! get_int_from_struct_by_name(structP, elem, (unsigned int *)&top_item->expires) ) goto error; free(elem); elem = concat(STATUS, index); - if(!get_string_from_struct_by_name(structP, elem, &string)) + if ( ! get_string_from_struct_by_name(structP, elem, &string) ) goto error; strncpy(top_item->status, string, sizeof(top_item->status)); free(string); @@ -419,7 +404,7 @@ int read_row(xmlrpc_value *structP, int index, TopItem *top_item) return 1; error: - if(string) + if ( string ) free(string); free(elem); @@ -430,41 +415,37 @@ void print_row(TopItem *ti) { char *fmt; - if(!ti) { - printf("%-15s %10s %10s %10s %-10s\n", "IP address", "HITS PREV", - "HITS CURR", "EXPIRES", "STATUS"); + if ( ! ti ) { + printf("%-15s %10s %10s %10s %-10s\n", "IP address", "HITS PREV", "HITS CURR", "EXPIRES", "STATUS"); return; } - if(strlen(ti->ip_addr) > 15) // IPv6 addr + if ( strlen(ti->ip_addr) > 15 ) // IPv6 addr fmt = "%s\n %10d %10d %10d %-10s\n"; else fmt = "%-15s %10d %10d %10d %-10s\n"; - printf(fmt, ti->ip_addr, ti->leaf_hits[0], ti->leaf_hits[1], ti->expires, - ti->status); + printf(fmt, ti->ip_addr, ti->leaf_hits[0], ti->leaf_hits[1], ti->expires, ti->status); } -void print_row_agg(TopItem *ti) /* IPv4 only */ +void print_row_agg(TopItem *ti) /* IPv4 only */ { char *fmt; - if(!ti) { - printf("%-15s %10s %10s %5s\n", "IP address", "HITS PREV", "HITS CURR", - "COUNT"); + if ( ! ti ) { + printf("%-15s %10s %10s %5s\n", "IP address", "HITS PREV", "HITS CURR", "COUNT"); return; } fmt = "%-15s %10d %10d %5d\n"; - printf(fmt, ti->ip_addr, ti->leaf_hits[0], ti->leaf_hits[1], - ti->num_of_ips); + printf(fmt, ti->ip_addr, ti->leaf_hits[0], ti->leaf_hits[1], ti->num_of_ips); } -uint32_t mask(int msklen) +uint32_t mask( int msklen ) { - if(msklen) - return 0xffffffff ^ ((1 << (32 - msklen)) - 1); + if ( msklen ) + return 0xffffffff ^ ((1 << (32-msklen)) - 1); else return 0; } @@ -474,54 +455,54 @@ void print_rows(TopItem *root, int nmemb, int mask_length) int i; void (*print_function)(TopItem *); - if(mask_length == 32) + if (mask_length == 32) print_function = print_row; else print_function = print_row_agg; print_function(0); - for(i = 0; i < nmemb; ++i, ++root) { + for ( i = 0; i < nmemb; ++i, ++root ) { print_function(root); } } -int main(int argc, char *argv[]) +int main( int argc, char *argv[] ) { xmlrpc_env env; - xmlrpc_value *resultP; - xmlrpc_value *keyP; - xmlrpc_value *valueP; + xmlrpc_value * resultP; + xmlrpc_value * keyP; + xmlrpc_value * valueP; int struct_size; int i, j; size_t length; - const char *str_key_value; - xmlrpc_int int_key_value; + const char * str_key_value; + xmlrpc_int int_key_value; unsigned int max_hits = 0; unsigned int rows = 0; int rv; char *uri; - int options; /* what kind of nodes should be processed */ - int uri_pos; /* position of first non option argument */ + int options; /* what kind of nodes should be processed */ + int uri_pos; /* position of first non option argument */ char stropts[16]; - int pos = 0; - int mask_length = 32; /* 32 means NO aggregate */ + int pos = 0; + int mask_length = 32; /* 32 means NO aggregate */ - if(argc - 1 < 1) { + if (argc-1 < 1) { print_help(); exit(0); } uri_pos = process_options(argc, argv, &options, &mask_length); - switch(options) { + switch (options) { case OPT_HOT: - sprintf(stropts, "HOT"); - break; + sprintf(stropts, "HOT"); + break; case OPT_ALL: - sprintf(stropts, "ALL"); - break; + sprintf(stropts, "ALL"); + break; case OPT_WARM: - sprintf(stropts, "WARM"); - break; + sprintf(stropts, "WARM"); + break; } printf("Nodes = %s\n", stropts); printf("Mask = /%d\n", mask_length); @@ -538,12 +519,14 @@ int main(int argc, char *argv[]) const char * const format, ...); */ asprintf(&uri, "http://%s/RPC2", argv[uri_pos]); - resultP = xmlrpc_client_call(&env, uri, "pike.top", "(s)", stropts); + resultP = xmlrpc_client_call(&env, uri, + "pike.top", + "(s)", stropts); free(uri); die_if_fault_occurred_line(&env, __LINE__); /* parse returned structure */ - if(xmlrpc_value_type(resultP) != XMLRPC_TYPE_STRUCT) { + if ( xmlrpc_value_type(resultP) != XMLRPC_TYPE_STRUCT ) { printf("unexpected result - should be structure\n"); xmlrpc_env_clean(&env); xmlrpc_client_cleanup(); @@ -552,84 +535,80 @@ int main(int argc, char *argv[]) struct_size = xmlrpc_struct_size(&env, resultP); die_if_fault_occurred_line(&env, __LINE__); - // printf("Struct size: %d\n", struct_size); +// printf("Struct size: %d\n", struct_size); - if(!get_int_from_struct_by_name(resultP, MAX_HITS, &max_hits)) { - fprintf(stderr, "ERROR: %s not foung in result\n", MAX_HITS); - exit(1); + if ( ! get_int_from_struct_by_name(resultP, MAX_HITS, &max_hits) ) { + fprintf(stderr, "ERROR: %s not found in result\n", MAX_HITS); + exit (1); } printf("max_hits = %d\n", max_hits); - if(!get_int_from_struct_by_name(resultP, NUMBER_OF_ROWS, &rows)) { - fprintf(stderr, "ERROR: %s not foung in result\n", NUMBER_OF_ROWS); - exit(1); + if ( ! get_int_from_struct_by_name(resultP, NUMBER_OF_ROWS, &rows) ) { + fprintf(stderr, "ERROR: %s not found in result\n", NUMBER_OF_ROWS); + exit (1); } printf("rows = %d\n", rows); TopItem top_items[rows]; - TopItem *item; /* tmp item ptr */ - TopItem *result_items = top_items; /* if no aggregation use this */ + TopItem *item; /* tmp item ptr */ + TopItem *result_items = top_items; /* if no aggregation use this */ memset(top_items, 0, sizeof(top_items)); /* aggregated values */ - if(rows == 0) + if ( rows == 0 ) return 0; - for(i = 0, item = top_items; i < rows; ++i, ++item) { - if(!read_row(resultP, i, item)) { + for ( i = 0, item = top_items; i < rows; ++i, ++item ) { + if ( ! read_row(resultP, i, item) ) { fprintf(stderr, "ERROR: while reading row number %d\n", i); } /* fill in ipv4 addr */ - // printf("item[%d].ip_addr = %s, len = %d\n", i, item->ip_addr, strlen(item->ip_addr)); +// printf("item[%d].ip_addr = %s, len = %d\n", i, item->ip_addr, strlen(item->ip_addr)); rv = inet_pton(AF_INET, item->ip_addr, &item->ipv4_addr); - if(rv > 0) { - // printf("IPv4 addr: %x\n", item->ipv4_addr); + if ( rv > 0 ) { +// printf("IPv4 addr: %x\n", item->ipv4_addr); } else { - fprintf(stderr, - "IP conversion failed - not an IPv4 address: '%s'\n", - item->ip_addr); /* conversion failed from any reason */ + fprintf(stderr, "IP conversion failed - not an IPv4 address: '%s'\n", item->ip_addr); /* conversion failed from any reason */ printf("item[%d].ipv4_addr = %x\n", i, item->ipv4_addr); } + } - assert(rows > 0); + assert( rows > 0 ); /* if IP mask length is shorter than 32 then aggregate list according to the mask */ - if(mask_length < 32) { + if ( mask_length < 32 ) { uint32_t ip_mask = htonl(mask(mask_length)); - qsort(top_items, rows, sizeof(TopItem), - compare_TopItem_ipv4_addr); /* sort by IPv4 */ + qsort(top_items, rows, sizeof(TopItem), compare_TopItem_ipv4_addr); /* sort by IPv4 */ /* skip items without ipv4 address */ - i = 0; /* index of non aggregated items */ - while(!top_items[i].ipv4_addr && i < rows) { - printf("Skip item[%d] - do not has IPv4 address: %s\n", i, - top_items[i].ip_addr); + i = 0; /* index of non aggregated items */ + while (!top_items[i].ipv4_addr && i < rows ) { + printf("Skip item[%d] - do not has IPv4 address: %s\n", i, top_items[i].ip_addr); memset(&top_items[i], 0, sizeof(TopItem)); ++i; } - j = 0; /* index of aggregated items */ - if(i == 0) + j = 0; /* index of aggregated items */ + if ( i == 0 ) ++i; top_items[0].ipv4_addr &= ip_mask; top_items[0].num_of_ips = 1; - inet_ntop(AF_INET, &top_items[0].ipv4_addr, top_items[0].ip_addr, - sizeof(top_items[0].ip_addr)); - while(i < rows) { + inet_ntop(AF_INET, &top_items[0].ipv4_addr, top_items[0].ip_addr, sizeof(top_items[0].ip_addr)); + while ( i < rows ) { top_items[i].ipv4_addr &= ip_mask; - if(top_items[j].ipv4_addr == top_items[i].ipv4_addr) { + if ( top_items[j].ipv4_addr == top_items[i].ipv4_addr ) { top_items[j].leaf_hits[0] += top_items[i].leaf_hits[0]; top_items[j].leaf_hits[1] += top_items[i].leaf_hits[1]; ++(top_items[j].num_of_ips); ++i; - } else { + } + else { ++j; top_items[j] = top_items[i]; top_items[j].num_of_ips = 1; - inet_ntop(AF_INET, &top_items[j].ipv4_addr, - top_items[j].ip_addr, sizeof(top_items[j].ip_addr)); + inet_ntop(AF_INET, &top_items[j].ipv4_addr, top_items[j].ip_addr, sizeof(top_items[j].ip_addr)); ++i; } } @@ -638,7 +617,7 @@ int main(int argc, char *argv[]) qsort(top_items, rows, sizeof(TopItem), compare_TopItem_hits_reverse); - print_rows(top_items, rows, mask_length); + print_rows( top_items, rows, mask_length ); /* Dispose of our result value. */ xmlrpc_DECREF(resultP); diff --git a/misc/tools/profile/launch.sh b/misc/tools/profile/launch.sh index e6699cc88..841c48820 100644 --- a/misc/tools/profile/launch.sh +++ b/misc/tools/profile/launch.sh @@ -69,7 +69,7 @@ function report() cat > $REP << EOF first line ... time spent in tested procedure second line (yyrestart) ... total time -third line (receive_msg) ... numer of calls +third line (receive_msg) ... number of calls % cumulative self self total time seconds seconds calls ms/call ms/call name EOF diff --git a/misc/tools/protoshoot/protoshoot.c b/misc/tools/protoshoot/protoshoot.c index 97bd5369f..6eced5fc2 100644 --- a/misc/tools/protoshoot/protoshoot.c +++ b/misc/tools/protoshoot/protoshoot.c @@ -25,6 +25,7 @@ */ + #include #include #include @@ -44,8 +45,8 @@ #include -static char *version = "protoshoot 0.4"; -static char *help_msg = "\ +static char *version="protoshoot 0.4"; +static char* help_msg="\ Usage: protoshoot -f file -d address -p port -c count [-v]\n\ Options:\n\ -f file file with the content of the udp packet (max 65k)\n\ @@ -68,23 +69,17 @@ Options:\n\ #define BUF_SIZE 65535 -enum protos -{ - PROTO_NONE, - PROTO_UDP, - PROTO_TCP, - PROTO_SCTP -}; +enum protos { PROTO_NONE, PROTO_UDP, PROTO_TCP, PROTO_SCTP }; -int main(int argc, char **argv) +int main (int argc, char** argv) { int fd; int sock; char c; - int n, r; - char *tmp; + int n,r; + char* tmp; char buf[BUF_SIZE]; - struct hostent *he; + struct hostent* he; struct sockaddr_in addr; int count; @@ -105,76 +100,76 @@ int main(int argc, char **argv) int err; /* init */ - count = 1; - verbose = 0; - fname = 0; - dst = "127.0.0.1"; - port = 5060; - usec = 0; - throttle = 0; - random_sleep = 0; - proto = PROTO_UDP; - tcp_rst = 0; - con_no = 1; - sctp_o2o = 0; - err = 0; + count=1; + verbose=0; + fname=0; + dst="127.0.0.1"; + port=5060; + usec=0; + throttle=0; + random_sleep=0; + proto=PROTO_UDP; + tcp_rst=0; + con_no=1; + sctp_o2o=0; + err=0; - opterr = 0; - while((c = getopt(argc, argv, "f:c:d:p:s:t:n:rTS1RvhV")) != -1) { - switch(c) { + opterr=0; + while ((c=getopt(argc,argv, "f:c:d:p:s:t:n:rTS1RvhV"))!=-1){ + switch(c){ case 'f': - fname = optarg; + fname=optarg; break; case 'v': verbose++; break; case 'd': - dst = optarg; + dst=optarg; break; case 'p': - port = strtol(optarg, &tmp, 10); - if((tmp == 0) || (*tmp)) { + port=strtol(optarg, &tmp, 10); + if ((tmp==0)||(*tmp)){ fprintf(stderr, "bad port number: -p %s\n", optarg); goto error; } break; case 'c': - count = strtol(optarg, &tmp, 10); - if((tmp == 0) || (*tmp)) { + count=strtol(optarg, &tmp, 10); + if ((tmp==0)||(*tmp)){ fprintf(stderr, "bad count: -c %s\n", optarg); goto error; } break; case 's': - usec = strtol(optarg, &tmp, 10); - if((tmp == 0) || (*tmp)) { + usec=strtol(optarg, &tmp, 10); + if ((tmp==0)||(*tmp)){ fprintf(stderr, "bad count: -c %s\n", optarg); goto error; } break; case 't': - throttle = strtol(optarg, &tmp, 10); - if((tmp == 0) || (*tmp)) { + throttle=strtol(optarg, &tmp, 10); + if ((tmp==0)||(*tmp)){ fprintf(stderr, "bad count: -c %s\n", optarg); goto error; } break; case 'n': - con_no = strtol(optarg, &tmp, 10); - if((tmp == 0) || (*tmp) || (con_no < 1)) { + con_no=strtol(optarg, &tmp, 10); + if ((tmp==0)||(*tmp)||(con_no<1)){ fprintf(stderr, "bad count: -c %s\n", optarg); goto error; } break; case 'r': - random_sleep = 1; + random_sleep=1; break; case 'T': - proto = PROTO_TCP; + proto=PROTO_TCP; break; case 'S': #ifdef USE_SCTP - proto = PROTO_SCTP; + proto=PROTO_SCTP; #else fprintf(stderr, "sctp not supported (recompile with " "-DUSE_SCTP)\n"); @@ -182,10 +177,10 @@ int main(int argc, char **argv) #endif /* USE_SCTP */ break; case '1': - sctp_o2o = 1; + sctp_o2o=1; break; case 'R': - tcp_rst = 1; + tcp_rst=1; break; case 'V': printf("version: %s\n", version); @@ -197,85 +192,84 @@ int main(int argc, char **argv) exit(0); break; case '?': - if(isprint(optopt)) + if (isprint(optopt)) fprintf(stderr, "Unknown option '-%c'\n", optopt); else fprintf(stderr, "Unknown character '\\x%x'\n", optopt); goto error; case ':': - fprintf(stderr, "Option '-%c' requires an argument.\n", optopt); + fprintf(stderr, "Option '-%c' requires an argument.\n", + optopt); goto error; break; default: - abort(); + abort(); } } /* check if all the required params are present */ - if(fname == 0) { + if (fname==0){ fprintf(stderr, "Missing -f file\n"); exit(-1); } - if(dst == 0) { + if (dst==0){ fprintf(stderr, "Missing destination (-d ...)\n"); exit(-1); } - if(port == 0) { + if(port==0){ fprintf(stderr, "Missing port number (-p port)\n"); exit(-1); - } else if(port < 0) { + }else if(port<0){ fprintf(stderr, "Invalid port number (-p %d)\n", port); exit(-1); } - if(count == 0) { + if(count==0){ fprintf(stderr, "Missing packet count (-c number)\n"); exit(-1); - } else if(count < 0) { + }else if(count<0){ fprintf(stderr, "Invalid packet count (-c %d)\n", count); exit(-1); } - if(proto == PROTO_UDP || (proto == PROTO_SCTP && !sctp_o2o)) - con_no = 1; + if (proto==PROTO_UDP || (proto==PROTO_SCTP && !sctp_o2o)) con_no=1; /* ignore sigpipe */ - if(signal(SIGPIPE, SIG_IGN) == SIG_ERR) { + if (signal(SIGPIPE, SIG_IGN)==SIG_ERR){ fprintf(stderr, "failed to ignore SIGPIPE: %s\n", strerror(errno)); exit(-1); } /* open packet file */ - fd = open(fname, O_RDONLY); - if(fd < 0) { + fd=open(fname, O_RDONLY); + if (fd<0){ fprintf(stderr, "ERROR: loading packet-file(%s): %s\n", fname, strerror(errno)); goto error; } - n = read(fd, buf, BUF_SIZE); - if(n < 0) { + n=read(fd, buf, BUF_SIZE); + if (n<0){ fprintf(stderr, "ERROR: reading file(%s): %s\n", fname, strerror(errno)); goto error; } - if(verbose) - printf("read %d bytes from file %s\n", n, fname); + if (verbose) printf("read %d bytes from file %s\n", n, fname); close(fd); /* resolve destination */ - he = gethostbyname(dst); - if(he == 0) { + he=gethostbyname(dst); + if (he==0){ fprintf(stderr, "ERROR: could not resolve %s\n", dst); goto error; } /* open socket*/ - addr.sin_family = he->h_addrtype; - addr.sin_port = htons(port); + addr.sin_family=he->h_addrtype; + addr.sin_port=htons(port); #ifdef HAVE_SOCKADDR_SA_LEN - addr.sin_len = sizeof(struct sockaddr_in); + addr.sin_len=sizeof(struct sockaddr_in); #endif memcpy(&addr.sin_addr.s_addr, he->h_addr_list[0], he->h_length); - for(k = 0; k < con_no; k++) { - switch(proto) { + for (k=0; kh_addrtype, SOCK_DGRAM, 0); break; @@ -285,112 +279,100 @@ int main(int argc, char **argv) #ifdef USE_SCTP case PROTO_SCTP: sock = socket(he->h_addrtype, - sctp_o2o ? SOCK_STREAM : SOCK_SEQPACKET, IPPROTO_SCTP); + sctp_o2o?SOCK_STREAM:SOCK_SEQPACKET, + IPPROTO_SCTP); break; #endif /* USE_SCTP */ default: fprintf(stderr, "BUG: unkown proto %d\n", proto); goto error; } - if(sock == -1) { + if (sock==-1){ fprintf(stderr, "ERROR: socket: %s\n", strerror(errno)); goto error; } - if(proto == PROTO_TCP) { - t = 1; - if(setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &t, sizeof(t)) < 0) { + if (proto==PROTO_TCP){ + t=1; + if (setsockopt(sock, IPPROTO_TCP , TCP_NODELAY, &t, sizeof(t))<0){ fprintf(stderr, "ERROR: could not disable Nagle: %s\n", - strerror(errno)); + strerror(errno)); } - if(tcp_rst) { - t_linger.l_onoff = 1; - t_linger.l_linger = 0; - if(setsockopt(sock, SOL_SOCKET, SO_LINGER, &t_linger, - sizeof(t_linger)) - < 0) { + if (tcp_rst){ + t_linger.l_onoff=1; + t_linger.l_linger=0; + if (setsockopt(sock, SOL_SOCKET, SO_LINGER, &t_linger, + sizeof(t_linger))<0){ fprintf(stderr, "ERROR: could not set SO_LINGER: %s\n", - strerror(errno)); + strerror(errno)); } } } #ifdef USE_SCTP - else if(proto == PROTO_SCTP) { - t = 1; - if(setsockopt(sock, IPPROTO_SCTP, SCTP_NODELAY, &t, sizeof(t)) - < 0) { + else if (proto==PROTO_SCTP){ + t=1; + if (setsockopt(sock, IPPROTO_SCTP, SCTP_NODELAY, &t, sizeof(t))<0){ fprintf(stderr, "ERROR: could not disable Nagle: %s\n", - strerror(errno)); + strerror(errno)); } } #endif /* USE_SCTP */ - if( + if ( #ifdef USE_SCTP - (proto != PROTO_SCTP || sctp_o2o) && + (proto!=PROTO_SCTP || sctp_o2o) && #endif /* USE_SCTP */ - (connect(sock, (struct sockaddr *)&addr, - sizeof(struct sockaddr)) - != 0)) { + (connect(sock, (struct sockaddr*) &addr, + sizeof(struct sockaddr))!=0)){ fprintf(stderr, "ERROR: connect: %s\n", strerror(errno)); goto error; } /* flood loop */ - t = throttle; - for(r = 0; r < count; r++) { - if((verbose > 1) && ((r % 1000) == 999)) { - putchar('.'); - fflush(stdout); - } + t=throttle; + for (r=0; r1)&&((r%1000)==999)){ putchar('.'); fflush(stdout); } #ifdef USE_SCTP - if(proto == PROTO_SCTP && !sctp_o2o) { - if(sctp_sendmsg(sock, buf, n, (struct sockaddr *)&addr, - sizeof(struct sockaddr), 0, SCTP_UNORDERED, 0, 0, 0) - == -1) { + if (proto==PROTO_SCTP && !sctp_o2o){ + if (sctp_sendmsg(sock, buf, n, (struct sockaddr*) &addr, + sizeof(struct sockaddr), 0, SCTP_UNORDERED, + 0, 0, 0)==-1){ fprintf(stderr, "Error(%d): send: %s\n", err, strerror(errno)); - err++; - ; + err++;; } - } else + }else #endif /* USE_SCTP */ { - if(send(sock, buf, n, 0) == -1) { + if (send(sock, buf, n, 0)==-1) { fprintf(stderr, "Error(%d): send: %s\n", err, strerror(errno)); - err++; - ; + err++;; } } - if(usec) { + if (usec){ t--; - if(t == 0) { - usleep(random_sleep ? (unsigned long)((double)usec * rand() - / RAND_MAX) - : usec); - t = throttle; + if (t==0){ + usleep(random_sleep? + (unsigned long)((double)usec*rand()/RAND_MAX):usec); + t=throttle; } } } close(sock); - if((verbose) && (k % 1000 == 999)) { - putchar('#'); - fflush(stdout); - } + if ((verbose) && (k%1000==999)) { putchar('#'); fflush(stdout); } } - if(proto == PROTO_TCP || proto == PROTO_SCTP) { + if (proto==PROTO_TCP || proto==PROTO_SCTP){ printf("\n%d packets sent on %d %s connections (%d on each of them)," - " %d bytes each => total %d bytes\n", - count * con_no - err, con_no, - (proto == PROTO_TCP) ? "tcp" : "sctp", count, n, - (con_no * count - err) * n); - } else { + " %d bytes each => total %d bytes\n", + count*con_no-err, con_no, (proto==PROTO_TCP)?"tcp":"sctp", + count, n, + (con_no*count-err)*n); + }else{ printf("\n%d packets sent, %d bytes each => total %d bytes\n", - count - err, n, n * (count - err)); + count-err, n, n*(count-err)); } - if(err) - printf("%d errors\n", err); + if (err) printf("%d errors\n", err); exit(0); error: diff --git a/misc/tools/sipgrep/sipgrep b/misc/tools/sipgrep/sipgrep index 748ae2fec..2afae567d 100755 --- a/misc/tools/sipgrep/sipgrep +++ b/misc/tools/sipgrep/sipgrep @@ -81,7 +81,7 @@ $debugfilecolors=$options{c}; unlink $filedebug if(defined $filedebug); #open PIPE -open(PIPE,"$ngrep $ngrep_flags |") or die "Can't run '$ngrep' programm: $!\n"; +open(PIPE,"$ngrep $ngrep_flags |") or die "Can't run '$ngrep' programme: $!\n"; select(PIPE); $| = 1; # make unbuffered select(STDOUT); $| = 1; # make unbuffered diff --git a/pkg/kamailio/alpine/APKBUILD b/pkg/kamailio/alpine/APKBUILD index 506bf79dd..4b56df12b 100644 --- a/pkg/kamailio/alpine/APKBUILD +++ b/pkg/kamailio/alpine/APKBUILD @@ -4,7 +4,7 @@ # Maintainer: Nathan Angelacos pkgname=kamailio -pkgver=5.7.4 +pkgver=5.8.1 pkgrel=0 # If building from a git snapshot, specify the gitcommit @@ -27,7 +27,7 @@ depends="gawk" options="!check" makedepends="bison db-dev flex freeradius-client-dev expat-dev lksctp-tools-dev perl-dev postgresql-dev python3-dev - pcre-dev mariadb-dev libxml2-dev curl-dev unixodbc-dev + pcre2-dev mariadb-dev libxml2-dev curl-dev unixodbc-dev confuse-dev ncurses-dev sqlite-dev lua-dev openldap-dev openssl-dev net-snmp-dev libuuid libev-dev jansson-dev json-c-dev libevent-dev linux-headers libmemcached-dev rabbitmq-c-dev hiredis-dev @@ -79,7 +79,7 @@ _mod_list_dbuid="db2_ops uid_auth_db uid_avp_db uid_domain uid_gflags \ # - modules for devel purposes _mod_list_devel="misctest print print_lib" -# - modules depending on pcre3 library +# - modules depending on pcre2 library _mod_list_pcre="dialplan lcr regex" # - modules depending on radius client library @@ -131,7 +131,7 @@ _mod_list_purple="purple" _mod_list_memcached="memcached" # - modules depending on openssl library -_mod_list_tls="auth_identity crypto tls" +_mod_list_tls="crypto tls" # - modules depending on openssl library _mod_list_outbound="outbound" @@ -227,9 +227,6 @@ _mod_list_jansson="acc_json jansson janssonrpcc" # - modules depending on libm _mod_list_jsdt="app_jsdt" -# - modules depending on sqlang -_mod_list_sqlang="app_sqlang" - # - modules depending on rabbitmq _mod_list_rabbitmq="rabbitmq" @@ -251,7 +248,7 @@ for _i in db postgres sqlite dbtext mysql \ cpl xml unixodbc snmpstats xmpp carrierroute \ ldap utils tls presence lua ims outbound debugger \ extras json websocket authephemeral mongodb\ - uuid ev memcached redis geoip2 jansson sqlang sipdump \ + uuid ev memcached redis geoip2 jansson sipdump \ jsdt http_async kazoo rabbitmq sctp radius perl \ python3 ruby; do @@ -557,11 +554,6 @@ ruby() { "$_mod_list_ruby" } -sqlang() { - _generic_pkg "Squirrel Language (SQLang) for Kamailio" \ - "$_mod_list_sqlang" -} - rabbitmq() { _generic_pkg "RabbitMQ related modules for Kamailio" \ "$_mod_list_rabbitmq" diff --git a/pkg/kamailio/deb/bionic/changelog b/pkg/kamailio/deb/bionic/changelog index a41d9e3d2..ee68e4dc2 100644 --- a/pkg/kamailio/deb/bionic/changelog +++ b/pkg/kamailio/deb/bionic/changelog @@ -1,72 +1,41 @@ -kamailio (5.7.4) unstable; urgency=medium +kamailio (5.8.1) unstable; urgency=medium - * version set 5.7.4 + * version set 5.8.1 - -- Victor Seva Thu, 18 Jan 2024 10:29:35 +0100 + -- Victor Seva Wed, 03 Apr 2024 08:21:53 +0200 -kamailio (5.7.3) unstable; urgency=medium +kamailio (5.8.0) unstable; urgency=medium - * version set 5.7.3 + * version set 5.8.0 - -- Victor Seva Fri, 17 Nov 2023 09:50:31 +0100 + -- Victor Seva Thu, 07 Mar 2024 11:40:20 +0100 -kamailio (5.7.2) unstable; urgency=medium +kamailio (5.8.0~rc0) unstable; urgency=medium - * version set 5.7.2 + * version set 5.8.0~rc0 - -- Victor Seva Wed, 27 Sep 2023 08:44:32 +0200 + -- Victor Seva Fri, 23 Feb 2024 20:04:35 +0100 -kamailio (5.7.1) unstable; urgency=medium +kamailio (5.8.0~pre0) unstable; urgency=medium - * version set 5.7.1 + * version set 5.8.0~pre0 - -- Victor Seva Wed, 28 Jun 2023 09:35:54 +0200 + -- Victor Seva Fri, 02 Feb 2024 15:20:05 +0100 -kamailio (5.7.0) unstable; urgency=medium +kamailio (5.8.0~dev2) unstable; urgency=medium - * version set 5.7.0 + * version set 5.8.0~dev2 - -- Victor Seva Tue, 16 May 2023 12:57:51 +0200 + -- Victor Seva Tue, 05 Dec 2023 12:04:06 +0100 -kamailio (5.7.0~rc0) unstable; urgency=medium +kamailio (5.8.0~dev1) unstable; urgency=medium - * version set 5.7.0~rc0 + * version set 5.8.0~dev1 - -- Victor Seva Thu, 04 May 2023 21:41:57 +0200 + -- Victor Seva Wed, 28 Jun 2023 15:03:56 +0200 -kamailio (5.7.0~pre0) unstable; urgency=medium +kamailio (5.8.0~dev0) unstable; urgency=medium - * version set 5.7.0~pre0 - - -- Victor Seva Mon, 17 Apr 2023 09:08:01 +0200 - -kamailio (5.7.0~dev4) unstable; urgency=medium - - * version set 5.7.0~dev4 - - -- Victor Seva Mon, 17 Apr 2023 09:07:10 +0200 - -kamailio (5.7.0~dev3) unstable; urgency=medium - - * version set 5.7.0~dev3 - - -- Victor Seva Tue, 10 Jan 2023 14:07:12 +0100 - -kamailio (5.7.0~dev2) unstable; urgency=medium - - * version set 5.7.0~dev2 - - -- Victor Seva Mon, 28 Nov 2022 11:54:03 +0100 - -kamailio (5.7.0~dev1) unstable; urgency=medium - - * version set 5.7.0~dev1 - - -- Victor Seva Sun, 28 Aug 2022 22:36:28 +0200 - -kamailio (5.7.0~dev0) unstable; urgency=medium - - * version set 5.7.0~dev0 - - -- Victor Seva Thu, 05 May 2022 12:47:44 +0200 + * version set 5.8.0~dev0 + -- Victor Seva Thu, 04 May 2023 21:45:08 +0200 diff --git a/pkg/kamailio/deb/bionic/control b/pkg/kamailio/deb/bionic/control index 13c2c636a..553b57362 100644 --- a/pkg/kamailio/deb/bionic/control +++ b/pkg/kamailio/deb/bionic/control @@ -31,7 +31,7 @@ Build-Depends: libmono-2.0-dev [amd64 armel armhf i386 mipsel kfreebsd-amd64 kfreebsd-i386 ppc64 ppc64el s390x], libmosquitto-dev, libncurses5-dev, - libpcre3-dev, + libpcre2-dev, libperl-dev, libphonenumber-dev (>= 7), libpq-dev, diff --git a/pkg/kamailio/deb/bionic/rules b/pkg/kamailio/deb/bionic/rules index fcb844e23..1d16d9809 100755 --- a/pkg/kamailio/deb/bionic/rules +++ b/pkg/kamailio/deb/bionic/rules @@ -18,6 +18,7 @@ ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) endif export RADCLI=1 +export WOLFSSL_INTERNAL=no # tlsa export KTLS_INCLUDE_TLSA=yes export LIBSSL_STATIC_SRCLIB=yes @@ -39,6 +40,8 @@ EXTRA_EXCLUDED_MODULES += java EXTRA_EXCLUDED_MODULES += secsipid EXTRA_EXCLUDED_MODULES += lwsc EXTRA_EXCLUDED_MODULES += nats +EXTRA_EXCLUDED_MODULES += microhttpd +EXTRA_EXCLUDED_MODULES += tls_wolfssl ## --EXCLUDED-- @@ -93,6 +96,10 @@ EXTRA_GROUPS += jansson EXTRA_GROUPS += uuid EXTRA_GROUPS += http_async +.PHONY: skip-modules +skip-modules: + @echo "$(EXCLUDED_MODULES) $(EXTRA_EXCLUDED_MODULES)" + D = $(CURDIR)/debian/$(DEB_SOURCE) # Name of libdir in the path for libraries (e.g., the multiarch triplet). diff --git a/pkg/kamailio/deb/bookworm/changelog b/pkg/kamailio/deb/bookworm/changelog index a41d9e3d2..ee68e4dc2 100644 --- a/pkg/kamailio/deb/bookworm/changelog +++ b/pkg/kamailio/deb/bookworm/changelog @@ -1,72 +1,41 @@ -kamailio (5.7.4) unstable; urgency=medium +kamailio (5.8.1) unstable; urgency=medium - * version set 5.7.4 + * version set 5.8.1 - -- Victor Seva Thu, 18 Jan 2024 10:29:35 +0100 + -- Victor Seva Wed, 03 Apr 2024 08:21:53 +0200 -kamailio (5.7.3) unstable; urgency=medium +kamailio (5.8.0) unstable; urgency=medium - * version set 5.7.3 + * version set 5.8.0 - -- Victor Seva Fri, 17 Nov 2023 09:50:31 +0100 + -- Victor Seva Thu, 07 Mar 2024 11:40:20 +0100 -kamailio (5.7.2) unstable; urgency=medium +kamailio (5.8.0~rc0) unstable; urgency=medium - * version set 5.7.2 + * version set 5.8.0~rc0 - -- Victor Seva Wed, 27 Sep 2023 08:44:32 +0200 + -- Victor Seva Fri, 23 Feb 2024 20:04:35 +0100 -kamailio (5.7.1) unstable; urgency=medium +kamailio (5.8.0~pre0) unstable; urgency=medium - * version set 5.7.1 + * version set 5.8.0~pre0 - -- Victor Seva Wed, 28 Jun 2023 09:35:54 +0200 + -- Victor Seva Fri, 02 Feb 2024 15:20:05 +0100 -kamailio (5.7.0) unstable; urgency=medium +kamailio (5.8.0~dev2) unstable; urgency=medium - * version set 5.7.0 + * version set 5.8.0~dev2 - -- Victor Seva Tue, 16 May 2023 12:57:51 +0200 + -- Victor Seva Tue, 05 Dec 2023 12:04:06 +0100 -kamailio (5.7.0~rc0) unstable; urgency=medium +kamailio (5.8.0~dev1) unstable; urgency=medium - * version set 5.7.0~rc0 + * version set 5.8.0~dev1 - -- Victor Seva Thu, 04 May 2023 21:41:57 +0200 + -- Victor Seva Wed, 28 Jun 2023 15:03:56 +0200 -kamailio (5.7.0~pre0) unstable; urgency=medium +kamailio (5.8.0~dev0) unstable; urgency=medium - * version set 5.7.0~pre0 - - -- Victor Seva Mon, 17 Apr 2023 09:08:01 +0200 - -kamailio (5.7.0~dev4) unstable; urgency=medium - - * version set 5.7.0~dev4 - - -- Victor Seva Mon, 17 Apr 2023 09:07:10 +0200 - -kamailio (5.7.0~dev3) unstable; urgency=medium - - * version set 5.7.0~dev3 - - -- Victor Seva Tue, 10 Jan 2023 14:07:12 +0100 - -kamailio (5.7.0~dev2) unstable; urgency=medium - - * version set 5.7.0~dev2 - - -- Victor Seva Mon, 28 Nov 2022 11:54:03 +0100 - -kamailio (5.7.0~dev1) unstable; urgency=medium - - * version set 5.7.0~dev1 - - -- Victor Seva Sun, 28 Aug 2022 22:36:28 +0200 - -kamailio (5.7.0~dev0) unstable; urgency=medium - - * version set 5.7.0~dev0 - - -- Victor Seva Thu, 05 May 2022 12:47:44 +0200 + * version set 5.8.0~dev0 + -- Victor Seva Thu, 04 May 2023 21:45:08 +0200 diff --git a/pkg/kamailio/deb/bookworm/control b/pkg/kamailio/deb/bookworm/control index 8d6af8ecc..2ec6d74a4 100644 --- a/pkg/kamailio/deb/bookworm/control +++ b/pkg/kamailio/deb/bookworm/control @@ -25,13 +25,14 @@ Build-Depends: liblua5.1-0-dev, libmaxminddb-dev, libmemcached-dev, + libmicrohttpd-dev, libmnl-dev, libmongoc-dev, libmono-2.0-dev [amd64 armel armhf i386 mipsel kfreebsd-amd64 kfreebsd-i386 ppc64 ppc64el s390x], libmosquitto-dev, libnats-dev, libncurses-dev, - libpcre3-dev, + libpcre2-dev, libperl-dev, libphonenumber-dev (>= 7), libpq-dev, @@ -47,6 +48,7 @@ Build-Depends: libsystemd-dev, libunistring-dev, libwebsockets-dev, + libwolfssl-dev, libxml2-dev, openssl, pkg-config, @@ -618,6 +620,23 @@ Description: TLS support for the Kamailio SIP server (authentication, transport) This package provides TLS support for encrypted and authenticated SIP connections as well as generic TLS support for many Kamailio modules. +Package: kamailio-wolftls-modules +Architecture: any +Multi-Arch: same +Pre-Depends: + ${misc:Pre-Depends}, +Depends: + kamailio (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Description: TLS support for the Kamailio SIP server (authentication, transport) + Kamailio is a very fast and flexible SIP (RFC3261) + server. Written entirely in C, Kamailio can handle thousands calls + per second even on low-budget hardware. + . + This package provides TLS support for encrypted and authenticated using wolfssl + SIP connections as well as generic TLS support for many Kamailio modules. + Package: kamailio-outbound-modules Architecture: any Multi-Arch: same @@ -862,6 +881,22 @@ Description: Nats module for the Kamailio SIP server NATS is a real time distributed messaging platform, more details about it can be found at nats.io. +Package: kamailio-microhttpd-modules +Architecture: any +Multi-Arch: same +Pre-Depends: + ${misc:Pre-Depends}, +Depends: + kamailio (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Description: Microhttpd module for the Kamailio SIP server + Kamailio is a very fast and flexible SIP (RFC3261) + server. Written entirely in C, Kamailio can handle thousands calls + per second even on low-budget hardware. + . + This package provides an embedded HTTP server using libmicrohttpd. + Package: kamailio-extra-modules Architecture: any Multi-Arch: same diff --git a/pkg/kamailio/deb/bookworm/rules b/pkg/kamailio/deb/bookworm/rules index 33095212b..f7b603151 100755 --- a/pkg/kamailio/deb/bookworm/rules +++ b/pkg/kamailio/deb/bookworm/rules @@ -18,6 +18,7 @@ ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) endif export RADCLI=1 +export WOLFSSL_INTERNAL=no # tlsa export KTLS_INCLUDE_TLSA=yes export LIBSSL_STATIC_SRCLIB=yes @@ -85,6 +86,8 @@ PACKAGE_GROUPS += mqtt PACKAGE_GROUPS += secsipid PACKAGE_GROUPS += lwsc PACKAGE_GROUPS += nats +PACKAGE_GROUPS += tls_wolfssl +PACKAGE_GROUPS += microhttpd # Module groups to be packaged onto kamailio-extra-modules. EXTRA_GROUPS += ev @@ -93,6 +96,10 @@ EXTRA_GROUPS += jansson EXTRA_GROUPS += uuid EXTRA_GROUPS += http_async +.PHONY: skip-modules +skip-modules: + @echo "$(EXCLUDED_MODULES) $(EXTRA_EXCLUDED_MODULES)" + D = $(CURDIR)/debian/$(DEB_SOURCE) # Name of libdir in the path for libraries (e.g., the multiarch triplet). diff --git a/pkg/kamailio/deb/bullseye/changelog b/pkg/kamailio/deb/bullseye/changelog index a41d9e3d2..ee68e4dc2 100644 --- a/pkg/kamailio/deb/bullseye/changelog +++ b/pkg/kamailio/deb/bullseye/changelog @@ -1,72 +1,41 @@ -kamailio (5.7.4) unstable; urgency=medium +kamailio (5.8.1) unstable; urgency=medium - * version set 5.7.4 + * version set 5.8.1 - -- Victor Seva Thu, 18 Jan 2024 10:29:35 +0100 + -- Victor Seva Wed, 03 Apr 2024 08:21:53 +0200 -kamailio (5.7.3) unstable; urgency=medium +kamailio (5.8.0) unstable; urgency=medium - * version set 5.7.3 + * version set 5.8.0 - -- Victor Seva Fri, 17 Nov 2023 09:50:31 +0100 + -- Victor Seva Thu, 07 Mar 2024 11:40:20 +0100 -kamailio (5.7.2) unstable; urgency=medium +kamailio (5.8.0~rc0) unstable; urgency=medium - * version set 5.7.2 + * version set 5.8.0~rc0 - -- Victor Seva Wed, 27 Sep 2023 08:44:32 +0200 + -- Victor Seva Fri, 23 Feb 2024 20:04:35 +0100 -kamailio (5.7.1) unstable; urgency=medium +kamailio (5.8.0~pre0) unstable; urgency=medium - * version set 5.7.1 + * version set 5.8.0~pre0 - -- Victor Seva Wed, 28 Jun 2023 09:35:54 +0200 + -- Victor Seva Fri, 02 Feb 2024 15:20:05 +0100 -kamailio (5.7.0) unstable; urgency=medium +kamailio (5.8.0~dev2) unstable; urgency=medium - * version set 5.7.0 + * version set 5.8.0~dev2 - -- Victor Seva Tue, 16 May 2023 12:57:51 +0200 + -- Victor Seva Tue, 05 Dec 2023 12:04:06 +0100 -kamailio (5.7.0~rc0) unstable; urgency=medium +kamailio (5.8.0~dev1) unstable; urgency=medium - * version set 5.7.0~rc0 + * version set 5.8.0~dev1 - -- Victor Seva Thu, 04 May 2023 21:41:57 +0200 + -- Victor Seva Wed, 28 Jun 2023 15:03:56 +0200 -kamailio (5.7.0~pre0) unstable; urgency=medium +kamailio (5.8.0~dev0) unstable; urgency=medium - * version set 5.7.0~pre0 - - -- Victor Seva Mon, 17 Apr 2023 09:08:01 +0200 - -kamailio (5.7.0~dev4) unstable; urgency=medium - - * version set 5.7.0~dev4 - - -- Victor Seva Mon, 17 Apr 2023 09:07:10 +0200 - -kamailio (5.7.0~dev3) unstable; urgency=medium - - * version set 5.7.0~dev3 - - -- Victor Seva Tue, 10 Jan 2023 14:07:12 +0100 - -kamailio (5.7.0~dev2) unstable; urgency=medium - - * version set 5.7.0~dev2 - - -- Victor Seva Mon, 28 Nov 2022 11:54:03 +0100 - -kamailio (5.7.0~dev1) unstable; urgency=medium - - * version set 5.7.0~dev1 - - -- Victor Seva Sun, 28 Aug 2022 22:36:28 +0200 - -kamailio (5.7.0~dev0) unstable; urgency=medium - - * version set 5.7.0~dev0 - - -- Victor Seva Thu, 05 May 2022 12:47:44 +0200 + * version set 5.8.0~dev0 + -- Victor Seva Thu, 04 May 2023 21:45:08 +0200 diff --git a/pkg/kamailio/deb/bullseye/control b/pkg/kamailio/deb/bullseye/control index e575b6925..b9deb27c5 100644 --- a/pkg/kamailio/deb/bullseye/control +++ b/pkg/kamailio/deb/bullseye/control @@ -25,12 +25,13 @@ Build-Depends: liblua5.1-0-dev, libmaxminddb-dev, libmemcached-dev, + libmicrohttpd-dev, libmnl-dev, libmongoc-dev, libmono-2.0-dev [amd64 armel armhf i386 mipsel kfreebsd-amd64 kfreebsd-i386 ppc64 ppc64el s390x], libmosquitto-dev, libncurses5-dev, - libpcre3-dev, + libpcre2-dev, libperl-dev, libphonenumber-dev (>= 7), libpq-dev, @@ -863,6 +864,22 @@ Description: Libwebsockets module for the Kamailio SIP server This package contains the lwcs module, which provides a client-side WebSockets API through libwebsockets. +Package: kamailio-microhttpd-modules +Architecture: any +Multi-Arch: same +Pre-Depends: + ${misc:Pre-Depends}, +Depends: + kamailio (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Description: Microhttpd module for the Kamailio SIP server + Kamailio is a very fast and flexible SIP (RFC3261) + server. Written entirely in C, Kamailio can handle thousands calls + per second even on low-budget hardware. + . + This package provides an embedded HTTP server using libmicrohttpd. + Package: kamailio-extra-modules Architecture: any Multi-Arch: same diff --git a/pkg/kamailio/deb/bullseye/rules b/pkg/kamailio/deb/bullseye/rules index 79c4b36e4..e9089f94f 100755 --- a/pkg/kamailio/deb/bullseye/rules +++ b/pkg/kamailio/deb/bullseye/rules @@ -18,6 +18,7 @@ ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) endif export RADCLI=1 +export WOLFSSL_INTERNAL=no # tlsa export KTLS_INCLUDE_TLSA=yes export LIBSSL_STATIC_SRCLIB=yes @@ -37,6 +38,7 @@ EXTRA_EXCLUDED_MODULES += iptrtpproxy EXTRA_EXCLUDED_MODULES += dnssec EXTRA_EXCLUDED_MODULES += java EXTRA_EXCLUDED_MODULES += nats +EXTRA_EXCLUDED_MODULES += tls_wolfssl ## --EXCLUDED-- @@ -85,6 +87,7 @@ PACKAGE_GROUPS += python3 PACKAGE_GROUPS += mqtt PACKAGE_GROUPS += secsipid PACKAGE_GROUPS += lwsc +PACKAGE_GROUPS += microhttpd # Module groups to be packaged onto kamailio-extra-modules. EXTRA_GROUPS += ev @@ -93,6 +96,10 @@ EXTRA_GROUPS += jansson EXTRA_GROUPS += uuid EXTRA_GROUPS += http_async +.PHONY: skip-modules +skip-modules: + @echo "$(EXCLUDED_MODULES) $(EXTRA_EXCLUDED_MODULES)" + D = $(CURDIR)/debian/$(DEB_SOURCE) # Name of libdir in the path for libraries (e.g., the multiarch triplet). diff --git a/pkg/kamailio/deb/buster/changelog b/pkg/kamailio/deb/buster/changelog index a41d9e3d2..ee68e4dc2 100644 --- a/pkg/kamailio/deb/buster/changelog +++ b/pkg/kamailio/deb/buster/changelog @@ -1,72 +1,41 @@ -kamailio (5.7.4) unstable; urgency=medium +kamailio (5.8.1) unstable; urgency=medium - * version set 5.7.4 + * version set 5.8.1 - -- Victor Seva Thu, 18 Jan 2024 10:29:35 +0100 + -- Victor Seva Wed, 03 Apr 2024 08:21:53 +0200 -kamailio (5.7.3) unstable; urgency=medium +kamailio (5.8.0) unstable; urgency=medium - * version set 5.7.3 + * version set 5.8.0 - -- Victor Seva Fri, 17 Nov 2023 09:50:31 +0100 + -- Victor Seva Thu, 07 Mar 2024 11:40:20 +0100 -kamailio (5.7.2) unstable; urgency=medium +kamailio (5.8.0~rc0) unstable; urgency=medium - * version set 5.7.2 + * version set 5.8.0~rc0 - -- Victor Seva Wed, 27 Sep 2023 08:44:32 +0200 + -- Victor Seva Fri, 23 Feb 2024 20:04:35 +0100 -kamailio (5.7.1) unstable; urgency=medium +kamailio (5.8.0~pre0) unstable; urgency=medium - * version set 5.7.1 + * version set 5.8.0~pre0 - -- Victor Seva Wed, 28 Jun 2023 09:35:54 +0200 + -- Victor Seva Fri, 02 Feb 2024 15:20:05 +0100 -kamailio (5.7.0) unstable; urgency=medium +kamailio (5.8.0~dev2) unstable; urgency=medium - * version set 5.7.0 + * version set 5.8.0~dev2 - -- Victor Seva Tue, 16 May 2023 12:57:51 +0200 + -- Victor Seva Tue, 05 Dec 2023 12:04:06 +0100 -kamailio (5.7.0~rc0) unstable; urgency=medium +kamailio (5.8.0~dev1) unstable; urgency=medium - * version set 5.7.0~rc0 + * version set 5.8.0~dev1 - -- Victor Seva Thu, 04 May 2023 21:41:57 +0200 + -- Victor Seva Wed, 28 Jun 2023 15:03:56 +0200 -kamailio (5.7.0~pre0) unstable; urgency=medium +kamailio (5.8.0~dev0) unstable; urgency=medium - * version set 5.7.0~pre0 - - -- Victor Seva Mon, 17 Apr 2023 09:08:01 +0200 - -kamailio (5.7.0~dev4) unstable; urgency=medium - - * version set 5.7.0~dev4 - - -- Victor Seva Mon, 17 Apr 2023 09:07:10 +0200 - -kamailio (5.7.0~dev3) unstable; urgency=medium - - * version set 5.7.0~dev3 - - -- Victor Seva Tue, 10 Jan 2023 14:07:12 +0100 - -kamailio (5.7.0~dev2) unstable; urgency=medium - - * version set 5.7.0~dev2 - - -- Victor Seva Mon, 28 Nov 2022 11:54:03 +0100 - -kamailio (5.7.0~dev1) unstable; urgency=medium - - * version set 5.7.0~dev1 - - -- Victor Seva Sun, 28 Aug 2022 22:36:28 +0200 - -kamailio (5.7.0~dev0) unstable; urgency=medium - - * version set 5.7.0~dev0 - - -- Victor Seva Thu, 05 May 2022 12:47:44 +0200 + * version set 5.8.0~dev0 + -- Victor Seva Thu, 04 May 2023 21:45:08 +0200 diff --git a/pkg/kamailio/deb/buster/control b/pkg/kamailio/deb/buster/control index 13c2c636a..553b57362 100644 --- a/pkg/kamailio/deb/buster/control +++ b/pkg/kamailio/deb/buster/control @@ -31,7 +31,7 @@ Build-Depends: libmono-2.0-dev [amd64 armel armhf i386 mipsel kfreebsd-amd64 kfreebsd-i386 ppc64 ppc64el s390x], libmosquitto-dev, libncurses5-dev, - libpcre3-dev, + libpcre2-dev, libperl-dev, libphonenumber-dev (>= 7), libpq-dev, diff --git a/pkg/kamailio/deb/buster/rules b/pkg/kamailio/deb/buster/rules index fcb844e23..1d16d9809 100755 --- a/pkg/kamailio/deb/buster/rules +++ b/pkg/kamailio/deb/buster/rules @@ -18,6 +18,7 @@ ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) endif export RADCLI=1 +export WOLFSSL_INTERNAL=no # tlsa export KTLS_INCLUDE_TLSA=yes export LIBSSL_STATIC_SRCLIB=yes @@ -39,6 +40,8 @@ EXTRA_EXCLUDED_MODULES += java EXTRA_EXCLUDED_MODULES += secsipid EXTRA_EXCLUDED_MODULES += lwsc EXTRA_EXCLUDED_MODULES += nats +EXTRA_EXCLUDED_MODULES += microhttpd +EXTRA_EXCLUDED_MODULES += tls_wolfssl ## --EXCLUDED-- @@ -93,6 +96,10 @@ EXTRA_GROUPS += jansson EXTRA_GROUPS += uuid EXTRA_GROUPS += http_async +.PHONY: skip-modules +skip-modules: + @echo "$(EXCLUDED_MODULES) $(EXTRA_EXCLUDED_MODULES)" + D = $(CURDIR)/debian/$(DEB_SOURCE) # Name of libdir in the path for libraries (e.g., the multiarch triplet). diff --git a/pkg/kamailio/deb/debian/backports/bionic b/pkg/kamailio/deb/debian/backports/bionic index 5ae42277d..88bd6ba71 100755 --- a/pkg/kamailio/deb/debian/backports/bionic +++ b/pkg/kamailio/deb/debian/backports/bionic @@ -38,6 +38,20 @@ sed -i -e '/^ libnats-dev,/d' \ sed -i -e '/^PACKAGE_GROUPS += nats/d' ${DIST}/rules sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += nats' ${DIST}/rules +# libmicrohttpd too old +sed -i -e '/^ libmicrohttpd-dev,/d' \ + -e '/^Package: kamailio-microhttpd-modules/,/^$/d' \ + ${DIST}/control +sed -i -e '/^PACKAGE_GROUPS += microhttpd/d' ${DIST}/rules +sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += microhttpd' ${DIST}/rules + +# libwolfssl-dev < 5.2 +sed -i -e '/^ libwolfssl-dev,/d' \ + -e '/^Package: kamailio-wolftls-modules/,/^$/d' \ + ${DIST}/control +sed -i -e '/^PACKAGE_GROUPS += tls_wolfssl/d' ${DIST}/rules +sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += tls_wolfssl' ${DIST}/rules + wrap-and-sort -sat -d ${DIST} # clean backports scripts diff --git a/pkg/kamailio/deb/debian/backports/bullseye b/pkg/kamailio/deb/debian/backports/bullseye index 6fe54e358..1355722ce 100755 --- a/pkg/kamailio/deb/debian/backports/bullseye +++ b/pkg/kamailio/deb/debian/backports/bullseye @@ -29,6 +29,13 @@ sed -i -e '/^ libnats-dev,/d' \ sed -i -e '/^PACKAGE_GROUPS += nats/d' ${DIST}/rules sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += nats' ${DIST}/rules +# libwolfssl-dev < 5.2 +sed -i -e '/^ libwolfssl-dev,/d' \ + -e '/^Package: kamailio-wolftls-modules/,/^$/d' \ + ${DIST}/control +sed -i -e '/^PACKAGE_GROUPS += tls_wolfssl/d' ${DIST}/rules +sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += tls_wolfssl' ${DIST}/rules + wrap-and-sort -sat -d ${DIST} # clean backports scripts diff --git a/pkg/kamailio/deb/debian/backports/buster b/pkg/kamailio/deb/debian/backports/buster index f4690179c..cb9425f8b 100755 --- a/pkg/kamailio/deb/debian/backports/buster +++ b/pkg/kamailio/deb/debian/backports/buster @@ -38,6 +38,20 @@ sed -i -e '/^ libnats-dev,/d' \ sed -i -e '/^PACKAGE_GROUPS += nats/d' ${DIST}/rules sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += nats' ${DIST}/rules +# libmicrohttpd too old +sed -i -e '/^ libmicrohttpd-dev,/d' \ + -e '/^Package: kamailio-microhttpd-modules/,/^$/d' \ + ${DIST}/control +sed -i -e '/^PACKAGE_GROUPS += microhttpd/d' ${DIST}/rules +sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += microhttpd' ${DIST}/rules + +# libwolfssl-dev < 5.2 +sed -i -e '/^ libwolfssl-dev,/d' \ + -e '/^Package: kamailio-wolftls-modules/,/^$/d' \ + ${DIST}/control +sed -i -e '/^PACKAGE_GROUPS += tls_wolfssl/d' ${DIST}/rules +sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += tls_wolfssl' ${DIST}/rules + wrap-and-sort -sat -d ${DIST} # clean backports scripts diff --git a/pkg/kamailio/deb/debian/backports/focal b/pkg/kamailio/deb/debian/backports/focal index 0c6455ab7..bf8dd81cc 100755 --- a/pkg/kamailio/deb/debian/backports/focal +++ b/pkg/kamailio/deb/debian/backports/focal @@ -32,6 +32,20 @@ sed -i -e '/^ libnats-dev,/d' \ sed -i -e '/^PACKAGE_GROUPS += nats/d' ${DIST}/rules sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += nats' ${DIST}/rules +# libmicrohttpd too old +sed -i -e '/^ libmicrohttpd-dev,/d' \ + -e '/^Package: kamailio-microhttpd-modules/,/^$/d' \ + ${DIST}/control +sed -i -e '/^PACKAGE_GROUPS += microhttpd/d' ${DIST}/rules +sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += microhttpd' ${DIST}/rules + +# libwolfssl-dev < 5.2 +sed -i -e '/^ libwolfssl-dev,/d' \ + -e '/^Package: kamailio-wolftls-modules/,/^$/d' \ + ${DIST}/control +sed -i -e '/^PACKAGE_GROUPS += tls_wolfssl/d' ${DIST}/rules +sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += tls_wolfssl' ${DIST}/rules + wrap-and-sort -sat -d ${DIST} # clean backports scripts diff --git a/pkg/kamailio/deb/debian/backports/jessie b/pkg/kamailio/deb/debian/backports/jessie index c11de5ab6..62c7f4666 100755 --- a/pkg/kamailio/deb/debian/backports/jessie +++ b/pkg/kamailio/deb/debian/backports/jessie @@ -55,6 +55,16 @@ sed -i -e '/^ libnats-dev,/d' \ sed -i -e '/^PACKAGE_GROUPS += nats/d' ${DIST}/rules sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += nats' ${DIST}/rules +# no libpcre2-dev +sed -i -e 's/libpcre2-dev/libpcre3-dev/' ${DIST}/control + +# libwolfssl-dev < 5.2 +sed -i -e '/^ libwolfssl-dev,/d' \ + -e '/^Package: kamailio-wolftls-modules/,/^$/d' \ + ${DIST}/control +sed -i -e '/^PACKAGE_GROUPS += tls_wolfssl/d' ${DIST}/rules +sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += tls_wolfssl' ${DIST}/rules + wrap-and-sort -sat -d ${DIST} # clean backports scripts diff --git a/pkg/kamailio/deb/debian/backports/precise b/pkg/kamailio/deb/debian/backports/precise index f7174252f..e0ea38892 100755 --- a/pkg/kamailio/deb/debian/backports/precise +++ b/pkg/kamailio/deb/debian/backports/precise @@ -118,6 +118,16 @@ sed -i -e '/^ libnats-dev,/d' \ sed -i -e '/^PACKAGE_GROUPS += nats/d' ${DIST}/rules sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += nats' ${DIST}/rules +# no libpcre2-dev +sed -i -e 's/libpcre2-dev/libpcre3-dev/' ${DIST}/control + +# libwolfssl-dev < 5.2 +sed -i -e '/^ libwolfssl-dev,/d' \ + -e '/^Package: kamailio-wolftls-modules/,/^$/d' \ + ${DIST}/control +sed -i -e '/^PACKAGE_GROUPS += tls_wolfssl/d' ${DIST}/rules +sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += tls_wolfssl' ${DIST}/rules + wrap-and-sort -sat -d ${DIST} # clean backports scripts diff --git a/pkg/kamailio/deb/debian/backports/stretch b/pkg/kamailio/deb/debian/backports/stretch index c2981c336..4e656343e 100755 --- a/pkg/kamailio/deb/debian/backports/stretch +++ b/pkg/kamailio/deb/debian/backports/stretch @@ -35,6 +35,26 @@ sed -i -e '/^ libnats-dev,/d' \ sed -i -e '/^PACKAGE_GROUPS += nats/d' ${DIST}/rules sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += nats' ${DIST}/rules +# libmicrohttpd too old +sed -i -e '/^ libmicrohttpd-dev,/d' \ + -e '/^Package: kamailio-microhttpd-modules/,/^$/d' \ + ${DIST}/control +sed -i -e '/^PACKAGE_GROUPS += microhttpd/d' ${DIST}/rules +sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += microhttpd' ${DIST}/rules + +# libssl >= v1.1.1 +sed -i -e '/^Package: kamailio-ims-modules/,/^$/d' \ + ${DIST}/control +sed -i -e '/^PACKAGE_GROUPS += ims/d' ${DIST}/rules +sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += ims' ${DIST}/rules + +# libwolfssl-dev < 5.2 +sed -i -e '/^ libwolfssl-dev,/d' \ + -e '/^Package: kamailio-wolftls-modules/,/^$/d' \ + ${DIST}/control +sed -i -e '/^PACKAGE_GROUPS += tls_wolfssl/d' ${DIST}/rules +sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += tls_wolfssl' ${DIST}/rules + wrap-and-sort -sat -d ${DIST} # clean backports scripts diff --git a/pkg/kamailio/deb/debian/backports/trusty b/pkg/kamailio/deb/debian/backports/trusty index 5893ab4b1..3482a7165 100755 --- a/pkg/kamailio/deb/debian/backports/trusty +++ b/pkg/kamailio/deb/debian/backports/trusty @@ -81,6 +81,16 @@ sed -i -e '/^ libnats-dev,/d' \ sed -i -e '/^PACKAGE_GROUPS += nats/d' ${DIST}/rules sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += nats' ${DIST}/rules +# no libpcre2-dev +sed -i -e 's/libpcre2-dev/libpcre3-dev/' ${DIST}/control + +# libwolfssl-dev < 5.2 +sed -i -e '/^ libwolfssl-dev,/d' \ + -e '/^Package: kamailio-wolftls-modules/,/^$/d' \ + ${DIST}/control +sed -i -e '/^PACKAGE_GROUPS += tls_wolfssl/d' ${DIST}/rules +sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += tls_wolfssl' ${DIST}/rules + wrap-and-sort -sat -d ${DIST} # clean backports scripts diff --git a/pkg/kamailio/deb/debian/backports/wheezy b/pkg/kamailio/deb/debian/backports/wheezy index 9c1eacd3d..4afb1f3df 100755 --- a/pkg/kamailio/deb/debian/backports/wheezy +++ b/pkg/kamailio/deb/debian/backports/wheezy @@ -118,6 +118,22 @@ sed -i -e '/^ libnats-dev,/d' \ sed -i -e '/^PACKAGE_GROUPS += nats/d' ${DIST}/rules sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += nats' ${DIST}/rules +# no libpcre2-dev +sed -i -e 's/libpcre2-dev/libpcre3-dev/' ${DIST}/control + +# no libmono-2.0-dev +sed -i -e '/libmono-2.0-dev/d' -e '/^Package: kamailio-mono-modules/,/^$/d' \ + ${DIST}/control +sed -i -e '/^PACKAGE_GROUPS += mono/d' ${DIST}/rules +sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += mono' ${DIST}/rules + +# libwolfssl-dev < 5.2 +sed -i -e '/^ libwolfssl-dev,/d' \ + -e '/^Package: kamailio-wolftls-modules/,/^$/d' \ + ${DIST}/control +sed -i -e '/^PACKAGE_GROUPS += tls_wolfssl/d' ${DIST}/rules +sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += tls_wolfssl' ${DIST}/rules + wrap-and-sort -sat -d ${DIST} # clean backports scripts diff --git a/pkg/kamailio/deb/debian/backports/xenial b/pkg/kamailio/deb/debian/backports/xenial index 95e956cbd..e3ebe44e0 100755 --- a/pkg/kamailio/deb/debian/backports/xenial +++ b/pkg/kamailio/deb/debian/backports/xenial @@ -44,6 +44,26 @@ sed -i -e '/^ libnats-dev,/d' \ sed -i -e '/^PACKAGE_GROUPS += nats/d' ${DIST}/rules sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += nats' ${DIST}/rules +# libmicrohttpd too old +sed -i -e '/^ libmicrohttpd-dev,/d' \ + -e '/^Package: kamailio-microhttpd-modules/,/^$/d' \ + ${DIST}/control +sed -i -e '/^PACKAGE_GROUPS += microhttpd/d' ${DIST}/rules +sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += microhttpd' ${DIST}/rules + +# libssl >= v1.1.1 +sed -i -e '/^Package: kamailio-ims-modules/,/^$/d' \ + ${DIST}/control +sed -i -e '/^PACKAGE_GROUPS += ims/d' ${DIST}/rules +sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += ims' ${DIST}/rules + +# libwolfssl-dev < 5.2 +sed -i -e '/^ libwolfssl-dev,/d' \ + -e '/^Package: kamailio-wolftls-modules/,/^$/d' \ + ${DIST}/control +sed -i -e '/^PACKAGE_GROUPS += tls_wolfssl/d' ${DIST}/rules +sed -i -e '/--EXCLUDED--/i EXTRA_EXCLUDED_MODULES += tls_wolfssl' ${DIST}/rules + # tlsa build fails sed -i -e 's/KTLS_INCLUDE_TLSA=yes/KTLS_INCLUDE_TLSA=no/' ${DIST}/rules diff --git a/pkg/kamailio/deb/debian/changelog b/pkg/kamailio/deb/debian/changelog index a41d9e3d2..ee68e4dc2 100644 --- a/pkg/kamailio/deb/debian/changelog +++ b/pkg/kamailio/deb/debian/changelog @@ -1,72 +1,41 @@ -kamailio (5.7.4) unstable; urgency=medium +kamailio (5.8.1) unstable; urgency=medium - * version set 5.7.4 + * version set 5.8.1 - -- Victor Seva Thu, 18 Jan 2024 10:29:35 +0100 + -- Victor Seva Wed, 03 Apr 2024 08:21:53 +0200 -kamailio (5.7.3) unstable; urgency=medium +kamailio (5.8.0) unstable; urgency=medium - * version set 5.7.3 + * version set 5.8.0 - -- Victor Seva Fri, 17 Nov 2023 09:50:31 +0100 + -- Victor Seva Thu, 07 Mar 2024 11:40:20 +0100 -kamailio (5.7.2) unstable; urgency=medium +kamailio (5.8.0~rc0) unstable; urgency=medium - * version set 5.7.2 + * version set 5.8.0~rc0 - -- Victor Seva Wed, 27 Sep 2023 08:44:32 +0200 + -- Victor Seva Fri, 23 Feb 2024 20:04:35 +0100 -kamailio (5.7.1) unstable; urgency=medium +kamailio (5.8.0~pre0) unstable; urgency=medium - * version set 5.7.1 + * version set 5.8.0~pre0 - -- Victor Seva Wed, 28 Jun 2023 09:35:54 +0200 + -- Victor Seva Fri, 02 Feb 2024 15:20:05 +0100 -kamailio (5.7.0) unstable; urgency=medium +kamailio (5.8.0~dev2) unstable; urgency=medium - * version set 5.7.0 + * version set 5.8.0~dev2 - -- Victor Seva Tue, 16 May 2023 12:57:51 +0200 + -- Victor Seva Tue, 05 Dec 2023 12:04:06 +0100 -kamailio (5.7.0~rc0) unstable; urgency=medium +kamailio (5.8.0~dev1) unstable; urgency=medium - * version set 5.7.0~rc0 + * version set 5.8.0~dev1 - -- Victor Seva Thu, 04 May 2023 21:41:57 +0200 + -- Victor Seva Wed, 28 Jun 2023 15:03:56 +0200 -kamailio (5.7.0~pre0) unstable; urgency=medium +kamailio (5.8.0~dev0) unstable; urgency=medium - * version set 5.7.0~pre0 - - -- Victor Seva Mon, 17 Apr 2023 09:08:01 +0200 - -kamailio (5.7.0~dev4) unstable; urgency=medium - - * version set 5.7.0~dev4 - - -- Victor Seva Mon, 17 Apr 2023 09:07:10 +0200 - -kamailio (5.7.0~dev3) unstable; urgency=medium - - * version set 5.7.0~dev3 - - -- Victor Seva Tue, 10 Jan 2023 14:07:12 +0100 - -kamailio (5.7.0~dev2) unstable; urgency=medium - - * version set 5.7.0~dev2 - - -- Victor Seva Mon, 28 Nov 2022 11:54:03 +0100 - -kamailio (5.7.0~dev1) unstable; urgency=medium - - * version set 5.7.0~dev1 - - -- Victor Seva Sun, 28 Aug 2022 22:36:28 +0200 - -kamailio (5.7.0~dev0) unstable; urgency=medium - - * version set 5.7.0~dev0 - - -- Victor Seva Thu, 05 May 2022 12:47:44 +0200 + * version set 5.8.0~dev0 + -- Victor Seva Thu, 04 May 2023 21:45:08 +0200 diff --git a/pkg/kamailio/deb/debian/control b/pkg/kamailio/deb/debian/control index b1378987b..b454421bf 100644 --- a/pkg/kamailio/deb/debian/control +++ b/pkg/kamailio/deb/debian/control @@ -27,13 +27,14 @@ Build-Depends: liblua5.1-0-dev, libmaxminddb-dev, libmemcached-dev, + libmicrohttpd-dev, libmnl-dev, libmongoc-dev, libmono-2.0-dev [amd64 armel armhf i386 mipsel kfreebsd-amd64 kfreebsd-i386 ppc64 ppc64el s390x], libmosquitto-dev, libnats-dev, libncurses5-dev, - libpcre3-dev, + libpcre2-dev, libperl-dev, libphonenumber-dev (>= 7), libpq-dev, @@ -50,6 +51,7 @@ Build-Depends: libunistring-dev, libval-dev, libwebsockets-dev, + libwolfssl-dev, libxml2-dev, openssl, pkg-config, @@ -659,6 +661,23 @@ Description: TLS support for the Kamailio SIP server (authentication, transport) This package provides TLS support for encrypted and authenticated SIP connections as well as generic TLS support for many Kamailio modules. +Package: kamailio-wolftls-modules +Architecture: any +Multi-Arch: same +Pre-Depends: + ${misc:Pre-Depends}, +Depends: + kamailio (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Description: TLS support for the Kamailio SIP server (authentication, transport) + Kamailio is a very fast and flexible SIP (RFC3261) + server. Written entirely in C, Kamailio can handle thousands calls + per second even on low-budget hardware. + . + This package provides TLS support for encrypted and authenticated using wolfssl + SIP connections as well as generic TLS support for many Kamailio modules. + Package: kamailio-outbound-modules Architecture: any Multi-Arch: same @@ -919,6 +938,22 @@ Description: Nats module for the Kamailio SIP server NATS is a real time distributed messaging platform, more details about it can be found at nats.io. +Package: kamailio-microhttpd-modules +Architecture: any +Multi-Arch: same +Pre-Depends: + ${misc:Pre-Depends}, +Depends: + kamailio (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Description: Microhttpd module for the Kamailio SIP server + Kamailio is a very fast and flexible SIP (RFC3261) + server. Written entirely in C, Kamailio can handle thousands calls + per second even on low-budget hardware. + . + This package provides an embedded HTTP server using libmicrohttpd. + Package: kamailio-extra-modules Architecture: any Multi-Arch: same diff --git a/pkg/kamailio/deb/debian/rules b/pkg/kamailio/deb/debian/rules index 7b3f97e05..cbf680015 100755 --- a/pkg/kamailio/deb/debian/rules +++ b/pkg/kamailio/deb/debian/rules @@ -19,6 +19,7 @@ endif export JAVA_HOME=/usr/lib/jvm/java-gcj export RADCLI=1 +export WOLFSSL_INTERNAL=no # tlsa export KTLS_INCLUDE_TLSA=yes export LIBSSL_STATIC_SRCLIB=yes @@ -86,6 +87,8 @@ PACKAGE_GROUPS += mqtt PACKAGE_GROUPS += secsipid PACKAGE_GROUPS += lwsc PACKAGE_GROUPS += nats +PACKAGE_GROUPS += tls_wolfssl +PACKAGE_GROUPS += microhttpd # Module groups to be packaged onto kamailio-extra-modules. EXTRA_GROUPS += ev @@ -94,6 +97,10 @@ EXTRA_GROUPS += jansson EXTRA_GROUPS += uuid EXTRA_GROUPS += http_async +.PHONY: skip-modules +skip-modules: + @echo "$(EXCLUDED_MODULES) $(EXTRA_EXCLUDED_MODULES)" + D = $(CURDIR)/debian/$(DEB_SOURCE) # Name of libdir in the path for libraries (e.g., the multiarch triplet). diff --git a/pkg/kamailio/deb/focal/changelog b/pkg/kamailio/deb/focal/changelog index a41d9e3d2..ee68e4dc2 100644 --- a/pkg/kamailio/deb/focal/changelog +++ b/pkg/kamailio/deb/focal/changelog @@ -1,72 +1,41 @@ -kamailio (5.7.4) unstable; urgency=medium +kamailio (5.8.1) unstable; urgency=medium - * version set 5.7.4 + * version set 5.8.1 - -- Victor Seva Thu, 18 Jan 2024 10:29:35 +0100 + -- Victor Seva Wed, 03 Apr 2024 08:21:53 +0200 -kamailio (5.7.3) unstable; urgency=medium +kamailio (5.8.0) unstable; urgency=medium - * version set 5.7.3 + * version set 5.8.0 - -- Victor Seva Fri, 17 Nov 2023 09:50:31 +0100 + -- Victor Seva Thu, 07 Mar 2024 11:40:20 +0100 -kamailio (5.7.2) unstable; urgency=medium +kamailio (5.8.0~rc0) unstable; urgency=medium - * version set 5.7.2 + * version set 5.8.0~rc0 - -- Victor Seva Wed, 27 Sep 2023 08:44:32 +0200 + -- Victor Seva Fri, 23 Feb 2024 20:04:35 +0100 -kamailio (5.7.1) unstable; urgency=medium +kamailio (5.8.0~pre0) unstable; urgency=medium - * version set 5.7.1 + * version set 5.8.0~pre0 - -- Victor Seva Wed, 28 Jun 2023 09:35:54 +0200 + -- Victor Seva Fri, 02 Feb 2024 15:20:05 +0100 -kamailio (5.7.0) unstable; urgency=medium +kamailio (5.8.0~dev2) unstable; urgency=medium - * version set 5.7.0 + * version set 5.8.0~dev2 - -- Victor Seva Tue, 16 May 2023 12:57:51 +0200 + -- Victor Seva Tue, 05 Dec 2023 12:04:06 +0100 -kamailio (5.7.0~rc0) unstable; urgency=medium +kamailio (5.8.0~dev1) unstable; urgency=medium - * version set 5.7.0~rc0 + * version set 5.8.0~dev1 - -- Victor Seva Thu, 04 May 2023 21:41:57 +0200 + -- Victor Seva Wed, 28 Jun 2023 15:03:56 +0200 -kamailio (5.7.0~pre0) unstable; urgency=medium +kamailio (5.8.0~dev0) unstable; urgency=medium - * version set 5.7.0~pre0 - - -- Victor Seva Mon, 17 Apr 2023 09:08:01 +0200 - -kamailio (5.7.0~dev4) unstable; urgency=medium - - * version set 5.7.0~dev4 - - -- Victor Seva Mon, 17 Apr 2023 09:07:10 +0200 - -kamailio (5.7.0~dev3) unstable; urgency=medium - - * version set 5.7.0~dev3 - - -- Victor Seva Tue, 10 Jan 2023 14:07:12 +0100 - -kamailio (5.7.0~dev2) unstable; urgency=medium - - * version set 5.7.0~dev2 - - -- Victor Seva Mon, 28 Nov 2022 11:54:03 +0100 - -kamailio (5.7.0~dev1) unstable; urgency=medium - - * version set 5.7.0~dev1 - - -- Victor Seva Sun, 28 Aug 2022 22:36:28 +0200 - -kamailio (5.7.0~dev0) unstable; urgency=medium - - * version set 5.7.0~dev0 - - -- Victor Seva Thu, 05 May 2022 12:47:44 +0200 + * version set 5.8.0~dev0 + -- Victor Seva Thu, 04 May 2023 21:45:08 +0200 diff --git a/pkg/kamailio/deb/focal/control b/pkg/kamailio/deb/focal/control index 7505faac0..0bea172d9 100644 --- a/pkg/kamailio/deb/focal/control +++ b/pkg/kamailio/deb/focal/control @@ -31,7 +31,7 @@ Build-Depends: libmono-2.0-dev [amd64 armel armhf i386 mipsel kfreebsd-amd64 kfreebsd-i386 ppc64 ppc64el s390x], libmosquitto-dev, libncurses5-dev, - libpcre3-dev, + libpcre2-dev, libperl-dev, libphonenumber-dev (>= 7), libpq-dev, diff --git a/pkg/kamailio/deb/focal/rules b/pkg/kamailio/deb/focal/rules index b461e60b1..58a6020cd 100755 --- a/pkg/kamailio/deb/focal/rules +++ b/pkg/kamailio/deb/focal/rules @@ -18,6 +18,7 @@ ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) endif export RADCLI=1 +export WOLFSSL_INTERNAL=no # tlsa export KTLS_INCLUDE_TLSA=yes export LIBSSL_STATIC_SRCLIB=yes @@ -38,6 +39,8 @@ EXTRA_EXCLUDED_MODULES += dnssec EXTRA_EXCLUDED_MODULES += java EXTRA_EXCLUDED_MODULES += secsipid EXTRA_EXCLUDED_MODULES += nats +EXTRA_EXCLUDED_MODULES += microhttpd +EXTRA_EXCLUDED_MODULES += tls_wolfssl ## --EXCLUDED-- @@ -93,6 +96,10 @@ EXTRA_GROUPS += jansson EXTRA_GROUPS += uuid EXTRA_GROUPS += http_async +.PHONY: skip-modules +skip-modules: + @echo "$(EXCLUDED_MODULES) $(EXTRA_EXCLUDED_MODULES)" + D = $(CURDIR)/debian/$(DEB_SOURCE) # Name of libdir in the path for libraries (e.g., the multiarch triplet). diff --git a/pkg/kamailio/deb/jammy/changelog b/pkg/kamailio/deb/jammy/changelog index a41d9e3d2..ee68e4dc2 100644 --- a/pkg/kamailio/deb/jammy/changelog +++ b/pkg/kamailio/deb/jammy/changelog @@ -1,72 +1,41 @@ -kamailio (5.7.4) unstable; urgency=medium +kamailio (5.8.1) unstable; urgency=medium - * version set 5.7.4 + * version set 5.8.1 - -- Victor Seva Thu, 18 Jan 2024 10:29:35 +0100 + -- Victor Seva Wed, 03 Apr 2024 08:21:53 +0200 -kamailio (5.7.3) unstable; urgency=medium +kamailio (5.8.0) unstable; urgency=medium - * version set 5.7.3 + * version set 5.8.0 - -- Victor Seva Fri, 17 Nov 2023 09:50:31 +0100 + -- Victor Seva Thu, 07 Mar 2024 11:40:20 +0100 -kamailio (5.7.2) unstable; urgency=medium +kamailio (5.8.0~rc0) unstable; urgency=medium - * version set 5.7.2 + * version set 5.8.0~rc0 - -- Victor Seva Wed, 27 Sep 2023 08:44:32 +0200 + -- Victor Seva Fri, 23 Feb 2024 20:04:35 +0100 -kamailio (5.7.1) unstable; urgency=medium +kamailio (5.8.0~pre0) unstable; urgency=medium - * version set 5.7.1 + * version set 5.8.0~pre0 - -- Victor Seva Wed, 28 Jun 2023 09:35:54 +0200 + -- Victor Seva Fri, 02 Feb 2024 15:20:05 +0100 -kamailio (5.7.0) unstable; urgency=medium +kamailio (5.8.0~dev2) unstable; urgency=medium - * version set 5.7.0 + * version set 5.8.0~dev2 - -- Victor Seva Tue, 16 May 2023 12:57:51 +0200 + -- Victor Seva Tue, 05 Dec 2023 12:04:06 +0100 -kamailio (5.7.0~rc0) unstable; urgency=medium +kamailio (5.8.0~dev1) unstable; urgency=medium - * version set 5.7.0~rc0 + * version set 5.8.0~dev1 - -- Victor Seva Thu, 04 May 2023 21:41:57 +0200 + -- Victor Seva Wed, 28 Jun 2023 15:03:56 +0200 -kamailio (5.7.0~pre0) unstable; urgency=medium +kamailio (5.8.0~dev0) unstable; urgency=medium - * version set 5.7.0~pre0 - - -- Victor Seva Mon, 17 Apr 2023 09:08:01 +0200 - -kamailio (5.7.0~dev4) unstable; urgency=medium - - * version set 5.7.0~dev4 - - -- Victor Seva Mon, 17 Apr 2023 09:07:10 +0200 - -kamailio (5.7.0~dev3) unstable; urgency=medium - - * version set 5.7.0~dev3 - - -- Victor Seva Tue, 10 Jan 2023 14:07:12 +0100 - -kamailio (5.7.0~dev2) unstable; urgency=medium - - * version set 5.7.0~dev2 - - -- Victor Seva Mon, 28 Nov 2022 11:54:03 +0100 - -kamailio (5.7.0~dev1) unstable; urgency=medium - - * version set 5.7.0~dev1 - - -- Victor Seva Sun, 28 Aug 2022 22:36:28 +0200 - -kamailio (5.7.0~dev0) unstable; urgency=medium - - * version set 5.7.0~dev0 - - -- Victor Seva Thu, 05 May 2022 12:47:44 +0200 + * version set 5.8.0~dev0 + -- Victor Seva Thu, 04 May 2023 21:45:08 +0200 diff --git a/pkg/kamailio/deb/jammy/control b/pkg/kamailio/deb/jammy/control index c7a784b3f..9ed6ed531 100644 --- a/pkg/kamailio/deb/jammy/control +++ b/pkg/kamailio/deb/jammy/control @@ -25,13 +25,14 @@ Build-Depends: liblua5.1-0-dev, libmaxminddb-dev, libmemcached-dev, + libmicrohttpd-dev, libmnl-dev, libmongoc-dev, libmono-2.0-dev [amd64 armel armhf i386 mipsel kfreebsd-amd64 kfreebsd-i386 ppc64 ppc64el s390x], libmosquitto-dev, libnats-dev, libncurses5-dev, - libpcre3-dev, + libpcre2-dev, libperl-dev, libphonenumber-dev (>= 7), libpq-dev, @@ -47,6 +48,7 @@ Build-Depends: libsystemd-dev, libunistring-dev, libwebsockets-dev, + libwolfssl-dev, libxml2-dev, openssl, pkg-config, @@ -619,6 +621,23 @@ Description: TLS support for the Kamailio SIP server (authentication, transport) This package provides TLS support for encrypted and authenticated SIP connections as well as generic TLS support for many Kamailio modules. +Package: kamailio-wolftls-modules +Architecture: any +Multi-Arch: same +Pre-Depends: + ${misc:Pre-Depends}, +Depends: + kamailio (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Description: TLS support for the Kamailio SIP server (authentication, transport) + Kamailio is a very fast and flexible SIP (RFC3261) + server. Written entirely in C, Kamailio can handle thousands calls + per second even on low-budget hardware. + . + This package provides TLS support for encrypted and authenticated using wolfssl + SIP connections as well as generic TLS support for many Kamailio modules. + Package: kamailio-outbound-modules Architecture: any Multi-Arch: same @@ -863,6 +882,22 @@ Description: Nats module for the Kamailio SIP server NATS is a real time distributed messaging platform, more details about it can be found at nats.io. +Package: kamailio-microhttpd-modules +Architecture: any +Multi-Arch: same +Pre-Depends: + ${misc:Pre-Depends}, +Depends: + kamailio (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Description: Microhttpd module for the Kamailio SIP server + Kamailio is a very fast and flexible SIP (RFC3261) + server. Written entirely in C, Kamailio can handle thousands calls + per second even on low-budget hardware. + . + This package provides an embedded HTTP server using libmicrohttpd. + Package: kamailio-extra-modules Architecture: any Multi-Arch: same diff --git a/pkg/kamailio/deb/jammy/rules b/pkg/kamailio/deb/jammy/rules index 33095212b..f7b603151 100755 --- a/pkg/kamailio/deb/jammy/rules +++ b/pkg/kamailio/deb/jammy/rules @@ -18,6 +18,7 @@ ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) endif export RADCLI=1 +export WOLFSSL_INTERNAL=no # tlsa export KTLS_INCLUDE_TLSA=yes export LIBSSL_STATIC_SRCLIB=yes @@ -85,6 +86,8 @@ PACKAGE_GROUPS += mqtt PACKAGE_GROUPS += secsipid PACKAGE_GROUPS += lwsc PACKAGE_GROUPS += nats +PACKAGE_GROUPS += tls_wolfssl +PACKAGE_GROUPS += microhttpd # Module groups to be packaged onto kamailio-extra-modules. EXTRA_GROUPS += ev @@ -93,6 +96,10 @@ EXTRA_GROUPS += jansson EXTRA_GROUPS += uuid EXTRA_GROUPS += http_async +.PHONY: skip-modules +skip-modules: + @echo "$(EXCLUDED_MODULES) $(EXTRA_EXCLUDED_MODULES)" + D = $(CURDIR)/debian/$(DEB_SOURCE) # Name of libdir in the path for libraries (e.g., the multiarch triplet). diff --git a/pkg/kamailio/deb/jessie/changelog b/pkg/kamailio/deb/jessie/changelog index a41d9e3d2..ee68e4dc2 100644 --- a/pkg/kamailio/deb/jessie/changelog +++ b/pkg/kamailio/deb/jessie/changelog @@ -1,72 +1,41 @@ -kamailio (5.7.4) unstable; urgency=medium +kamailio (5.8.1) unstable; urgency=medium - * version set 5.7.4 + * version set 5.8.1 - -- Victor Seva Thu, 18 Jan 2024 10:29:35 +0100 + -- Victor Seva Wed, 03 Apr 2024 08:21:53 +0200 -kamailio (5.7.3) unstable; urgency=medium +kamailio (5.8.0) unstable; urgency=medium - * version set 5.7.3 + * version set 5.8.0 - -- Victor Seva Fri, 17 Nov 2023 09:50:31 +0100 + -- Victor Seva Thu, 07 Mar 2024 11:40:20 +0100 -kamailio (5.7.2) unstable; urgency=medium +kamailio (5.8.0~rc0) unstable; urgency=medium - * version set 5.7.2 + * version set 5.8.0~rc0 - -- Victor Seva Wed, 27 Sep 2023 08:44:32 +0200 + -- Victor Seva Fri, 23 Feb 2024 20:04:35 +0100 -kamailio (5.7.1) unstable; urgency=medium +kamailio (5.8.0~pre0) unstable; urgency=medium - * version set 5.7.1 + * version set 5.8.0~pre0 - -- Victor Seva Wed, 28 Jun 2023 09:35:54 +0200 + -- Victor Seva Fri, 02 Feb 2024 15:20:05 +0100 -kamailio (5.7.0) unstable; urgency=medium +kamailio (5.8.0~dev2) unstable; urgency=medium - * version set 5.7.0 + * version set 5.8.0~dev2 - -- Victor Seva Tue, 16 May 2023 12:57:51 +0200 + -- Victor Seva Tue, 05 Dec 2023 12:04:06 +0100 -kamailio (5.7.0~rc0) unstable; urgency=medium +kamailio (5.8.0~dev1) unstable; urgency=medium - * version set 5.7.0~rc0 + * version set 5.8.0~dev1 - -- Victor Seva Thu, 04 May 2023 21:41:57 +0200 + -- Victor Seva Wed, 28 Jun 2023 15:03:56 +0200 -kamailio (5.7.0~pre0) unstable; urgency=medium +kamailio (5.8.0~dev0) unstable; urgency=medium - * version set 5.7.0~pre0 - - -- Victor Seva Mon, 17 Apr 2023 09:08:01 +0200 - -kamailio (5.7.0~dev4) unstable; urgency=medium - - * version set 5.7.0~dev4 - - -- Victor Seva Mon, 17 Apr 2023 09:07:10 +0200 - -kamailio (5.7.0~dev3) unstable; urgency=medium - - * version set 5.7.0~dev3 - - -- Victor Seva Tue, 10 Jan 2023 14:07:12 +0100 - -kamailio (5.7.0~dev2) unstable; urgency=medium - - * version set 5.7.0~dev2 - - -- Victor Seva Mon, 28 Nov 2022 11:54:03 +0100 - -kamailio (5.7.0~dev1) unstable; urgency=medium - - * version set 5.7.0~dev1 - - -- Victor Seva Sun, 28 Aug 2022 22:36:28 +0200 - -kamailio (5.7.0~dev0) unstable; urgency=medium - - * version set 5.7.0~dev0 - - -- Victor Seva Thu, 05 May 2022 12:47:44 +0200 + * version set 5.8.0~dev0 + -- Victor Seva Thu, 04 May 2023 21:45:08 +0200 diff --git a/pkg/kamailio/deb/jessie/control b/pkg/kamailio/deb/jessie/control index c39e3f067..f67868f1a 100644 --- a/pkg/kamailio/deb/jessie/control +++ b/pkg/kamailio/deb/jessie/control @@ -26,6 +26,7 @@ Build-Depends: libldap2-dev, liblua5.1-0-dev, libmemcached-dev, + libmicrohttpd-dev, libmnl-dev, libmono-2.0-dev [amd64 armel armhf i386 mipsel kfreebsd-amd64 kfreebsd-i386 ppc64 ppc64el s390x], libmosquitto-dev, @@ -810,6 +811,22 @@ Description: MQTT modules for the Kamailio SIP Server Messages can be published from any point in the routing script. Also the subscriptions can be fully controlled by scripting commands. +Package: kamailio-microhttpd-modules +Architecture: any +Multi-Arch: same +Pre-Depends: + ${misc:Pre-Depends}, +Depends: + kamailio (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Description: Microhttpd module for the Kamailio SIP server + Kamailio is a very fast and flexible SIP (RFC3261) + server. Written entirely in C, Kamailio can handle thousands calls + per second even on low-budget hardware. + . + This package provides an embedded HTTP server using libmicrohttpd. + Package: kamailio-extra-modules Architecture: any Multi-Arch: same diff --git a/pkg/kamailio/deb/jessie/rules b/pkg/kamailio/deb/jessie/rules index aec4057ee..b1a114b29 100755 --- a/pkg/kamailio/deb/jessie/rules +++ b/pkg/kamailio/deb/jessie/rules @@ -19,6 +19,7 @@ endif export JAVA_HOME=/usr/lib/jvm/java-gcj export FREERADIUS=1 +export WOLFSSL_INTERNAL=no # tlsa export KTLS_INCLUDE_TLSA=yes export LIBSSL_STATIC_SRCLIB=yes @@ -41,6 +42,7 @@ EXTRA_EXCLUDED_MODULES += mongodb EXTRA_EXCLUDED_MODULES += secsipid EXTRA_EXCLUDED_MODULES += lwsc EXTRA_EXCLUDED_MODULES += nats +EXTRA_EXCLUDED_MODULES += tls_wolfssl ## --EXCLUDED-- @@ -86,6 +88,7 @@ PACKAGE_GROUPS += systemd PACKAGE_GROUPS += rabbitmq PACKAGE_GROUPS += python3 PACKAGE_GROUPS += mqtt +PACKAGE_GROUPS += microhttpd # Module groups to be packaged onto kamailio-extra-modules. EXTRA_GROUPS += ev @@ -94,6 +97,10 @@ EXTRA_GROUPS += jansson EXTRA_GROUPS += uuid EXTRA_GROUPS += http_async +.PHONY: skip-modules +skip-modules: + @echo "$(EXCLUDED_MODULES) $(EXTRA_EXCLUDED_MODULES)" + D = $(CURDIR)/debian/$(DEB_SOURCE) # Name of libdir in the path for libraries (e.g., the multiarch triplet). diff --git a/pkg/kamailio/deb/precise/changelog b/pkg/kamailio/deb/precise/changelog index a41d9e3d2..ee68e4dc2 100644 --- a/pkg/kamailio/deb/precise/changelog +++ b/pkg/kamailio/deb/precise/changelog @@ -1,72 +1,41 @@ -kamailio (5.7.4) unstable; urgency=medium +kamailio (5.8.1) unstable; urgency=medium - * version set 5.7.4 + * version set 5.8.1 - -- Victor Seva Thu, 18 Jan 2024 10:29:35 +0100 + -- Victor Seva Wed, 03 Apr 2024 08:21:53 +0200 -kamailio (5.7.3) unstable; urgency=medium +kamailio (5.8.0) unstable; urgency=medium - * version set 5.7.3 + * version set 5.8.0 - -- Victor Seva Fri, 17 Nov 2023 09:50:31 +0100 + -- Victor Seva Thu, 07 Mar 2024 11:40:20 +0100 -kamailio (5.7.2) unstable; urgency=medium +kamailio (5.8.0~rc0) unstable; urgency=medium - * version set 5.7.2 + * version set 5.8.0~rc0 - -- Victor Seva Wed, 27 Sep 2023 08:44:32 +0200 + -- Victor Seva Fri, 23 Feb 2024 20:04:35 +0100 -kamailio (5.7.1) unstable; urgency=medium +kamailio (5.8.0~pre0) unstable; urgency=medium - * version set 5.7.1 + * version set 5.8.0~pre0 - -- Victor Seva Wed, 28 Jun 2023 09:35:54 +0200 + -- Victor Seva Fri, 02 Feb 2024 15:20:05 +0100 -kamailio (5.7.0) unstable; urgency=medium +kamailio (5.8.0~dev2) unstable; urgency=medium - * version set 5.7.0 + * version set 5.8.0~dev2 - -- Victor Seva Tue, 16 May 2023 12:57:51 +0200 + -- Victor Seva Tue, 05 Dec 2023 12:04:06 +0100 -kamailio (5.7.0~rc0) unstable; urgency=medium +kamailio (5.8.0~dev1) unstable; urgency=medium - * version set 5.7.0~rc0 + * version set 5.8.0~dev1 - -- Victor Seva Thu, 04 May 2023 21:41:57 +0200 + -- Victor Seva Wed, 28 Jun 2023 15:03:56 +0200 -kamailio (5.7.0~pre0) unstable; urgency=medium +kamailio (5.8.0~dev0) unstable; urgency=medium - * version set 5.7.0~pre0 - - -- Victor Seva Mon, 17 Apr 2023 09:08:01 +0200 - -kamailio (5.7.0~dev4) unstable; urgency=medium - - * version set 5.7.0~dev4 - - -- Victor Seva Mon, 17 Apr 2023 09:07:10 +0200 - -kamailio (5.7.0~dev3) unstable; urgency=medium - - * version set 5.7.0~dev3 - - -- Victor Seva Tue, 10 Jan 2023 14:07:12 +0100 - -kamailio (5.7.0~dev2) unstable; urgency=medium - - * version set 5.7.0~dev2 - - -- Victor Seva Mon, 28 Nov 2022 11:54:03 +0100 - -kamailio (5.7.0~dev1) unstable; urgency=medium - - * version set 5.7.0~dev1 - - -- Victor Seva Sun, 28 Aug 2022 22:36:28 +0200 - -kamailio (5.7.0~dev0) unstable; urgency=medium - - * version set 5.7.0~dev0 - - -- Victor Seva Thu, 05 May 2022 12:47:44 +0200 + * version set 5.8.0~dev0 + -- Victor Seva Thu, 04 May 2023 21:45:08 +0200 diff --git a/pkg/kamailio/deb/precise/control b/pkg/kamailio/deb/precise/control index e58d364da..16719f809 100644 --- a/pkg/kamailio/deb/precise/control +++ b/pkg/kamailio/deb/precise/control @@ -24,6 +24,7 @@ Build-Depends: libldap2-dev, liblua5.1-0-dev, libmemcached-dev, + libmicrohttpd-dev, libmnl-dev, libmono-2.0-dev [amd64 armel armhf i386 mipsel kfreebsd-amd64 kfreebsd-i386 ppc64 ppc64el s390x], libmysqlclient-dev, @@ -660,6 +661,22 @@ Description: Erlang modules for the Kamailio SIP server SIP routing scripts. The module allows sending, receiving Erlang messages and RPC calls between each other. +Package: kamailio-microhttpd-modules +Architecture: any +Multi-Arch: same +Pre-Depends: + ${misc:Pre-Depends}, +Depends: + kamailio (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Description: Microhttpd module for the Kamailio SIP server + Kamailio is a very fast and flexible SIP (RFC3261) + server. Written entirely in C, Kamailio can handle thousands calls + per second even on low-budget hardware. + . + This package provides an embedded HTTP server using libmicrohttpd. + Package: kamailio-extra-modules Architecture: any Multi-Arch: same diff --git a/pkg/kamailio/deb/precise/rules b/pkg/kamailio/deb/precise/rules index 21dc6664f..6bd8a12ab 100755 --- a/pkg/kamailio/deb/precise/rules +++ b/pkg/kamailio/deb/precise/rules @@ -18,6 +18,7 @@ ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) endif export JAVA_HOME=/usr/lib/jvm/java-gcj +export WOLFSSL_INTERNAL=no # tlsa export KTLS_INCLUDE_TLSA=yes export LIBSSL_STATIC_SRCLIB=yes @@ -48,6 +49,7 @@ EXTRA_EXCLUDED_MODULES += mqtt EXTRA_EXCLUDED_MODULES += secsipid EXTRA_EXCLUDED_MODULES += lwsc EXTRA_EXCLUDED_MODULES += nats +EXTRA_EXCLUDED_MODULES += tls_wolfssl ## --EXCLUDED-- @@ -85,6 +87,7 @@ PACKAGE_GROUPS += outbound PACKAGE_GROUPS += websocket PACKAGE_GROUPS += autheph PACKAGE_GROUPS += erlang +PACKAGE_GROUPS += microhttpd # Module groups to be packaged onto kamailio-extra-modules. EXTRA_GROUPS += ev @@ -93,6 +96,10 @@ EXTRA_GROUPS += jansson EXTRA_GROUPS += uuid EXTRA_GROUPS += http_async +.PHONY: skip-modules +skip-modules: + @echo "$(EXCLUDED_MODULES) $(EXTRA_EXCLUDED_MODULES)" + D = $(CURDIR)/debian/$(DEB_SOURCE) # Name of libdir in the path for libraries (e.g., the multiarch triplet). diff --git a/pkg/kamailio/deb/sid/changelog b/pkg/kamailio/deb/sid/changelog index a41d9e3d2..ee68e4dc2 100644 --- a/pkg/kamailio/deb/sid/changelog +++ b/pkg/kamailio/deb/sid/changelog @@ -1,72 +1,41 @@ -kamailio (5.7.4) unstable; urgency=medium +kamailio (5.8.1) unstable; urgency=medium - * version set 5.7.4 + * version set 5.8.1 - -- Victor Seva Thu, 18 Jan 2024 10:29:35 +0100 + -- Victor Seva Wed, 03 Apr 2024 08:21:53 +0200 -kamailio (5.7.3) unstable; urgency=medium +kamailio (5.8.0) unstable; urgency=medium - * version set 5.7.3 + * version set 5.8.0 - -- Victor Seva Fri, 17 Nov 2023 09:50:31 +0100 + -- Victor Seva Thu, 07 Mar 2024 11:40:20 +0100 -kamailio (5.7.2) unstable; urgency=medium +kamailio (5.8.0~rc0) unstable; urgency=medium - * version set 5.7.2 + * version set 5.8.0~rc0 - -- Victor Seva Wed, 27 Sep 2023 08:44:32 +0200 + -- Victor Seva Fri, 23 Feb 2024 20:04:35 +0100 -kamailio (5.7.1) unstable; urgency=medium +kamailio (5.8.0~pre0) unstable; urgency=medium - * version set 5.7.1 + * version set 5.8.0~pre0 - -- Victor Seva Wed, 28 Jun 2023 09:35:54 +0200 + -- Victor Seva Fri, 02 Feb 2024 15:20:05 +0100 -kamailio (5.7.0) unstable; urgency=medium +kamailio (5.8.0~dev2) unstable; urgency=medium - * version set 5.7.0 + * version set 5.8.0~dev2 - -- Victor Seva Tue, 16 May 2023 12:57:51 +0200 + -- Victor Seva Tue, 05 Dec 2023 12:04:06 +0100 -kamailio (5.7.0~rc0) unstable; urgency=medium +kamailio (5.8.0~dev1) unstable; urgency=medium - * version set 5.7.0~rc0 + * version set 5.8.0~dev1 - -- Victor Seva Thu, 04 May 2023 21:41:57 +0200 + -- Victor Seva Wed, 28 Jun 2023 15:03:56 +0200 -kamailio (5.7.0~pre0) unstable; urgency=medium +kamailio (5.8.0~dev0) unstable; urgency=medium - * version set 5.7.0~pre0 - - -- Victor Seva Mon, 17 Apr 2023 09:08:01 +0200 - -kamailio (5.7.0~dev4) unstable; urgency=medium - - * version set 5.7.0~dev4 - - -- Victor Seva Mon, 17 Apr 2023 09:07:10 +0200 - -kamailio (5.7.0~dev3) unstable; urgency=medium - - * version set 5.7.0~dev3 - - -- Victor Seva Tue, 10 Jan 2023 14:07:12 +0100 - -kamailio (5.7.0~dev2) unstable; urgency=medium - - * version set 5.7.0~dev2 - - -- Victor Seva Mon, 28 Nov 2022 11:54:03 +0100 - -kamailio (5.7.0~dev1) unstable; urgency=medium - - * version set 5.7.0~dev1 - - -- Victor Seva Sun, 28 Aug 2022 22:36:28 +0200 - -kamailio (5.7.0~dev0) unstable; urgency=medium - - * version set 5.7.0~dev0 - - -- Victor Seva Thu, 05 May 2022 12:47:44 +0200 + * version set 5.8.0~dev0 + -- Victor Seva Thu, 04 May 2023 21:45:08 +0200 diff --git a/pkg/kamailio/deb/sid/control b/pkg/kamailio/deb/sid/control index 8d6af8ecc..2ec6d74a4 100644 --- a/pkg/kamailio/deb/sid/control +++ b/pkg/kamailio/deb/sid/control @@ -25,13 +25,14 @@ Build-Depends: liblua5.1-0-dev, libmaxminddb-dev, libmemcached-dev, + libmicrohttpd-dev, libmnl-dev, libmongoc-dev, libmono-2.0-dev [amd64 armel armhf i386 mipsel kfreebsd-amd64 kfreebsd-i386 ppc64 ppc64el s390x], libmosquitto-dev, libnats-dev, libncurses-dev, - libpcre3-dev, + libpcre2-dev, libperl-dev, libphonenumber-dev (>= 7), libpq-dev, @@ -47,6 +48,7 @@ Build-Depends: libsystemd-dev, libunistring-dev, libwebsockets-dev, + libwolfssl-dev, libxml2-dev, openssl, pkg-config, @@ -618,6 +620,23 @@ Description: TLS support for the Kamailio SIP server (authentication, transport) This package provides TLS support for encrypted and authenticated SIP connections as well as generic TLS support for many Kamailio modules. +Package: kamailio-wolftls-modules +Architecture: any +Multi-Arch: same +Pre-Depends: + ${misc:Pre-Depends}, +Depends: + kamailio (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Description: TLS support for the Kamailio SIP server (authentication, transport) + Kamailio is a very fast and flexible SIP (RFC3261) + server. Written entirely in C, Kamailio can handle thousands calls + per second even on low-budget hardware. + . + This package provides TLS support for encrypted and authenticated using wolfssl + SIP connections as well as generic TLS support for many Kamailio modules. + Package: kamailio-outbound-modules Architecture: any Multi-Arch: same @@ -862,6 +881,22 @@ Description: Nats module for the Kamailio SIP server NATS is a real time distributed messaging platform, more details about it can be found at nats.io. +Package: kamailio-microhttpd-modules +Architecture: any +Multi-Arch: same +Pre-Depends: + ${misc:Pre-Depends}, +Depends: + kamailio (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Description: Microhttpd module for the Kamailio SIP server + Kamailio is a very fast and flexible SIP (RFC3261) + server. Written entirely in C, Kamailio can handle thousands calls + per second even on low-budget hardware. + . + This package provides an embedded HTTP server using libmicrohttpd. + Package: kamailio-extra-modules Architecture: any Multi-Arch: same diff --git a/pkg/kamailio/deb/sid/rules b/pkg/kamailio/deb/sid/rules index 33095212b..f7b603151 100755 --- a/pkg/kamailio/deb/sid/rules +++ b/pkg/kamailio/deb/sid/rules @@ -18,6 +18,7 @@ ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) endif export RADCLI=1 +export WOLFSSL_INTERNAL=no # tlsa export KTLS_INCLUDE_TLSA=yes export LIBSSL_STATIC_SRCLIB=yes @@ -85,6 +86,8 @@ PACKAGE_GROUPS += mqtt PACKAGE_GROUPS += secsipid PACKAGE_GROUPS += lwsc PACKAGE_GROUPS += nats +PACKAGE_GROUPS += tls_wolfssl +PACKAGE_GROUPS += microhttpd # Module groups to be packaged onto kamailio-extra-modules. EXTRA_GROUPS += ev @@ -93,6 +96,10 @@ EXTRA_GROUPS += jansson EXTRA_GROUPS += uuid EXTRA_GROUPS += http_async +.PHONY: skip-modules +skip-modules: + @echo "$(EXCLUDED_MODULES) $(EXTRA_EXCLUDED_MODULES)" + D = $(CURDIR)/debian/$(DEB_SOURCE) # Name of libdir in the path for libraries (e.g., the multiarch triplet). diff --git a/pkg/kamailio/deb/stretch/changelog b/pkg/kamailio/deb/stretch/changelog index a41d9e3d2..ee68e4dc2 100644 --- a/pkg/kamailio/deb/stretch/changelog +++ b/pkg/kamailio/deb/stretch/changelog @@ -1,72 +1,41 @@ -kamailio (5.7.4) unstable; urgency=medium +kamailio (5.8.1) unstable; urgency=medium - * version set 5.7.4 + * version set 5.8.1 - -- Victor Seva Thu, 18 Jan 2024 10:29:35 +0100 + -- Victor Seva Wed, 03 Apr 2024 08:21:53 +0200 -kamailio (5.7.3) unstable; urgency=medium +kamailio (5.8.0) unstable; urgency=medium - * version set 5.7.3 + * version set 5.8.0 - -- Victor Seva Fri, 17 Nov 2023 09:50:31 +0100 + -- Victor Seva Thu, 07 Mar 2024 11:40:20 +0100 -kamailio (5.7.2) unstable; urgency=medium +kamailio (5.8.0~rc0) unstable; urgency=medium - * version set 5.7.2 + * version set 5.8.0~rc0 - -- Victor Seva Wed, 27 Sep 2023 08:44:32 +0200 + -- Victor Seva Fri, 23 Feb 2024 20:04:35 +0100 -kamailio (5.7.1) unstable; urgency=medium +kamailio (5.8.0~pre0) unstable; urgency=medium - * version set 5.7.1 + * version set 5.8.0~pre0 - -- Victor Seva Wed, 28 Jun 2023 09:35:54 +0200 + -- Victor Seva Fri, 02 Feb 2024 15:20:05 +0100 -kamailio (5.7.0) unstable; urgency=medium +kamailio (5.8.0~dev2) unstable; urgency=medium - * version set 5.7.0 + * version set 5.8.0~dev2 - -- Victor Seva Tue, 16 May 2023 12:57:51 +0200 + -- Victor Seva Tue, 05 Dec 2023 12:04:06 +0100 -kamailio (5.7.0~rc0) unstable; urgency=medium +kamailio (5.8.0~dev1) unstable; urgency=medium - * version set 5.7.0~rc0 + * version set 5.8.0~dev1 - -- Victor Seva Thu, 04 May 2023 21:41:57 +0200 + -- Victor Seva Wed, 28 Jun 2023 15:03:56 +0200 -kamailio (5.7.0~pre0) unstable; urgency=medium +kamailio (5.8.0~dev0) unstable; urgency=medium - * version set 5.7.0~pre0 - - -- Victor Seva Mon, 17 Apr 2023 09:08:01 +0200 - -kamailio (5.7.0~dev4) unstable; urgency=medium - - * version set 5.7.0~dev4 - - -- Victor Seva Mon, 17 Apr 2023 09:07:10 +0200 - -kamailio (5.7.0~dev3) unstable; urgency=medium - - * version set 5.7.0~dev3 - - -- Victor Seva Tue, 10 Jan 2023 14:07:12 +0100 - -kamailio (5.7.0~dev2) unstable; urgency=medium - - * version set 5.7.0~dev2 - - -- Victor Seva Mon, 28 Nov 2022 11:54:03 +0100 - -kamailio (5.7.0~dev1) unstable; urgency=medium - - * version set 5.7.0~dev1 - - -- Victor Seva Sun, 28 Aug 2022 22:36:28 +0200 - -kamailio (5.7.0~dev0) unstable; urgency=medium - - * version set 5.7.0~dev0 - - -- Victor Seva Thu, 05 May 2022 12:47:44 +0200 + * version set 5.8.0~dev0 + -- Victor Seva Thu, 04 May 2023 21:45:08 +0200 diff --git a/pkg/kamailio/deb/stretch/control b/pkg/kamailio/deb/stretch/control index 84c396711..2793e0875 100644 --- a/pkg/kamailio/deb/stretch/control +++ b/pkg/kamailio/deb/stretch/control @@ -33,7 +33,7 @@ Build-Depends: libmono-2.0-dev [amd64 armel armhf i386 mipsel kfreebsd-amd64 kfreebsd-i386 ppc64 ppc64el s390x], libmosquitto-dev, libncurses5-dev, - libpcre3-dev, + libpcre2-dev, libperl-dev, libphonenumber-dev (>= 7), libpq-dev, @@ -570,23 +570,6 @@ Description: LDAP modules for the Kamailio SIP server queries from the Kamailio routing scripts and storage of SIP account data in an LDAP directory. -Package: kamailio-ims-modules -Architecture: any -Multi-Arch: same -Pre-Depends: - ${misc:Pre-Depends}, -Depends: - kamailio (= ${binary:Version}), - ${misc:Depends}, - ${shlibs:Depends}, -Description: IMS module for the Kamailio SIP server - Kamailio is a very fast and flexible SIP (RFC3261) - server. Written entirely in C, Kamailio can handle thousands calls - per second even on low-budget hardware. - . - This package contains various Diameter interfaces and modules for Kamailio - to run as an IMS core. - Package: kamailio-utils-modules Architecture: any Multi-Arch: same diff --git a/pkg/kamailio/deb/stretch/rules b/pkg/kamailio/deb/stretch/rules index 673ed05c0..bcd0f0544 100755 --- a/pkg/kamailio/deb/stretch/rules +++ b/pkg/kamailio/deb/stretch/rules @@ -19,6 +19,7 @@ endif export JAVA_HOME=/usr/lib/jvm/java-gcj export RADCLI=1 +export WOLFSSL_INTERNAL=no # tlsa export KTLS_INCLUDE_TLSA=yes export LIBSSL_STATIC_SRCLIB=yes @@ -39,6 +40,9 @@ EXTRA_EXCLUDED_MODULES += dnssec EXTRA_EXCLUDED_MODULES += secsipid EXTRA_EXCLUDED_MODULES += lwsc EXTRA_EXCLUDED_MODULES += nats +EXTRA_EXCLUDED_MODULES += microhttpd +EXTRA_EXCLUDED_MODULES += ims +EXTRA_EXCLUDED_MODULES += tls_wolfssl ## --EXCLUDED-- @@ -70,7 +74,6 @@ PACKAGE_GROUPS += sqlite PACKAGE_GROUPS += json PACKAGE_GROUPS += mono PACKAGE_GROUPS += ruby -PACKAGE_GROUPS += ims PACKAGE_GROUPS += sctp PACKAGE_GROUPS += java PACKAGE_GROUPS += tls @@ -94,6 +97,10 @@ EXTRA_GROUPS += jansson EXTRA_GROUPS += uuid EXTRA_GROUPS += http_async +.PHONY: skip-modules +skip-modules: + @echo "$(EXCLUDED_MODULES) $(EXTRA_EXCLUDED_MODULES)" + D = $(CURDIR)/debian/$(DEB_SOURCE) # Name of libdir in the path for libraries (e.g., the multiarch triplet). diff --git a/pkg/kamailio/deb/trusty/changelog b/pkg/kamailio/deb/trusty/changelog index a41d9e3d2..ee68e4dc2 100644 --- a/pkg/kamailio/deb/trusty/changelog +++ b/pkg/kamailio/deb/trusty/changelog @@ -1,72 +1,41 @@ -kamailio (5.7.4) unstable; urgency=medium +kamailio (5.8.1) unstable; urgency=medium - * version set 5.7.4 + * version set 5.8.1 - -- Victor Seva Thu, 18 Jan 2024 10:29:35 +0100 + -- Victor Seva Wed, 03 Apr 2024 08:21:53 +0200 -kamailio (5.7.3) unstable; urgency=medium +kamailio (5.8.0) unstable; urgency=medium - * version set 5.7.3 + * version set 5.8.0 - -- Victor Seva Fri, 17 Nov 2023 09:50:31 +0100 + -- Victor Seva Thu, 07 Mar 2024 11:40:20 +0100 -kamailio (5.7.2) unstable; urgency=medium +kamailio (5.8.0~rc0) unstable; urgency=medium - * version set 5.7.2 + * version set 5.8.0~rc0 - -- Victor Seva Wed, 27 Sep 2023 08:44:32 +0200 + -- Victor Seva Fri, 23 Feb 2024 20:04:35 +0100 -kamailio (5.7.1) unstable; urgency=medium +kamailio (5.8.0~pre0) unstable; urgency=medium - * version set 5.7.1 + * version set 5.8.0~pre0 - -- Victor Seva Wed, 28 Jun 2023 09:35:54 +0200 + -- Victor Seva Fri, 02 Feb 2024 15:20:05 +0100 -kamailio (5.7.0) unstable; urgency=medium +kamailio (5.8.0~dev2) unstable; urgency=medium - * version set 5.7.0 + * version set 5.8.0~dev2 - -- Victor Seva Tue, 16 May 2023 12:57:51 +0200 + -- Victor Seva Tue, 05 Dec 2023 12:04:06 +0100 -kamailio (5.7.0~rc0) unstable; urgency=medium +kamailio (5.8.0~dev1) unstable; urgency=medium - * version set 5.7.0~rc0 + * version set 5.8.0~dev1 - -- Victor Seva Thu, 04 May 2023 21:41:57 +0200 + -- Victor Seva Wed, 28 Jun 2023 15:03:56 +0200 -kamailio (5.7.0~pre0) unstable; urgency=medium +kamailio (5.8.0~dev0) unstable; urgency=medium - * version set 5.7.0~pre0 - - -- Victor Seva Mon, 17 Apr 2023 09:08:01 +0200 - -kamailio (5.7.0~dev4) unstable; urgency=medium - - * version set 5.7.0~dev4 - - -- Victor Seva Mon, 17 Apr 2023 09:07:10 +0200 - -kamailio (5.7.0~dev3) unstable; urgency=medium - - * version set 5.7.0~dev3 - - -- Victor Seva Tue, 10 Jan 2023 14:07:12 +0100 - -kamailio (5.7.0~dev2) unstable; urgency=medium - - * version set 5.7.0~dev2 - - -- Victor Seva Mon, 28 Nov 2022 11:54:03 +0100 - -kamailio (5.7.0~dev1) unstable; urgency=medium - - * version set 5.7.0~dev1 - - -- Victor Seva Sun, 28 Aug 2022 22:36:28 +0200 - -kamailio (5.7.0~dev0) unstable; urgency=medium - - * version set 5.7.0~dev0 - - -- Victor Seva Thu, 05 May 2022 12:47:44 +0200 + * version set 5.8.0~dev0 + -- Victor Seva Thu, 04 May 2023 21:45:08 +0200 diff --git a/pkg/kamailio/deb/trusty/control b/pkg/kamailio/deb/trusty/control index 33b7d6eca..ef0f37f78 100644 --- a/pkg/kamailio/deb/trusty/control +++ b/pkg/kamailio/deb/trusty/control @@ -25,6 +25,7 @@ Build-Depends: libldap2-dev, liblua5.1-0-dev, libmemcached-dev, + libmicrohttpd-dev, libmnl-dev, libmono-2.0-dev [amd64 armel armhf i386 mipsel kfreebsd-amd64 kfreebsd-i386 ppc64 ppc64el s390x], libmysqlclient-dev, @@ -751,6 +752,22 @@ Description: Erlang modules for the Kamailio SIP server SIP routing scripts. The module allows sending, receiving Erlang messages and RPC calls between each other. +Package: kamailio-microhttpd-modules +Architecture: any +Multi-Arch: same +Pre-Depends: + ${misc:Pre-Depends}, +Depends: + kamailio (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Description: Microhttpd module for the Kamailio SIP server + Kamailio is a very fast and flexible SIP (RFC3261) + server. Written entirely in C, Kamailio can handle thousands calls + per second even on low-budget hardware. + . + This package provides an embedded HTTP server using libmicrohttpd. + Package: kamailio-extra-modules Architecture: any Multi-Arch: same diff --git a/pkg/kamailio/deb/trusty/rules b/pkg/kamailio/deb/trusty/rules index bb0f6135c..997e2635c 100755 --- a/pkg/kamailio/deb/trusty/rules +++ b/pkg/kamailio/deb/trusty/rules @@ -19,6 +19,7 @@ endif export JAVA_HOME=/usr/lib/jvm/java-gcj export FREERADIUS=1 +export WOLFSSL_INTERNAL=no # tlsa export KTLS_INCLUDE_TLSA=yes export LIBSSL_STATIC_SRCLIB=yes @@ -44,6 +45,7 @@ EXTRA_EXCLUDED_MODULES += mqtt EXTRA_EXCLUDED_MODULES += secsipid EXTRA_EXCLUDED_MODULES += lwsc EXTRA_EXCLUDED_MODULES += nats +EXTRA_EXCLUDED_MODULES += tls_wolfssl ## --EXCLUDED-- @@ -86,6 +88,7 @@ PACKAGE_GROUPS += cnxcc PACKAGE_GROUPS += erlang PACKAGE_GROUPS += rabbitmq PACKAGE_GROUPS += python3 +PACKAGE_GROUPS += microhttpd # Module groups to be packaged onto kamailio-extra-modules. EXTRA_GROUPS += ev @@ -94,6 +97,10 @@ EXTRA_GROUPS += jansson EXTRA_GROUPS += uuid EXTRA_GROUPS += http_async +.PHONY: skip-modules +skip-modules: + @echo "$(EXCLUDED_MODULES) $(EXTRA_EXCLUDED_MODULES)" + D = $(CURDIR)/debian/$(DEB_SOURCE) # Name of libdir in the path for libraries (e.g., the multiarch triplet). diff --git a/pkg/kamailio/deb/wheezy/changelog b/pkg/kamailio/deb/wheezy/changelog index a41d9e3d2..ee68e4dc2 100644 --- a/pkg/kamailio/deb/wheezy/changelog +++ b/pkg/kamailio/deb/wheezy/changelog @@ -1,72 +1,41 @@ -kamailio (5.7.4) unstable; urgency=medium +kamailio (5.8.1) unstable; urgency=medium - * version set 5.7.4 + * version set 5.8.1 - -- Victor Seva Thu, 18 Jan 2024 10:29:35 +0100 + -- Victor Seva Wed, 03 Apr 2024 08:21:53 +0200 -kamailio (5.7.3) unstable; urgency=medium +kamailio (5.8.0) unstable; urgency=medium - * version set 5.7.3 + * version set 5.8.0 - -- Victor Seva Fri, 17 Nov 2023 09:50:31 +0100 + -- Victor Seva Thu, 07 Mar 2024 11:40:20 +0100 -kamailio (5.7.2) unstable; urgency=medium +kamailio (5.8.0~rc0) unstable; urgency=medium - * version set 5.7.2 + * version set 5.8.0~rc0 - -- Victor Seva Wed, 27 Sep 2023 08:44:32 +0200 + -- Victor Seva Fri, 23 Feb 2024 20:04:35 +0100 -kamailio (5.7.1) unstable; urgency=medium +kamailio (5.8.0~pre0) unstable; urgency=medium - * version set 5.7.1 + * version set 5.8.0~pre0 - -- Victor Seva Wed, 28 Jun 2023 09:35:54 +0200 + -- Victor Seva Fri, 02 Feb 2024 15:20:05 +0100 -kamailio (5.7.0) unstable; urgency=medium +kamailio (5.8.0~dev2) unstable; urgency=medium - * version set 5.7.0 + * version set 5.8.0~dev2 - -- Victor Seva Tue, 16 May 2023 12:57:51 +0200 + -- Victor Seva Tue, 05 Dec 2023 12:04:06 +0100 -kamailio (5.7.0~rc0) unstable; urgency=medium +kamailio (5.8.0~dev1) unstable; urgency=medium - * version set 5.7.0~rc0 + * version set 5.8.0~dev1 - -- Victor Seva Thu, 04 May 2023 21:41:57 +0200 + -- Victor Seva Wed, 28 Jun 2023 15:03:56 +0200 -kamailio (5.7.0~pre0) unstable; urgency=medium +kamailio (5.8.0~dev0) unstable; urgency=medium - * version set 5.7.0~pre0 - - -- Victor Seva Mon, 17 Apr 2023 09:08:01 +0200 - -kamailio (5.7.0~dev4) unstable; urgency=medium - - * version set 5.7.0~dev4 - - -- Victor Seva Mon, 17 Apr 2023 09:07:10 +0200 - -kamailio (5.7.0~dev3) unstable; urgency=medium - - * version set 5.7.0~dev3 - - -- Victor Seva Tue, 10 Jan 2023 14:07:12 +0100 - -kamailio (5.7.0~dev2) unstable; urgency=medium - - * version set 5.7.0~dev2 - - -- Victor Seva Mon, 28 Nov 2022 11:54:03 +0100 - -kamailio (5.7.0~dev1) unstable; urgency=medium - - * version set 5.7.0~dev1 - - -- Victor Seva Sun, 28 Aug 2022 22:36:28 +0200 - -kamailio (5.7.0~dev0) unstable; urgency=medium - - * version set 5.7.0~dev0 - - -- Victor Seva Thu, 05 May 2022 12:47:44 +0200 + * version set 5.8.0~dev0 + -- Victor Seva Thu, 04 May 2023 21:45:08 +0200 diff --git a/pkg/kamailio/deb/wheezy/control b/pkg/kamailio/deb/wheezy/control index e58d364da..ed5f1aa50 100644 --- a/pkg/kamailio/deb/wheezy/control +++ b/pkg/kamailio/deb/wheezy/control @@ -24,8 +24,8 @@ Build-Depends: libldap2-dev, liblua5.1-0-dev, libmemcached-dev, + libmicrohttpd-dev, libmnl-dev, - libmono-2.0-dev [amd64 armel armhf i386 mipsel kfreebsd-amd64 kfreebsd-i386 ppc64 ppc64el s390x], libmysqlclient-dev, libncurses5-dev, libpcre3-dev, @@ -218,23 +218,6 @@ Description: The app_lua module for Kamailio Lua support execute embedded Lua applications within the configuration file as well as writing the entire configuration file in Lua. -Package: kamailio-mono-modules -Architecture: any -Multi-Arch: same -Pre-Depends: - ${misc:Pre-Depends}, -Depends: - kamailio (= ${binary:Version}), - ${misc:Depends}, - ${shlibs:Depends}, -Description: The app_mono module for the Kamailio SIP server - Kamailio is a very fast and flexible SIP (RFC3261) - server. Written entirely in C, Kamailio can handle thousands calls - per second even on low-budget hardware. - . - This package provides the app_mono module, an extension allowing to - execute embedded Mono applications within the Kamailio SIP routing script. - Package: kamailio-python-modules Architecture: any Multi-Arch: same @@ -660,6 +643,22 @@ Description: Erlang modules for the Kamailio SIP server SIP routing scripts. The module allows sending, receiving Erlang messages and RPC calls between each other. +Package: kamailio-microhttpd-modules +Architecture: any +Multi-Arch: same +Pre-Depends: + ${misc:Pre-Depends}, +Depends: + kamailio (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Description: Microhttpd module for the Kamailio SIP server + Kamailio is a very fast and flexible SIP (RFC3261) + server. Written entirely in C, Kamailio can handle thousands calls + per second even on low-budget hardware. + . + This package provides an embedded HTTP server using libmicrohttpd. + Package: kamailio-extra-modules Architecture: any Multi-Arch: same diff --git a/pkg/kamailio/deb/wheezy/rules b/pkg/kamailio/deb/wheezy/rules index 21dc6664f..e30d2b138 100755 --- a/pkg/kamailio/deb/wheezy/rules +++ b/pkg/kamailio/deb/wheezy/rules @@ -18,6 +18,7 @@ ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) endif export JAVA_HOME=/usr/lib/jvm/java-gcj +export WOLFSSL_INTERNAL=no # tlsa export KTLS_INCLUDE_TLSA=yes export LIBSSL_STATIC_SRCLIB=yes @@ -48,6 +49,8 @@ EXTRA_EXCLUDED_MODULES += mqtt EXTRA_EXCLUDED_MODULES += secsipid EXTRA_EXCLUDED_MODULES += lwsc EXTRA_EXCLUDED_MODULES += nats +EXTRA_EXCLUDED_MODULES += mono +EXTRA_EXCLUDED_MODULES += tls_wolfssl ## --EXCLUDED-- @@ -76,7 +79,6 @@ PACKAGE_GROUPS += python PACKAGE_GROUPS += geoip PACKAGE_GROUPS += sqlite PACKAGE_GROUPS += json -PACKAGE_GROUPS += mono PACKAGE_GROUPS += ims PACKAGE_GROUPS += sctp PACKAGE_GROUPS += java @@ -85,6 +87,7 @@ PACKAGE_GROUPS += outbound PACKAGE_GROUPS += websocket PACKAGE_GROUPS += autheph PACKAGE_GROUPS += erlang +PACKAGE_GROUPS += microhttpd # Module groups to be packaged onto kamailio-extra-modules. EXTRA_GROUPS += ev @@ -93,6 +96,10 @@ EXTRA_GROUPS += jansson EXTRA_GROUPS += uuid EXTRA_GROUPS += http_async +.PHONY: skip-modules +skip-modules: + @echo "$(EXCLUDED_MODULES) $(EXTRA_EXCLUDED_MODULES)" + D = $(CURDIR)/debian/$(DEB_SOURCE) # Name of libdir in the path for libraries (e.g., the multiarch triplet). diff --git a/pkg/kamailio/deb/xenial/changelog b/pkg/kamailio/deb/xenial/changelog index a41d9e3d2..ee68e4dc2 100644 --- a/pkg/kamailio/deb/xenial/changelog +++ b/pkg/kamailio/deb/xenial/changelog @@ -1,72 +1,41 @@ -kamailio (5.7.4) unstable; urgency=medium +kamailio (5.8.1) unstable; urgency=medium - * version set 5.7.4 + * version set 5.8.1 - -- Victor Seva Thu, 18 Jan 2024 10:29:35 +0100 + -- Victor Seva Wed, 03 Apr 2024 08:21:53 +0200 -kamailio (5.7.3) unstable; urgency=medium +kamailio (5.8.0) unstable; urgency=medium - * version set 5.7.3 + * version set 5.8.0 - -- Victor Seva Fri, 17 Nov 2023 09:50:31 +0100 + -- Victor Seva Thu, 07 Mar 2024 11:40:20 +0100 -kamailio (5.7.2) unstable; urgency=medium +kamailio (5.8.0~rc0) unstable; urgency=medium - * version set 5.7.2 + * version set 5.8.0~rc0 - -- Victor Seva Wed, 27 Sep 2023 08:44:32 +0200 + -- Victor Seva Fri, 23 Feb 2024 20:04:35 +0100 -kamailio (5.7.1) unstable; urgency=medium +kamailio (5.8.0~pre0) unstable; urgency=medium - * version set 5.7.1 + * version set 5.8.0~pre0 - -- Victor Seva Wed, 28 Jun 2023 09:35:54 +0200 + -- Victor Seva Fri, 02 Feb 2024 15:20:05 +0100 -kamailio (5.7.0) unstable; urgency=medium +kamailio (5.8.0~dev2) unstable; urgency=medium - * version set 5.7.0 + * version set 5.8.0~dev2 - -- Victor Seva Tue, 16 May 2023 12:57:51 +0200 + -- Victor Seva Tue, 05 Dec 2023 12:04:06 +0100 -kamailio (5.7.0~rc0) unstable; urgency=medium +kamailio (5.8.0~dev1) unstable; urgency=medium - * version set 5.7.0~rc0 + * version set 5.8.0~dev1 - -- Victor Seva Thu, 04 May 2023 21:41:57 +0200 + -- Victor Seva Wed, 28 Jun 2023 15:03:56 +0200 -kamailio (5.7.0~pre0) unstable; urgency=medium +kamailio (5.8.0~dev0) unstable; urgency=medium - * version set 5.7.0~pre0 - - -- Victor Seva Mon, 17 Apr 2023 09:08:01 +0200 - -kamailio (5.7.0~dev4) unstable; urgency=medium - - * version set 5.7.0~dev4 - - -- Victor Seva Mon, 17 Apr 2023 09:07:10 +0200 - -kamailio (5.7.0~dev3) unstable; urgency=medium - - * version set 5.7.0~dev3 - - -- Victor Seva Tue, 10 Jan 2023 14:07:12 +0100 - -kamailio (5.7.0~dev2) unstable; urgency=medium - - * version set 5.7.0~dev2 - - -- Victor Seva Mon, 28 Nov 2022 11:54:03 +0100 - -kamailio (5.7.0~dev1) unstable; urgency=medium - - * version set 5.7.0~dev1 - - -- Victor Seva Sun, 28 Aug 2022 22:36:28 +0200 - -kamailio (5.7.0~dev0) unstable; urgency=medium - - * version set 5.7.0~dev0 - - -- Victor Seva Thu, 05 May 2022 12:47:44 +0200 + * version set 5.8.0~dev0 + -- Victor Seva Thu, 04 May 2023 21:45:08 +0200 diff --git a/pkg/kamailio/deb/xenial/control b/pkg/kamailio/deb/xenial/control index 340f6fcfd..4443167ad 100644 --- a/pkg/kamailio/deb/xenial/control +++ b/pkg/kamailio/deb/xenial/control @@ -34,7 +34,7 @@ Build-Depends: libmosquitto-dev, libmysqlclient-dev, libncurses5-dev, - libpcre3-dev, + libpcre2-dev, libperl-dev, libphonenumber-dev (>= 7), libpq-dev, @@ -572,23 +572,6 @@ Description: LDAP modules for the Kamailio SIP server queries from the Kamailio routing scripts and storage of SIP account data in an LDAP directory. -Package: kamailio-ims-modules -Architecture: any -Multi-Arch: same -Pre-Depends: - ${misc:Pre-Depends}, -Depends: - kamailio (= ${binary:Version}), - ${misc:Depends}, - ${shlibs:Depends}, -Description: IMS module for the Kamailio SIP server - Kamailio is a very fast and flexible SIP (RFC3261) - server. Written entirely in C, Kamailio can handle thousands calls - per second even on low-budget hardware. - . - This package contains various Diameter interfaces and modules for Kamailio - to run as an IMS core. - Package: kamailio-utils-modules Architecture: any Multi-Arch: same diff --git a/pkg/kamailio/deb/xenial/rules b/pkg/kamailio/deb/xenial/rules index b0beca9bc..f441bd6dc 100755 --- a/pkg/kamailio/deb/xenial/rules +++ b/pkg/kamailio/deb/xenial/rules @@ -19,6 +19,7 @@ endif export JAVA_HOME=/usr/lib/jvm/java-gcj export RADCLI=1 +export WOLFSSL_INTERNAL=no # tlsa export KTLS_INCLUDE_TLSA=no export LIBSSL_STATIC_SRCLIB=yes @@ -38,6 +39,9 @@ EXTRA_EXCLUDED_MODULES += iptrtpproxy EXTRA_EXCLUDED_MODULES += secsipid EXTRA_EXCLUDED_MODULES += lwsc EXTRA_EXCLUDED_MODULES += nats +EXTRA_EXCLUDED_MODULES += microhttpd +EXTRA_EXCLUDED_MODULES += ims +EXTRA_EXCLUDED_MODULES += tls_wolfssl ## --EXCLUDED-- @@ -69,7 +73,6 @@ PACKAGE_GROUPS += sqlite PACKAGE_GROUPS += json PACKAGE_GROUPS += mono PACKAGE_GROUPS += ruby -PACKAGE_GROUPS += ims PACKAGE_GROUPS += sctp PACKAGE_GROUPS += java PACKAGE_GROUPS += tls @@ -94,6 +97,10 @@ EXTRA_GROUPS += jansson EXTRA_GROUPS += uuid EXTRA_GROUPS += http_async +.PHONY: skip-modules +skip-modules: + @echo "$(EXCLUDED_MODULES) $(EXTRA_EXCLUDED_MODULES)" + D = $(CURDIR)/debian/$(DEB_SOURCE) # Name of libdir in the path for libraries (e.g., the multiarch triplet). diff --git a/pkg/kamailio/obs/kamailio-9-x86_64.cfg b/pkg/kamailio/obs/kamailio-9-x86_64.cfg index 2c78b5f7e..977769b2f 100644 --- a/pkg/kamailio/obs/kamailio-9-x86_64.cfg +++ b/pkg/kamailio/obs/kamailio-9-x86_64.cfg @@ -13,6 +13,11 @@ config_opts['dnf.conf'] += """ name=Support packages for kamailio baseurl=http://rpm.kamailio.org/centos/$releasever/master/master/$basearch/ gpgkey=file:///etc/pki/mock/kamailio-rpm-pub.key + +[copr-wolfssl] +name=wolfSSL packages +baseurl=https://download.copr.fedorainfracloud.org/results/beaveryoga/wolfSSL/epel-$releasever-$basearch/ +gpgkey=https://download.copr.fedorainfracloud.org/results/beaveryoga/wolfSSL/pubkey.gpg """ # since EL9 the chroots don't include C/C++ development tools diff --git a/pkg/kamailio/obs/kamailio.init b/pkg/kamailio/obs/kamailio.init old mode 100644 new mode 100755 index 166a69ae0..a001cb5bc --- a/pkg/kamailio/obs/kamailio.init +++ b/pkg/kamailio/obs/kamailio.init @@ -48,7 +48,7 @@ check_kamailio_config () retcode=$? if [ "$retcode" != '0' ]; then echo "Not starting $PROG: invalid configuration file!" - echo -e "\n$out\n" + printf "\n$out\n\n" exit 1 fi } diff --git a/pkg/kamailio/obs/kamailio.spec b/pkg/kamailio/obs/kamailio.spec index e3e002dfa..ee339c02d 100644 --- a/pkg/kamailio/obs/kamailio.spec +++ b/pkg/kamailio/obs/kamailio.spec @@ -1,5 +1,5 @@ %define name kamailio -%define ver 5.7.4 +%define ver 5.8.1 %define rel dev1.0%{dist} %if 0%{?fedora} @@ -29,41 +29,7 @@ %bcond_without sctp %bcond_without websocket %bcond_without xmlrpc -%endif - -%if 0%{?rhel} == 6 -%if 0%{?centos_ver} -%define dist_name centos -%define dist_version %{?centos} -%endif -%if 0%{?centos_ver} == 0 -%define dist_name rhel -%define dist_version %{?rhel} -%endif -%bcond_with cnxcc -%bcond_without dnssec -%bcond_without evapi -%bcond_without geoip -%bcond_without http_async_client -%bcond_without ims -%bcond_without jansson -%bcond_without json -%bcond_without lua -%bcond_with lwsc -%bcond_without kazoo -%bcond_without memcached -%bcond_with mongodb -%bcond_with nats -%bcond_without perl -%bcond_with phonenum -%bcond_without python2 -%bcond_with python3 -%bcond_with rabbitmq -%bcond_with redis -%bcond_with ruby -%bcond_without sctp -%bcond_without websocket -%bcond_without xmlrpc +%bcond_without wolfssl %endif %if 0%{?rhel} == 7 @@ -100,6 +66,7 @@ %bcond_without sctp %bcond_without websocket %bcond_without xmlrpc +%bcond_without wolfssl %endif %if 0%{?rhel} == 8 @@ -146,6 +113,7 @@ %bcond_without sctp %bcond_without websocket %bcond_without xmlrpc +%bcond_without wolfssl %endif %if 0%{?rhel} == 9 @@ -192,6 +160,7 @@ %bcond_without sctp %bcond_without websocket %bcond_without xmlrpc +%bcond_without wolfssl %endif %if 0%{?suse_version} @@ -221,11 +190,7 @@ %bcond_without sctp %bcond_without websocket %bcond_without xmlrpc -%endif - -# Defining missing macros on RHEL/CentOS 6 -%if 0%{?rhel} == 6 -%define _rundir %{_localstatedir}/run +%bcond_without wolfssl %endif # build with openssl 1.1.1 on RHEL 7 based dists @@ -400,7 +365,7 @@ Group: %{PKGGROUP} Requires: kamailio = %ver %description cfgt -The unit test config file execution tracing module for Kamailio. +The unit test config file execution tracing module for Kamailio. %if %{with cnxcc} @@ -452,14 +417,14 @@ BuildRequires: libopenssl-devel %endif %description crypto -This module provides various cryptography tools for use in Kamailio configuration file. It relies on OpenSSL libraries for cryptographic operations (libssl, libcrypto). +This module provides various cryptography tools for use in Kamailio configuration file. It relies on OpenSSL libraries for cryptographic operations (libssl, libcrypto). %package dialplan Summary: String translations based on rules for Kamailio Group: %{PKGGROUP} -Requires: pcre, kamailio = %ver -BuildRequires: pcre-devel +Requires: pcre2, kamailio = %ver +BuildRequires: pcre2-devel %description dialplan String translations based on rules for Kamailio. @@ -505,8 +470,8 @@ suspended when sending the event, to be resumed at a later point, maybe triggere %package geoip Summary: MaxMind GeoIP support for Kamailio Group: %{PKGGROUP} -Requires: GeoIP, kamailio = %ver -BuildRequires: GeoIP-devel +Requires: GeoIP, libmaxminddb, kamailio = %ver +BuildRequires: GeoIP-devel, libmaxminddb-devel %description geoip MaxMind GeoIP support for Kamailio. @@ -560,7 +525,7 @@ BuildRequires: libxml2-devel, libcurl-devel, zlib-devel %endif %description http_client -This module implements protocol functions that use the libcurl to communicate with HTTP servers. +This module implements protocol functions that use the libcurl to communicate with HTTP servers. %if %{with ims} @@ -647,8 +612,8 @@ Kazoo module for Kamailio. %package lcr Summary: Least cost routing for Kamailio Group: %{PKGGROUP} -Requires: pcre, kamailio = %ver -BuildRequires: pcre-devel +Requires: pcre2, kamailio = %ver +BuildRequires: pcre2-devel %description lcr Least cost routing for Kamailio. @@ -778,7 +743,7 @@ Protocol (SIP)" support for Kamailio. %if %{with perl} %package perl Summary: Perl extensions and database driver for Kamailio -Group: %{PKGGROUP} +Group: %{PKGGROUP} Requires: kamailio = %ver %if 0%{?suse_version} Requires: perl @@ -903,8 +868,8 @@ Redis configuration file support for Kamailio. %package regex Summary: PCRE mtaching operations for Kamailio Group: %{PKGGROUP} -Requires: pcre, kamailio = %ver -BuildRequires: pcre-devel +Requires: pcre2, kamailio = %ver +BuildRequires: pcre2-devel %description regex PCRE mtaching operations for Kamailio. @@ -996,7 +961,7 @@ BuildRequires: libcurl-devel %endif %description slack -This module provides integration with Slack over webhooks. +This module provides integration with Slack over webhooks. %package smsops @@ -1005,7 +970,7 @@ Group: %{PKGGROUP} Requires: kamailio = %ver %description smsops -This module collects the Transformations for 3GPP-SMS. +This module collects the Transformations for 3GPP-SMS. %package snmpstats @@ -1030,7 +995,7 @@ Group: %{PKGGROUP} Requires: kamailio = %ver %description statsc -This module provides a statistics collector engine. +This module provides a statistics collector engine. %package statsd @@ -1049,7 +1014,7 @@ Requires: kamailio = %version BuildRequires: gcc-c++ %description sqlang -app_sqlang module for Kamailio. +Squirrel Language (SQLang) for Kamailio %package sqlite @@ -1077,6 +1042,17 @@ BuildRequires: openssl-devel TLS transport for Kamailio. +%if %{with wolfssl} +%package tls_wolfssl +Summary: TLS transport for Kamailio based on wolfSSL +Group: %{PKGGROUP} +BuildRequires: pkgconfig(wolfssl) + +%description tls_wolfssl +TLS transport for Kamailio based on wolfSSL +%endif + + %package tcpops Summary: On demand and per socket control to the TCP options Group: %{PKGGROUP} @@ -1238,6 +1214,7 @@ make every-module skip_modules="app_mono db_cassandra db_oracle iptrtpproxy \ %if 0%{?rhel} >= 8 PYTHON3=python3.9 \ %endif + WOLFSSL_INTERNAL=no \ group_include="kstandard kautheph kberkeley kcarrierroute \ %if %{with cnxcc} kcnxcc \ @@ -1251,6 +1228,7 @@ make every-module skip_modules="app_mono db_cassandra db_oracle iptrtpproxy \ %endif %if %{with geoip} kgeoip \ + kgeoip2 \ %endif kgzcompress \ %if %{with http_async_client} @@ -1320,7 +1298,11 @@ make every-module skip_modules="app_mono db_cassandra db_oracle iptrtpproxy \ %if "%{?_unitdir}" != "" ksystemd \ %endif - ktls kunixodbc kutils \ + ktls \ +%if %{with wolfssl} + ktls_wolfssl \ +%endif + kunixodbc kutils \ %if %{with websocket} kwebsocket \ %endif @@ -1345,6 +1327,7 @@ make install-modules-all skip_modules="app_mono db_cassandra db_oracle \ %if 0%{?rhel} >= 8 PYTHON3=python3.9 \ %endif + WOLFSSL_INTERNAL=no \ group_include="kstandard kautheph kberkeley kcarrierroute \ %if %{with cnxcc} kcnxcc \ @@ -1358,6 +1341,7 @@ make install-modules-all skip_modules="app_mono db_cassandra db_oracle \ %endif %if %{with geoip} kgeoip \ + kgeoip2 \ %endif kgzcompress \ %if %{with http_async_client} @@ -1427,7 +1411,11 @@ make install-modules-all skip_modules="app_mono db_cassandra db_oracle \ %if "%{?_unitdir}" != "" ksystemd \ %endif - ktls kunixodbc kutils \ + ktls \ +%if %{with wolfssl} + ktls_wolfssl \ +%endif + kunixodbc kutils \ %if %{with websocket} kwebsocket \ %endif @@ -1562,9 +1550,11 @@ fi %doc %{_docdir}/kamailio/modules/README.drouting %doc %{_docdir}/kamailio/modules/README.enum %doc %{_docdir}/kamailio/modules/README.exec +%doc %{_docdir}/kamailio/modules/README.file_out %doc %{_docdir}/kamailio/modules/README.group %doc %{_docdir}/kamailio/modules/README.htable %doc %{_docdir}/kamailio/modules/README.imc +%doc %{_docdir}/kamailio/modules/README.influxdbc %doc %{_docdir}/kamailio/modules/README.ipops %doc %{_docdir}/kamailio/modules/README.kemix %doc %{_docdir}/kamailio/modules/README.kex @@ -1724,9 +1714,11 @@ fi %{_libdir}/kamailio/modules/drouting.so %{_libdir}/kamailio/modules/enum.so %{_libdir}/kamailio/modules/exec.so +%{_libdir}/kamailio/modules/file_out.so %{_libdir}/kamailio/modules/group.so %{_libdir}/kamailio/modules/htable.so %{_libdir}/kamailio/modules/imc.so +%{_libdir}/kamailio/modules/influxdbc.so %{_libdir}/kamailio/modules/ipops.so %{_libdir}/kamailio/modules/kemix.so %{_libdir}/kamailio/modules/kex.so @@ -1945,7 +1937,9 @@ fi %files geoip %defattr(-,root,root) %doc %{_docdir}/kamailio/modules/README.geoip +%doc %{_docdir}/kamailio/modules/README.geoip2 %{_libdir}/kamailio/modules/geoip.so +%{_libdir}/kamailio/modules/geoip2.so %endif @@ -2342,12 +2336,6 @@ fi %{_libdir}/kamailio/modules/statsd.so -%files sqlang -%defattr(-,root,root) -%doc %{_docdir}/kamailio/modules/README.app_sqlang -%{_libdir}/kamailio/modules/app_sqlang.so - - %files sqlite %defattr(-,root,root) %doc %{_docdir}/kamailio/modules/README.db_sqlite @@ -2360,12 +2348,16 @@ fi %files tls %defattr(-,root,root) -%dir %{_libdir}/kamailio/openssl_mutex_shared -%doc %{_docdir}/kamailio/modules/README.auth_identity %doc %{_docdir}/kamailio/modules/README.tls -%{_libdir}/kamailio/modules/auth_identity.so %{_libdir}/kamailio/modules/tls.so -%{_libdir}/kamailio/openssl_mutex_shared/openssl_mutex_shared.so + + +%if %{with wolfssl} +%files tls_wolfssl +%defattr(-,root,root) +%doc %{_docdir}/kamailio/modules/README.tls_wolfssl +%{_libdir}/kamailio/modules/tls_wolfssl.so +%endif %files tcpops @@ -2461,7 +2453,7 @@ fi - fix http_client package * Fri Nov 04 2016 Marcel Weinberg - Updated to Kamailio version 5.0 and CentOS / RHEL 7.2 - - added new modules available with Kamailio 5.x + - added new modules available with Kamailio 5.x - cfgt - crypto - http_client @@ -2470,10 +2462,10 @@ fi - statsc - topos - removed dialog_ng references and added ims_dialog to replace dialog_ng - - removed java module which requires libgcj + - removed java module which requires libgcj - libgcj is no longer supported by RHEL / CentOS (Version >= 7) - it's recommended to replace libgcj as dependency - - added the ims_registrar_pcscf module + - added the ims_registrar_pcscf module * Tue Dec 3 2013 Peter Dunkley - Updated version to 4.2.0 * Mon Oct 7 2013 Peter Dunkley @@ -2538,4 +2530,3 @@ fi * Mon Jun 18 2012 Peter Dunkley - Consolidating changelog for 3.3.0 into a single entry... - See revision control for details this far back - diff --git a/src/Makefile b/src/Makefile index 6c2b35b41..28106b068 100644 --- a/src/Makefile +++ b/src/Makefile @@ -32,7 +32,7 @@ include Makefile.targets err_fail?=1 # whether or not to install $(MAIN_NAME).cfg or just $(MAIN_NAME).cfg.default -# ($(MAIN_NAME).cfg will never be overwritten by make install, this is usefull +# ($(MAIN_NAME).cfg will never be overwritten by make install, this is useful # when creating packages) skip_cfg_install?= diff --git a/src/Makefile.defs b/src/Makefile.defs index d393653c4..0f960b447 100644 --- a/src/Makefile.defs +++ b/src/Makefile.defs @@ -105,8 +105,8 @@ INSTALL_FLAVOUR=$(FLAVOUR) # version number VERSION = 5 -PATCHLEVEL = 7 -SUBLEVEL = 4 +PATCHLEVEL = 8 +SUBLEVEL = 1 EXTRAVERSION = # memory manager switcher @@ -307,12 +307,8 @@ ifneq (,$(findstring gcc, $(CC_LONGVER))) -e 's/8\.[0-9]$$/8.0+/' \ -e 's/9\.[0-9]\..*/9.0+/' \ -e 's/9\.[0-9]$$/9.0+/' \ - -e 's/10\.[0-9]\..*/9.0+/' \ - -e 's/10\.[0-9]$$/9.0+/' \ - -e 's/11\.[0-9]\..*/9.0+/' \ - -e 's/11\.[0-9]$$/9.0+/' \ - -e 's/12\.[0-9]\..*/9.0+/' \ - -e 's/12\.[0-9]$$/9.0+/') + -e 's/1[0-4]\.[0-9]\..*/9.0+/' \ + -e 's/1[0-4]\.[0-9]$$/9.0+/') ifeq (,$(strip $(filter-out 3.0 3.4 4.x 4.2+ 4.5+ 5.0+ 6.0+ 7.0+ 8.0+ 9.0+,$(CC_SHORTVER)))) # dependencies can be generated on-the-fly while compiling *.c CC_MKDEP_OPTS=-MMD -MP @@ -593,15 +589,11 @@ data_target = $(prefix)/$(data_dir) # uses a faster malloc # -DDBG_QM_MALLOC # qm_malloc debug code, will cause pkg_malloc and shm_malloc -# to keep and display lot of debuging information: file name, +# to keep and display lot of debugging information: file name, # function, line number of malloc/free call for each block, # extra error checking (trying to free the same pointer # twice, trying to free a pointer alloc'ed with a different # malloc etc.) -# -DVQ_MALLOC -# additional option to PKG_MALLOC which utilizes a fater then -# qm version -# (not true anymore, q_malloc performs approx. the same) # -DQ_MALLOC # custom quick malloc, recommended for debugging # -DF_MALLOC @@ -623,7 +615,7 @@ data_target = $(prefix)/$(data_dir) # -DMEM_JOIN_FREE # enable the join of free memory chunks (see also mem_join cfg param) # -DFAST_LOCK -# uses fast arhitecture specific locking (see the arh. specific section) +# uses fast architecture specific locking (see the arch. specific section) # -DUSE_SYSV_SEM # uses sys v sems for locking (slower & limited number) # -DUSE_PTHREAD_MUTEX @@ -735,7 +727,6 @@ C_DEFS+= -DSHM_MMAP \ -DUSE_DNS_FAILOVER \ -DUSE_DST_BLOCKLIST \ -DUSE_NAPTR \ - -DWITH_XAVP \ #-DUSE_DNS_CACHE_STATS \ #-DUSE_DST_BLOCKLIST_STATS \ #-DDNS_WATCHDOG_SUPPORT \ @@ -745,7 +736,6 @@ C_DEFS+= -DSHM_MMAP \ #-DDBG_F_MALLOC \ #-DNO_DEBUG \ #-DEXTRA_DEBUG \ - #-DVQ_MALLOC \ #-DDBG_LOCK \ #-DNOSMP \ #-DNO_LOG \ @@ -1008,9 +998,9 @@ ifeq ($(CC_NAME), icc) CFLAGS+=-O3 -ipo -ipo_obj -unroll $(PROFILE) \ -tpp6 -xK #-openmp #optimize for PIII # -prefetch doesn't seem to work - #( ty to inline acroos files, unroll loops,prefetch, + #( try to inline across files, unroll loops, prefetch, # optimize for PIII, use PIII instructions & vect., - # mutlithread loops) + # multithread loops) else #other compilers $(error Unsupported compiler ($(CC):$(CC_NAME)), try gcc) @@ -1091,9 +1081,9 @@ ifeq ($(CC_NAME), icc) CFLAGS+=-O3 -ipo -ipo_obj -unroll $(PROFILE) \ -tpp6 -xK #-openmp #optimize for PIII # -prefetch doesn't seem to work - #( ty to inline acroos files, unroll loops,prefetch, + #( try to inline across files, unroll loops, prefetch, # optimize for PIII, use PIII instructions & vect., - # mutlithread loops) + # multithread loops) else #other compilers $(error Unsupported compiler ($(CC):$(CC_NAME)), try gcc) @@ -2222,4 +2212,3 @@ export $(saved_chg_vars) endif # ifneq ($(exported_vars),1) endif # ifeq ($(makefile_defs),1) - diff --git a/src/Makefile.groups b/src/Makefile.groups index ee4ec90e8..fec21d47b 100644 --- a/src/Makefile.groups +++ b/src/Makefile.groups @@ -22,8 +22,8 @@ mod_list_basic=async auth benchmark blst cfg_rpc cfgutils corex counters \ mod_list_extra=avp auth_diameter call_control call_obj dmq domainpolicy msrp \ carrierroute pdb qos sca seas sms sst timer tmrec uac_redirect \ xhttp xhttp_rpc xprint jsonrpcs nosip dmq_usrloc statsd rtjson \ - log_custom keepalive ss7ops app_sqlang acc_diameter evrexec \ - sipjson lrkproxy math posops xhttp_prom + log_custom keepalive ss7ops acc_diameter evrexec file_out \ + sipjson lrkproxy math posops xhttp_prom dlgs sworker influxdbc # - common modules depending on database mod_list_db=acc alias_db auth_db avpops cfg_db db_text db_flatstore \ @@ -91,9 +91,6 @@ mod_list_tlsdeps=crypto tls # - modules depending on static openssl library mod_list_tlsa=tlsa -# - modules depending on openssl (+curl) library -mod_list_tlsdeps_curl=auth_identity - # - modules depending on static wolfssl library mod_list_tls_wolfssl=tls_wolfssl @@ -214,7 +211,7 @@ mod_list_erlang=erlang # - modules depending on systemd library mod_list_systemd=log_systemd systemdops -# - modules depending on libnsq (+libev libevbuffsock liblcurl libjson-c) library +# - modules depending on libnsq (+libev libevbuffsock libcurl libjson-c) library mod_list_nsq=nsq # - modules depending on librabbitmq library @@ -235,6 +232,12 @@ mod_list_nats=nats # - modules depending on ruxc library mod_list_ruxc=ruxc +# - modules depending on microhttpd library +mod_list_microhttpd=microhttpd + +# - modules depending on libgcrypt library +mod_list_gcrypt=gcrypt + # - modules depending on secsipid library mod_list_secsipid=secsipid secsipid_proc @@ -252,7 +255,7 @@ mod_list_all=$(sort $(mod_list_basic) $(mod_list_extra) \ $(mod_list_xmpp) \ $(mod_list_berkeley) $(mod_list_utils) \ $(mod_list_memcached) \ - $(mod_list_tlsdeps) $(mod_list_tlsdeps_curl) \ + $(mod_list_tlsdeps) \ $(mod_list_websocket) \ $(mod_list_snmpstats) $(mod_list_presence) \ $(mod_list_lua) $(mod_list_python) \ @@ -284,6 +287,8 @@ mod_list_all=$(sort $(mod_list_basic) $(mod_list_extra) \ $(mod_list_stirshaken) \ $(mod_list_tlsa) \ $(mod_list_tls_wolfssl) \ + $(mod_list_microhttpd) \ + $(mod_list_gcrypt) \ $(mod_list_rtp_media_server) @@ -310,7 +315,7 @@ module_group_standard=$(mod_list_basic) $(mod_list_extra) \ module_group_common=$(mod_list_db) $(mod_list_dbuid) \ $(mod_list_pcre) $(mod_list_radius) \ $(mod_list_xmldeps) $(mod_list_presence) \ - $(mod_list_tlsdeps) $(mod_list_tlsdeps_curl) + $(mod_list_tlsdeps) # For db use (db modules, excluding drivers) module_group_db=$(mod_list_db) @@ -405,10 +410,10 @@ module_group_ktls_basic=$(mod_list_tlsdeps) ifeq ($(KTLS_INCLUDE_TLSA),yes) # pkg tls module with curl -module_group_ktls=$(mod_list_tlsdeps) $(mod_list_tlsdeps_curl) $(mod_list_tlsa) +module_group_ktls=$(mod_list_tlsdeps) $(mod_list_tlsa) else # pkg tls module with curl -module_group_ktls=$(mod_list_tlsdeps) $(mod_list_tlsdeps_curl) +module_group_ktls=$(mod_list_tlsdeps) # pkg tlsa module module_group_ktlsa=$(mod_list_tlsa) @@ -534,6 +539,12 @@ module_group_knats=$(mod_list_nats) # K ruxc modules module_group_kruxc=$(mod_list_ruxc) +# K microhttpd module +module_group_kmicrohttpd=$(mod_list_microhttpd) + +# K gcrypt module +module_group_kgcrypt=$(mod_list_gcrypt) + # K secsipid modules module_group_ksecsipid=$(mod_list_secsipid) diff --git a/src/Makefile.modules b/src/Makefile.modules index 7c3722d03..3521d44a9 100644 --- a/src/Makefile.modules +++ b/src/Makefile.modules @@ -58,7 +58,7 @@ override static_modules_path= # INCLUDES += -I$(COREPATH) # temporary def (visible only in the module, not exported) -DEFS += -DMOD_NAME='"$(MOD_NAME)"' +DEFS += -DMOD_NAME='"$(MOD_NAME)"' -DMOD_NAMEID='$(MOD_NAME)' ifneq ($(makefile_defs_included),1) diff --git a/src/Makefile.targets b/src/Makefile.targets index 9f9bf667c..054aa9b91 100644 --- a/src/Makefile.targets +++ b/src/Makefile.targets @@ -16,7 +16,7 @@ clean_targets:= clean proper distclean-old realclean maintainer-clean local-clea clean-modules proper-modules realclean-modules \ distclean-modules maintainer-clean-modules \ clean-utils proper-utils realclean-utils distclean-utils \ - maintaner-clean-utils \ + maintainer-clean-utils \ clean-libs proper-libs realclean-libs distclean-libs \ maintainer-clean-libs \ clean-tmp clean_doxygen clean-extra-names \ @@ -26,7 +26,7 @@ doc_targets:= README man install-doc install-man install-ser-man \ $(foreach m,$(modules_dirs),$(m)-doc $(m)-readme $(m)-man) \ $(foreach m,$(modules_dirs),install-$(m)-doc install-$(m)-man) -# auxiliary: maintance, debugging, etc. (don't affect code/objects) +# auxiliary: maintenance, debugging, etc. (don't affect code/objects) aux_targets:= TAGS tar dist cfg-defs cfg config config.mak print-modules \ dbg dbinstall librpath.lst makecfg.lst modules.lst modules-cfg \ modules-list modules-lst mk-install_dirs autover.h deb @@ -36,6 +36,6 @@ ext_targets:= every-module modules-all $(modules_dirs) libs utils \ $(foreach m,$(modules_dirs),install-$(m)) \ install-share -# all the targets that don't require code dependecies in the current dir. +# all the targets that don't require code dependencies in the current dir. nodep_targets:= $(clean_targets) $(doc_targets) $(aux_targets) $(ext_targets) diff --git a/src/core/action.c b/src/core/action.c index 4a29a73b0..bd75eacec 100644 --- a/src/core/action.c +++ b/src/core/action.c @@ -1413,7 +1413,7 @@ int do_action(struct run_act_ctx *h, struct action *a, struct sip_msg *msg) ret = 1; /* continue processing */ break; case UDP_MTU_TRY_PROTO_T: - msg->msg_flags |= (unsigned int)a->val[0].u.number & FL_MTU_FB_MASK; + msg->msg_flags |= (msg_flags_t)a->val[0].u.number & FL_MTU_FB_MASK; ret = 1; /* continue processing */ break; case SET_ADV_ADDR_T: diff --git a/src/core/async_task.c b/src/core/async_task.c index 927cdd2c6..376924ae5 100644 --- a/src/core/async_task.c +++ b/src/core/async_task.c @@ -143,7 +143,7 @@ int async_task_init(void) int nrg = 0; async_wgroup_t *awg; - LM_DBG("start initializing asynk task framework\n"); + LM_DBG("start initializing async task framework\n"); if(_async_wgroup_list == NULL || _async_wgroup_list->workers <= 0) return 0; @@ -184,7 +184,7 @@ int async_task_child_init(int rank) if(_async_wgroup_list == NULL || _async_wgroup_list->workers <= 0) return 0; - LM_DBG("child initializing asynk task framework\n"); + LM_DBG("child initializing async task framework\n"); if(rank == PROC_INIT) { if(async_task_init_sockets() < 0) { @@ -406,7 +406,7 @@ int async_task_push(async_task_t *task) len = write(_async_wgroup_list->sockets[1], &task, sizeof(async_task_t *)); if(len <= 0) { - LM_ERR("failed to pass the task to asynk workers\n"); + LM_ERR("failed to pass the task to async workers\n"); return -1; } LM_DBG("task sent [%p]\n", task); diff --git a/src/core/atomic/atomic_x86.h b/src/core/atomic/atomic_x86.h index fd9d12775..03a6c2bb9 100644 --- a/src/core/atomic/atomic_x86.h +++ b/src/core/atomic/atomic_x86.h @@ -315,9 +315,9 @@ inline static void mb_atomic_set_int(volatile int *v, int i) : "m"(*v), "0"(i) : "memory" #else - : "+q"(i), "=m"(*v) - : "m"(*v) - : "memory" + : "+q"(i), "=m"(*v) + : "m"(*v) + : "memory" #endif ); } diff --git a/src/core/autover.h b/src/core/autover.h index 797537aee..781aea380 100644 --- a/src/core/autover.h +++ b/src/core/autover.h @@ -2,6 +2,6 @@ * DO NOT EDIT IT */ -#define REPO_VER "dc393e" -#define REPO_HASH "dc393e" +#define REPO_VER "384843" +#define REPO_HASH "384843" #define REPO_STATE "" diff --git a/src/core/cfg.lex b/src/core/cfg.lex index 82278d544..aa998d379 100644 --- a/src/core/cfg.lex +++ b/src/core/cfg.lex @@ -304,6 +304,7 @@ LOGENGINETYPE log_engine_type LOGENGINEDATA log_engine_data XAVPVIAPARAMS xavp_via_params XAVPVIAFIELDS xavp_via_fields +XAVPVIAREPLYPARAMS xavp_via_reply_params LISTEN listen ADVERTISE advertise|ADVERTISE VIRTUAL virtual @@ -362,6 +363,7 @@ PORT port STAT statistics STATS_NAMESEP stats_name_separator MAXBUFFER maxbuffer +MAXSNDBUFFER maxsndbuffer SQL_BUFFER_SIZE sql_buffer_size MSG_RECV_MAX_SIZE msg_recv_max_size TCP_MSG_READ_TIMEOUT tcp_msg_read_timeout @@ -383,6 +385,7 @@ MEMLOG "memlog"|"mem_log" MEMDBG "memdbg"|"mem_dbg" MEMSUM "mem_summary" MEMSAFETY "mem_safety" +MEMADDSIZE "mem_add_size" MEMJOIN "mem_join" MEMSTATUSMODE "mem_status_mode" CORELOG "corelog"|"core_log" @@ -439,6 +442,7 @@ TCP_WAIT_DATA "tcp_wait_data" TCP_SCRIPT_MODE "tcp_script_mode" DISABLE_TLS "disable_tls"|"tls_disable" ENABLE_TLS "enable_tls"|"tls_enable" +TLS_THREADS_MODE "tls_threads_mode" TLSLOG "tlslog"|"tls_log" TLS_PORT_NO "tls_port_no" TLS_METHOD "tls_method" @@ -489,6 +493,7 @@ WAIT_WORKER1_TIME "wait_worker1_time" WAIT_WORKER1_USLEEP "wait_worker1_usleep" KEMI "kemi" +REQUEST_ROUTE_CALLBACK "request_route_callback" ONSEND_ROUTE_CALLBACK "onsend_route_callback" REPLY_ROUTE_CALLBACK "reply_route_callback" EVENT_ROUTE_CALLBACK "event_route_callback" @@ -758,6 +763,7 @@ IMPORTFILE "import_file" {LOGENGINEDATA} { yylval.strval=yytext; return LOGENGINEDATA; } {XAVPVIAPARAMS} { yylval.strval=yytext; return XAVPVIAPARAMS; } {XAVPVIAFIELDS} { yylval.strval=yytext; return XAVPVIAFIELDS; } +{XAVPVIAREPLYPARAMS} { yylval.strval=yytext; return XAVPVIAREPLYPARAMS; } {LISTEN} { count(); yylval.strval=yytext; return LISTEN; } {ADVERTISE} { count(); yylval.strval=yytext; return ADVERTISE; } {VIRTUAL} { count(); yylval.strval=yytext; return VIRTUAL; } @@ -849,6 +855,7 @@ IMPORTFILE "import_file" {STAT} { count(); yylval.strval=yytext; return STAT; } {STATS_NAMESEP} { count(); yylval.strval=yytext; return STATS_NAMESEP; } {MAXBUFFER} { count(); yylval.strval=yytext; return MAXBUFFER; } +{MAXSNDBUFFER} { count(); yylval.strval=yytext; return MAXSNDBUFFER; } {SQL_BUFFER_SIZE} { count(); yylval.strval=yytext; return SQL_BUFFER_SIZE; } {MSG_RECV_MAX_SIZE} { count(); yylval.strval=yytext; return MSG_RECV_MAX_SIZE; } {TCP_MSG_READ_TIMEOUT} { count(); yylval.strval=yytext; return TCP_MSG_READ_TIMEOUT; } @@ -869,6 +876,7 @@ IMPORTFILE "import_file" {MEMDBG} { count(); yylval.strval=yytext; return MEMDBG; } {MEMSUM} { count(); yylval.strval=yytext; return MEMSUM; } {MEMSAFETY} { count(); yylval.strval=yytext; return MEMSAFETY; } +{MEMADDSIZE} { count(); yylval.strval=yytext; return MEMADDSIZE; } {MEMJOIN} { count(); yylval.strval=yytext; return MEMJOIN; } {MEMSTATUSMODE} { count(); yylval.strval=yytext; return MEMSTATUSMODE; } {SIP_PARSER_LOG_ONELINE} { count(); yylval.strval=yytext; return SIP_PARSER_LOG_ONELINE; } @@ -953,6 +961,7 @@ IMPORTFILE "import_file" {TCP_SCRIPT_MODE} { count(); yylval.strval=yytext; return TCP_SCRIPT_MODE; } {DISABLE_TLS} { count(); yylval.strval=yytext; return DISABLE_TLS; } {ENABLE_TLS} { count(); yylval.strval=yytext; return ENABLE_TLS; } +{TLS_THREADS_MODE} { count(); yylval.strval=yytext; return TLS_THREADS_MODE; } {TLSLOG} { count(); yylval.strval=yytext; return TLS_PORT_NO; } {TLS_PORT_NO} { count(); yylval.strval=yytext; return TLS_PORT_NO; } {TLS_METHOD} { count(); yylval.strval=yytext; return TLS_METHOD; } @@ -1038,6 +1047,7 @@ IMPORTFILE "import_file" {WAIT_WORKER1_USLEEP} { count(); yylval.strval=yytext; return WAIT_WORKER1_USLEEP; } {SERVER_ID} { count(); yylval.strval=yytext; return SERVER_ID;} {KEMI} { count(); yylval.strval=yytext; return KEMI;} +{REQUEST_ROUTE_CALLBACK} { count(); yylval.strval=yytext; return REQUEST_ROUTE_CALLBACK;} {REPLY_ROUTE_CALLBACK} { count(); yylval.strval=yytext; return REPLY_ROUTE_CALLBACK;} {ONSEND_ROUTE_CALLBACK} { count(); yylval.strval=yytext; return ONSEND_ROUTE_CALLBACK;} {EVENT_ROUTE_CALLBACK} { count(); yylval.strval=yytext; return EVENT_ROUTE_CALLBACK;} diff --git a/src/core/cfg.y b/src/core/cfg.y index 1f2ad7fb3..799c95697 100644 --- a/src/core/cfg.y +++ b/src/core/cfg.y @@ -328,6 +328,7 @@ extern char *default_routename; %token LOGENGINEDATA %token XAVPVIAPARAMS %token XAVPVIAFIELDS +%token XAVPVIAREPLYPARAMS %token LISTEN %token ADVERTISE %token VIRTUAL @@ -400,6 +401,7 @@ extern char *default_routename; %token MEMDBG %token MEMSUM %token MEMSAFETY +%token MEMADDSIZE %token MEMJOIN %token MEMSTATUSMODE %token SIP_PARSER_LOG_ONELINE @@ -418,6 +420,7 @@ extern char *default_routename; %token MODPARAMX %token CFGENGINE %token MAXBUFFER +%token MAXSNDBUFFER %token SQL_BUFFER_SIZE %token MSG_RECV_MAX_SIZE %token TCP_MSG_READ_TIMEOUT @@ -469,6 +472,7 @@ extern char *default_routename; %token TCP_SCRIPT_MODE %token DISABLE_TLS %token ENABLE_TLS +%token TLS_THREADS_MODE %token TLSLOG %token TLS_PORT_NO %token TLS_METHOD @@ -521,6 +525,7 @@ extern char *default_routename; %token CFG_DESCRIPTION %token SERVER_ID %token KEMI +%token REQUEST_ROUTE_CALLBACK %token ONSEND_ROUTE_CALLBACK %token REPLY_ROUTE_CALLBACK %token EVENT_ROUTE_CALLBACK @@ -626,7 +631,7 @@ extern char *default_routename; %type id_lst %type phostport %type listen_phostport -%type proto eqproto port +%type proto eqproto xproto port %type equalop strop cmpop rve_cmpop rve_equalop %type uri_type %type attr_id @@ -750,6 +755,15 @@ eqproto: | WSS { $$=PROTO_WSS; } | STAR { $$=0; } ; +xproto: + UDP { $$=PROTO_UDP; } + | TCP { $$=PROTO_TCP; } + | TLS { $$=PROTO_TLS; } + | SCTP { $$=PROTO_SCTP; } + | WS { $$=PROTO_WS; } + | WSS { $$=PROTO_WSS; } + ; + port: NUMBER { $$=$1; } | STAR { $$=0; } @@ -845,6 +859,12 @@ socket_lattr: tmp_sa.useaddr.len = strlen(tmp_sa.useaddr.s); tmp_sa.useport = $5; } + | ADVERTISE EQUAL proto COLON listen_id COLON NUMBER { + tmp_sa.useproto = $3; + tmp_sa.useaddr.s = $5; + tmp_sa.useaddr.len = strlen(tmp_sa.useaddr.s); + tmp_sa.useport = $7; + } | WORKERS EQUAL NUMBER { tmp_sa.workers=$3; } | WORKERS EQUAL error { yyerror("number expected"); } | VIRTUAL EQUAL NUMBER { if($3!=0) { tmp_sa.sflags |= SI_IS_VIRTUAL; } } @@ -895,6 +915,10 @@ assign_stm: _ksr_xavp_via_fields.len=strlen($3); } | XAVPVIAFIELDS EQUAL error { yyerror("string value expected"); } + | XAVPVIAREPLYPARAMS EQUAL STRING { _ksr_xavp_via_reply_params.s=$3; + _ksr_xavp_via_reply_params.len=strlen($3); + } + | XAVPVIAREPLYPARAMS EQUAL error { yyerror("string value expected"); } | DNS EQUAL NUMBER { received_dns|= ($3)?DO_DNS:0; } | DNS EQUAL error { yyerror("boolean value expected"); } | REV_DNS EQUAL NUMBER { received_dns|= ($3)?DO_REV_DNS:0; } @@ -1001,7 +1025,9 @@ assign_stm: | PORT EQUAL error { yyerror("number expected"); } | MAXBUFFER EQUAL NUMBER { maxbuffer=$3; } | MAXBUFFER EQUAL error { yyerror("number expected"); } - | SQL_BUFFER_SIZE EQUAL NUMBER { sql_buffer_size=$3; } + | MAXSNDBUFFER EQUAL NUMBER { maxsndbuffer=$3; } + | MAXSNDBUFFER EQUAL error { yyerror("number expected"); } + | SQL_BUFFER_SIZE EQUAL NUMBER { sql_buffer_size=$3; } | SQL_BUFFER_SIZE EQUAL error { yyerror("number expected"); } | MSG_RECV_MAX_SIZE EQUAL NUMBER { ksr_msg_recv_max_size=$3; } | MSG_RECV_MAX_SIZE EQUAL error { yyerror("number expected"); } @@ -1048,6 +1074,8 @@ assign_stm: | MEMSUM EQUAL error { yyerror("int value expected"); } | MEMSAFETY EQUAL intno { default_core_cfg.mem_safety=$3; } | MEMSAFETY EQUAL error { yyerror("int value expected"); } + | MEMADDSIZE EQUAL intno { ksr_mem_add_size=$3; } + | MEMADDSIZE EQUAL error { yyerror("int value expected"); } | MEMJOIN EQUAL intno { default_core_cfg.mem_join=$3; } | MEMJOIN EQUAL error { yyerror("int value expected"); } | MEMSTATUSMODE EQUAL intno { default_core_cfg.mem_status_mode=$3; } @@ -1440,6 +1468,14 @@ assign_stm: #endif } | ENABLE_TLS EQUAL error { yyerror("boolean value expected"); } + | TLS_THREADS_MODE EQUAL NUMBER { + #ifdef USE_TLS + ksr_tls_threads_mode = $3; + #else + warn("tls support not compiled in"); + #endif + } + | TLS_THREADS_MODE EQUAL error { yyerror("int value expected"); } | TLSLOG EQUAL NUMBER { #ifdef CORE_TLS tls_log=$3; @@ -1642,7 +1678,20 @@ assign_stm: if (add_listen_advertise_iface( lst_tmp->addr_lst->name, lst_tmp->addr_lst->next, lst_tmp->port, lst_tmp->proto, - $5, $7, + PROTO_NONE, $5, $7, + lst_tmp->flags)!=0) { + LM_CRIT("cfg. parser: failed to add listen address\n"); + break; + } + } + free_socket_id_lst($3); + } + | LISTEN EQUAL id_lst ADVERTISE xproto COLON listen_id COLON NUMBER { + for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) { + if (add_listen_advertise_iface( lst_tmp->addr_lst->name, + lst_tmp->addr_lst->next, + lst_tmp->port, lst_tmp->proto, + $5, $7, $9, lst_tmp->flags)!=0) { LM_CRIT("cfg. parser: failed to add listen address\n"); break; @@ -1656,7 +1705,7 @@ assign_stm: if (add_listen_advertise_iface( lst_tmp->addr_lst->name, lst_tmp->addr_lst->next, lst_tmp->port, lst_tmp->proto, - $5, $7, + PROTO_NONE, $5, $7, lst_tmp->flags)!=0) { LM_CRIT("cfg. parser: failed to add listen address\n"); break; @@ -1669,7 +1718,20 @@ assign_stm: if (add_listen_advertise_iface_name(lst_tmp->addr_lst->name, lst_tmp->addr_lst->next, lst_tmp->port, lst_tmp->proto, - $5, $7, $9, + PROTO_NONE, $5, $7, $9, + lst_tmp->flags)!=0) { + LM_CRIT("cfg. parser: failed to add listen address\n"); + break; + } + } + free_socket_id_lst($3); + } + | LISTEN EQUAL id_lst ADVERTISE xproto COLON listen_id COLON NUMBER STRNAME STRING { + for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) { + if (add_listen_advertise_iface_name(lst_tmp->addr_lst->name, + lst_tmp->addr_lst->next, + lst_tmp->port, lst_tmp->proto, + $5, $7, $9, $11, lst_tmp->flags)!=0) { LM_CRIT("cfg. parser: failed to add listen address\n"); break; @@ -1683,7 +1745,21 @@ assign_stm: if (add_listen_advertise_iface_name(lst_tmp->addr_lst->name, lst_tmp->addr_lst->next, lst_tmp->port, lst_tmp->proto, - $5, $7, $9, + PROTO_NONE, $5, $7, $9, + lst_tmp->flags)!=0) { + LM_CRIT("cfg. parser: failed to add listen address\n"); + break; + } + } + free_socket_id_lst($3); + } + | LISTEN EQUAL id_lst ADVERTISE xproto COLON listen_id COLON NUMBER STRNAME STRING VIRTUAL { + for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) { + lst_tmp->flags |= SI_IS_VIRTUAL; + if (add_listen_advertise_iface_name(lst_tmp->addr_lst->name, + lst_tmp->addr_lst->next, + lst_tmp->port, lst_tmp->proto, + $5, $7, $9, $11, lst_tmp->flags)!=0) { LM_CRIT("cfg. parser: failed to add listen address\n"); break; @@ -1696,7 +1772,7 @@ assign_stm: if (add_listen_advertise_iface( lst_tmp->addr_lst->name, lst_tmp->addr_lst->next, lst_tmp->port, lst_tmp->proto, - $5, 0, + PROTO_NONE, $5, 0, lst_tmp->flags)!=0) { LM_CRIT("cfg. parser: failed to add listen address\n"); break; @@ -1710,7 +1786,7 @@ assign_stm: if (add_listen_advertise_iface( lst_tmp->addr_lst->name, lst_tmp->addr_lst->next, lst_tmp->port, lst_tmp->proto, - $5, 0, + PROTO_NONE, $5, 0, lst_tmp->flags)!=0) { LM_CRIT("cfg. parser: failed to add listen address\n"); break; @@ -1723,7 +1799,7 @@ assign_stm: if (add_listen_advertise_iface_name(lst_tmp->addr_lst->name, lst_tmp->addr_lst->next, lst_tmp->port, lst_tmp->proto, - $5, 0, $7, + PROTO_NONE, $5, 0, $7, lst_tmp->flags)!=0) { LM_CRIT("cfg. parser: failed to add listen address\n"); break; @@ -1737,7 +1813,7 @@ assign_stm: if (add_listen_advertise_iface_name(lst_tmp->addr_lst->name, lst_tmp->addr_lst->next, lst_tmp->port, lst_tmp->proto, - $5, 0, $7, + PROTO_NONE, $5, 0, $7, lst_tmp->flags)!=0) { LM_CRIT("cfg. parser: failed to add listen address\n"); break; @@ -1798,11 +1874,18 @@ assign_stm: | OPEN_FD_LIMIT EQUAL NUMBER { open_files_limit=$3; } | OPEN_FD_LIMIT EQUAL error { yyerror("number expected"); } | SHM_MEM_SZ EQUAL NUMBER { - if (shm_initialized()) + if (shm_initialized()) { yyerror("shm/shm_mem_size must be before any modparam or the" " route blocks"); - else if (shm_mem_size == 0 || shm_mem_size == SHM_MEM_POOL_SIZE) + } else if (shm_mem_size == 0 || shm_mem_size == SHM_MEM_POOL_SIZE) { + /* safety check for upper limit of 16TB */ + if($3 <= 0 || $3 > 16L * 1024 * 1024) { + LM_ERR("out of limits shmem size number: %ld\n", (long int)$3); + yyerror("invalid config option"); + YYABORT; + } shm_mem_size=$3 * 1024 * 1024; + } } | SHM_MEM_SZ EQUAL error { yyerror("number expected"); } | SHM_FORCE_ALLOC EQUAL NUMBER { @@ -1919,6 +2002,14 @@ assign_stm: | SERVER_ID EQUAL error { yyerror("number expected"); } | RETURN_MODE EQUAL NUMBER { ksr_return_mode=$3; } | RETURN_MODE EQUAL error { yyerror("number expected"); } + | KEMI DOT REQUEST_ROUTE_CALLBACK EQUAL STRING { + kemi_request_route_callback.s = $5; + kemi_request_route_callback.len = strlen($5); + if(kemi_request_route_callback.len==0) { + yyerror("empty name for request route callback function"); + } + } + | KEMI DOT REQUEST_ROUTE_CALLBACK EQUAL error { yyerror("string expected"); } | KEMI DOT ONSEND_ROUTE_CALLBACK EQUAL STRING { kemi_onsend_route_callback.s = $5; kemi_onsend_route_callback.len = strlen($5); @@ -2689,11 +2780,13 @@ host_if_id: ID | NUM_ID | NUMBER { /* get string version */ - $$=pkg_malloc(strlen(yy_number_str)+1); + i_tmp = strlen(yy_number_str); + $$=pkg_malloc(i_tmp + 1); if ($$==0) { PKG_MEM_ERROR; } else { - strcpy($$, yy_number_str); + memcpy($$, yy_number_str, i_tmp); + $$[i_tmp] = '\0'; } } ; diff --git a/src/core/cfg_core.c b/src/core/cfg_core.c index 52629bd90..982cd6c92 100644 --- a/src/core/cfg_core.c +++ b/src/core/cfg_core.c @@ -55,6 +55,7 @@ #include "sock_ut.h" #include "cfg/cfg.h" #include "cfg_core.h" +#include "pvapi.h" struct cfg_group_core default_core_cfg = { L_WARN, /*!< print only msg. < L_WARN */ @@ -121,6 +122,7 @@ struct cfg_group_core default_core_cfg = { 0, /*!< latency limit db */ 0, /*!< latency limit action */ 0, /*!< latency limit cfg */ + 0, /*!< pv_cache_dump */ 2048, /*!< pv_cache_limit */ 0 /*!< pv_cache_action */ }; @@ -336,6 +338,8 @@ cfg_def_t core_cfg_def[] = { "limit in ms for alerting on time consuming config actions"}, {"latency_limit_cfg", CFG_VAR_INT | CFG_ATOMIC, 0, 0, 0, 0, "limit in ms for alerting on time consuming config execution"}, + {"pv_cache_dump", CFG_VAR_INT, 0, 0, 0, pv_cache_dump_cb, + "dump process pv cache, parameter: pid_number"}, {"pv_cache_limit", CFG_VAR_INT | CFG_ATOMIC, 0, 0, 0, 0, "limit to alert if too many vars in pv cache"}, {"pv_cache_action", CFG_VAR_INT | CFG_ATOMIC, 0, 0, 0, 0, diff --git a/src/core/cfg_core.h b/src/core/cfg_core.h index e0f5c3570..18dc3b059 100644 --- a/src/core/cfg_core.h +++ b/src/core/cfg_core.h @@ -112,6 +112,7 @@ struct cfg_group_core int latency_limit_db; /*!< alert limit of running db commands */ int latency_limit_action; /*!< alert limit of running cfg actions */ int latency_limit_cfg; /*!< alert limit of running cfg routing script */ + int pv_cache_dump; /*!< dump process pv cache, parameter: pid_number */ int pv_cache_limit; /*!< alert limit of having too many vars in pv cache */ int pv_cache_action; /*!< action to be taken on pv cache limit */ }; diff --git a/src/core/core_cmd.c b/src/core/core_cmd.c index 73b74c6b5..f3bb16f2c 100644 --- a/src/core/core_cmd.c +++ b/src/core/core_cmd.c @@ -137,24 +137,20 @@ static const char *dns_cache_stats_get_doc[] = { #ifdef DNS_WATCHDOG_SUPPORT void dns_set_server_state_rpc(rpc_t *rpc, void *ctx); -static const char - *dns_set_server_state_doc[] = - { - "sets the state of the DNS servers " - "(0: all the servers are down, 1: at least one server " - "is up)", /* Documentation string */ - 0 /* Method signature(s) */ +static const char *dns_set_server_state_doc[] = { + "sets the state of the DNS servers " + "(0: all the servers are down, 1: at least one server " + "is up)", /* Documentation string */ + 0 /* Method signature(s) */ }; void dns_get_server_state_rpc(rpc_t *rpc, void *ctx); -static const char - *dns_get_server_state_doc[] = - { - "prints the state of the DNS servers " - "(0: all the servers are down, 1: at least one server " - "is up)", /* Documentation string */ - 0 /* Method signature(s) */ +static const char *dns_get_server_state_doc[] = { + "prints the state of the DNS servers " + "(0: all the servers are down, 1: at least one server " + "is up)", /* Documentation string */ + 0 /* Method signature(s) */ }; #endif /* DNS_WATCHDOG_SUPPORT */ @@ -174,14 +170,10 @@ static const char *dst_blst_debug_doc[] = { "dst blocklist debug info.", /* Documentation string */ 0 /* Method signature(s) */ }; -static const char - * - dst_blst_view_doc - [] = - { - "dst blocklist dump in human-readable " - "format.", /* Documentation string */ - 0 /* Method signature(s) */ +static const char *dst_blst_view_doc[] = { + "dst blocklist dump in human-readable " + "format.", /* Documentation string */ + 0 /* Method signature(s) */ }; static const char *dst_blst_delete_all_doc[] = { "Deletes all the entries from the dst blocklist except the permanent " @@ -208,13 +200,10 @@ static const char *dst_blst_stats_get_doc[] = { static char up_since_ctime[MAX_CTIME_LEN]; -static const char - * - system_listMethods_doc[] = - { - "Lists all RPC methods supported by the " - "server.", /* Documentation string */ - 0 /* Method signature(s) */ +static const char *system_listMethods_doc[] = { + "Lists all RPC methods supported by the " + "server.", /* Documentation string */ + 0 /* Method signature(s) */ }; static void system_listMethods(rpc_t *rpc, void *c) @@ -309,12 +298,10 @@ static void core_echo(rpc_t *rpc, void *c) } -static const char - *core_echo_delta_doc[] = - { - "Returns back its parameters with execution delta " - "limit.", /* Documentation string */ - 0 /* Method signature(s) */ +static const char *core_echo_delta_doc[] = { + "Returns back its parameters with execution delta " + "limit.", /* Documentation string */ + 0 /* Method signature(s) */ }; @@ -368,13 +355,10 @@ static void core_info(rpc_t *rpc, void *c) } -static const char - * - core_runinfo_doc[] = - { - "Runtime info - binary name, version, uptime, " - "...", /* Documentation string */ - 0 /* Method signature(s) */ +static const char *core_runinfo_doc[] = { + "Runtime info - binary name, version, uptime, " + "...", /* Documentation string */ + 0 /* Method signature(s) */ }; static void core_runinfo(rpc_t *rpc, void *c) @@ -444,14 +428,10 @@ static void core_uptime(rpc_t *rpc, void *c) } -static const char - * - core_ps_doc - [] = - { - "Returns the description of running " - "processes.", /* Documentation string */ - 0 /* Method signature(s) */ +static const char *core_ps_doc[] = { + "Returns the description of running " + "processes.", /* Documentation string */ + 0 /* Method signature(s) */ }; @@ -531,12 +511,10 @@ static void core_pwd(rpc_t *rpc, void *c) } -static const char - *core_arg_doc[] = - { - "Returns the list of command line arguments used on " - "startup.", /* Documentation string */ - 0 /* Method signature(s) */ +static const char *core_arg_doc[] = { + "Returns the list of command line arguments used on " + "startup.", /* Documentation string */ + 0 /* Method signature(s) */ }; @@ -1029,14 +1007,10 @@ static void core_ppdefines(rpc_t *rpc, void *c) /** * */ -static const char - * - core_ppdefines_full_doc - [] = - { - "List preprocessor defines with full " - "details", /* Documentation string */ - 0 /* Method signature(s) */ +static const char *core_ppdefines_full_doc[] = { + "List preprocessor defines with full " + "details", /* Documentation string */ + 0 /* Method signature(s) */ }; /** diff --git a/src/core/dns_cache.c b/src/core/dns_cache.c index d06d1b566..1fba5a036 100644 --- a/src/core/dns_cache.c +++ b/src/core/dns_cache.c @@ -30,9 +30,7 @@ #ifdef USE_DNS_CACHE -#ifdef DNS_SRV_LB -#include /* FIXME: rand() */ -#endif +#include #include #include "globals.h" @@ -1698,6 +1696,9 @@ inline static struct dns_hash_entry *dns_get_related( l = e; LM_DBG("(%p (%.*s, %d), %d, *%p) (%d)\n", e, e->name_len, e->name, e->type, type, *records, cname_chain_len); + if(l->prev != NULL || l->next != NULL) { + LM_WARN("record not alone: %p - type: %d\n", l, (int)l->type); + } clist_init(l, next, prev); if(type == e->type) { ret = e; @@ -2042,6 +2043,9 @@ inline static struct dns_hash_entry *dns_cache_do_request(str *name, int type) } #endif end: + if(e != NULL && e->prev == NULL && e->next == NULL) { + LM_WARN("record not linked: %p - type: %d\n", e, (int)e->type); + } return e; } diff --git a/src/core/dprint.h b/src/core/dprint.h index 993a6ebb8..13957b269 100644 --- a/src/core/dprint.h +++ b/src/core/dprint.h @@ -109,6 +109,22 @@ #define LOG2SYSLOG_LEVEL(level) \ (log_level_info[(level) - (L_ALERT)].syslog_level) +/** + * + */ +typedef struct ksr_loglevels { + int ll_alert; + int ll_bug; + int ll_crit; + int ll_err; + int ll_warn; + int ll_notice; + int ll_info; + int ll_dbg; +} ksr_loglevels_t; + +#define KSR_LOGLEVELS_DEFAULTS {L_ALERT, L_BUG, L_CRIT2, L_ERR, L_WARN, \ + L_NOTICE, L_INFO, L_DBG} /** * data fileds used for structured logging */ @@ -406,6 +422,21 @@ void log_prefix_init(void); /* obsolete, do not use */ #define DEBUG(...) DBG(__VA_ARGS__) +/* use local log level mapping (not implemented for sun) */ +#define LLM_ALERT(...) LOG(L_ALERT, __VA_ARGS__) +#define LLM_BUG(...) LOG(L_BUG, __VA_ARGS__) +#define LLM_ERR(...) LOG(L_ERR, __VA_ARGS__) +#define LLM_WARN(...) LOG(L_WARN, __VA_ARGS__) +#define LLM_NOTICE(...) LOG(L_NOTICE, __VA_ARGS__) +#define LLM_INFO(...) LOG(L_INFO, __VA_ARGS__) +#define LLM_CRIT(...) LOG(L_CRIT2, __VA_ARGS__) + +#ifdef NO_DEBUG +#define LLM_DBG(...) +#else +#define LLM_DBG(...) LOG(L_DBG, __VA_ARGS__) +#endif + #else /* ! __SUNPRO_C */ #define NPRL(fmt, args...) LOG(L_NPRL, fmt, ##args) #define ALERT(fmt, args...) LOG(L_ALERT, fmt, ##args) @@ -425,6 +456,29 @@ void log_prefix_init(void); /* obsolete, do not use */ #define DEBUG(fmt, args...) DBG(fmt, ##args) +#ifdef MOD_NAMEID + +#define KSR_LLMODVAR_COMBINEZ(X,Y) X##Y +#define KSR_LLMODVAR_COMBINE(X,Y) KSR_LLMODVAR_COMBINEZ(X,Y) +#define KSR_LLMODVAR KSR_LLMODVAR_COMBINE(_ksr_loglevels_,MOD_NAMEID) + +/* use local log level mapping */ +#define LLM_ALERT(fmt, args...) LOG(KSR_LLMODVAR.alert, fmt, ##args) +#define LLM_BUG(fmt, args...) LOG(KSR_LLMODVAR.buf, fmt, ##args) +#define LLM_ERR(fmt, args...) LOG(KSR_LLMODVAR.bug, fmt, ##args) +#define LLM_WARN(fmt, args...) LOG(KSR_LLMODVAR.warn, fmt, ##args) +#define LLM_NOTICE(fmt, args...) LOG(KSR_LLMODVAR.notice, fmt, ##args) +#define LLM_INFO(fmt, args...) LOG(KSR_LLMODVAR.ll_info, fmt, ##args) +#define LLM_CRIT(fmt, args...) LOG(KSR_LLMODVAR.crit, fmt, ##args) + +#ifdef NO_DEBUG +#define LLM_DBG(fmt, args...) +#else +#define LLM_DBG(fmt, args...) LOG(KSR_LLMODVAR.ll_dbg, fmt, ##args) +#endif + +#endif /* MOD_NAMEID */ + #endif /* __SUNPRO_C */ diff --git a/src/core/fastlock.h b/src/core/fastlock.h index a4f729e1b..657130570 100644 --- a/src/core/fastlock.h +++ b/src/core/fastlock.h @@ -414,7 +414,7 @@ inline static void release_lock(fl_lock_t *lock) #ifdef __CPU_mips #warning mips1 smp mode not supported (no membars), try compiling with -DNOSMP #else - " sync \n\t" + " sync \n\t" #endif #endif " sw $0, %0 \n\t" diff --git a/src/core/fix_lumps.h b/src/core/fix_lumps.h index 43f45b7ed..3f4873bb3 100644 --- a/src/core/fix_lumps.h +++ b/src/core/fix_lumps.h @@ -28,12 +28,10 @@ * \brief Kamailio core :: Lump handling * \ingroup core * Module: \ref core - * here, we delete message lumps which are generated in + * delete message lumps which are generated in * core functions using pkg_malloc and applied to shmem * requests; not doing so would result ugly memory problems - * - * I admit it is not a nice hack; -jiri -*/ + */ #ifndef _FIX_LUMPS_H @@ -51,8 +49,7 @@ is stored in shmem for branch picking, forwarded lated and Via removal is applied to the shmem-ed message - the same thing for Content-Length lumps (FIXME: this - should be done in a nicer way) + the same thing for Content-Length lumps */ inline static void free_via_clen_lump(struct lump **list) { diff --git a/src/core/forward.c b/src/core/forward.c index 74acc945d..0276f8a5a 100644 --- a/src/core/forward.c +++ b/src/core/forward.c @@ -72,7 +72,7 @@ /* return a socket_info_pointer to the sending socket; as opposed to - * get_send_socket, which returns process's default socket, get_out_socket + * get_send_socket, which returns process' default socket, get_out_socket * attempts to determine the outbound interface which will be used; * it uses a temporary connected socket to determine it; it will * be very likely noticeably slower, but it can deal better with @@ -290,10 +290,10 @@ not_forced: case PROTO_WS: case PROTO_TCP: /* on tcp just use the "main address", we don't really know the - * sending address (we can find it out, but we'll need also to see - * if we listen on it, and if yes on which port -> too complicated*/ + * sending address (we can find it out, but we'll need also to see + * if we listen on it, and if yes on which port + * -> too complicated */ switch(to->s.sa_family) { - /* FIXME */ case AF_INET: send_sock = sendipv4_tcp; break; @@ -310,7 +310,6 @@ not_forced: case PROTO_WSS: case PROTO_TLS: switch(to->s.sa_family) { - /* FIXME */ case AF_INET: send_sock = sendipv4_tls; break; diff --git a/src/core/globals.h b/src/core/globals.h index 207205c99..0ec87c89a 100644 --- a/src/core/globals.h +++ b/src/core/globals.h @@ -56,38 +56,39 @@ extern int uid; extern int gid; extern char *pid_file; extern char *pgid_file; -extern int - own_pgid; /* whether or not we have our own pgid (and it's ok to use kill(0, sig) */ +/* whether or not we have our own pgid (and it's ok to use kill(0, sig) */ +extern int own_pgid; extern int server_id; /* A unique ID of the SIP server */ extern struct socket_info *bind_address; /* pointer to the crt. proc. listening address */ -extern struct socket_info *sendipv4; /* ipv4 socket to use when msg. - comes from ipv6*/ +extern struct socket_info *sendipv4; /* ipv4 socket to use when msg + comes from ipv6 */ extern struct socket_info *sendipv6; /* same as above for ipv6 */ #ifdef USE_RAW_SOCKS extern int raw_udp4_send_sock; #endif /* USE_RAW_SOCKS */ #ifdef USE_TCP -extern struct socket_info *sendipv4_tcp; /* ipv4 socket to use when msg. - comes from ipv6*/ +extern struct socket_info *sendipv4_tcp; /* ipv4 socket to use when msg + comes from ipv6 */ extern struct socket_info *sendipv6_tcp; /* same as above for ipv6 */ -extern int unix_tcp_sock; /* socket used for communication with tcp main*/ +extern int unix_tcp_sock; /* socket used for communication with tcp main */ #endif #ifdef USE_TLS -extern struct socket_info *sendipv4_tls; /* ipv4 socket to use when msg. - comes from ipv6*/ +extern struct socket_info *sendipv4_tls; /* ipv4 socket to use when msg + comes from ipv6 */ extern struct socket_info *sendipv6_tls; /* same as above for ipv6 */ #endif #ifdef USE_SCTP -extern struct socket_info *sendipv4_sctp; /* ipv4 socket to use when msg. - comes from ipv6*/ +extern struct socket_info *sendipv4_sctp; /* ipv4 socket to use when msg + comes from ipv6 */ extern struct socket_info *sendipv6_sctp; /* same as above for ipv6 */ #endif extern unsigned int maxbuffer; +extern unsigned int maxsndbuffer; extern unsigned int sql_buffer_size; extern int children_no; extern int socket_workers; @@ -108,6 +109,7 @@ extern int ksr_tcp_script_mode; #ifdef USE_TLS extern int tls_disable; extern unsigned short tls_port_no; +extern int ksr_tls_threads_mode; #endif #ifdef USE_SCTP extern int sctp_disable; @@ -164,6 +166,8 @@ extern int reply_to_via; extern int _ksr_is_main; extern int fixup_complete; +extern int ksr_mem_add_size; + /* debugging level for dumping memory status */ extern int memlog; /* debugging level for malloc debugging messages */ @@ -218,6 +222,7 @@ extern int ksr_all_errors; extern int ksr_route_locks_size; extern str _ksr_xavp_via_params; extern str _ksr_xavp_via_fields; +extern str _ksr_xavp_via_reply_params; extern int ksr_sip_parser_mode; extern int ksr_cfg_print_mode; extern int ksr_return_mode; diff --git a/src/core/io_wait.h b/src/core/io_wait.h index 8a60ae280..14d93f593 100644 --- a/src/core/io_wait.h +++ b/src/core/io_wait.h @@ -47,7 +47,9 @@ #include /* sigprocmask, sigwait a.s.o */ #endif +#ifndef _GNU_SOURCE #define _GNU_SOURCE /* for POLLRDHUP on linux */ +#endif #include #include diff --git a/src/core/ip_addr.c b/src/core/ip_addr.c index bc42b4532..02c26f969 100644 --- a/src/core/ip_addr.c +++ b/src/core/ip_addr.c @@ -705,6 +705,44 @@ char *get_proto_name(unsigned int proto) } } +/** get protocol id from string value. + * @param protoval - protocol value + * @return int value of the protocol. + */ +int get_valid_proto_id(str *protoval) +{ + if(protoval == NULL || protoval->s == NULL || protoval->len <= 0) { + return PROTO_NONE; + } + switch(protoval->len) { + case 2: + if(strncasecmp(protoval->s, "ws", 2) == 0) { + return PROTO_WS; + } + break; + case 3: + if(strncasecmp(protoval->s, "udp", 3) == 0) { + return PROTO_UDP; + } + if(strncasecmp(protoval->s, "tcp", 3) == 0) { + return PROTO_TCP; + } + if(strncasecmp(protoval->s, "tls", 3) == 0) { + return PROTO_TLS; + } + if(strncasecmp(protoval->s, "wss", 3) == 0) { + return PROTO_WSS; + } + break; + case 4: + if(strncasecmp(protoval->s, "sctp", 4) == 0) { + return PROTO_SCTP; + } + break; + } + return PROTO_NONE; +} + /** get address family name (asciiz). * @param af - address family id * @return string with the adderess family name or "unknown". diff --git a/src/core/ip_addr.h b/src/core/ip_addr.h index 15e8e74e5..a8f9660b9 100644 --- a/src/core/ip_addr.h +++ b/src/core/ip_addr.h @@ -121,10 +121,12 @@ typedef struct addr_info typedef struct advertise_info { str name; /* name - eg.: foo.bar or 10.0.0.1 */ + int proto; /* protocol id */ + int af; /* address family based on [ ] around name */ unsigned short port_no; /* port number */ short port_pad; /* padding field */ str port_no_str; /* port number converted to string -- optimization*/ - str address_str; /*ip address converted to string -- optimization*/ + str address_str; /* ip address converted to string -- optimization*/ struct ip_addr address; /* ip address */ str sock_str; /* Socket proto, ip, and port as string */ } advertise_info_t; @@ -161,6 +163,7 @@ typedef struct socket_attrs int bindproto; str bindaddr; int bindport; + int useproto; str useaddr; int useport; str sockname; @@ -336,6 +339,7 @@ char *get_proto_name(unsigned int proto); int get_valid_proto_string( unsigned int iproto, int utype, int vtype, str *sproto); +int get_valid_proto_id(str *protoval); char *get_af_name(unsigned int af); diff --git a/src/core/kemi.c b/src/core/kemi.c index cab42315a..8bf0aacb4 100644 --- a/src/core/kemi.c +++ b/src/core/kemi.c @@ -47,6 +47,7 @@ #define SR_KEMI_HNAME_SIZE 128 /* names for kemi callback functions */ +str kemi_request_route_callback = str_init("ksr_request_route"); str kemi_onsend_route_callback = str_init("ksr_onsend_route"); str kemi_reply_route_callback = str_init("ksr_reply_route"); str kemi_event_route_callback = str_init(""); @@ -1750,359 +1751,464 @@ static int sr_kemi_core_to_af_ipv6(sip_msg_t *msg) return SR_KEMI_FALSE; } +/* clang-format off */ /** * */ static sr_kemi_t _sr_kemi_core[] = { - {str_init(""), str_init("dbg"), SR_KEMIP_NONE, sr_kemi_core_dbg, - {SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("err"), SR_KEMIP_NONE, sr_kemi_core_err, - {SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("info"), SR_KEMIP_NONE, sr_kemi_core_info, - {SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("warn"), SR_KEMIP_NONE, sr_kemi_core_warn, - {SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("notice"), SR_KEMIP_NONE, sr_kemi_core_notice, - {SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("crit"), SR_KEMIP_NONE, sr_kemi_core_crit, - {SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("log"), SR_KEMIP_NONE, sr_kemi_core_log, - {SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("set_drop"), SR_KEMIP_NONE, - sr_kemi_core_set_drop, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_myself"), SR_KEMIP_BOOL, - sr_kemi_core_is_myself, - {SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_myself_ruri"), SR_KEMIP_BOOL, - sr_kemi_core_is_myself_ruri, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_myself_duri"), SR_KEMIP_BOOL, - sr_kemi_core_is_myself_duri, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_myself_nhuri"), SR_KEMIP_BOOL, - sr_kemi_core_is_myself_nhuri, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_myself_furi"), SR_KEMIP_BOOL, - sr_kemi_core_is_myself_furi, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_myself_turi"), SR_KEMIP_BOOL, - sr_kemi_core_is_myself_turi, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_myself_suri"), SR_KEMIP_BOOL, - sr_kemi_core_is_myself_suri, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_myself_srcip"), SR_KEMIP_BOOL, - sr_kemi_core_is_myself_srcip, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("setflag"), SR_KEMIP_BOOL, sr_kemi_core_setflag, - {SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("resetflag"), SR_KEMIP_BOOL, - sr_kemi_core_resetflag, - {SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("isflagset"), SR_KEMIP_BOOL, - sr_kemi_core_isflagset, - {SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("setbflag"), SR_KEMIP_BOOL, - sr_kemi_core_setbflag, - {SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("resetbflag"), SR_KEMIP_BOOL, - sr_kemi_core_resetbflag, - {SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("isbflagset"), SR_KEMIP_BOOL, - sr_kemi_core_isbflagset, - {SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("setbiflag"), SR_KEMIP_BOOL, - sr_kemi_core_setbiflag, - {SR_KEMIP_INT, SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("resetbiflag"), SR_KEMIP_BOOL, - sr_kemi_core_resetbiflag, - {SR_KEMIP_INT, SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("isbiflagset"), SR_KEMIP_BOOL, - sr_kemi_core_isbiflagset, - {SR_KEMIP_INT, SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("setsflag"), SR_KEMIP_BOOL, - sr_kemi_core_setsflag, - {SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("resetsflag"), SR_KEMIP_BOOL, - sr_kemi_core_resetsflag, - {SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("issflagset"), SR_KEMIP_BOOL, - sr_kemi_core_issflagset, - {SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("seturi"), SR_KEMIP_BOOL, sr_kemi_core_seturi, - {SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("setuser"), SR_KEMIP_BOOL, sr_kemi_core_setuser, - {SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("sethost"), SR_KEMIP_BOOL, sr_kemi_core_sethost, - {SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("setdsturi"), SR_KEMIP_BOOL, - sr_kemi_core_setdsturi, - {SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("resetdsturi"), SR_KEMIP_BOOL, - sr_kemi_core_resetdsturi, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("isdsturiset"), SR_KEMIP_BOOL, - sr_kemi_core_isdsturiset, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("force_rport"), SR_KEMIP_BOOL, - sr_kemi_core_force_rport, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("add_local_rport"), SR_KEMIP_BOOL, - sr_kemi_core_add_local_rport, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_method"), SR_KEMIP_BOOL, - sr_kemi_core_is_method, - {SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_method_in"), SR_KEMIP_BOOL, - sr_kemi_core_is_method_in, - {SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("forward"), SR_KEMIP_INT, sr_kemi_core_forward, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("forward_uri"), SR_KEMIP_INT, - sr_kemi_core_forward_uri, - {SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("set_forward_close"), SR_KEMIP_BOOL, - sr_kemi_core_set_forward_close, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("set_forward_no_connect"), SR_KEMIP_BOOL, - sr_kemi_core_set_forward_no_connect, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("set_reply_close"), SR_KEMIP_BOOL, - sr_kemi_core_set_reply_close, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("set_reply_no_connect"), SR_KEMIP_BOOL, - sr_kemi_core_set_reply_no_connect, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("set_advertised_address"), SR_KEMIP_INT, - sr_kemi_core_set_advertised_address, - {SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("set_advertised_port"), SR_KEMIP_INT, - sr_kemi_core_set_advertised_port, - {SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("add_tcp_alias"), SR_KEMIP_INT, - sr_kemi_core_add_tcp_alias, - {SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("add_tcp_alias_via"), SR_KEMIP_INT, - sr_kemi_core_add_tcp_alias_via, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_INVITE"), SR_KEMIP_BOOL, - sr_kemi_core_is_method_invite, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_ACK"), SR_KEMIP_BOOL, - sr_kemi_core_is_method_ack, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_BYE"), SR_KEMIP_BOOL, - sr_kemi_core_is_method_bye, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_CANCEL"), SR_KEMIP_BOOL, - sr_kemi_core_is_method_cancel, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_REGISTER"), SR_KEMIP_BOOL, - sr_kemi_core_is_method_register, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_OPTIONS"), SR_KEMIP_BOOL, - sr_kemi_core_is_method_options, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_SUBSCRIBE"), SR_KEMIP_BOOL, - sr_kemi_core_is_method_subscribe, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_PUBLISH"), SR_KEMIP_BOOL, - sr_kemi_core_is_method_publish, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_NOTIFY"), SR_KEMIP_BOOL, - sr_kemi_core_is_method_notify, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_REFER"), SR_KEMIP_BOOL, - sr_kemi_core_is_method_refer, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_INFO"), SR_KEMIP_BOOL, - sr_kemi_core_is_method_info, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_UPDATE"), SR_KEMIP_BOOL, - sr_kemi_core_is_method_update, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_PRACK"), SR_KEMIP_BOOL, - sr_kemi_core_is_method_prack, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_MESSAGE"), SR_KEMIP_BOOL, - sr_kemi_core_is_method_message, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_KDMQ"), SR_KEMIP_BOOL, - sr_kemi_core_is_method_kdmq, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_GET"), SR_KEMIP_BOOL, - sr_kemi_core_is_method_get, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_POST"), SR_KEMIP_BOOL, - sr_kemi_core_is_method_post, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_PUT"), SR_KEMIP_BOOL, - sr_kemi_core_is_method_put, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_DELETE"), SR_KEMIP_BOOL, - sr_kemi_core_is_method_delete, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_UDP"), SR_KEMIP_BOOL, - sr_kemi_core_is_proto_udp, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_TCP"), SR_KEMIP_BOOL, - sr_kemi_core_is_proto_tcp, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_TLS"), SR_KEMIP_BOOL, - sr_kemi_core_is_proto_tls, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_WS"), SR_KEMIP_BOOL, - sr_kemi_core_is_proto_ws, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_WSS"), SR_KEMIP_BOOL, - sr_kemi_core_is_proto_wss, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_WSX"), SR_KEMIP_BOOL, - sr_kemi_core_is_proto_wsx, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_SCTP"), SR_KEMIP_BOOL, - sr_kemi_core_is_proto_sctp, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_proto"), SR_KEMIP_BOOL, - sr_kemi_core_is_proto, - {SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_IPv4"), SR_KEMIP_BOOL, - sr_kemi_core_is_af_ipv4, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_IPv6"), SR_KEMIP_BOOL, - sr_kemi_core_is_af_ipv6, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("to_UDP"), SR_KEMIP_BOOL, - sr_kemi_core_to_proto_udp, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("to_TCP"), SR_KEMIP_BOOL, - sr_kemi_core_to_proto_tcp, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("to_TLS"), SR_KEMIP_BOOL, - sr_kemi_core_to_proto_tls, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("to_SCTP"), SR_KEMIP_BOOL, - sr_kemi_core_to_proto_sctp, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("to_WS"), SR_KEMIP_BOOL, - sr_kemi_core_to_proto_ws, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("to_WSS"), SR_KEMIP_BOOL, - sr_kemi_core_to_proto_wss, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("to_WSX"), SR_KEMIP_BOOL, - sr_kemi_core_to_proto_wsx, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("to_IPv4"), SR_KEMIP_BOOL, - sr_kemi_core_to_af_ipv4, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("to_IPv6"), SR_KEMIP_BOOL, - sr_kemi_core_to_af_ipv6, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_src_port"), SR_KEMIP_BOOL, - sr_kemi_core_is_src_port, - {SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("is_dst_port"), SR_KEMIP_BOOL, - sr_kemi_core_is_dst_port, - {SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("get_debug"), SR_KEMIP_INT, - sr_kemi_core_get_debug, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init(""), str_init("route"), SR_KEMIP_INT, sr_kemi_core_route, - {SR_KEMIP_STR, 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}}}; + { str_init(""), str_init("dbg"), + SR_KEMIP_NONE, sr_kemi_core_dbg, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("err"), + SR_KEMIP_NONE, sr_kemi_core_err, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("info"), + SR_KEMIP_NONE, sr_kemi_core_info, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("warn"), + SR_KEMIP_NONE, sr_kemi_core_warn, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("notice"), + SR_KEMIP_NONE, sr_kemi_core_notice, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("crit"), + SR_KEMIP_NONE, sr_kemi_core_crit, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("log"), + SR_KEMIP_NONE, sr_kemi_core_log, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("set_drop"), + SR_KEMIP_NONE, sr_kemi_core_set_drop, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_myself"), + SR_KEMIP_BOOL, sr_kemi_core_is_myself, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_myself_ruri"), + SR_KEMIP_BOOL, sr_kemi_core_is_myself_ruri, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_myself_duri"), + SR_KEMIP_BOOL, sr_kemi_core_is_myself_duri, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_myself_nhuri"), + SR_KEMIP_BOOL, sr_kemi_core_is_myself_nhuri, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_myself_furi"), + SR_KEMIP_BOOL, sr_kemi_core_is_myself_furi, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_myself_turi"), + SR_KEMIP_BOOL, sr_kemi_core_is_myself_turi, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_myself_suri"), + SR_KEMIP_BOOL, sr_kemi_core_is_myself_suri, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_myself_srcip"), + SR_KEMIP_BOOL, sr_kemi_core_is_myself_srcip, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("setflag"), + SR_KEMIP_BOOL, sr_kemi_core_setflag, + { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("resetflag"), + SR_KEMIP_BOOL, sr_kemi_core_resetflag, + { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("isflagset"), + SR_KEMIP_BOOL, sr_kemi_core_isflagset, + { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("setbflag"), + SR_KEMIP_BOOL, sr_kemi_core_setbflag, + { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("resetbflag"), + SR_KEMIP_BOOL, sr_kemi_core_resetbflag, + { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("isbflagset"), + SR_KEMIP_BOOL, sr_kemi_core_isbflagset, + { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("setbiflag"), + SR_KEMIP_BOOL, sr_kemi_core_setbiflag, + { SR_KEMIP_INT, SR_KEMIP_INT, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("resetbiflag"), + SR_KEMIP_BOOL, sr_kemi_core_resetbiflag, + { SR_KEMIP_INT, SR_KEMIP_INT, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("isbiflagset"), + SR_KEMIP_BOOL, sr_kemi_core_isbiflagset, + { SR_KEMIP_INT, SR_KEMIP_INT, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("setsflag"), + SR_KEMIP_BOOL, sr_kemi_core_setsflag, + { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("resetsflag"), + SR_KEMIP_BOOL, sr_kemi_core_resetsflag, + { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("issflagset"), + SR_KEMIP_BOOL, sr_kemi_core_issflagset, + { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("seturi"), + SR_KEMIP_BOOL, sr_kemi_core_seturi, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("setuser"), + SR_KEMIP_BOOL, sr_kemi_core_setuser, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE}}, + { str_init(""), str_init("sethost"), + SR_KEMIP_BOOL, sr_kemi_core_sethost, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("setdsturi"), + SR_KEMIP_BOOL, sr_kemi_core_setdsturi, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("resetdsturi"), + SR_KEMIP_BOOL, sr_kemi_core_resetdsturi, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("isdsturiset"), + SR_KEMIP_BOOL, sr_kemi_core_isdsturiset, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("force_rport"), + SR_KEMIP_BOOL, sr_kemi_core_force_rport, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("add_local_rport"), + SR_KEMIP_BOOL, sr_kemi_core_add_local_rport, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_method"), + SR_KEMIP_BOOL, sr_kemi_core_is_method, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_method_in"), + SR_KEMIP_BOOL, sr_kemi_core_is_method_in, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("forward"), + SR_KEMIP_INT, sr_kemi_core_forward, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("forward_uri"), + SR_KEMIP_INT, sr_kemi_core_forward_uri, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("set_forward_close"), + SR_KEMIP_BOOL, sr_kemi_core_set_forward_close, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("set_forward_no_connect"), + SR_KEMIP_BOOL, sr_kemi_core_set_forward_no_connect, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("set_reply_close"), + SR_KEMIP_BOOL, sr_kemi_core_set_reply_close, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("set_reply_no_connect"), + SR_KEMIP_BOOL, sr_kemi_core_set_reply_no_connect, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("set_advertised_address"), + SR_KEMIP_INT, sr_kemi_core_set_advertised_address, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("set_advertised_port"), + SR_KEMIP_INT, sr_kemi_core_set_advertised_port, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("add_tcp_alias"), + SR_KEMIP_INT, sr_kemi_core_add_tcp_alias, + { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("add_tcp_alias_via"), + SR_KEMIP_INT, sr_kemi_core_add_tcp_alias_via, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_INVITE"), + SR_KEMIP_BOOL, sr_kemi_core_is_method_invite, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_ACK"), + SR_KEMIP_BOOL, sr_kemi_core_is_method_ack, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_BYE"), + SR_KEMIP_BOOL, sr_kemi_core_is_method_bye, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_CANCEL"), + SR_KEMIP_BOOL, sr_kemi_core_is_method_cancel, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_REGISTER"), + SR_KEMIP_BOOL, sr_kemi_core_is_method_register, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_OPTIONS"), + SR_KEMIP_BOOL, sr_kemi_core_is_method_options, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_SUBSCRIBE"), + SR_KEMIP_BOOL, sr_kemi_core_is_method_subscribe, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_PUBLISH"), + SR_KEMIP_BOOL, sr_kemi_core_is_method_publish, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_NOTIFY"), + SR_KEMIP_BOOL, sr_kemi_core_is_method_notify, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_REFER"), + SR_KEMIP_BOOL, sr_kemi_core_is_method_refer, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_INFO"), + SR_KEMIP_BOOL, sr_kemi_core_is_method_info, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_UPDATE"), + SR_KEMIP_BOOL, sr_kemi_core_is_method_update, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_PRACK"), + SR_KEMIP_BOOL, sr_kemi_core_is_method_prack, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_MESSAGE"), + SR_KEMIP_BOOL, sr_kemi_core_is_method_message, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_KDMQ"), + SR_KEMIP_BOOL, sr_kemi_core_is_method_kdmq, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_GET"), + SR_KEMIP_BOOL, sr_kemi_core_is_method_get, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_POST"), + SR_KEMIP_BOOL, sr_kemi_core_is_method_post, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_PUT"), + SR_KEMIP_BOOL, sr_kemi_core_is_method_put, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_DELETE"), + SR_KEMIP_BOOL, sr_kemi_core_is_method_delete, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_UDP"), + SR_KEMIP_BOOL, sr_kemi_core_is_proto_udp, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_TCP"), + SR_KEMIP_BOOL, sr_kemi_core_is_proto_tcp, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_TLS"), + SR_KEMIP_BOOL, sr_kemi_core_is_proto_tls, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_WS"), + SR_KEMIP_BOOL, sr_kemi_core_is_proto_ws, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_WSS"), + SR_KEMIP_BOOL, sr_kemi_core_is_proto_wss, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_WSX"), + SR_KEMIP_BOOL, sr_kemi_core_is_proto_wsx, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_SCTP"), + SR_KEMIP_BOOL, sr_kemi_core_is_proto_sctp, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_proto"), + SR_KEMIP_BOOL, sr_kemi_core_is_proto, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_IPv4"), + SR_KEMIP_BOOL, sr_kemi_core_is_af_ipv4, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_IPv6"), + SR_KEMIP_BOOL, sr_kemi_core_is_af_ipv6, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("to_UDP"), + SR_KEMIP_BOOL, sr_kemi_core_to_proto_udp, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("to_TCP"), + SR_KEMIP_BOOL, sr_kemi_core_to_proto_tcp, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("to_TLS"), + SR_KEMIP_BOOL, sr_kemi_core_to_proto_tls, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("to_SCTP"), + SR_KEMIP_BOOL, sr_kemi_core_to_proto_sctp, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("to_WS"), SR_KEMIP_BOOL, + sr_kemi_core_to_proto_ws, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("to_WSS"), + SR_KEMIP_BOOL, sr_kemi_core_to_proto_wss, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("to_WSX"), + SR_KEMIP_BOOL, sr_kemi_core_to_proto_wsx, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("to_IPv4"), + SR_KEMIP_BOOL, sr_kemi_core_to_af_ipv4, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("to_IPv6"), + SR_KEMIP_BOOL, sr_kemi_core_to_af_ipv6, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_src_port"), + SR_KEMIP_BOOL, sr_kemi_core_is_src_port, + { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("is_dst_port"), + SR_KEMIP_BOOL, sr_kemi_core_is_dst_port, + { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("get_debug"), + SR_KEMIP_INT, sr_kemi_core_get_debug, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init(""), str_init("route"), + SR_KEMIP_INT, sr_kemi_core_route, + { SR_KEMIP_STR, 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} } +}; +/* clang-format off */ /** * diff --git a/src/core/kemi.h b/src/core/kemi.h index fd06f4f1c..2797d645f 100644 --- a/src/core/kemi.h +++ b/src/core/kemi.h @@ -41,6 +41,7 @@ #define SR_KEMI_PARAMS_MAX 6 +extern str kemi_request_route_callback; extern str kemi_onsend_route_callback; extern str kemi_reply_route_callback; extern str kemi_event_route_callback; diff --git a/src/core/local_timer.c b/src/core/local_timer.c index 6a9c25553..64fc2a1e6 100644 --- a/src/core/local_timer.c +++ b/src/core/local_timer.c @@ -192,7 +192,7 @@ inline static void local_timer_list_expire( tl = h->next; _timer_rm_list(tl); /* detach */ tl->next = tl->prev = 0; /* debugging */ - /*FIXME: process tcpconn */ + /* note to review: process tcpconn */ ret = tl->f(t, tl, tl->data); if(ret != 0) { /* not one-shot, re-add it */ diff --git a/src/core/mem/dl_config.h b/src/core/mem/dl_config.h deleted file mode 100644 index 72037c9a6..000000000 --- a/src/core/mem/dl_config.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _DL_CONFIG_H -#define _DL_CONFIG_H - -#define MSPACES 1 -#define USE_DL_PREFIX 1 -#define MALLOC_ALIGNMENT 16 -/* enable FOOTERS for extra consistency checks */ -/* #define FOOTERS 1 */ - -#endif /* _DL_CONFIG_H */ diff --git a/src/core/mem/dl_malloc.c b/src/core/mem/dl_malloc.c deleted file mode 100644 index d67a02f20..000000000 --- a/src/core/mem/dl_malloc.c +++ /dev/null @@ -1,5152 +0,0 @@ -/* - This is a version (aka dlmalloc) of malloc/free/realloc written by - Doug Lea and released to the public domain, as explained at - http://creativecommons.org/licenses/publicdomain. Send questions, - comments, complaints, performance data, etc to dl@cs.oswego.edu - -* Version 2.8.3 Thu Sep 22 11:16:15 2005 Doug Lea (dl at gee) - - Note: There may be an updated version of this malloc obtainable at - ftp://gee.cs.oswego.edu/pub/misc/malloc.c - Check before installing! - -* Quickstart - - This library is all in one file to simplify the most common usage: - ftp it, compile it (-O3), and link it into another program. All of - the compile-time options default to reasonable values for use on - most platforms. You might later want to step through various - compile-time and dynamic tuning options. - - For convenience, an include file for code using this malloc is at: - ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.3.h - You don't really need this .h file unless you call functions not - defined in your system include files. The .h file contains only the - excerpts from this file needed for using this malloc on ANSI C/C++ - systems, so long as you haven't changed compile-time options about - naming and tuning parameters. If you do, then you can create your - own malloc.h that does include all settings by cutting at the point - indicated below. Note that you may already by default be using a C - library containing a malloc that is based on some version of this - malloc (for example in linux). You might still want to use the one - in this file to customize settings or to avoid overheads associated - with library versions. - -* Vital statistics: - - Supported pointer/size_t representation: 4 or 8 bytes - size_t MUST be an unsigned type of the same width as - pointers. (If you are using an ancient system that declares - size_t as a signed type, or need it to be a different width - than pointers, you can use a previous release of this malloc - (e.g. 2.7.2) supporting these.) - - Alignment: 8 bytes (default) - This suffices for nearly all current machines and C compilers. - However, you can define MALLOC_ALIGNMENT to be wider than this - if necessary (up to 128bytes), at the expense of using more space. - - Minimum overhead per allocated chunk: 4 or 8 bytes (if 4byte sizes) - 8 or 16 bytes (if 8byte sizes) - Each malloced chunk has a hidden word of overhead holding size - and status information, and additional cross-check word - if FOOTERS is defined. - - Minimum allocated size: 4-byte ptrs: 16 bytes (including overhead) - 8-byte ptrs: 32 bytes (including overhead) - - Even a request for zero bytes (i.e., malloc(0)) returns a - pointer to something of the minimum allocatable size. - The maximum overhead wastage (i.e., number of extra bytes - allocated than were requested in malloc) is less than or equal - to the minimum size, except for requests >= mmap_threshold that - are serviced via mmap(), where the worst case wastage is about - 32 bytes plus the remainder from a system page (the minimal - mmap unit); typically 4096 or 8192 bytes. - - Security: static-safe; optionally more or less - The "security" of malloc refers to the ability of malicious - code to accentuate the effects of errors (for example, freeing - space that is not currently malloc'ed or overwriting past the - ends of chunks) in code that calls malloc. This malloc - guarantees not to modify any memory locations below the base of - heap, i.e., static variables, even in the presence of usage - errors. The routines additionally detect most improper frees - and reallocs. All this holds as long as the static bookkeeping - for malloc itself is not corrupted by some other means. This - is only one aspect of security -- these checks do not, and - cannot, detect all possible programming errors. - - If FOOTERS is defined nonzero, then each allocated chunk - carries an additional check word to verify that it was malloced - from its space. These check words are the same within each - execution of a program using malloc, but differ across - executions, so externally crafted fake chunks cannot be - freed. This improves security by rejecting frees/reallocs that - could corrupt heap memory, in addition to the checks preventing - writes to statics that are always on. This may further improve - security at the expense of time and space overhead. (Note that - FOOTERS may also be worth using with MSPACES.) - - By default detected errors cause the program to abort (calling - "abort()"). You can override this to instead proceed past - errors by defining PROCEED_ON_ERROR. In this case, a bad free - has no effect, and a malloc that encounters a bad address - caused by user overwrites will ignore the bad address by - dropping pointers and indices to all known memory. This may - be appropriate for programs that should continue if at all - possible in the face of programming errors, although they may - run out of memory because dropped memory is never reclaimed. - - If you don't like either of these options, you can define - CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything - else. And if if you are sure that your program using malloc has - no errors or vulnerabilities, you can define INSECURE to 1, - which might (or might not) provide a small performance improvement. - - Thread-safety: NOT thread-safe unless USE_LOCKS defined - When USE_LOCKS is defined, each public call to malloc, free, - etc is surrounded with either a pthread mutex or a win32 - spinlock (depending on WIN32). This is not especially fast, and - can be a major bottleneck. It is designed only to provide - minimal protection in concurrent environments, and to provide a - basis for extensions. If you are using malloc in a concurrent - program, consider instead using ptmalloc, which is derived from - a version of this malloc. (See http://www.malloc.de). - - System requirements: Any combination of MORECORE and/or MMAP/MUNMAP - This malloc can use unix sbrk or any emulation (invoked using - the CALL_MORECORE macro) and/or mmap/munmap or any emulation - (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system - memory. On most unix systems, it tends to work best if both - MORECORE and MMAP are enabled. On Win32, it uses emulations - based on VirtualAlloc. It also uses common C library functions - like memset. - - Compliance: I believe it is compliant with the Single Unix Specification - (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably - others as well. - -* Overview of algorithms - - This is not the fastest, most space-conserving, most portable, or - most tunable malloc ever written. However it is among the fastest - while also being among the most space-conserving, portable and - tunable. Consistent balance across these factors results in a good - general-purpose allocator for malloc-intensive programs. - - In most ways, this malloc is a best-fit allocator. Generally, it - chooses the best-fitting existing chunk for a request, with ties - broken in approximately least-recently-used order. (This strategy - normally maintains low fragmentation.) However, for requests less - than 256bytes, it deviates from best-fit when there is not an - exactly fitting available chunk by preferring to use space adjacent - to that used for the previous small request, as well as by breaking - ties in approximately most-recently-used order. (These enhance - locality of series of small allocations.) And for very large requests - (>= 256Kb by default), it relies on system memory mapping - facilities, if supported. (This helps avoid carrying around and - possibly fragmenting memory used only for large chunks.) - - All operations (except malloc_stats and mallinfo) have execution - times that are bounded by a constant factor of the number of bits in - a size_t, not counting any clearing in calloc or copying in realloc, - or actions surrounding MORECORE and MMAP that have times - proportional to the number of non-contiguous regions returned by - system allocation routines, which is often just 1. - - The implementation is not very modular and seriously overuses - macros. Perhaps someday all C compilers will do as good a job - inlining modular code as can now be done by brute-force expansion, - but now, enough of them seem not to. - - Some compilers issue a lot of warnings about code that is - dead/unreachable only on some platforms, and also about intentional - uses of negation on unsigned types. All known cases of each can be - ignored. - - For a longer but out of date high-level description, see - http://gee.cs.oswego.edu/dl/html/malloc.html - -* MSPACES - If MSPACES is defined, then in addition to malloc, free, etc., - this file also defines mspace_malloc, mspace_free, etc. These - are versions of malloc routines that take an "mspace" argument - obtained using create_mspace, to control all internal bookkeeping. - If ONLY_MSPACES is defined, only these versions are compiled. - So if you would like to use this allocator for only some allocations, - and your system malloc for others, you can compile with - ONLY_MSPACES and then do something like... - static mspace mymspace = create_mspace(0,0); // for example - #define mymalloc(bytes) mspace_malloc(mymspace, bytes) - - (Note: If you only need one instance of an mspace, you can instead - use "USE_DL_PREFIX" to relabel the global malloc.) - - You can similarly create thread-local allocators by storing - mspaces as thread-locals. For example: - static __thread mspace tlms = 0; - void* tlmalloc(size_t bytes) { - if (tlms == 0) tlms = create_mspace(0, 0); - return mspace_malloc(tlms, bytes); - } - void tlfree(void* mem) { mspace_free(tlms, mem); } - - Unless FOOTERS is defined, each mspace is completely independent. - You cannot allocate from one and free to another (although - conformance is only weakly checked, so usage errors are not always - caught). If FOOTERS is defined, then each chunk carries around a tag - indicating its originating mspace, and frees are directed to their - originating spaces. - - ------------------------- Compile-time options --------------------------- - -Be careful in setting #define values for numerical constants of type -size_t. On some systems, literal values are not automatically extended -to size_t precision unless they are explicitly casted. - -WIN32 default: defined if _WIN32 defined - Defining WIN32 sets up defaults for MS environment and compilers. - Otherwise defaults are for unix. - -MALLOC_ALIGNMENT default: (size_t)8 - Controls the minimum alignment for malloc'ed chunks. It must be a - power of two and at least 8, even on machines for which smaller - alignments would suffice. It may be defined as larger than this - though. Note however that code and data structures are optimized for - the case of 8-byte alignment. - -MSPACES default: 0 (false) - If true, compile in support for independent allocation spaces. - This is only supported if HAVE_MMAP is true. - -ONLY_MSPACES default: 0 (false) - If true, only compile in mspace versions, not regular versions. - -USE_LOCKS default: 0 (false) - Causes each call to each public routine to be surrounded with - pthread or WIN32 mutex lock/unlock. (If set true, this can be - overridden on a per-mspace basis for mspace versions.) - -FOOTERS default: 0 - If true, provide extra checking and dispatching by placing - information in the footers of allocated chunks. This adds - space and time overhead. - -INSECURE default: 0 - If true, omit checks for usage errors and heap space overwrites. - -USE_DL_PREFIX default: NOT defined - Causes compiler to prefix all public routines with the string 'dl'. - This can be useful when you only want to use this malloc in one part - of a program, using your regular system malloc elsewhere. - -ABORT default: defined as abort() - Defines how to abort on failed checks. On most systems, a failed - check cannot die with an "assert" or even print an informative - message, because the underlying print routines in turn call malloc, - which will fail again. Generally, the best policy is to simply call - abort(). It's not very useful to do more than this because many - errors due to overwriting will show up as address faults (null, odd - addresses etc) rather than malloc-triggered checks, so will also - abort. Also, most compilers know that abort() does not return, so - can better optimize code conditionally calling it. - -PROCEED_ON_ERROR default: defined as 0 (false) - Controls whether detected bad addresses cause them to bypassed - rather than aborting. If set, detected bad arguments to free and - realloc are ignored. And all bookkeeping information is zeroed out - upon a detected overwrite of freed heap space, thus losing the - ability to ever return it from malloc again, but enabling the - application to proceed. If PROCEED_ON_ERROR is defined, the - static variable malloc_corruption_error_count is compiled in - and can be examined to see if errors have occurred. This option - generates slower code than the default abort policy. - -DEBUG default: NOT defined - The DEBUG setting is mainly intended for people trying to modify - this code or diagnose problems when porting to new platforms. - However, it may also be able to better isolate user errors than just - using runtime checks. The assertions in the check routines spell - out in more detail the assumptions and invariants underlying the - algorithms. The checking is fairly extensive, and will slow down - execution noticeably. Calling malloc_stats or mallinfo with DEBUG - set will attempt to check every non-mmapped allocated and free chunk - in the course of computing the summaries. - -ABORT_ON_ASSERT_FAILURE default: defined as 1 (true) - Debugging assertion failures can be nearly impossible if your - version of the assert macro causes malloc to be called, which will - lead to a cascade of further failures, blowing the runtime stack. - ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(), - which will usually make debugging easier. - -MALLOC_FAILURE_ACTION default: sets errno to ENOMEM, or no-op on win32 - The action to take before "return 0" when malloc fails to be able to - return memory because there is none available. - -HAVE_MORECORE default: 1 (true) unless win32 or ONLY_MSPACES - True if this system supports sbrk or an emulation of it. - -MORECORE default: sbrk - The name of the sbrk-style system routine to call to obtain more - memory. See below for guidance on writing custom MORECORE - functions. The type of the argument to sbrk/MORECORE varies across - systems. It cannot be size_t, because it supports negative - arguments, so it is normally the signed type of the same width as - size_t (sometimes declared as "intptr_t"). It doesn't much matter - though. Internally, we only call it with arguments less than half - the max value of a size_t, which should work across all reasonable - possibilities, although sometimes generating compiler warnings. See - near the end of this file for guidelines for creating a custom - version of MORECORE. - -MORECORE_CONTIGUOUS default: 1 (true) - If true, take advantage of fact that consecutive calls to MORECORE - with positive arguments always return contiguous increasing - addresses. This is true of unix sbrk. It does not hurt too much to - set it true anyway, since malloc copes with non-contiguities. - Setting it false when definitely non-contiguous saves time - and possibly wasted space it would take to discover this though. - -MORECORE_CANNOT_TRIM default: NOT defined - True if MORECORE cannot release space back to the system when given - negative arguments. This is generally necessary only if you are - using a hand-crafted MORECORE function that cannot handle negative - arguments. - -HAVE_MMAP default: 1 (true) - True if this system supports mmap or an emulation of it. If so, and - HAVE_MORECORE is not true, MMAP is used for all system - allocation. If set and HAVE_MORECORE is true as well, MMAP is - primarily used to directly allocate very large blocks. It is also - used as a backup strategy in cases where MORECORE fails to provide - space from system. Note: A single call to MUNMAP is assumed to be - able to unmap memory that may have be allocated using multiple calls - to MMAP, so long as they are adjacent. - -HAVE_MREMAP default: 1 on linux, else 0 - If true realloc() uses mremap() to re-allocate large blocks and - extend or shrink allocation spaces. - -MMAP_CLEARS default: 1 on unix - True if mmap clears memory so calloc doesn't need to. This is true - for standard unix mmap using /dev/zero. - -USE_BUILTIN_FFS default: 0 (i.e., not used) - Causes malloc to use the builtin ffs() function to compute indices. - Some compilers may recognize and intrinsify ffs to be faster than the - supplied C version. Also, the case of x86 using gcc is special-cased - to an asm instruction, so is already as fast as it can be, and so - this setting has no effect. (On most x86s, the asm version is only - slightly faster than the C version.) - -malloc_getpagesize default: derive from system includes, or 4096. - The system page size. To the extent possible, this malloc manages - memory from the system in page-size units. This may be (and - usually is) a function rather than a constant. This is ignored - if WIN32, where page size is determined using getSystemInfo during - initialization. - -USE_DEV_RANDOM default: 0 (i.e., not used) - Causes malloc to use /dev/random to initialize secure magic seed for - stamping footers. Otherwise, the current time is used. - -NO_MALLINFO default: 0 - If defined, don't compile "mallinfo". This can be a simple way - of dealing with mismatches between system declarations and - those in this file. - -MALLINFO_FIELD_TYPE default: size_t - The type of the fields in the mallinfo struct. This was originally - defined as "int" in SVID etc, but is more usefully defined as - size_t. The value is used only if HAVE_USR_INCLUDE_MALLOC_H is not set - -REALLOC_ZERO_BYTES_FREES default: not defined - This should be set if a call to realloc with zero bytes should - be the same as a call to free. Some people think it should. Otherwise, - since this malloc returns a unique pointer for malloc(0), so does - realloc(p, 0). - -LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H -LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H, LACKS_ERRNO_H -LACKS_STDLIB_H default: NOT defined unless on WIN32 - Define these if your system does not have these header files. - You might need to manually insert some of the declarations they provide. - -DEFAULT_GRANULARITY default: page size if MORECORE_CONTIGUOUS, - system_info.dwAllocationGranularity in WIN32, - otherwise 64K. - Also settable using mallopt(M_GRANULARITY, x) - The unit for allocating and deallocating memory from the system. On - most systems with contiguous MORECORE, there is no reason to - make this more than a page. However, systems with MMAP tend to - either require or encourage larger granularities. You can increase - this value to prevent system allocation functions to be called so - often, especially if they are slow. The value must be at least one - page and must be a power of two. Setting to 0 causes initialization - to either page size or win32 region size. (Note: In previous - versions of malloc, the equivalent of this option was called - "TOP_PAD") - -DEFAULT_TRIM_THRESHOLD default: 2MB - Also settable using mallopt(M_TRIM_THRESHOLD, x) - The maximum amount of unused top-most memory to keep before - releasing via malloc_trim in free(). Automatic trimming is mainly - useful in long-lived programs using contiguous MORECORE. Because - trimming via sbrk can be slow on some systems, and can sometimes be - wasteful (in cases where programs immediately afterward allocate - more large chunks) the value should be high enough so that your - overall system performance would improve by releasing this much - memory. As a rough guide, you might set to a value close to the - average size of a process (program) running on your system. - Releasing this much memory would allow such a process to run in - memory. Generally, it is worth tuning trim thresholds when a - program undergoes phases where several large chunks are allocated - and released in ways that can reuse each other's storage, perhaps - mixed with phases where there are no such chunks at all. The trim - value must be greater than page size to have any useful effect. To - disable trimming completely, you can set to MAX_SIZE_T. Note that the trick - some people use of mallocing a huge space and then freeing it at - program startup, in an attempt to reserve system memory, doesn't - have the intended effect under automatic trimming, since that memory - will immediately be returned to the system. - -DEFAULT_MMAP_THRESHOLD default: 256K - Also settable using mallopt(M_MMAP_THRESHOLD, x) - The request size threshold for using MMAP to directly service a - request. Requests of at least this size that cannot be allocated - using already-existing space will be serviced via mmap. (If enough - normal freed space already exists it is used instead.) Using mmap - segregates relatively large chunks of memory so that they can be - individually obtained and released from the host system. A request - serviced through mmap is never reused by any other request (at least - not directly; the system may just so happen to remap successive - requests to the same locations). Segregating space in this way has - the benefits that: Mmapped space can always be individually released - back to the system, which helps keep the system level memory demands - of a long-lived program low. Also, mapped memory doesn't become - `locked' between other chunks, as can happen with normally allocated - chunks, which means that even trimming via malloc_trim would not - release them. However, it has the disadvantage that the space - cannot be reclaimed, consolidated, and then used to service later - requests, as happens with normal chunks. The advantages of mmap - nearly always outweigh disadvantages for "large" chunks, but the - value of "large" may vary across systems. The default is an - empirically derived value that works well in most systems. You can - disable mmap by setting to MAX_SIZE_T. - -*/ -#ifdef DL_MALLOC - -#include "dl_config.h" -#include "meminfo.h" - -#ifndef WIN32 -#ifdef _WIN32 -#define WIN32 1 -#endif /* _WIN32 */ -#endif /* WIN32 */ -#ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#define HAVE_MMAP 1 -#define HAVE_MORECORE 0 -#define LACKS_UNISTD_H -#define LACKS_SYS_PARAM_H -#define LACKS_SYS_MMAN_H -#define LACKS_STRING_H -#define LACKS_STRINGS_H -#define LACKS_SYS_TYPES_H -#define LACKS_ERRNO_H -#define MALLOC_FAILURE_ACTION -#define MMAP_CLEARS 0 /* WINCE and some others apparently don't clear */ -#endif /* WIN32 */ - -#if defined(DARWIN) || defined(_DARWIN) -/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */ -#ifndef HAVE_MORECORE -#define HAVE_MORECORE 0 -#define HAVE_MMAP 1 -#endif /* HAVE_MORECORE */ -#endif /* DARWIN */ - -#ifndef LACKS_SYS_TYPES_H -#include /* For size_t */ -#endif /* LACKS_SYS_TYPES_H */ - -/* The maximum possible size_t value has all bits set */ -#define MAX_SIZE_T (~(size_t)0) - -#ifndef ONLY_MSPACES -#define ONLY_MSPACES 0 -#endif /* ONLY_MSPACES */ -#ifndef MSPACES -#if ONLY_MSPACES -#define MSPACES 1 -#else /* ONLY_MSPACES */ -#define MSPACES 0 -#endif /* ONLY_MSPACES */ -#endif /* MSPACES */ -#ifndef MALLOC_ALIGNMENT -#define MALLOC_ALIGNMENT ((size_t)8U) -#endif /* MALLOC_ALIGNMENT */ -#ifndef FOOTERS -#define FOOTERS 0 -#endif /* FOOTERS */ -#ifndef ABORT -#define ABORT abort() -#endif /* ABORT */ -#ifndef ABORT_ON_ASSERT_FAILURE -#define ABORT_ON_ASSERT_FAILURE 1 -#endif /* ABORT_ON_ASSERT_FAILURE */ -#ifndef PROCEED_ON_ERROR -#define PROCEED_ON_ERROR 0 -#endif /* PROCEED_ON_ERROR */ -#ifndef USE_LOCKS -#define USE_LOCKS 0 -#endif /* USE_LOCKS */ -#ifndef INSECURE -#define INSECURE 0 -#endif /* INSECURE */ -#ifndef HAVE_MMAP -#define HAVE_MMAP 1 -#endif /* HAVE_MMAP */ -#ifndef MMAP_CLEARS -#define MMAP_CLEARS 1 -#endif /* MMAP_CLEARS */ -#ifndef HAVE_MREMAP -#ifdef linux -#define HAVE_MREMAP 1 -#else /* linux */ -#define HAVE_MREMAP 0 -#endif /* linux */ -#endif /* HAVE_MREMAP */ -#ifndef MALLOC_FAILURE_ACTION -#define MALLOC_FAILURE_ACTION errno = ENOMEM; -#endif /* MALLOC_FAILURE_ACTION */ -#ifndef HAVE_MORECORE -#if ONLY_MSPACES -#define HAVE_MORECORE 0 -#else /* ONLY_MSPACES */ -#define HAVE_MORECORE 1 -#endif /* ONLY_MSPACES */ -#endif /* HAVE_MORECORE */ -#if !HAVE_MORECORE -#define MORECORE_CONTIGUOUS 0 -#else /* !HAVE_MORECORE */ -#ifndef MORECORE -#define MORECORE sbrk -#endif /* MORECORE */ -#ifndef MORECORE_CONTIGUOUS -#define MORECORE_CONTIGUOUS 1 -#endif /* MORECORE_CONTIGUOUS */ -#endif /* HAVE_MORECORE */ -#ifndef DEFAULT_GRANULARITY -#if MORECORE_CONTIGUOUS -#define DEFAULT_GRANULARITY (0) /* 0 means to compute in init_mparams */ -#else /* MORECORE_CONTIGUOUS */ -#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U) -#endif /* MORECORE_CONTIGUOUS */ -#endif /* DEFAULT_GRANULARITY */ -#ifndef DEFAULT_TRIM_THRESHOLD -#ifndef MORECORE_CANNOT_TRIM -#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U) -#else /* MORECORE_CANNOT_TRIM */ -#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T -#endif /* MORECORE_CANNOT_TRIM */ -#endif /* DEFAULT_TRIM_THRESHOLD */ -#ifndef DEFAULT_MMAP_THRESHOLD -#if HAVE_MMAP -#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U) -#else /* HAVE_MMAP */ -#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T -#endif /* HAVE_MMAP */ -#endif /* DEFAULT_MMAP_THRESHOLD */ -#ifndef USE_BUILTIN_FFS -#define USE_BUILTIN_FFS 0 -#endif /* USE_BUILTIN_FFS */ -#ifndef USE_DEV_RANDOM -#define USE_DEV_RANDOM 0 -#endif /* USE_DEV_RANDOM */ -#ifndef NO_MALLINFO -#define NO_MALLINFO 0 -#endif /* NO_MALLINFO */ -#ifndef MALLINFO_FIELD_TYPE -#define MALLINFO_FIELD_TYPE size_t -#endif /* MALLINFO_FIELD_TYPE */ - -/* - mallopt tuning options. SVID/XPG defines four standard parameter - numbers for mallopt, normally defined in malloc.h. None of these - are used in this malloc, so setting them has no effect. But this - malloc does support the following options. -*/ - -#define M_TRIM_THRESHOLD (-1) -#define M_GRANULARITY (-2) -#define M_MMAP_THRESHOLD (-3) - -/* ------------------------ Mallinfo declarations ------------------------ */ - -#if !NO_MALLINFO -/* - This version of malloc supports the standard SVID/XPG mallinfo - routine that returns a struct containing usage properties and - statistics. It should work on any system that has a - /usr/include/malloc.h defining struct mallinfo. The main - declaration needed is the mallinfo struct that is returned (by-copy) - by mallinfo(). The malloinfo struct contains a bunch of fields that - are not even meaningful in this version of malloc. These fields are - are instead filled by mallinfo() with other numbers that might be of - interest. - - HAVE_USR_INCLUDE_MALLOC_H should be set if you have a - /usr/include/malloc.h file that includes a declaration of struct - mallinfo. If so, it is included; else a compliant version is - declared below. These must be precisely the same for mallinfo() to - work. The original SVID version of this struct, defined on most - systems with mallinfo, declares all fields as ints. But some others - define as unsigned long. If your system defines the fields using a - type of different width than listed here, you MUST #include your - system version and #define HAVE_USR_INCLUDE_MALLOC_H. -*/ - -/* #define HAVE_USR_INCLUDE_MALLOC_H */ - -#ifdef HAVE_USR_INCLUDE_MALLOC_H -#include "/usr/include/malloc.h" -#else /* HAVE_USR_INCLUDE_MALLOC_H */ - -struct mallinfo -{ - MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ - MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ - MALLINFO_FIELD_TYPE smblks; /* always 0 */ - MALLINFO_FIELD_TYPE hblks; /* always 0 */ - MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ - MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ - MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ - MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ - MALLINFO_FIELD_TYPE fordblks; /* total free space */ - MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ -}; - -#endif /* HAVE_USR_INCLUDE_MALLOC_H */ -#endif /* NO_MALLINFO */ - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -#if !ONLY_MSPACES - - /* ------------------- Declarations of public routines ------------------- */ - -#ifndef USE_DL_PREFIX -#define dlcalloc calloc -#define dlfree free -#define dlmalloc malloc -#define dlmemalign memalign -#define dlrealloc realloc -#define dlvalloc valloc -#define dlpvalloc pvalloc -#define dlmallinfo mallinfo -#define dlmallopt mallopt -#define dlmalloc_trim malloc_trim -#define dlmalloc_stats malloc_stats -#define dlmalloc_usable_size malloc_usable_size -#define dlmalloc_footprint malloc_footprint -#define dlmalloc_max_footprint malloc_max_footprint -#define dlindependent_calloc independent_calloc -#define dlindependent_comalloc independent_comalloc -#endif /* USE_DL_PREFIX */ - - - /* - malloc(size_t n) - Returns a pointer to a newly allocated chunk of at least n bytes, or - null if no space is available, in which case errno is set to ENOMEM - on ANSI C systems. - - If n is zero, malloc returns a minimum-sized chunk. (The minimum - size is 16 bytes on most 32bit systems, and 32 bytes on 64bit - systems.) Note that size_t is an unsigned type, so calls with - arguments that would be negative if signed are interpreted as - requests for huge amounts of space, which will often fail. The - maximum supported value of n differs across systems, but is in all - cases less than the maximum representable value of a size_t. -*/ - void *dlmalloc(size_t); - - /* - free(void* p) - Releases the chunk of memory pointed to by p, that had been previously - allocated using malloc or a related routine such as realloc. - It has no effect if p is null. If p was not malloced or already - freed, free(p) will by default cause the current program to abort. -*/ - void dlfree(void *); - - /* - calloc(size_t n_elements, size_t element_size); - Returns a pointer to n_elements * element_size bytes, with all locations - set to zero. -*/ - void *dlcalloc(size_t, size_t); - - /* - realloc(void* p, size_t n) - Returns a pointer to a chunk of size n that contains the same data - as does chunk p up to the minimum of (n, p's size) bytes, or null - if no space is available. - - The returned pointer may or may not be the same as p. The algorithm - prefers extending p in most cases when possible, otherwise it - employs the equivalent of a malloc-copy-free sequence. - - If p is null, realloc is equivalent to malloc. - - If space is not available, realloc returns null, errno is set (if on - ANSI) and p is NOT freed. - - if n is for fewer bytes than already held by p, the newly unused - space is lopped off and freed if possible. realloc with a size - argument of zero (re)allocates a minimum-sized chunk. - - The old unix realloc convention of allowing the last-free'd chunk - to be used as an argument to realloc is not supported. -*/ - - void *dlrealloc(void *, size_t); - - /* - memalign(size_t alignment, size_t n); - Returns a pointer to a newly allocated chunk of n bytes, aligned - in accord with the alignment argument. - - The alignment argument should be a power of two. If the argument is - not a power of two, the nearest greater power is used. - 8-byte alignment is guaranteed by normal malloc calls, so don't - bother calling memalign with an argument of 8 or less. - - Overreliance on memalign is a sure way to fragment space. -*/ - void *dlmemalign(size_t, size_t); - - /* - valloc(size_t n); - Equivalent to memalign(pagesize, n), where pagesize is the page - size of the system. If the pagesize is unknown, 4096 is used. -*/ - void *dlvalloc(size_t); - - /* - mallopt(int parameter_number, int parameter_value) - Sets tunable parameters The format is to provide a - (parameter-number, parameter-value) pair. mallopt then sets the - corresponding parameter to the argument value if it can (i.e., so - long as the value is meaningful), and returns 1 if successful else - 0. SVID/XPG/ANSI defines four standard param numbers for mallopt, - normally defined in malloc.h. None of these are use in this malloc, - so setting them has no effect. But this malloc also supports other - options in mallopt. See below for details. Briefly, supported - parameters are as follows (listed defaults are for "typical" - configurations). - - Symbol param # default allowed param values - M_TRIM_THRESHOLD -1 2*1024*1024 any (MAX_SIZE_T disables) - M_GRANULARITY -2 page size any power of 2 >= page size - M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) -*/ - int dlmallopt(int, int); - - /* - malloc_footprint(); - Returns the number of bytes obtained from the system. The total - number of bytes allocated by malloc, realloc etc., is less than this - value. Unlike mallinfo, this function returns only a precomputed - result, so can be called frequently to monitor memory consumption. - Even if locks are otherwise defined, this function does not use them, - so results might not be up to date. -*/ - size_t dlmalloc_footprint(void); - - /* - malloc_max_footprint(); - Returns the maximum number of bytes obtained from the system. This - value will be greater than current footprint if deallocated space - has been reclaimed by the system. The peak number of bytes allocated - by malloc, realloc etc., is less than this value. Unlike mallinfo, - this function returns only a precomputed result, so can be called - frequently to monitor memory consumption. Even if locks are - otherwise defined, this function does not use them, so results might - not be up to date. -*/ - size_t dlmalloc_max_footprint(void); - -#if !NO_MALLINFO - /* - mallinfo() - Returns (by copy) a struct containing various summary statistics: - - arena: current total non-mmapped bytes allocated from system - ordblks: the number of free chunks - smblks: always zero. - hblks: current number of mmapped regions - hblkhd: total bytes held in mmapped regions - usmblks: the maximum total allocated space. This will be greater - than current total if trimming has occurred. - fsmblks: always zero - uordblks: current total allocated space (normal or mmapped) - fordblks: total free space - keepcost: the maximum number of bytes that could ideally be released - back to system via malloc_trim. ("ideally" means that - it ignores page restrictions etc.) - - Because these fields are ints, but internal bookkeeping may - be kept as longs, the reported values may wrap around zero and - thus be inaccurate. -*/ - struct mallinfo dlmallinfo(void); -#endif /* NO_MALLINFO */ - - /* - independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); - - independent_calloc is similar to calloc, but instead of returning a - single cleared space, it returns an array of pointers to n_elements - independent elements that can hold contents of size elem_size, each - of which starts out cleared, and can be independently freed, - realloc'ed etc. The elements are guaranteed to be adjacently - allocated (this is not guaranteed to occur with multiple callocs or - mallocs), which may also improve cache locality in some - applications. - - The "chunks" argument is optional (i.e., may be null, which is - probably the most typical usage). If it is null, the returned array - is itself dynamically allocated and should also be freed when it is - no longer needed. Otherwise, the chunks array must be of at least - n_elements in length. It is filled in with the pointers to the - chunks. - - In either case, independent_calloc returns this pointer array, or - null if the allocation failed. If n_elements is zero and "chunks" - is null, it returns a chunk representing an array with zero elements - (which should be freed if not wanted). - - Each element must be individually freed when it is no longer - needed. If you'd like to instead be able to free all at once, you - should instead use regular calloc and assign pointers into this - space to represent elements. (In this case though, you cannot - independently free elements.) - - independent_calloc simplifies and speeds up implementations of many - kinds of pools. It may also be useful when constructing large data - structures that initially have a fixed number of fixed-sized nodes, - but the number is not known at compile time, and some of the nodes - may later need to be freed. For example: - - struct Node { int item; struct Node* next; }; - - struct Node* build_list() { - struct Node** pool; - int n = read_number_of_nodes_needed(); - if (n <= 0) return 0; - pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); - if (pool == 0) die(); - // organize into a linked list... - struct Node* first = pool[0]; - for (i = 0; i < n-1; ++i) - pool[i]->next = pool[i+1]; - free(pool); // Can now free the array (or not, if it is needed later) - return first; - } -*/ - void **dlindependent_calloc(size_t, size_t, void **); - - /* - independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); - - independent_comalloc allocates, all at once, a set of n_elements - chunks with sizes indicated in the "sizes" array. It returns - an array of pointers to these elements, each of which can be - independently freed, realloc'ed etc. The elements are guaranteed to - be adjacently allocated (this is not guaranteed to occur with - multiple callocs or mallocs), which may also improve cache locality - in some applications. - - The "chunks" argument is optional (i.e., may be null). If it is null - the returned array is itself dynamically allocated and should also - be freed when it is no longer needed. Otherwise, the chunks array - must be of at least n_elements in length. It is filled in with the - pointers to the chunks. - - In either case, independent_comalloc returns this pointer array, or - null if the allocation failed. If n_elements is zero and chunks is - null, it returns a chunk representing an array with zero elements - (which should be freed if not wanted). - - Each element must be individually freed when it is no longer - needed. If you'd like to instead be able to free all at once, you - should instead use a single regular malloc, and assign pointers at - particular offsets in the aggregate space. (In this case though, you - cannot independently free elements.) - - independent_comallac differs from independent_calloc in that each - element may have a different size, and also that it does not - automatically clear elements. - - independent_comalloc can be used to speed up allocation in cases - where several structs or objects must always be allocated at the - same time. For example: - - struct Head { ... } - struct Foot { ... } - - void send_message(char* msg) { - int msglen = strlen(msg); - size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; - void* chunks[3]; - if (independent_comalloc(3, sizes, chunks) == 0) - die(); - struct Head* head = (struct Head*)(chunks[0]); - char* body = (char*)(chunks[1]); - struct Foot* foot = (struct Foot*)(chunks[2]); - // ... - } - - In general though, independent_comalloc is worth using only for - larger values of n_elements. For small values, you probably won't - detect enough difference from series of malloc calls to bother. - - Overuse of independent_comalloc can increase overall memory usage, - since it cannot reuse existing noncontiguous small chunks that - might be available for some of the elements. -*/ - void **dlindependent_comalloc(size_t, size_t *, void **); - - - /* - pvalloc(size_t n); - Equivalent to valloc(minimum-page-that-holds(n)), that is, - round up n to nearest pagesize. - */ - void *dlpvalloc(size_t); - - /* - malloc_trim(size_t pad); - - If possible, gives memory back to the system (via negative arguments - to sbrk) if there is unused memory at the `high' end of the malloc - pool or in unused MMAP segments. You can call this after freeing - large blocks of memory to potentially reduce the system-level memory - requirements of a program. However, it cannot guarantee to reduce - memory. Under some allocation patterns, some large free blocks of - memory will be locked between two used chunks, so they cannot be - given back to the system. - - The `pad' argument to malloc_trim represents the amount of free - trailing space to leave untrimmed. If this argument is zero, only - the minimum amount of memory to maintain internal data structures - will be left. Non-zero arguments can be supplied to maintain enough - trailing space to service future expected allocations without having - to re-obtain memory from the system. - - Malloc_trim returns 1 if it actually released any memory, else 0. -*/ - int dlmalloc_trim(size_t); - - /* - malloc_usable_size(void* p); - - Returns the number of bytes you can actually use in - an allocated chunk, which may be more than you requested (although - often not) due to alignment and minimum size constraints. - You can use this many bytes without worrying about - overwriting other allocated objects. This is not a particularly great - programming practice. malloc_usable_size can be more useful in - debugging and assertions, for example: - - p = malloc(n); - assert(malloc_usable_size(p) >= 256); -*/ - size_t dlmalloc_usable_size(void *); - - /* - malloc_stats(); - Prints on stderr the amount of space obtained from the system (both - via sbrk and mmap), the maximum amount (which may be more than - current if malloc_trim and/or munmap got called), and the current - number of bytes allocated via malloc (or realloc, etc) but not yet - freed. Note that this is the number of bytes allocated, not the - number requested. It will be larger than the number requested - because of alignment and bookkeeping overhead. Because it includes - alignment wastage as being in use, this figure may be greater than - zero even when no user-level chunks are allocated. - - The reported current and maximum system memory can be inaccurate if - a program makes other calls to system memory allocation functions - (normally sbrk) outside of malloc. - - malloc_stats prints only the most commonly interesting statistics. - More information can be obtained by calling mallinfo. -*/ - void dlmalloc_stats(void); - -#endif /* ONLY_MSPACES */ - -#if MSPACES - - /* - mspace is an opaque type representing an independent - region of space that supports mspace_malloc, etc. -*/ - typedef void *mspace; - - /* - create_mspace creates and returns a new independent space with the - given initial capacity, or, if 0, the default granularity size. It - returns null if there is no system memory available to create the - space. If argument locked is non-zero, the space uses a separate - lock to control access. The capacity of the space will grow - dynamically as needed to service mspace_malloc requests. You can - control the sizes of incremental increases of this space by - compiling with a different DEFAULT_GRANULARITY or dynamically - setting with mallopt(M_GRANULARITY, value). -*/ - mspace create_mspace(size_t capacity, int locked); - - /* - destroy_mspace destroys the given space, and attempts to return all - of its memory back to the system, returning the total number of - bytes freed. After destruction, the results of access to all memory - used by the space become undefined. -*/ - size_t destroy_mspace(mspace msp); - - /* - create_mspace_with_base uses the memory supplied as the initial base - of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this - space is used for bookkeeping, so the capacity must be at least this - large. (Otherwise 0 is returned.) When this initial space is - exhausted, additional memory will be obtained from the system. - Destroying this space will deallocate all additionally allocated - space (if possible) but not the initial base. -*/ - mspace create_mspace_with_base(void *base, size_t capacity, int locked); - - /* - mspace_malloc behaves as malloc, but operates within - the given space. -*/ - void *mspace_malloc(mspace msp, size_t bytes); - - /* - mspace_free behaves as free, but operates within - the given space. - - If compiled with FOOTERS==1, mspace_free is not actually needed. - free may be called instead of mspace_free because freed chunks from - any space are handled by their originating spaces. -*/ - void mspace_free(mspace msp, void *mem); - - /* - mspace_realloc behaves as realloc, but operates within - the given space. - - If compiled with FOOTERS==1, mspace_realloc is not actually - needed. realloc may be called instead of mspace_realloc because - realloced chunks from any space are handled by their originating - spaces. -*/ - void *mspace_realloc(mspace msp, void *mem, size_t newsize); - - /* - mspace_calloc behaves as calloc, but operates within - the given space. -*/ - void *mspace_calloc(mspace msp, size_t n_elements, size_t elem_size); - - /* - mspace_memalign behaves as memalign, but operates within - the given space. -*/ - void *mspace_memalign(mspace msp, size_t alignment, size_t bytes); - - /* - mspace_independent_calloc behaves as independent_calloc, but - operates within the given space. -*/ - void **mspace_independent_calloc( - mspace msp, size_t n_elements, size_t elem_size, void *chunks[]); - - /* - mspace_independent_comalloc behaves as independent_comalloc, but - operates within the given space. -*/ - void **mspace_independent_comalloc( - mspace msp, size_t n_elements, size_t sizes[], void *chunks[]); - - /* - mspace_footprint() returns the number of bytes obtained from the - system for this space. -*/ - size_t mspace_footprint(mspace msp); - - /* - mspace_max_footprint() returns the peak number of bytes obtained from the - system for this space. -*/ - size_t mspace_max_footprint(mspace msp); - - -#if !NO_MALLINFO - /* - mspace_mallinfo behaves as mallinfo, but reports properties of - the given space. -*/ - struct mallinfo mspace_mallinfo(mspace msp); -#endif /* NO_MALLINFO */ - - /* - mspace_malloc_stats behaves as malloc_stats, but reports - properties of the given space. -*/ - void mspace_malloc_stats(mspace msp); - - /* - mspace_trim behaves as malloc_trim, but - operates within the given space. -*/ - int mspace_trim(mspace msp, size_t pad); - - /* - An alias for mallopt. -*/ - int mspace_mallopt(int, int); - -#endif /* MSPACES */ - -#ifdef __cplusplus -}; /* end of extern "C" */ -#endif /* __cplusplus */ - - /* - ======================================================================== - To make a fully customizable malloc.h header file, cut everything - above this line, put into file malloc.h, edit to suit, and #include it - on the next line, as well as in programs that use this malloc. - ======================================================================== -*/ - - /* #include "malloc.h" */ - - /*------------------------------ internal #includes ---------------------- */ - -#ifdef WIN32 -#pragma warning(disable : 4146) /* no "unsigned" warnings */ -#endif /* WIN32 */ - -#include /* for printing in malloc_stats */ - -#ifndef LACKS_ERRNO_H -#include /* for MALLOC_FAILURE_ACTION */ -#endif /* LACKS_ERRNO_H */ -#if FOOTERS -#include /* for magic initialization */ -#endif /* FOOTERS */ -#ifndef LACKS_STDLIB_H -#include /* for abort() */ -#endif /* LACKS_STDLIB_H */ -#ifdef DEBUG -#if ABORT_ON_ASSERT_FAILURE -#define assert(x) \ - if(!(x)) \ - ABORT -#else /* ABORT_ON_ASSERT_FAILURE */ -#include -#endif /* ABORT_ON_ASSERT_FAILURE */ -#else /* DEBUG */ -#define assert(x) -#endif /* DEBUG */ -#ifndef LACKS_STRING_H -#include /* for memset etc */ -#endif /* LACKS_STRING_H */ -#if USE_BUILTIN_FFS -#ifndef LACKS_STRINGS_H -#include /* for ffs */ -#endif /* LACKS_STRINGS_H */ -#endif /* USE_BUILTIN_FFS */ -#if HAVE_MMAP -#ifndef LACKS_SYS_MMAN_H -#include /* for mmap */ -#endif /* LACKS_SYS_MMAN_H */ -#ifndef LACKS_FCNTL_H -#include -#endif /* LACKS_FCNTL_H */ -#endif /* HAVE_MMAP */ -#if HAVE_MORECORE -#ifndef LACKS_UNISTD_H -#include /* for sbrk */ -#else /* LACKS_UNISTD_H */ -#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) -extern void *sbrk(ptrdiff_t); -#endif /* FreeBSD etc */ -#endif /* LACKS_UNISTD_H */ -#endif /* HAVE_MORECORE */ - -#ifndef WIN32 -#ifndef malloc_getpagesize -#ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */ -#ifndef _SC_PAGE_SIZE -#define _SC_PAGE_SIZE _SC_PAGESIZE -#endif -#endif -#ifdef _SC_PAGE_SIZE -#define malloc_getpagesize sysconf(_SC_PAGE_SIZE) -#else -#if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE) -extern size_t getpagesize(); -#define malloc_getpagesize getpagesize() -#else -#ifdef WIN32 /* use supplied emulation of getpagesize */ -#define malloc_getpagesize getpagesize() -#else -#ifndef LACKS_SYS_PARAM_H -#include -#endif -#ifdef EXEC_PAGESIZE -#define malloc_getpagesize EXEC_PAGESIZE -#else -#ifdef NBPG -#ifndef CLSIZE -#define malloc_getpagesize NBPG -#else -#define malloc_getpagesize (NBPG * CLSIZE) -#endif -#else -#ifdef NBPC -#define malloc_getpagesize NBPC -#else -#ifdef PAGESIZE -#define malloc_getpagesize PAGESIZE -#else /* just guess */ -#define malloc_getpagesize ((size_t)4096U) -#endif -#endif -#endif -#endif -#endif -#endif -#endif -#endif -#endif - -/* ------------------- size_t and alignment properties -------------------- */ - -/* The byte and bit size of a size_t */ -#define SIZE_T_SIZE (sizeof(size_t)) -#define SIZE_T_BITSIZE (sizeof(size_t) << 3) - -/* Some constants coerced to size_t */ -/* Annoying but necessary to avoid errors on some plaftorms */ -#define SIZE_T_ZERO ((size_t)0) -#define SIZE_T_ONE ((size_t)1) -#define SIZE_T_TWO ((size_t)2) -#define TWO_SIZE_T_SIZES (SIZE_T_SIZE << 1) -#define FOUR_SIZE_T_SIZES (SIZE_T_SIZE << 2) -#define SIX_SIZE_T_SIZES (FOUR_SIZE_T_SIZES + TWO_SIZE_T_SIZES) -#define HALF_MAX_SIZE_T (MAX_SIZE_T / 2U) - -/* The bit mask value corresponding to MALLOC_ALIGNMENT */ -#define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE) - -/* True if address A has acceptable alignment */ -#define is_aligned(A) (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0) - -/* the number of bytes to offset an address to align it */ -#define align_offset(A) \ - ((((size_t)(A)&CHUNK_ALIGN_MASK) == 0) \ - ? 0 \ - : ((MALLOC_ALIGNMENT - ((size_t)(A)&CHUNK_ALIGN_MASK)) \ - & CHUNK_ALIGN_MASK)) - -/* -------------------------- MMAP preliminaries ------------------------- */ - -/* - If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and - checks to fail so compiler optimizer can delete code rather than - using so many "#if"s. -*/ - - -/* MORECORE and MMAP must return MFAIL on failure */ -#define MFAIL ((void *)(MAX_SIZE_T)) -#define CMFAIL ((char *)(MFAIL)) /* defined for convenience */ - -#if !HAVE_MMAP -#define IS_MMAPPED_BIT (SIZE_T_ZERO) -#define USE_MMAP_BIT (SIZE_T_ZERO) -#define CALL_MMAP(s) MFAIL -#define CALL_MUNMAP(a, s) (-1) -#define DIRECT_MMAP(s) MFAIL - -#else /* HAVE_MMAP */ -#define IS_MMAPPED_BIT (SIZE_T_ONE) -#define USE_MMAP_BIT (SIZE_T_ONE) - -#ifndef WIN32 -#define CALL_MUNMAP(a, s) munmap((a), (s)) -#define MMAP_PROT (PROT_READ | PROT_WRITE) -#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) -#define MAP_ANONYMOUS MAP_ANON -#endif /* MAP_ANON */ -#ifdef MAP_ANONYMOUS -#define MMAP_FLAGS (MAP_PRIVATE | MAP_ANONYMOUS) -#define CALL_MMAP(s) mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0) -#else /* MAP_ANONYMOUS */ -/* - Nearly all versions of mmap support MAP_ANONYMOUS, so the following - is unlikely to be needed, but is supplied just in case. -*/ -#define MMAP_FLAGS (MAP_PRIVATE) -static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */ -#define CALL_MMAP(s) \ - ((dev_zero_fd < 0) ? (dev_zero_fd = open("/dev/zero", O_RDWR), \ - mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) \ - : mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) -#endif /* MAP_ANONYMOUS */ - -#define DIRECT_MMAP(s) CALL_MMAP(s) -#else /* WIN32 */ - -/* Win32 MMAP via VirtualAlloc */ -static void *win32mmap(size_t size) -{ - void *ptr = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); - return (ptr != 0) ? ptr : MFAIL; -} - -/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */ -static void *win32direct_mmap(size_t size) -{ - void *ptr = VirtualAlloc( - 0, size, MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE); - return (ptr != 0) ? ptr : MFAIL; -} - -/* This function supports releasing coalesed segments */ -static int win32munmap(void *ptr, size_t size) -{ - MEMORY_BASIC_INFORMATION minfo; - char *cptr = ptr; - while(size) { - if(VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0) - return -1; - if(minfo.BaseAddress != cptr || minfo.AllocationBase != cptr - || minfo.State != MEM_COMMIT || minfo.RegionSize > size) - return -1; - if(VirtualFree(cptr, 0, MEM_RELEASE) == 0) - return -1; - cptr += minfo.RegionSize; - size -= minfo.RegionSize; - } - return 0; -} - -#define CALL_MMAP(s) win32mmap(s) -#define CALL_MUNMAP(a, s) win32munmap((a), (s)) -#define DIRECT_MMAP(s) win32direct_mmap(s) -#endif /* WIN32 */ -#endif /* HAVE_MMAP */ - -#if HAVE_MMAP && HAVE_MREMAP -#define CALL_MREMAP(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv)) -#else /* HAVE_MMAP && HAVE_MREMAP */ -#define CALL_MREMAP(addr, osz, nsz, mv) MFAIL -#endif /* HAVE_MMAP && HAVE_MREMAP */ - -#if HAVE_MORECORE -#define CALL_MORECORE(S) MORECORE(S) -#else /* HAVE_MORECORE */ -#define CALL_MORECORE(S) MFAIL -#endif /* HAVE_MORECORE */ - -/* mstate bit set if contiguous morecore disabled or failed */ -#define USE_NONCONTIGUOUS_BIT (4U) - -/* segment bit set in create_mspace_with_base */ -#define EXTERN_BIT (8U) - - - /* --------------------------- Lock preliminaries ------------------------ */ - -#if USE_LOCKS - - /* - When locks are defined, there are up to two global locks: - - * If HAVE_MORECORE, morecore_mutex protects sequences of calls to - MORECORE. In many cases sys_alloc requires two calls, that should - not be interleaved with calls by other threads. This does not - protect against direct calls to MORECORE by other threads not - using this lock, so there is still code to cope the best we can on - interference. - - * magic_init_mutex ensures that mparams.magic and other - unique mparams values are initialized only once. -*/ - -#ifndef WIN32 -/* By default use posix locks */ -#include -#define MLOCK_T pthread_mutex_t -#define INITIAL_LOCK(l) pthread_mutex_init(l, NULL) -#define ACQUIRE_LOCK(l) pthread_mutex_lock(l) -#define RELEASE_LOCK(l) pthread_mutex_unlock(l) - -#if HAVE_MORECORE -static MLOCK_T morecore_mutex = PTHREAD_MUTEX_INITIALIZER; -#endif /* HAVE_MORECORE */ - -static MLOCK_T magic_init_mutex = PTHREAD_MUTEX_INITIALIZER; - -#else /* WIN32 */ -/* - Because lock-protected regions have bounded times, and there - are no recursive lock calls, we can use simple spinlocks. -*/ - -#define MLOCK_T long -static int win32_acquire_lock(MLOCK_T *sl) -{ - for(;;) { -#ifdef InterlockedCompareExchangePointer - if(!InterlockedCompareExchange(sl, 1, 0)) - return 0; -#else /* Use older void* version */ - if(!InterlockedCompareExchange((void **)sl, (void *)1, (void *)0)) - return 0; -#endif /* InterlockedCompareExchangePointer */ - Sleep(0); - } -} - -static void win32_release_lock(MLOCK_T *sl) -{ - InterlockedExchange(sl, 0); -} - -#define INITIAL_LOCK(l) *(l) = 0 -#define ACQUIRE_LOCK(l) win32_acquire_lock(l) -#define RELEASE_LOCK(l) win32_release_lock(l) -#if HAVE_MORECORE -static MLOCK_T morecore_mutex; -#endif /* HAVE_MORECORE */ -static MLOCK_T magic_init_mutex; -#endif /* WIN32 */ - -#define USE_LOCK_BIT (2U) -#else /* USE_LOCKS */ -#define USE_LOCK_BIT (0U) -#define INITIAL_LOCK(l) -#endif /* USE_LOCKS */ - -#if USE_LOCKS && HAVE_MORECORE -#define ACQUIRE_MORECORE_LOCK() ACQUIRE_LOCK(&morecore_mutex); -#define RELEASE_MORECORE_LOCK() RELEASE_LOCK(&morecore_mutex); -#else /* USE_LOCKS && HAVE_MORECORE */ -#define ACQUIRE_MORECORE_LOCK() -#define RELEASE_MORECORE_LOCK() -#endif /* USE_LOCKS && HAVE_MORECORE */ - -#if USE_LOCKS -#define ACQUIRE_MAGIC_INIT_LOCK() ACQUIRE_LOCK(&magic_init_mutex); -#define RELEASE_MAGIC_INIT_LOCK() RELEASE_LOCK(&magic_init_mutex); -#else /* USE_LOCKS */ -#define ACQUIRE_MAGIC_INIT_LOCK() -#define RELEASE_MAGIC_INIT_LOCK() -#endif /* USE_LOCKS */ - - -/* ----------------------- Chunk representations ------------------------ */ - -/* - (The following includes lightly edited explanations by Colin Plumb.) - - The malloc_chunk declaration below is misleading (but accurate and - necessary). It declares a "view" into memory allowing access to - necessary fields at known offsets from a given base. - - Chunks of memory are maintained using a `boundary tag' method as - originally described by Knuth. (See the paper by Paul Wilson - ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such - techniques.) Sizes of free chunks are stored both in the front of - each chunk and at the end. This makes consolidating fragmented - chunks into bigger chunks fast. The head fields also hold bits - representing whether chunks are free or in use. - - Here are some pictures to make it clearer. They are "exploded" to - show that the state of a chunk can be thought of as extending from - the high 31 bits of the head field of its header through the - prev_foot and PINUSE_BIT bit of the following chunk header. - - A chunk that's in use looks like: - - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of previous chunk (if P = 1) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| - | Size of this chunk 1| +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - +- -+ - | | - +- -+ - | : - +- size - sizeof(size_t) available payload bytes -+ - : | - chunk-> +- -+ - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1| - | Size of next chunk (may or may not be in use) | +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - And if it's free, it looks like this: - - chunk-> +- -+ - | User payload (must be in use, or we would have merged!) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| - | Size of this chunk 0| +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Next pointer | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Prev pointer | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | : - +- size - sizeof(struct chunk) unused bytes -+ - : | - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of this chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0| - | Size of next chunk (must be in use, or we would have merged)| +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | : - +- User payload -+ - : | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - |0| - +-+ - Note that since we always merge adjacent free chunks, the chunks - adjacent to a free chunk must be in use. - - Given a pointer to a chunk (which can be derived trivially from the - payload pointer) we can, in O(1) time, find out whether the adjacent - chunks are free, and if so, unlink them from the lists that they - are on and merge them with the current chunk. - - Chunks always begin on even word boundaries, so the mem portion - (which is returned to the user) is also on an even word boundary, and - thus at least double-word aligned. - - The P (PINUSE_BIT) bit, stored in the unused low-order bit of the - chunk size (which is always a multiple of two words), is an in-use - bit for the *previous* chunk. If that bit is *clear*, then the - word before the current chunk size contains the previous chunk - size, and can be used to find the front of the previous chunk. - The very first chunk allocated always has this bit set, preventing - access to non-existent (or non-owned) memory. If pinuse is set for - any given chunk, then you CANNOT determine the size of the - previous chunk, and might even get a memory addressing fault when - trying to do so. - - The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of - the chunk size redundantly records whether the current chunk is - inuse. This redundancy enables usage checks within free and realloc, - and reduces indirection when freeing and consolidating chunks. - - Each freshly allocated chunk must have both cinuse and pinuse set. - That is, each allocated chunk borders either a previously allocated - and still in-use chunk, or the base of its memory arena. This is - ensured by making all allocations from the `lowest' part of any - found chunk. Further, no free chunk physically borders another one, - so each free chunk is known to be preceded and followed by either - inuse chunks or the ends of memory. - - Note that the `foot' of the current chunk is actually represented - as the prev_foot of the NEXT chunk. This makes it easier to - deal with alignments etc but can be very confusing when trying - to extend or adapt this code. - - The exceptions to all this are - - 1. The special chunk `top' is the top-most available chunk (i.e., - the one bordering the end of available memory). It is treated - specially. Top is never included in any bin, is used only if - no other chunk is available, and is released back to the - system if it is very large (see M_TRIM_THRESHOLD). In effect, - the top chunk is treated as larger (and thus less well - fitting) than any other available chunk. The top chunk - doesn't update its trailing size field since there is no next - contiguous chunk that would have to index off it. However, - space is still allocated for it (TOP_FOOT_SIZE) to enable - separation or merging when space is extended. - - 3. Chunks allocated via mmap, which have the lowest-order bit - (IS_MMAPPED_BIT) set in their prev_foot fields, and do not set - PINUSE_BIT in their head fields. Because they are allocated - one-by-one, each must carry its own prev_foot field, which is - also used to hold the offset this chunk has within its mmapped - region, which is needed to preserve alignment. Each mmapped - chunk is trailed by the first two fields of a fake next-chunk - for sake of usage checks. - -*/ - -struct malloc_chunk -{ - size_t prev_foot; /* Size of previous chunk (if free). */ - size_t head; /* Size and inuse bits. */ - struct malloc_chunk *fd; /* double links -- used only if free. */ - struct malloc_chunk *bk; -}; - -typedef struct malloc_chunk mchunk; -typedef struct malloc_chunk *mchunkptr; -typedef struct malloc_chunk *sbinptr; /* The type of bins of chunks */ -typedef unsigned int bindex_t; /* Described below */ -typedef unsigned int binmap_t; /* Described below */ -typedef unsigned int flag_t; /* The type of various bit flag sets */ - -/* ------------------- Chunks sizes and alignments ----------------------- */ - -#define MCHUNK_SIZE (sizeof(mchunk)) - -#if FOOTERS -#define CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) -#else /* FOOTERS */ -#define CHUNK_OVERHEAD (SIZE_T_SIZE) -#endif /* FOOTERS */ - -/* MMapped chunks need a second word of overhead ... */ -#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) -/* ... and additional padding for fake next-chunk at foot */ -#define MMAP_FOOT_PAD (FOUR_SIZE_T_SIZES) - -/* The smallest size we can malloc is an aligned minimal chunk */ -#define MIN_CHUNK_SIZE ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) - -/* conversion from malloc headers to user pointers, and back */ -#define chunk2mem(p) ((void *)((char *)(p) + TWO_SIZE_T_SIZES)) -#define mem2chunk(mem) ((mchunkptr)((char *)(mem)-TWO_SIZE_T_SIZES)) -/* chunk associated with aligned address A */ -#define align_as_chunk(A) (mchunkptr)((A) + align_offset(chunk2mem(A))) - -/* Bounds on request (not chunk) sizes. */ -#define MAX_REQUEST ((-MIN_CHUNK_SIZE) << 2) -#define MIN_REQUEST (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE) - -/* pad request bytes into a usable size */ -#define pad_request(req) \ - (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) - -/* pad request, checking for minimum (but not maximum) */ -#define request2size(req) \ - (((req) < MIN_REQUEST) ? MIN_CHUNK_SIZE : pad_request(req)) - - -/* ------------------ Operations on head and foot fields ----------------- */ - -/* - The head field of a chunk is or'ed with PINUSE_BIT when previous - adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in - use. If the chunk was obtained with mmap, the prev_foot field has - IS_MMAPPED_BIT set, otherwise holding the offset of the base of the - mmapped region to the base of the chunk. -*/ - -#define PINUSE_BIT (SIZE_T_ONE) -#define CINUSE_BIT (SIZE_T_TWO) -#define INUSE_BITS (PINUSE_BIT | CINUSE_BIT) - -/* Head value for fenceposts */ -#define FENCEPOST_HEAD (INUSE_BITS | SIZE_T_SIZE) - -/* extraction of fields from head words */ -#define cinuse(p) ((p)->head & CINUSE_BIT) -#define pinuse(p) ((p)->head & PINUSE_BIT) -#define chunksize(p) ((p)->head & ~(INUSE_BITS)) - -#define clear_pinuse(p) ((p)->head &= ~PINUSE_BIT) -#define clear_cinuse(p) ((p)->head &= ~CINUSE_BIT) - -/* Treat space at ptr +/- offset as a chunk */ -#define chunk_plus_offset(p, s) ((mchunkptr)(((char *)(p)) + (s))) -#define chunk_minus_offset(p, s) ((mchunkptr)(((char *)(p)) - (s))) - -/* Ptr to next or previous physical malloc_chunk. */ -#define next_chunk(p) ((mchunkptr)(((char *)(p)) + ((p)->head & ~INUSE_BITS))) -#define prev_chunk(p) ((mchunkptr)(((char *)(p)) - ((p)->prev_foot))) - -/* extract next chunk's pinuse bit */ -#define next_pinuse(p) ((next_chunk(p)->head) & PINUSE_BIT) - -/* Get/set size at footer */ -#define get_foot(p, s) (((mchunkptr)((char *)(p) + (s)))->prev_foot) -#define set_foot(p, s) (((mchunkptr)((char *)(p) + (s)))->prev_foot = (s)) - -/* Set size, pinuse bit, and foot */ -#define set_size_and_pinuse_of_free_chunk(p, s) \ - ((p)->head = (s | PINUSE_BIT), set_foot(p, s)) - -/* Set size, pinuse bit, foot, and clear next pinuse */ -#define set_free_with_pinuse(p, s, n) \ - (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s)) - -#define is_mmapped(p) \ - (!((p)->head & PINUSE_BIT) && ((p)->prev_foot & IS_MMAPPED_BIT)) - -/* Get the internal overhead associated with chunk p */ -#define overhead_for(p) (is_mmapped(p) ? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD) - -/* Return true if malloced space is not necessarily cleared */ -#if MMAP_CLEARS -#define calloc_must_clear(p) (!is_mmapped(p)) -#else /* MMAP_CLEARS */ -#define calloc_must_clear(p) (1) -#endif /* MMAP_CLEARS */ - -/* ---------------------- Overlaid data structures ----------------------- */ - -/* - When chunks are not in use, they are treated as nodes of either - lists or trees. - - "Small" chunks are stored in circular doubly-linked lists, and look - like this: - - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of previous chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `head:' | Size of chunk, in bytes |P| - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Forward pointer to next chunk in list | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Back pointer to previous chunk in list | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Unused space (may be 0 bytes long) . - . . - . | -nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `foot:' | Size of chunk, in bytes | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - Larger chunks are kept in a form of bitwise digital trees (aka - tries) keyed on chunksizes. Because malloc_tree_chunks are only for - free chunks greater than 256 bytes, their size doesn't impose any - constraints on user chunk sizes. Each node looks like: - - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of previous chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `head:' | Size of chunk, in bytes |P| - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Forward pointer to next chunk of same size | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Back pointer to previous chunk of same size | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Pointer to left child (child[0]) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Pointer to right child (child[1]) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Pointer to parent | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | bin index of this chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Unused space . - . | -nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `foot:' | Size of chunk, in bytes | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - Each tree holding treenodes is a tree of unique chunk sizes. Chunks - of the same size are arranged in a circularly-linked list, with only - the oldest chunk (the next to be used, in our FIFO ordering) - actually in the tree. (Tree members are distinguished by a non-null - parent pointer.) If a chunk with the same size an an existing node - is inserted, it is linked off the existing node using pointers that - work in the same way as fd/bk pointers of small chunks. - - Each tree contains a power of 2 sized range of chunk sizes (the - smallest is 0x100 <= x < 0x180), which is is divided in half at each - tree level, with the chunks in the smaller half of the range (0x100 - <= x < 0x140 for the top nose) in the left subtree and the larger - half (0x140 <= x < 0x180) in the right subtree. This is, of course, - done by inspecting individual bits. - - Using these rules, each node's left subtree contains all smaller - sizes than its right subtree. However, the node at the root of each - subtree has no particular ordering relationship to either. (The - dividing line between the subtree sizes is based on trie relation.) - If we remove the last chunk of a given size from the interior of the - tree, we need to replace it with a leaf node. The tree ordering - rules permit a node to be replaced by any leaf below it. - - The smallest chunk in a tree (a common operation in a best-fit - allocator) can be found by walking a path to the leftmost leaf in - the tree. Unlike a usual binary tree, where we follow left child - pointers until we reach a null, here we follow the right child - pointer any time the left one is null, until we reach a leaf with - both child pointers null. The smallest chunk in the tree will be - somewhere along that path. - - The worst case number of steps to add, find, or remove a node is - bounded by the number of bits differentiating chunks within - bins. Under current bin calculations, this ranges from 6 up to 21 - (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case - is of course much better. -*/ - -struct malloc_tree_chunk -{ - /* The first four fields must be compatible with malloc_chunk */ - size_t prev_foot; - size_t head; - struct malloc_tree_chunk *fd; - struct malloc_tree_chunk *bk; - - struct malloc_tree_chunk *child[2]; - struct malloc_tree_chunk *parent; - bindex_t index; -}; - -typedef struct malloc_tree_chunk tchunk; -typedef struct malloc_tree_chunk *tchunkptr; -typedef struct malloc_tree_chunk *tbinptr; /* The type of bins of trees */ - -/* A little helper macro for trees */ -#define leftmost_child(t) ((t)->child[0] != 0 ? (t)->child[0] : (t)->child[1]) - -/* ----------------------------- Segments -------------------------------- */ - -/* - Each malloc space may include non-contiguous segments, held in a - list headed by an embedded malloc_segment record representing the - top-most space. Segments also include flags holding properties of - the space. Large chunks that are directly allocated by mmap are not - included in this list. They are instead independently created and - destroyed without otherwise keeping track of them. - - Segment management mainly comes into play for spaces allocated by - MMAP. Any call to MMAP might or might not return memory that is - adjacent to an existing segment. MORECORE normally contiguously - extends the current space, so this space is almost always adjacent, - which is simpler and faster to deal with. (This is why MORECORE is - used preferentially to MMAP when both are available -- see - sys_alloc.) When allocating using MMAP, we don't use any of the - hinting mechanisms (inconsistently) supported in various - implementations of unix mmap, or distinguish reserving from - committing memory. Instead, we just ask for space, and exploit - contiguity when we get it. It is probably possible to do - better than this on some systems, but no general scheme seems - to be significantly better. - - Management entails a simpler variant of the consolidation scheme - used for chunks to reduce fragmentation -- new adjacent memory is - normally prepended or appended to an existing segment. However, - there are limitations compared to chunk consolidation that mostly - reflect the fact that segment processing is relatively infrequent - (occurring only when getting memory from system) and that we - don't expect to have huge numbers of segments: - - * Segments are not indexed, so traversal requires linear scans. (It - would be possible to index these, but is not worth the extra - overhead and complexity for most programs on most platforms.) - * New segments are only appended to old ones when holding top-most - memory; if they cannot be prepended to others, they are held in - different segments. - - Except for the top-most segment of an mstate, each segment record - is kept at the tail of its segment. Segments are added by pushing - segment records onto the list headed by &mstate.seg for the - containing mstate. - - Segment flags control allocation/merge/deallocation policies: - * If EXTERN_BIT set, then we did not allocate this segment, - and so should not try to deallocate or merge with others. - (This currently holds only for the initial segment passed - into create_mspace_with_base.) - * If IS_MMAPPED_BIT set, the segment may be merged with - other surrounding mmapped segments and trimmed/de-allocated - using munmap. - * If neither bit is set, then the segment was obtained using - MORECORE so can be merged with surrounding MORECORE'd segments - and deallocated/trimmed using MORECORE with negative arguments. -*/ - -struct malloc_segment -{ - char *base; /* base address */ - size_t size; /* allocated size */ - struct malloc_segment *next; /* ptr to next segment */ - flag_t sflags; /* mmap and extern flag */ -}; - -#define is_mmapped_segment(S) ((S)->sflags & IS_MMAPPED_BIT) -#define is_extern_segment(S) ((S)->sflags & EXTERN_BIT) - -typedef struct malloc_segment msegment; -typedef struct malloc_segment *msegmentptr; - -/* ---------------------------- malloc_state ----------------------------- */ - -/* - A malloc_state holds all of the bookkeeping for a space. - The main fields are: - - Top - The topmost chunk of the currently active segment. Its size is - cached in topsize. The actual size of topmost space is - topsize+TOP_FOOT_SIZE, which includes space reserved for adding - fenceposts and segment records if necessary when getting more - space from the system. The size at which to autotrim top is - cached from mparams in trim_check, except that it is disabled if - an autotrim fails. - - Designated victim (dv) - This is the preferred chunk for servicing small requests that - don't have exact fits. It is normally the chunk split off most - recently to service another small request. Its size is cached in - dvsize. The link fields of this chunk are not maintained since it - is not kept in a bin. - - SmallBins - An array of bin headers for free chunks. These bins hold chunks - with sizes less than MIN_LARGE_SIZE bytes. Each bin contains - chunks of all the same size, spaced 8 bytes apart. To simplify - use in double-linked lists, each bin header acts as a malloc_chunk - pointing to the real first node, if it exists (else pointing to - itself). This avoids special-casing for headers. But to avoid - waste, we allocate only the fd/bk pointers of bins, and then use - repositioning tricks to treat these as the fields of a chunk. - - TreeBins - Treebins are pointers to the roots of trees holding a range of - sizes. There are 2 equally spaced treebins for each power of two - from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything - larger. - - Bin maps - There is one bit map for small bins ("smallmap") and one for - treebins ("treemap). Each bin sets its bit when non-empty, and - clears the bit when empty. Bit operations are then used to avoid - bin-by-bin searching -- nearly all "search" is done without ever - looking at bins that won't be selected. The bit maps - conservatively use 32 bits per map word, even if on 64bit system. - For a good description of some of the bit-based techniques used - here, see Henry S. Warren Jr's book "Hacker's Delight" (and - supplement at http://hackersdelight.org/). Many of these are - intended to reduce the branchiness of paths through malloc etc, as - well as to reduce the number of memory locations read or written. - - Segments - A list of segments headed by an embedded malloc_segment record - representing the initial space. - - Address check support - The least_addr field is the least address ever obtained from - MORECORE or MMAP. Attempted frees and reallocs of any address less - than this are trapped (unless INSECURE is defined). - - Magic tag - A cross-check field that should always hold same value as mparams.magic. - - Flags - Bits recording whether to use MMAP, locks, or contiguous MORECORE - - Statistics - Each space keeps track of current and maximum system memory - obtained via MORECORE or MMAP. - - Locking - If USE_LOCKS is defined, the "mutex" lock is acquired and released - around every public call using this mspace. -*/ - -/* Bin types, widths and sizes */ -#define NSMALLBINS (32U) -#define NTREEBINS (32U) -#define SMALLBIN_SHIFT (3U) -#define SMALLBIN_WIDTH (SIZE_T_ONE << SMALLBIN_SHIFT) -#define TREEBIN_SHIFT (8U) -#define MIN_LARGE_SIZE (SIZE_T_ONE << TREEBIN_SHIFT) -#define MAX_SMALL_SIZE (MIN_LARGE_SIZE - SIZE_T_ONE) -#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD) - -struct malloc_state -{ - binmap_t smallmap; - binmap_t treemap; - size_t dvsize; - size_t topsize; - char *least_addr; - mchunkptr dv; - mchunkptr top; - size_t trim_check; - size_t magic; - mchunkptr smallbins[(NSMALLBINS + 1) * 2]; - tbinptr treebins[NTREEBINS]; - size_t footprint; - size_t max_footprint; - flag_t mflags; -#if USE_LOCKS - MLOCK_T mutex; /* locate lock among fields that rarely change */ -#endif /* USE_LOCKS */ - msegment seg; -}; - -typedef struct malloc_state *mstate; - -/* ------------- Global malloc_state and malloc_params ------------------- */ - -/* - malloc_params holds global properties, including those that can be - dynamically set using mallopt. There is a single instance, mparams, - initialized in init_mparams. -*/ - -struct malloc_params -{ - size_t magic; - size_t page_size; - size_t granularity; - size_t mmap_threshold; - size_t trim_threshold; - flag_t default_mflags; -}; - -static struct malloc_params mparams; - -/* The global malloc_state used for all non-"mspace" calls */ -static struct malloc_state _gm_; -#define gm (&_gm_) -#define is_global(M) ((M) == &_gm_) -#define is_initialized(M) ((M)->top != 0) - -/* -------------------------- system alloc setup ------------------------- */ - -/* Operations on mflags */ - -#define use_lock(M) ((M)->mflags & USE_LOCK_BIT) -#define enable_lock(M) ((M)->mflags |= USE_LOCK_BIT) -#define disable_lock(M) ((M)->mflags &= ~USE_LOCK_BIT) - -#define use_mmap(M) ((M)->mflags & USE_MMAP_BIT) -#define enable_mmap(M) ((M)->mflags |= USE_MMAP_BIT) -#define disable_mmap(M) ((M)->mflags &= ~USE_MMAP_BIT) - -#define use_noncontiguous(M) ((M)->mflags & USE_NONCONTIGUOUS_BIT) -#define disable_contiguous(M) ((M)->mflags |= USE_NONCONTIGUOUS_BIT) - -#define set_lock(M, L) \ - ((M)->mflags = (L) ? ((M)->mflags | USE_LOCK_BIT) \ - : ((M)->mflags & ~USE_LOCK_BIT)) - -/* page-align a size */ -#define page_align(S) \ - (((S) + (mparams.page_size)) & ~(mparams.page_size - SIZE_T_ONE)) - -/* granularity-align a size */ -#define granularity_align(S) \ - (((S) + (mparams.granularity)) & ~(mparams.granularity - SIZE_T_ONE)) - -#define is_page_aligned(S) \ - (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0) -#define is_granularity_aligned(S) \ - (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0) - -/* True if segment S holds address A */ -#define segment_holds(S, A) \ - ((char *)(A) >= S->base && (char *)(A) < S->base + S->size) - -/* Return segment holding given address */ -static msegmentptr segment_holding(mstate m, char *addr) -{ - msegmentptr sp = &m->seg; - for(;;) { - if(addr >= sp->base && addr < sp->base + sp->size) - return sp; - if((sp = sp->next) == 0) - return 0; - } -} - -/* Return true if segment contains a segment link */ -static int has_segment_link(mstate m, msegmentptr ss) -{ - msegmentptr sp = &m->seg; - for(;;) { - if((char *)sp >= ss->base && (char *)sp < ss->base + ss->size) - return 1; - if((sp = sp->next) == 0) - return 0; - } -} - -#ifndef MORECORE_CANNOT_TRIM -#define should_trim(M, s) ((s) > (M)->trim_check) -#else /* MORECORE_CANNOT_TRIM */ -#define should_trim(M, s) (0) -#endif /* MORECORE_CANNOT_TRIM */ - -/* - TOP_FOOT_SIZE is padding at the end of a segment, including space - that may be needed to place segment records and fenceposts when new - noncontiguous segments are added. -*/ -#define TOP_FOOT_SIZE \ - (align_offset(chunk2mem(0)) + pad_request(sizeof(struct malloc_segment)) \ - + MIN_CHUNK_SIZE) - - -/* ------------------------------- Hooks -------------------------------- */ - -/* - PREACTION should be defined to return 0 on success, and nonzero on - failure. If you are not using locking, you can redefine these to do - anything you like. -*/ - -#if USE_LOCKS - -/* Ensure locks are initialized */ -#define GLOBALLY_INITIALIZE() (mparams.page_size == 0 && init_mparams()) - -#define PREACTION(M) \ - ((GLOBALLY_INITIALIZE() || use_lock(M)) ? ACQUIRE_LOCK(&(M)->mutex) : 0) -#define POSTACTION(M) \ - { \ - if(use_lock(M)) \ - RELEASE_LOCK(&(M)->mutex); \ - } -#else /* USE_LOCKS */ - -#ifndef PREACTION -#define PREACTION(M) (0) -#endif /* PREACTION */ - -#ifndef POSTACTION -#define POSTACTION(M) -#endif /* POSTACTION */ - -#endif /* USE_LOCKS */ - -/* - CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses. - USAGE_ERROR_ACTION is triggered on detected bad frees and - reallocs. The argument p is an address that might have triggered the - fault. It is ignored by the two predefined actions, but might be - useful in custom actions that try to help diagnose errors. -*/ - -#if PROCEED_ON_ERROR - -/* A count of the number of corruption errors causing resets */ -int malloc_corruption_error_count; - -/* default corruption action */ -static void reset_on_error(mstate m); - -#define CORRUPTION_ERROR_ACTION(m) reset_on_error(m) -#define USAGE_ERROR_ACTION(m, p) - -#else /* PROCEED_ON_ERROR */ - -#ifndef CORRUPTION_ERROR_ACTION -#define CORRUPTION_ERROR_ACTION(m) ABORT -#endif /* CORRUPTION_ERROR_ACTION */ - -#ifndef USAGE_ERROR_ACTION -#define USAGE_ERROR_ACTION(m, p) ABORT -#endif /* USAGE_ERROR_ACTION */ - -#endif /* PROCEED_ON_ERROR */ - -/* -------------------------- Debugging setup ---------------------------- */ - -#if !DEBUG - -#define check_free_chunk(M, P) -#define check_inuse_chunk(M, P) -#define check_malloced_chunk(M, P, N) -#define check_mmapped_chunk(M, P) -#define check_malloc_state(M) -#define check_top_chunk(M, P) - -#else /* DEBUG */ -#define check_free_chunk(M, P) do_check_free_chunk(M, P) -#define check_inuse_chunk(M, P) do_check_inuse_chunk(M, P) -#define check_top_chunk(M, P) do_check_top_chunk(M, P) -#define check_malloced_chunk(M, P, N) do_check_malloced_chunk(M, P, N) -#define check_mmapped_chunk(M, P) do_check_mmapped_chunk(M, P) -#define check_malloc_state(M) do_check_malloc_state(M) - -static void do_check_any_chunk(mstate m, mchunkptr p); -static void do_check_top_chunk(mstate m, mchunkptr p); -static void do_check_mmapped_chunk(mstate m, mchunkptr p); -static void do_check_inuse_chunk(mstate m, mchunkptr p); -static void do_check_free_chunk(mstate m, mchunkptr p); -static void do_check_malloced_chunk(mstate m, void *mem, size_t s); -static void do_check_tree(mstate m, tchunkptr t); -static void do_check_treebin(mstate m, bindex_t i); -static void do_check_smallbin(mstate m, bindex_t i); -static void do_check_malloc_state(mstate m); -static int bin_find(mstate m, mchunkptr x); -static size_t traverse_and_check(mstate m); -#endif /* DEBUG */ - -/* ---------------------------- Indexing Bins ---------------------------- */ - -#define is_small(s) (((s) >> SMALLBIN_SHIFT) < NSMALLBINS) -#define small_index(s) ((s) >> SMALLBIN_SHIFT) -#define small_index2size(i) ((i) << SMALLBIN_SHIFT) -#define MIN_SMALL_INDEX (small_index(MIN_CHUNK_SIZE)) - -/* addressing by index. See above about smallbin repositioning */ -#define smallbin_at(M, i) ((sbinptr)((char *)&((M)->smallbins[(i) << 1]))) -#define treebin_at(M, i) (&((M)->treebins[i])) - -/* assign tree index for size S to variable I */ -#if defined(__GNUC__) && defined(i386) -#define compute_tree_index(S, I) \ - { \ - size_t X = S >> TREEBIN_SHIFT; \ - if(X == 0) \ - I = 0; \ - else if(X > 0xFFFF) \ - I = NTREEBINS - 1; \ - else { \ - unsigned int K; \ - __asm__("bsrl %1,%0\n\t" : "=r"(K) : "rm"(X)); \ - I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT - 1)) & 1))); \ - } \ - } -#else /* GNUC */ -#define compute_tree_index(S, I) \ - { \ - size_t X = S >> TREEBIN_SHIFT; \ - if(X == 0) \ - I = 0; \ - else if(X > 0xFFFF) \ - I = NTREEBINS - 1; \ - else { \ - unsigned int Y = (unsigned int)X; \ - unsigned int N = ((Y - 0x100) >> 16) & 8; \ - unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4; \ - N += K; \ - N += K = (((Y <<= K) - 0x4000) >> 16) & 2; \ - K = 14 - N + ((Y <<= K) >> 15); \ - I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT - 1)) & 1)); \ - } \ - } -#endif /* GNUC */ - -/* Bit representing maximum resolved size in a treebin at i */ -#define bit_for_tree_index(i) \ - (i == NTREEBINS - 1) ? (SIZE_T_BITSIZE - 1) \ - : (((i) >> 1) + TREEBIN_SHIFT - 2) - -/* Shift placing maximum resolved bit in a treebin at i as sign bit */ -#define leftshift_for_tree_index(i) \ - ((i == NTREEBINS - 1) ? 0 \ - : ((SIZE_T_BITSIZE - SIZE_T_ONE) \ - - (((i) >> 1) + TREEBIN_SHIFT - 2))) - -/* The size of the smallest chunk held in bin with index i */ -#define minsize_for_tree_index(i) \ - ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) \ - | (((size_t)((i)&SIZE_T_ONE)) \ - << (((i) >> 1) + TREEBIN_SHIFT - 1))) - - -/* ------------------------ Operations on bin maps ----------------------- */ - -/* bit corresponding to given index */ -#define idx2bit(i) ((binmap_t)(1) << (i)) - -/* Mark/Clear bits with given index */ -#define mark_smallmap(M, i) ((M)->smallmap |= idx2bit(i)) -#define clear_smallmap(M, i) ((M)->smallmap &= ~idx2bit(i)) -#define smallmap_is_marked(M, i) ((M)->smallmap & idx2bit(i)) - -#define mark_treemap(M, i) ((M)->treemap |= idx2bit(i)) -#define clear_treemap(M, i) ((M)->treemap &= ~idx2bit(i)) -#define treemap_is_marked(M, i) ((M)->treemap & idx2bit(i)) - -/* index corresponding to given bit */ - -#if defined(__GNUC__) && defined(i386) -#define compute_bit2idx(X, I) \ - { \ - unsigned int J; \ - __asm__("bsfl %1,%0\n\t" : "=r"(J) : "rm"(X)); \ - I = (bindex_t)J; \ - } - -#else /* GNUC */ -#if USE_BUILTIN_FFS -#define compute_bit2idx(X, I) I = ffs(X) - 1 - -#else /* USE_BUILTIN_FFS */ -#define compute_bit2idx(X, I) \ - { \ - unsigned int Y = X - 1; \ - unsigned int K = Y >> (16 - 4) & 16; \ - unsigned int N = K; \ - Y >>= K; \ - N += K = Y >> (8 - 3) & 8; \ - Y >>= K; \ - N += K = Y >> (4 - 2) & 4; \ - Y >>= K; \ - N += K = Y >> (2 - 1) & 2; \ - Y >>= K; \ - N += K = Y >> (1 - 0) & 1; \ - Y >>= K; \ - I = (bindex_t)(N + Y); \ - } -#endif /* USE_BUILTIN_FFS */ -#endif /* GNUC */ - -/* isolate the least set bit of a bitmap */ -#define least_bit(x) ((x) & -(x)) - -/* mask with all bits to left of least bit of x on */ -#define left_bits(x) ((x << 1) | -(x << 1)) - -/* mask with all bits to left of or equal to least bit of x on */ -#define same_or_left_bits(x) ((x) | -(x)) - - -/* ----------------------- Runtime Check Support ------------------------- */ - -/* - For security, the main invariant is that malloc/free/etc never - writes to a static address other than malloc_state, unless static - malloc_state itself has been corrupted, which cannot occur via - malloc (because of these checks). In essence this means that we - believe all pointers, sizes, maps etc held in malloc_state, but - check all of those linked or offsetted from other embedded data - structures. These checks are interspersed with main code in a way - that tends to minimize their run-time cost. - - When FOOTERS is defined, in addition to range checking, we also - verify footer fields of inuse chunks, which can be used guarantee - that the mstate controlling malloc/free is intact. This is a - streamlined version of the approach described by William Robertson - et al in "Run-time Detection of Heap-based Overflows" LISA'03 - http://www.usenix.org/events/lisa03/tech/robertson.html The footer - of an inuse chunk holds the xor of its mstate and a random seed, - that is checked upon calls to free() and realloc(). This is - (probablistically) unguessable from outside the program, but can be - computed by any code successfully malloc'ing any chunk, so does not - itself provide protection against code that has already broken - security through some other means. Unlike Robertson et al, we - always dynamically check addresses of all offset chunks (previous, - next, etc). This turns out to be cheaper than relying on hashes. -*/ - -#if !INSECURE -/* Check if address a is at least as high as any from MORECORE or MMAP */ -#define ok_address(M, a) ((char *)(a) >= (M)->least_addr) -/* Check if address of next chunk n is higher than base chunk p */ -#define ok_next(p, n) ((char *)(p) < (char *)(n)) -/* Check if p has its cinuse bit on */ -#define ok_cinuse(p) cinuse(p) -/* Check if p has its pinuse bit on */ -#define ok_pinuse(p) pinuse(p) - -#else /* !INSECURE */ -#define ok_address(M, a) (1) -#define ok_next(b, n) (1) -#define ok_cinuse(p) (1) -#define ok_pinuse(p) (1) -#endif /* !INSECURE */ - -#if(FOOTERS && !INSECURE) -/* Check if (alleged) mstate m has expected magic field */ -#define ok_magic(M) ((M)->magic == mparams.magic) -#else /* (FOOTERS && !INSECURE) */ -#define ok_magic(M) (1) -#endif /* (FOOTERS && !INSECURE) */ - - -/* In gcc, use __builtin_expect to minimize impact of checks */ -#if !INSECURE -#if defined(__GNUC__) && __GNUC__ >= 3 -#define RTCHECK(e) __builtin_expect(e, 1) -#else /* GNUC */ -#define RTCHECK(e) (e) -#endif /* GNUC */ -#else /* !INSECURE */ -#define RTCHECK(e) (1) -#endif /* !INSECURE */ - -/* macros to set up inuse chunks with or without footers */ - -#if !FOOTERS - -#define mark_inuse_foot(M, p, s) - -/* Set cinuse bit and pinuse bit of next chunk */ -#define set_inuse(M, p, s) \ - ((p)->head = (((p)->head & PINUSE_BIT) | s | CINUSE_BIT), \ - ((mchunkptr)(((char *)(p)) + (s)))->head |= PINUSE_BIT) - -/* Set cinuse and pinuse of this chunk and pinuse of next chunk */ -#define set_inuse_and_pinuse(M, p, s) \ - ((p)->head = (s | PINUSE_BIT | CINUSE_BIT), \ - ((mchunkptr)(((char *)(p)) + (s)))->head |= PINUSE_BIT) - -/* Set size, cinuse and pinuse bit of this chunk */ -#define set_size_and_pinuse_of_inuse_chunk(M, p, s) \ - ((p)->head = (s | PINUSE_BIT | CINUSE_BIT)) - -#else /* FOOTERS */ - -/* Set foot of inuse chunk to be xor of mstate and seed */ -#define mark_inuse_foot(M, p, s) \ - (((mchunkptr)((char *)(p) + (s)))->prev_foot = \ - ((size_t)(M) ^ mparams.magic)) - -#define get_mstate_for(p) \ - ((mstate)(((mchunkptr)((char *)(p) + (chunksize(p))))->prev_foot \ - ^ mparams.magic)) - -#define set_inuse(M, p, s) \ - ((p)->head = (((p)->head & PINUSE_BIT) | s | CINUSE_BIT), \ - (((mchunkptr)(((char *)(p)) + (s)))->head |= PINUSE_BIT), \ - mark_inuse_foot(M, p, s)) - -#define set_inuse_and_pinuse(M, p, s) \ - ((p)->head = (s | PINUSE_BIT | CINUSE_BIT), \ - (((mchunkptr)(((char *)(p)) + (s)))->head |= PINUSE_BIT), \ - mark_inuse_foot(M, p, s)) - -#define set_size_and_pinuse_of_inuse_chunk(M, p, s) \ - ((p)->head = (s | PINUSE_BIT | CINUSE_BIT), mark_inuse_foot(M, p, s)) - -#endif /* !FOOTERS */ - -/* ---------------------------- setting mparams -------------------------- */ - -/* Initialize mparams */ -static int init_mparams(void) -{ - if(mparams.page_size == 0) { - size_t s; - - mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD; - mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD; -#if MORECORE_CONTIGUOUS - mparams.default_mflags = USE_LOCK_BIT | USE_MMAP_BIT; -#else /* MORECORE_CONTIGUOUS */ - mparams.default_mflags = - USE_LOCK_BIT | USE_MMAP_BIT | USE_NONCONTIGUOUS_BIT; -#endif /* MORECORE_CONTIGUOUS */ - -#if(FOOTERS && !INSECURE) - { -#if USE_DEV_RANDOM - int fd; - unsigned char buf[sizeof(size_t)]; - /* Try to use /dev/urandom, else fall back on using time */ - if((fd = open("/dev/urandom", O_RDONLY)) >= 0 - && read(fd, buf, sizeof(buf)) == sizeof(buf)) { - s = *((size_t *)buf); - close(fd); - } else -#endif /* USE_DEV_RANDOM */ - s = (size_t)(time(0) ^ (size_t)0x55555555U); - - s |= (size_t)8U; /* ensure nonzero */ - s &= ~(size_t)7U; /* improve chances of fault for bad values */ - } -#else /* (FOOTERS && !INSECURE) */ - s = (size_t)0x58585858U; -#endif /* (FOOTERS && !INSECURE) */ - ACQUIRE_MAGIC_INIT_LOCK(); - if(mparams.magic == 0) { - mparams.magic = s; - /* Set up lock for main malloc area */ - INITIAL_LOCK(&gm->mutex); - gm->mflags = mparams.default_mflags; - } - RELEASE_MAGIC_INIT_LOCK(); - -#ifndef WIN32 - mparams.page_size = malloc_getpagesize; - mparams.granularity = ((DEFAULT_GRANULARITY != 0) ? DEFAULT_GRANULARITY - : mparams.page_size); -#else /* WIN32 */ - { - SYSTEM_INFO system_info; - GetSystemInfo(&system_info); - mparams.page_size = system_info.dwPageSize; - mparams.granularity = system_info.dwAllocationGranularity; - } -#endif /* WIN32 */ - - /* Sanity-check configuration: - size_t must be unsigned and as wide as pointer type. - ints must be at least 4 bytes. - alignment must be at least 8. - Alignment, min chunk size, and page size must all be powers of 2. - */ - if((sizeof(size_t) != sizeof(char *)) || (MAX_SIZE_T < MIN_CHUNK_SIZE) - || (sizeof(int) < 4) || (MALLOC_ALIGNMENT < (size_t)8U) - || ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT - SIZE_T_ONE)) != 0) - || ((MCHUNK_SIZE & (MCHUNK_SIZE - SIZE_T_ONE)) != 0) - || ((mparams.granularity & (mparams.granularity - SIZE_T_ONE)) - != 0) - || ((mparams.page_size & (mparams.page_size - SIZE_T_ONE)) - != 0)) - ABORT; - } - return 0; -} - -/* support for mallopt */ -static int change_mparam(int param_number, int value) -{ - size_t val = (size_t)value; - init_mparams(); - switch(param_number) { - case M_TRIM_THRESHOLD: - mparams.trim_threshold = val; - return 1; - case M_GRANULARITY: - if(val >= mparams.page_size && ((val & (val - 1)) == 0)) { - mparams.granularity = val; - return 1; - } else - return 0; - case M_MMAP_THRESHOLD: - mparams.mmap_threshold = val; - return 1; - default: - return 0; - } -} - -#if DEBUG -/* ------------------------- Debugging Support --------------------------- */ - -/* Check properties of any chunk, whether free, inuse, mmapped etc */ -static void do_check_any_chunk(mstate m, mchunkptr p) -{ - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); -} - -/* Check properties of top chunk */ -static void do_check_top_chunk(mstate m, mchunkptr p) -{ - msegmentptr sp = segment_holding(m, (char *)p); - size_t sz = chunksize(p); - assert(sp != 0); - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); - assert(sz == m->topsize); - assert(sz > 0); - assert(sz == ((sp->base + sp->size) - (char *)p) - TOP_FOOT_SIZE); - assert(pinuse(p)); - assert(!next_pinuse(p)); -} - -/* Check properties of (inuse) mmapped chunks */ -static void do_check_mmapped_chunk(mstate m, mchunkptr p) -{ - size_t sz = chunksize(p); - size_t len = (sz + (p->prev_foot & ~IS_MMAPPED_BIT) + MMAP_FOOT_PAD); - assert(is_mmapped(p)); - assert(use_mmap(m)); - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); - assert(!is_small(sz)); - assert((len & (mparams.page_size - SIZE_T_ONE)) == 0); - assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD); - assert(chunk_plus_offset(p, sz + SIZE_T_SIZE)->head == 0); -} - -/* Check properties of inuse chunks */ -static void do_check_inuse_chunk(mstate m, mchunkptr p) -{ - do_check_any_chunk(m, p); - assert(cinuse(p)); - assert(next_pinuse(p)); - /* If not pinuse and not mmapped, previous chunk has OK offset */ - assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p); - if(is_mmapped(p)) - do_check_mmapped_chunk(m, p); -} - -/* Check properties of free chunks */ -static void do_check_free_chunk(mstate m, mchunkptr p) -{ - size_t sz = p->head & ~(PINUSE_BIT | CINUSE_BIT); - mchunkptr next = chunk_plus_offset(p, sz); - do_check_any_chunk(m, p); - assert(!cinuse(p)); - assert(!next_pinuse(p)); - assert(!is_mmapped(p)); - if(p != m->dv && p != m->top) { - if(sz >= MIN_CHUNK_SIZE) { - assert((sz & CHUNK_ALIGN_MASK) == 0); - assert(is_aligned(chunk2mem(p))); - assert(next->prev_foot == sz); - assert(pinuse(p)); - assert(next == m->top || cinuse(next)); - assert(p->fd->bk == p); - assert(p->bk->fd == p); - } else /* markers are always of size SIZE_T_SIZE */ - assert(sz == SIZE_T_SIZE); - } -} - -/* Check properties of malloced chunks at the point they are malloced */ -static void do_check_malloced_chunk(mstate m, void *mem, size_t s) -{ - if(mem != 0) { - mchunkptr p = mem2chunk(mem); - size_t sz = p->head & ~(PINUSE_BIT | CINUSE_BIT); - do_check_inuse_chunk(m, p); - assert((sz & CHUNK_ALIGN_MASK) == 0); - assert(sz >= MIN_CHUNK_SIZE); - assert(sz >= s); - /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */ - assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE)); - } -} - -/* Check a tree and its subtrees. */ -static void do_check_tree(mstate m, tchunkptr t) -{ - tchunkptr head = 0; - tchunkptr u = t; - bindex_t tindex = t->index; - size_t tsize = chunksize(t); - bindex_t idx; - compute_tree_index(tsize, idx); - assert(tindex == idx); - assert(tsize >= MIN_LARGE_SIZE); - assert(tsize >= minsize_for_tree_index(idx)); - assert((idx == NTREEBINS - 1) - || (tsize < minsize_for_tree_index((idx + 1)))); - - do { /* traverse through chain of same-sized nodes */ - do_check_any_chunk(m, ((mchunkptr)u)); - assert(u->index == tindex); - assert(chunksize(u) == tsize); - assert(!cinuse(u)); - assert(!next_pinuse(u)); - assert(u->fd->bk == u); - assert(u->bk->fd == u); - if(u->parent == 0) { - assert(u->child[0] == 0); - assert(u->child[1] == 0); - } else { - assert(head == 0); /* only one node on chain has parent */ - head = u; - assert(u->parent != u); - assert(u->parent->child[0] == u || u->parent->child[1] == u - || *((tbinptr *)(u->parent)) == u); - if(u->child[0] != 0) { - assert(u->child[0]->parent == u); - assert(u->child[0] != u); - do_check_tree(m, u->child[0]); - } - if(u->child[1] != 0) { - assert(u->child[1]->parent == u); - assert(u->child[1] != u); - do_check_tree(m, u->child[1]); - } - if(u->child[0] != 0 && u->child[1] != 0) { - assert(chunksize(u->child[0]) < chunksize(u->child[1])); - } - } - u = u->fd; - } while(u != t); - assert(head != 0); -} - -/* Check all the chunks in a treebin. */ -static void do_check_treebin(mstate m, bindex_t i) -{ - tbinptr *tb = treebin_at(m, i); - tchunkptr t = *tb; - int empty = (m->treemap & (1U << i)) == 0; - if(t == 0) - assert(empty); - if(!empty) - do_check_tree(m, t); -} - -/* Check all the chunks in a smallbin. */ -static void do_check_smallbin(mstate m, bindex_t i) -{ - sbinptr b = smallbin_at(m, i); - mchunkptr p = b->bk; - unsigned int empty = (m->smallmap & (1U << i)) == 0; - if(p == b) - assert(empty); - if(!empty) { - for(; p != b; p = p->bk) { - size_t size = chunksize(p); - mchunkptr q; - /* each chunk claims to be free */ - do_check_free_chunk(m, p); - /* chunk belongs in bin */ - assert(small_index(size) == i); - assert(p->bk == b || chunksize(p->bk) == chunksize(p)); - /* chunk is followed by an inuse chunk */ - q = next_chunk(p); - if(q->head != FENCEPOST_HEAD) - do_check_inuse_chunk(m, q); - } - } -} - -/* Find x in a bin. Used in other check functions. */ -static int bin_find(mstate m, mchunkptr x) -{ - size_t size = chunksize(x); - if(is_small(size)) { - bindex_t sidx = small_index(size); - sbinptr b = smallbin_at(m, sidx); - if(smallmap_is_marked(m, sidx)) { - mchunkptr p = b; - do { - if(p == x) - return 1; - } while((p = p->fd) != b); - } - } else { - bindex_t tidx; - compute_tree_index(size, tidx); - if(treemap_is_marked(m, tidx)) { - tchunkptr t = *treebin_at(m, tidx); - size_t sizebits = size << leftshift_for_tree_index(tidx); - while(t != 0 && chunksize(t) != size) { - t = t->child[(sizebits >> (SIZE_T_BITSIZE - SIZE_T_ONE)) & 1]; - sizebits <<= 1; - } - if(t != 0) { - tchunkptr u = t; - do { - if(u == (tchunkptr)x) - return 1; - } while((u = u->fd) != t); - } - } - } - return 0; -} - -/* Traverse each chunk and check it; return total */ -static size_t traverse_and_check(mstate m) -{ - size_t sum = 0; - if(is_initialized(m)) { - msegmentptr s = &m->seg; - sum += m->topsize + TOP_FOOT_SIZE; - while(s != 0) { - mchunkptr q = align_as_chunk(s->base); - mchunkptr lastq = 0; - assert(pinuse(q)); - while(segment_holds(s, q) && q != m->top - && q->head != FENCEPOST_HEAD) { - sum += chunksize(q); - if(cinuse(q)) { - assert(!bin_find(m, q)); - do_check_inuse_chunk(m, q); - } else { - assert(q == m->dv || bin_find(m, q)); - assert(lastq == 0 - || cinuse(lastq)); /* Not 2 consecutive free */ - do_check_free_chunk(m, q); - } - lastq = q; - q = next_chunk(q); - } - s = s->next; - } - } - return sum; -} - -/* Check all properties of malloc_state. */ -static void do_check_malloc_state(mstate m) -{ - bindex_t i; - size_t total; - /* check bins */ - for(i = 0; i < NSMALLBINS; ++i) - do_check_smallbin(m, i); - for(i = 0; i < NTREEBINS; ++i) - do_check_treebin(m, i); - - if(m->dvsize != 0) { /* check dv chunk */ - do_check_any_chunk(m, m->dv); - assert(m->dvsize == chunksize(m->dv)); - assert(m->dvsize >= MIN_CHUNK_SIZE); - assert(bin_find(m, m->dv) == 0); - } - - if(m->top != 0) { /* check top chunk */ - do_check_top_chunk(m, m->top); - assert(m->topsize == chunksize(m->top)); - assert(m->topsize > 0); - assert(bin_find(m, m->top) == 0); - } - - total = traverse_and_check(m); - assert(total <= m->footprint); - assert(m->footprint <= m->max_footprint); -} -#endif /* DEBUG */ - -/* ----------------------------- statistics ------------------------------ */ - -#if !NO_MALLINFO -static struct mallinfo internal_mallinfo(mstate m) -{ - struct mallinfo nm = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - if(!PREACTION(m)) { - check_malloc_state(m); - if(is_initialized(m)) { - size_t nfree = SIZE_T_ONE; /* top always free */ - size_t mfree = m->topsize + TOP_FOOT_SIZE; - size_t sum = mfree; - msegmentptr s = &m->seg; - while(s != 0) { - mchunkptr q = align_as_chunk(s->base); - while(segment_holds(s, q) && q != m->top - && q->head != FENCEPOST_HEAD) { - size_t sz = chunksize(q); - sum += sz; - if(!cinuse(q)) { - mfree += sz; - ++nfree; - } - q = next_chunk(q); - } - s = s->next; - } - - nm.arena = sum; - nm.ordblks = nfree; - nm.hblkhd = m->footprint - sum; - nm.usmblks = m->max_footprint; - nm.uordblks = m->footprint - mfree; - nm.fordblks = mfree; - nm.keepcost = m->topsize; - } - - POSTACTION(m); - } - return nm; -} -#endif /* !NO_MALLINFO */ - -static void internal_malloc_stats(mstate m) -{ - if(!PREACTION(m)) { - size_t maxfp = 0; - size_t fp = 0; - size_t used = 0; - check_malloc_state(m); - if(is_initialized(m)) { - msegmentptr s = &m->seg; - maxfp = m->max_footprint; - fp = m->footprint; - used = fp - (m->topsize + TOP_FOOT_SIZE); - - while(s != 0) { - mchunkptr q = align_as_chunk(s->base); - while(segment_holds(s, q) && q != m->top - && q->head != FENCEPOST_HEAD) { - if(!cinuse(q)) - used -= chunksize(q); - q = next_chunk(q); - } - s = s->next; - } - } - - fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp)); - fprintf(stderr, "system bytes = %10lu\n", (unsigned long)(fp)); - fprintf(stderr, "in use bytes = %10lu\n", (unsigned long)(used)); - - POSTACTION(m); - } -} - -/* ----------------------- Operations on smallbins ----------------------- */ - -/* - Various forms of linking and unlinking are defined as macros. Even - the ones for trees, which are very long but have very short typical - paths. This is ugly but reduces reliance on inlining support of - compilers. -*/ - -/* Link a free chunk into a smallbin */ -#define insert_small_chunk(M, P, S) \ - { \ - bindex_t I = small_index(S); \ - mchunkptr B = smallbin_at(M, I); \ - mchunkptr F = B; \ - assert(S >= MIN_CHUNK_SIZE); \ - if(!smallmap_is_marked(M, I)) \ - mark_smallmap(M, I); \ - else if(RTCHECK(ok_address(M, B->fd))) \ - F = B->fd; \ - else { \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - B->fd = P; \ - F->bk = P; \ - P->fd = F; \ - P->bk = B; \ - } - -/* Unlink a chunk from a smallbin */ -#define unlink_small_chunk(M, P, S) \ - { \ - mchunkptr F = P->fd; \ - mchunkptr B = P->bk; \ - bindex_t I = small_index(S); \ - assert(P != B); \ - assert(P != F); \ - assert(chunksize(P) == small_index2size(I)); \ - if(F == B) \ - clear_smallmap(M, I); \ - else if(RTCHECK((F == smallbin_at(M, I) || ok_address(M, F)) \ - && (B == smallbin_at(M, I) || ok_address(M, B)))) { \ - F->bk = B; \ - B->fd = F; \ - } else { \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - } - -/* Unlink the first chunk from a smallbin */ -#define unlink_first_small_chunk(M, B, P, I) \ - { \ - mchunkptr F = P->fd; \ - assert(P != B); \ - assert(P != F); \ - assert(chunksize(P) == small_index2size(I)); \ - if(B == F) \ - clear_smallmap(M, I); \ - else if(RTCHECK(ok_address(M, F))) { \ - B->fd = F; \ - F->bk = B; \ - } else { \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - } - -/* Replace dv node, binning the old one */ -/* Used only when dvsize known to be small */ -#define replace_dv(M, P, S) \ - { \ - size_t DVS = M->dvsize; \ - if(DVS != 0) { \ - mchunkptr DV = M->dv; \ - assert(is_small(DVS)); \ - insert_small_chunk(M, DV, DVS); \ - } \ - M->dvsize = S; \ - M->dv = P; \ - } - -/* ------------------------- Operations on trees ------------------------- */ - -/* Insert chunk into tree */ -#define insert_large_chunk(M, X, S) \ - { \ - tbinptr *H; \ - bindex_t I; \ - compute_tree_index(S, I); \ - H = treebin_at(M, I); \ - X->index = I; \ - X->child[0] = X->child[1] = 0; \ - if(!treemap_is_marked(M, I)) { \ - mark_treemap(M, I); \ - *H = X; \ - X->parent = (tchunkptr)H; \ - X->fd = X->bk = X; \ - } else { \ - tchunkptr T = *H; \ - size_t K = S << leftshift_for_tree_index(I); \ - for(;;) { \ - if(chunksize(T) != S) { \ - tchunkptr *C = \ - &(T->child[(K >> (SIZE_T_BITSIZE - SIZE_T_ONE)) \ - & 1]); \ - K <<= 1; \ - if(*C != 0) \ - T = *C; \ - else if(RTCHECK(ok_address(M, C))) { \ - *C = X; \ - X->parent = T; \ - X->fd = X->bk = X; \ - break; \ - } else { \ - CORRUPTION_ERROR_ACTION(M); \ - break; \ - } \ - } else { \ - tchunkptr F = T->fd; \ - if(RTCHECK(ok_address(M, T) && ok_address(M, F))) { \ - T->fd = F->bk = X; \ - X->fd = F; \ - X->bk = T; \ - X->parent = 0; \ - break; \ - } else { \ - CORRUPTION_ERROR_ACTION(M); \ - break; \ - } \ - } \ - } \ - } \ - } - -/* - Unlink steps: - - 1. If x is a chained node, unlink it from its same-sized fd/bk links - and choose its bk node as its replacement. - 2. If x was the last node of its size, but not a leaf node, it must - be replaced with a leaf node (not merely one with an open left or - right), to make sure that lefts and rights of descendents - correspond properly to bit masks. We use the rightmost descendent - of x. We could use any other leaf, but this is easy to locate and - tends to counteract removal of leftmosts elsewhere, and so keeps - paths shorter than minimally guaranteed. This doesn't loop much - because on average a node in a tree is near the bottom. - 3. If x is the base of a chain (i.e., has parent links) relink - x's parent and children to x's replacement (or null if none). -*/ - -#define unlink_large_chunk(M, X) \ - { \ - tchunkptr XP = X->parent; \ - tchunkptr R; \ - if(X->bk != X) { \ - tchunkptr F = X->fd; \ - R = X->bk; \ - if(RTCHECK(ok_address(M, F))) { \ - F->bk = R; \ - R->fd = F; \ - } else { \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - } else { \ - tchunkptr *RP; \ - if(((R = *(RP = &(X->child[1]))) != 0) \ - || ((R = *(RP = &(X->child[0]))) != 0)) { \ - tchunkptr *CP; \ - while((*(CP = &(R->child[1])) != 0) \ - || (*(CP = &(R->child[0])) != 0)) { \ - R = *(RP = CP); \ - } \ - if(RTCHECK(ok_address(M, RP))) \ - *RP = 0; \ - else { \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - } \ - } \ - if(XP != 0) { \ - tbinptr *H = treebin_at(M, X->index); \ - if(X == *H) { \ - if((*H = R) == 0) \ - clear_treemap(M, X->index); \ - } else if(RTCHECK(ok_address(M, XP))) { \ - if(XP->child[0] == X) \ - XP->child[0] = R; \ - else \ - XP->child[1] = R; \ - } else \ - CORRUPTION_ERROR_ACTION(M); \ - if(R != 0) { \ - if(RTCHECK(ok_address(M, R))) { \ - tchunkptr C0, C1; \ - R->parent = XP; \ - if((C0 = X->child[0]) != 0) { \ - if(RTCHECK(ok_address(M, C0))) { \ - R->child[0] = C0; \ - C0->parent = R; \ - } else \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - if((C1 = X->child[1]) != 0) { \ - if(RTCHECK(ok_address(M, C1))) { \ - R->child[1] = C1; \ - C1->parent = R; \ - } else \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - } else \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - } \ - } - -/* Relays to large vs small bin operations */ - -#define insert_chunk(M, P, S) \ - if(is_small(S)) \ - insert_small_chunk(M, P, S) else \ - { \ - tchunkptr TP = (tchunkptr)(P); \ - insert_large_chunk(M, TP, S); \ - } - -#define unlink_chunk(M, P, S) \ - if(is_small(S)) \ - unlink_small_chunk(M, P, S) else \ - { \ - tchunkptr TP = (tchunkptr)(P); \ - unlink_large_chunk(M, TP); \ - } - - -/* Relays to internal calls to malloc/free from realloc, memalign etc */ - -#if ONLY_MSPACES -#define internal_malloc(m, b) mspace_malloc(m, b) -#define internal_free(m, mem) mspace_free(m, mem); -#else /* ONLY_MSPACES */ -#if MSPACES -#define internal_malloc(m, b) (m == gm) ? dlmalloc(b) : mspace_malloc(m, b) -#define internal_free(m, mem) \ - if(m == gm) \ - dlfree(mem); \ - else \ - mspace_free(m, mem); -#else /* MSPACES */ -#define internal_malloc(m, b) dlmalloc(b) -#define internal_free(m, mem) dlfree(mem) -#endif /* MSPACES */ -#endif /* ONLY_MSPACES */ - -/* ----------------------- Direct-mmapping chunks ----------------------- */ - -/* - Directly mmapped chunks are set up with an offset to the start of - the mmapped region stored in the prev_foot field of the chunk. This - allows reconstruction of the required argument to MUNMAP when freed, - and also allows adjustment of the returned chunk to meet alignment - requirements (especially in memalign). There is also enough space - allocated to hold a fake next chunk of size SIZE_T_SIZE to maintain - the PINUSE bit so frees can be checked. -*/ - -/* Malloc using mmap */ -static void *mmap_alloc(mstate m, size_t nb) -{ - size_t mmsize = granularity_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - if(mmsize > nb) { /* Check for wrap around 0 */ - char *mm = (char *)(DIRECT_MMAP(mmsize)); - if(mm != CMFAIL) { - size_t offset = align_offset(chunk2mem(mm)); - size_t psize = mmsize - offset - MMAP_FOOT_PAD; - mchunkptr p = (mchunkptr)(mm + offset); - p->prev_foot = offset | IS_MMAPPED_BIT; - (p)->head = (psize | CINUSE_BIT); - mark_inuse_foot(m, p, psize); - chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD; - chunk_plus_offset(p, psize + SIZE_T_SIZE)->head = 0; - - if(mm < m->least_addr) - m->least_addr = mm; - if((m->footprint += mmsize) > m->max_footprint) - m->max_footprint = m->footprint; - assert(is_aligned(chunk2mem(p))); - check_mmapped_chunk(m, p); - return chunk2mem(p); - } - } - return 0; -} - -/* Realloc using mmap */ -static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb) -{ - size_t oldsize = chunksize(oldp); - if(is_small(nb)) /* Can't shrink mmap regions below small size */ - return 0; - /* Keep old chunk if big enough but not too big */ - if(oldsize >= nb + SIZE_T_SIZE - && (oldsize - nb) <= (mparams.granularity << 1)) - return oldp; - else { - size_t offset = oldp->prev_foot & ~IS_MMAPPED_BIT; - size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD; - size_t newmmsize = - granularity_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - char *cp = (char *)CALL_MREMAP( - (char *)oldp - offset, oldmmsize, newmmsize, 1); - if(cp != CMFAIL) { - mchunkptr newp = (mchunkptr)(cp + offset); - size_t psize = newmmsize - offset - MMAP_FOOT_PAD; - newp->head = (psize | CINUSE_BIT); - mark_inuse_foot(m, newp, psize); - chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD; - chunk_plus_offset(newp, psize + SIZE_T_SIZE)->head = 0; - - if(cp < m->least_addr) - m->least_addr = cp; - if((m->footprint += newmmsize - oldmmsize) > m->max_footprint) - m->max_footprint = m->footprint; - check_mmapped_chunk(m, newp); - return newp; - } - } - return 0; -} - -/* -------------------------- mspace management -------------------------- */ - -/* Initialize top chunk and its size */ -static void init_top(mstate m, mchunkptr p, size_t psize) -{ - /* Ensure alignment */ - size_t offset = align_offset(chunk2mem(p)); - p = (mchunkptr)((char *)p + offset); - psize -= offset; - - m->top = p; - m->topsize = psize; - p->head = psize | PINUSE_BIT; - /* set size of fake trailing chunk holding overhead space only once */ - chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE; - m->trim_check = mparams.trim_threshold; /* reset on each update */ -} - -/* Initialize bins for a new mstate that is otherwise zeroed out */ -static void init_bins(mstate m) -{ - /* Establish circular links for smallbins */ - bindex_t i; - for(i = 0; i < NSMALLBINS; ++i) { - sbinptr bin = smallbin_at(m, i); - bin->fd = bin->bk = bin; - } -} - -#if PROCEED_ON_ERROR - -/* default corruption action */ -static void reset_on_error(mstate m) -{ - int i; - ++malloc_corruption_error_count; - /* Reinitialize fields to forget about all memory */ - m->smallbins = m->treebins = 0; - m->dvsize = m->topsize = 0; - m->seg.base = 0; - m->seg.size = 0; - m->seg.next = 0; - m->top = m->dv = 0; - for(i = 0; i < NTREEBINS; ++i) - *treebin_at(m, i) = 0; - init_bins(m); -} -#endif /* PROCEED_ON_ERROR */ - -/* Allocate chunk and prepend remainder with chunk in successor base. */ -static void *prepend_alloc(mstate m, char *newbase, char *oldbase, size_t nb) -{ - mchunkptr p = align_as_chunk(newbase); - mchunkptr oldfirst = align_as_chunk(oldbase); - size_t psize = (char *)oldfirst - (char *)p; - mchunkptr q = chunk_plus_offset(p, nb); - size_t qsize = psize - nb; - set_size_and_pinuse_of_inuse_chunk(m, p, nb); - - assert((char *)oldfirst > (char *)q); - assert(pinuse(oldfirst)); - assert(qsize >= MIN_CHUNK_SIZE); - - /* consolidate remainder with first chunk of old base */ - if(oldfirst == m->top) { - size_t tsize = m->topsize += qsize; - m->top = q; - q->head = tsize | PINUSE_BIT; - check_top_chunk(m, q); - } else if(oldfirst == m->dv) { - size_t dsize = m->dvsize += qsize; - m->dv = q; - set_size_and_pinuse_of_free_chunk(q, dsize); - } else { - if(!cinuse(oldfirst)) { - size_t nsize = chunksize(oldfirst); - unlink_chunk(m, oldfirst, nsize); - oldfirst = chunk_plus_offset(oldfirst, nsize); - qsize += nsize; - } - set_free_with_pinuse(q, qsize, oldfirst); - insert_chunk(m, q, qsize); - check_free_chunk(m, q); - } - - check_malloced_chunk(m, chunk2mem(p), nb); - return chunk2mem(p); -} - - -/* Add a segment to hold a new noncontiguous region */ -static void add_segment(mstate m, char *tbase, size_t tsize, flag_t mmapped) -{ - /* Determine locations and sizes of segment, fenceposts, old top */ - char *old_top = (char *)m->top; - msegmentptr oldsp = segment_holding(m, old_top); - char *old_end = oldsp->base + oldsp->size; - size_t ssize = pad_request(sizeof(struct malloc_segment)); - char *rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - size_t offset = align_offset(chunk2mem(rawsp)); - char *asp = rawsp + offset; - char *csp = (asp < (old_top + MIN_CHUNK_SIZE)) ? old_top : asp; - mchunkptr sp = (mchunkptr)csp; - msegmentptr ss = (msegmentptr)(chunk2mem(sp)); - mchunkptr tnext = chunk_plus_offset(sp, ssize); - mchunkptr p = tnext; - int nfences = 0; - - /* reset top to new space */ - init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); - - /* Set up segment record */ - assert(is_aligned(ss)); - set_size_and_pinuse_of_inuse_chunk(m, sp, ssize); - *ss = m->seg; /* Push current record */ - m->seg.base = tbase; - m->seg.size = tsize; - m->seg.sflags = mmapped; - m->seg.next = ss; - - /* Insert trailing fenceposts */ - for(;;) { - mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE); - p->head = FENCEPOST_HEAD; - ++nfences; - if((char *)(&(nextp->head)) < old_end) - p = nextp; - else - break; - } - assert(nfences >= 2); - - /* Insert the rest of old top into a bin as an ordinary free chunk */ - if(csp != old_top) { - mchunkptr q = (mchunkptr)old_top; - size_t psize = csp - old_top; - mchunkptr tn = chunk_plus_offset(q, psize); - set_free_with_pinuse(q, psize, tn); - insert_chunk(m, q, psize); - } - - check_top_chunk(m, m->top); -} - -/* -------------------------- System allocation -------------------------- */ - -/* Get memory from system using MORECORE or MMAP */ -static void *sys_alloc(mstate m, size_t nb) -{ - char *tbase = CMFAIL; - size_t tsize = 0; - flag_t mmap_flag = 0; - - init_mparams(); - - /* Directly map large chunks */ - if(use_mmap(m) && nb >= mparams.mmap_threshold) { - void *mem = mmap_alloc(m, nb); - if(mem != 0) - return mem; - } - - /* - Try getting memory in any of three ways (in most-preferred to - least-preferred order): - 1. A call to MORECORE that can normally contiguously extend memory. - (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or - or main space is mmapped or a previous contiguous call failed) - 2. A call to MMAP new space (disabled if not HAVE_MMAP). - Note that under the default settings, if MORECORE is unable to - fulfill a request, and HAVE_MMAP is true, then mmap is - used as a noncontiguous system allocator. This is a useful backup - strategy for systems with holes in address spaces -- in this case - sbrk cannot contiguously expand the heap, but mmap may be able to - find space. - 3. A call to MORECORE that cannot usually contiguously extend memory. - (disabled if not HAVE_MORECORE) - */ - - if(MORECORE_CONTIGUOUS && !use_noncontiguous(m)) { - char *br = CMFAIL; - msegmentptr ss = (m->top == 0) ? 0 : segment_holding(m, (char *)m->top); - size_t asize = 0; - ACQUIRE_MORECORE_LOCK(); - - if(ss == 0) { /* First time through or recovery */ - char *base = (char *)CALL_MORECORE(0); - if(base != CMFAIL) { - asize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE); - /* Adjust to end on a page boundary */ - if(!is_page_aligned(base)) - asize += (page_align((size_t)base) - (size_t)base); - /* Can't call MORECORE if size is negative when treated as signed */ - if(asize < HALF_MAX_SIZE_T - && (br = (char *)(CALL_MORECORE(asize))) == base) { - tbase = base; - tsize = asize; - } - } - } else { - /* Subtract out existing available top space from MORECORE request. */ - asize = granularity_align( - nb - m->topsize + TOP_FOOT_SIZE + SIZE_T_ONE); - /* Use mem here only if it did continuously extend old space */ - if(asize < HALF_MAX_SIZE_T - && (br = (char *)(CALL_MORECORE(asize))) - == ss->base + ss->size) { - tbase = br; - tsize = asize; - } - } - - if(tbase == CMFAIL) { /* Cope with partial failure */ - if(br != CMFAIL) { /* Try to use/extend the space we did get */ - if(asize < HALF_MAX_SIZE_T - && asize < nb + TOP_FOOT_SIZE + SIZE_T_ONE) { - size_t esize = granularity_align( - nb + TOP_FOOT_SIZE + SIZE_T_ONE - asize); - if(esize < HALF_MAX_SIZE_T) { - char *end = (char *)CALL_MORECORE(esize); - if(end != CMFAIL) - asize += esize; - else { /* Can't use; try to release */ - CALL_MORECORE(-asize); - br = CMFAIL; - } - } - } - } - if(br != CMFAIL) { /* Use the space we did get */ - tbase = br; - tsize = asize; - } else - disable_contiguous( - m); /* Don't try contiguous path in the future */ - } - - RELEASE_MORECORE_LOCK(); - } - - if(HAVE_MMAP && tbase == CMFAIL) { /* Try MMAP */ - size_t req = nb + TOP_FOOT_SIZE + SIZE_T_ONE; - size_t rsize = granularity_align(req); - if(rsize > nb) { /* Fail if wraps around zero */ - char *mp = (char *)(CALL_MMAP(rsize)); - if(mp != CMFAIL) { - tbase = mp; - tsize = rsize; - mmap_flag = IS_MMAPPED_BIT; - } - } - } - - if(HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */ - size_t asize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE); - if(asize < HALF_MAX_SIZE_T) { - char *br = CMFAIL; - char *end = CMFAIL; - ACQUIRE_MORECORE_LOCK(); - br = (char *)(CALL_MORECORE(asize)); - end = (char *)(CALL_MORECORE(0)); - RELEASE_MORECORE_LOCK(); - if(br != CMFAIL && end != CMFAIL && br < end) { - size_t ssize = end - br; - if(ssize > nb + TOP_FOOT_SIZE) { - tbase = br; - tsize = ssize; - } - } - } - } - - if(tbase != CMFAIL) { - - if((m->footprint += tsize) > m->max_footprint) - m->max_footprint = m->footprint; - - if(!is_initialized(m)) { /* first-time initialization */ - m->seg.base = m->least_addr = tbase; - m->seg.size = tsize; - m->seg.sflags = mmap_flag; - m->magic = mparams.magic; - init_bins(m); - if(is_global(m)) - init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); - else { - /* Offset top by embedded malloc_state */ - mchunkptr mn = next_chunk(mem2chunk(m)); - init_top(m, mn, - (size_t)((tbase + tsize) - (char *)mn) - TOP_FOOT_SIZE); - } - } - - else { - /* Try to merge with an existing segment */ - msegmentptr sp = &m->seg; - while(sp != 0 && tbase != sp->base + sp->size) - sp = sp->next; - if(sp != 0 && !is_extern_segment(sp) - && (sp->sflags & IS_MMAPPED_BIT) == mmap_flag - && segment_holds(sp, m->top)) { /* append */ - sp->size += tsize; - init_top(m, m->top, m->topsize + tsize); - } else { - if(tbase < m->least_addr) - m->least_addr = tbase; - sp = &m->seg; - while(sp != 0 && sp->base != tbase + tsize) - sp = sp->next; - if(sp != 0 && !is_extern_segment(sp) - && (sp->sflags & IS_MMAPPED_BIT) == mmap_flag) { - char *oldbase = sp->base; - sp->base = tbase; - sp->size += tsize; - return prepend_alloc(m, tbase, oldbase, nb); - } else - add_segment(m, tbase, tsize, mmap_flag); - } - } - - if(nb < m->topsize) { /* Allocate from new or extended top space */ - size_t rsize = m->topsize -= nb; - mchunkptr p = m->top; - mchunkptr r = m->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; - set_size_and_pinuse_of_inuse_chunk(m, p, nb); - check_top_chunk(m, m->top); - check_malloced_chunk(m, chunk2mem(p), nb); - return chunk2mem(p); - } - } - - MALLOC_FAILURE_ACTION; - return 0; -} - -/* ----------------------- system deallocation -------------------------- */ - -/* Unmap and unlink any mmapped segments that don't contain used chunks */ -static size_t release_unused_segments(mstate m) -{ - size_t released = 0; - msegmentptr pred = &m->seg; - msegmentptr sp = pred->next; - while(sp != 0) { - char *base = sp->base; - size_t size = sp->size; - msegmentptr next = sp->next; - if(is_mmapped_segment(sp) && !is_extern_segment(sp)) { - mchunkptr p = align_as_chunk(base); - size_t psize = chunksize(p); - /* Can unmap if first chunk holds entire segment and not pinned */ - if(!cinuse(p) && (char *)p + psize >= base + size - TOP_FOOT_SIZE) { - tchunkptr tp = (tchunkptr)p; - assert(segment_holds(sp, (char *)sp)); - if(p == m->dv) { - m->dv = 0; - m->dvsize = 0; - } else { - unlink_large_chunk(m, tp); - } - if(CALL_MUNMAP(base, size) == 0) { - released += size; - m->footprint -= size; - /* unlink obsoleted record */ - sp = pred; - sp->next = next; - } else { /* back out if cannot unmap */ - insert_large_chunk(m, tp, psize); - } - } - } - pred = sp; - sp = next; - } - return released; -} - -static int sys_trim(mstate m, size_t pad) -{ - size_t released = 0; - if(pad < MAX_REQUEST && is_initialized(m)) { - pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */ - - if(m->topsize > pad) { - /* Shrink top space in granularity-size units, keeping at least one */ - size_t unit = mparams.granularity; - size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit - - SIZE_T_ONE) - * unit; - msegmentptr sp = segment_holding(m, (char *)m->top); - - if(!is_extern_segment(sp)) { - if(is_mmapped_segment(sp)) { - if(HAVE_MMAP && sp->size >= extra - && !has_segment_link( - m, sp)) { /* can't shrink if pinned */ - size_t newsize = sp->size - extra; - /* Prefer mremap, fall back to munmap */ - if((CALL_MREMAP(sp->base, sp->size, newsize, 0) - != MFAIL) - || (CALL_MUNMAP(sp->base + newsize, extra) - == 0)) { - released = extra; - } - } - } else if(HAVE_MORECORE) { - if(extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */ - extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit; - ACQUIRE_MORECORE_LOCK(); - { - /* Make sure end of memory is where we last set it. */ - char *old_br = (char *)(CALL_MORECORE(0)); - if(old_br == sp->base + sp->size) { - char *rel_br = (char *)(CALL_MORECORE(-extra)); - char *new_br = (char *)(CALL_MORECORE(0)); - if(rel_br != CMFAIL && new_br < old_br) - released = old_br - new_br; - } - } - RELEASE_MORECORE_LOCK(); - } - } - - if(released != 0) { - sp->size -= released; - m->footprint -= released; - init_top(m, m->top, m->topsize - released); - check_top_chunk(m, m->top); - } - } - - /* Unmap any unused mmapped segments */ - if(HAVE_MMAP) - released += release_unused_segments(m); - - /* On failure, disable autotrim to avoid repeated failed future calls */ - if(released == 0) - m->trim_check = MAX_SIZE_T; - } - - return (released != 0) ? 1 : 0; -} - -/* ---------------------------- malloc support --------------------------- */ - -/* allocate a large request from the best fitting chunk in a treebin */ -static void *tmalloc_large(mstate m, size_t nb) -{ - tchunkptr v = 0; - size_t rsize = -nb; /* Unsigned negation */ - tchunkptr t; - bindex_t idx; - compute_tree_index(nb, idx); - - if((t = *treebin_at(m, idx)) != 0) { - /* Traverse tree for this bin looking for node with size == nb */ - size_t sizebits = nb << leftshift_for_tree_index(idx); - tchunkptr rst = 0; /* The deepest untaken right subtree */ - for(;;) { - tchunkptr rt; - size_t trem = chunksize(t) - nb; - if(trem < rsize) { - v = t; - if((rsize = trem) == 0) - break; - } - rt = t->child[1]; - t = t->child[(sizebits >> (SIZE_T_BITSIZE - SIZE_T_ONE)) & 1]; - if(rt != 0 && rt != t) - rst = rt; - if(t == 0) { - t = rst; /* set t to least subtree holding sizes > nb */ - break; - } - sizebits <<= 1; - } - } - - if(t == 0 && v == 0) { /* set t to root of next non-empty treebin */ - binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap; - if(leftbits != 0) { - bindex_t i; - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - t = *treebin_at(m, i); - } - } - - while(t != 0) { /* find smallest of tree or subtree */ - size_t trem = chunksize(t) - nb; - if(trem < rsize) { - rsize = trem; - v = t; - } - t = leftmost_child(t); - } - - /* If dv is a better fit, return 0 so malloc will use it */ - if(v != 0 && rsize < (size_t)(m->dvsize - nb)) { - if(RTCHECK(ok_address(m, v))) { /* split */ - mchunkptr r = chunk_plus_offset(v, nb); - assert(chunksize(v) == rsize + nb); - if(RTCHECK(ok_next(v, r))) { - unlink_large_chunk(m, v); - if(rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(m, v, (rsize + nb)); - else { - set_size_and_pinuse_of_inuse_chunk(m, v, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - insert_chunk(m, r, rsize); - } - return chunk2mem(v); - } - } - CORRUPTION_ERROR_ACTION(m); - } - return 0; -} - -/* allocate a small request from the best fitting chunk in a treebin */ -static void *tmalloc_small(mstate m, size_t nb) -{ - tchunkptr t, v; - size_t rsize; - bindex_t i; - binmap_t leastbit = least_bit(m->treemap); - compute_bit2idx(leastbit, i); - - v = t = *treebin_at(m, i); - rsize = chunksize(t) - nb; - - while((t = leftmost_child(t)) != 0) { - size_t trem = chunksize(t) - nb; - if(trem < rsize) { - rsize = trem; - v = t; - } - } - - if(RTCHECK(ok_address(m, v))) { - mchunkptr r = chunk_plus_offset(v, nb); - assert(chunksize(v) == rsize + nb); - if(RTCHECK(ok_next(v, r))) { - unlink_large_chunk(m, v); - if(rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(m, v, (rsize + nb)); - else { - set_size_and_pinuse_of_inuse_chunk(m, v, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(m, r, rsize); - } - return chunk2mem(v); - } - } - - CORRUPTION_ERROR_ACTION(m); - return 0; -} - -/* --------------------------- realloc support --------------------------- */ - -static void *internal_realloc(mstate m, void *oldmem, size_t bytes) -{ - if(bytes >= MAX_REQUEST) { - MALLOC_FAILURE_ACTION; - return 0; - } - if(!PREACTION(m)) { - mchunkptr oldp = mem2chunk(oldmem); - size_t oldsize = chunksize(oldp); - mchunkptr next = chunk_plus_offset(oldp, oldsize); - mchunkptr newp = 0; - void *extra = 0; - - /* Try to either shrink or extend into top. Else malloc-copy-free */ - - if(RTCHECK(ok_address(m, oldp) && ok_cinuse(oldp) && ok_next(oldp, next) - && ok_pinuse(next))) { - size_t nb = request2size(bytes); - if(is_mmapped(oldp)) - newp = mmap_resize(m, oldp, nb); - else if(oldsize >= nb) { /* already big enough */ - size_t rsize = oldsize - nb; - newp = oldp; - if(rsize >= MIN_CHUNK_SIZE) { - mchunkptr remainder = chunk_plus_offset(newp, nb); - set_inuse(m, newp, nb); - set_inuse(m, remainder, rsize); - extra = chunk2mem(remainder); - } - } else if(next == m->top && oldsize + m->topsize > nb) { - /* Expand into top */ - size_t newsize = oldsize + m->topsize; - size_t newtopsize = newsize - nb; - mchunkptr newtop = chunk_plus_offset(oldp, nb); - set_inuse(m, oldp, nb); - newtop->head = newtopsize | PINUSE_BIT; - m->top = newtop; - m->topsize = newtopsize; - newp = oldp; - } - } else { - USAGE_ERROR_ACTION(m, oldmem); - POSTACTION(m); - return 0; - } - - POSTACTION(m); - - if(newp != 0) { - if(extra != 0) { - internal_free(m, extra); - } - check_inuse_chunk(m, newp); - return chunk2mem(newp); - } else { - void *newmem = internal_malloc(m, bytes); - if(newmem != 0) { - size_t oc = oldsize - overhead_for(oldp); - memcpy(newmem, oldmem, (oc < bytes) ? oc : bytes); - internal_free(m, oldmem); - } - return newmem; - } - } - return 0; -} - -/* --------------------------- memalign support -------------------------- */ - -static void *internal_memalign(mstate m, size_t alignment, size_t bytes) -{ - if(alignment <= MALLOC_ALIGNMENT) /* Can just use malloc */ - return internal_malloc(m, bytes); - if(alignment < MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */ - alignment = MIN_CHUNK_SIZE; - if((alignment & (alignment - SIZE_T_ONE)) != 0) { /* Ensure a power of 2 */ - size_t a = MALLOC_ALIGNMENT << 1; - while(a < alignment) - a <<= 1; - alignment = a; - } - - if(bytes >= MAX_REQUEST - alignment) { - if(m != 0) { /* Test isn't needed but avoids compiler warning */ - MALLOC_FAILURE_ACTION; - } - } else { - size_t nb = request2size(bytes); - size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD; - char *mem = (char *)internal_malloc(m, req); - if(mem != 0) { - void *leader = 0; - void *trailer = 0; - mchunkptr p = mem2chunk(mem); - - if(PREACTION(m)) - return 0; - if((((size_t)(mem)) % alignment) != 0) { /* misaligned */ - /* - Find an aligned spot inside chunk. Since we need to give - back leading space in a chunk of at least MIN_CHUNK_SIZE, if - the first calculation places us at a spot with less than - MIN_CHUNK_SIZE leader, we can move to the next aligned spot. - We've allocated enough total room so that this is always - possible. - */ - char *br = (char *)mem2chunk( - (size_t)(((size_t)(mem + alignment - SIZE_T_ONE)) - & -alignment)); - char *pos = ((size_t)(br - (char *)(p)) >= MIN_CHUNK_SIZE) - ? br - : br + alignment; - mchunkptr newp = (mchunkptr)pos; - size_t leadsize = pos - (char *)(p); - size_t newsize = chunksize(p) - leadsize; - - if(is_mmapped(p)) { /* For mmapped chunks, just adjust offset */ - newp->prev_foot = p->prev_foot + leadsize; - newp->head = (newsize | CINUSE_BIT); - } else { /* Otherwise, give back leader, use the rest */ - set_inuse(m, newp, newsize); - set_inuse(m, p, leadsize); - leader = chunk2mem(p); - } - p = newp; - } - - /* Give back spare room at the end */ - if(!is_mmapped(p)) { - size_t size = chunksize(p); - if(size > nb + MIN_CHUNK_SIZE) { - size_t remainder_size = size - nb; - mchunkptr remainder = chunk_plus_offset(p, nb); - set_inuse(m, p, nb); - set_inuse(m, remainder, remainder_size); - trailer = chunk2mem(remainder); - } - } - - assert(chunksize(p) >= nb); - assert((((size_t)(chunk2mem(p))) % alignment) == 0); - check_inuse_chunk(m, p); - POSTACTION(m); - if(leader != 0) { - internal_free(m, leader); - } - if(trailer != 0) { - internal_free(m, trailer); - } - return chunk2mem(p); - } - } - return 0; -} - -/* ------------------------ comalloc/coalloc support --------------------- */ - -static void **ialloc( - mstate m, size_t n_elements, size_t *sizes, int opts, void *chunks[]) -{ - /* - This provides common support for independent_X routines, handling - all of the combinations that can result. - - The opts arg has: - bit 0 set if all elements are same size (using sizes[0]) - bit 1 set if elements should be zeroed - */ - - size_t element_size; /* chunksize of each element, if all same */ - size_t contents_size; /* total size of elements */ - size_t array_size; /* request size of pointer array */ - void *mem; /* malloced aggregate space */ - mchunkptr p; /* corresponding chunk */ - size_t remainder_size; /* remaining bytes while splitting */ - void **marray; /* either "chunks" or malloced ptr array */ - mchunkptr array_chunk; /* chunk for malloced ptr array */ - flag_t was_enabled; /* to disable mmap */ - size_t size; - size_t i; - - /* compute array length, if needed */ - if(chunks != 0) { - if(n_elements == 0) - return chunks; /* nothing to do */ - marray = chunks; - array_size = 0; - } else { - /* if empty req, must still return chunk representing empty array */ - if(n_elements == 0) - return (void **)internal_malloc(m, 0); - marray = 0; - array_size = request2size(n_elements * (sizeof(void *))); - } - - /* compute total element size */ - if(opts & 0x1) { /* all-same-size */ - element_size = request2size(*sizes); - contents_size = n_elements * element_size; - } else { /* add up all the sizes */ - element_size = 0; - contents_size = 0; - for(i = 0; i != n_elements; ++i) - contents_size += request2size(sizes[i]); - } - - size = contents_size + array_size; - - /* - Allocate the aggregate chunk. First disable direct-mmapping so - malloc won't use it, since we would not be able to later - free/realloc space internal to a segregated mmap region. - */ - was_enabled = use_mmap(m); - disable_mmap(m); - mem = internal_malloc(m, size - CHUNK_OVERHEAD); - if(was_enabled) - enable_mmap(m); - if(mem == 0) - return 0; - - if(PREACTION(m)) - return 0; - p = mem2chunk(mem); - remainder_size = chunksize(p); - - assert(!is_mmapped(p)); - - if(opts & 0x2) { /* optionally clear the elements */ - memset((size_t *)mem, 0, remainder_size - SIZE_T_SIZE - array_size); - } - - /* If not provided, allocate the pointer array as final part of chunk */ - if(marray == 0) { - size_t array_chunk_size; - array_chunk = chunk_plus_offset(p, contents_size); - array_chunk_size = remainder_size - contents_size; - marray = (void **)(chunk2mem(array_chunk)); - set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size); - remainder_size = contents_size; - } - - /* split out elements */ - for(i = 0;; ++i) { - marray[i] = chunk2mem(p); - if(i != n_elements - 1) { - if(element_size != 0) - size = element_size; - else - size = request2size(sizes[i]); - remainder_size -= size; - set_size_and_pinuse_of_inuse_chunk(m, p, size); - p = chunk_plus_offset(p, size); - } else { /* the final element absorbs any overallocation slop */ - set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size); - break; - } - } - -#if DEBUG - if(marray != chunks) { - /* final element must have exactly exhausted chunk */ - if(element_size != 0) { - assert(remainder_size == element_size); - } else { - assert(remainder_size == request2size(sizes[i])); - } - check_inuse_chunk(m, mem2chunk(marray)); - } - for(i = 0; i != n_elements; ++i) - check_inuse_chunk(m, mem2chunk(marray[i])); - -#endif /* DEBUG */ - - POSTACTION(m); - return marray; -} - - -/* -------------------------- public routines ---------------------------- */ - -#if !ONLY_MSPACES - -void *dlmalloc(size_t bytes) -{ - /* - Basic algorithm: - If a small request (< 256 bytes minus per-chunk overhead): - 1. If one exists, use a remainderless chunk in associated smallbin. - (Remainderless means that there are too few excess bytes to - represent as a chunk.) - 2. If it is big enough, use the dv chunk, which is normally the - chunk adjacent to the one used for the most recent small request. - 3. If one exists, split the smallest available chunk in a bin, - saving remainder in dv. - 4. If it is big enough, use the top chunk. - 5. If available, get memory from system and use it - Otherwise, for a large request: - 1. Find the smallest available binned chunk that fits, and use it - if it is better fitting than dv chunk, splitting if necessary. - 2. If better fitting than any binned chunk, use the dv chunk. - 3. If it is big enough, use the top chunk. - 4. If request size >= mmap threshold, try to directly mmap this chunk. - 5. If available, get memory from system and use it - - The ugly goto's here ensure that postaction occurs along all paths. - */ - - if(!PREACTION(gm)) { - void *mem; - size_t nb; - if(bytes <= MAX_SMALL_REQUEST) { - bindex_t idx; - binmap_t smallbits; - nb = (bytes < MIN_REQUEST) ? MIN_CHUNK_SIZE : pad_request(bytes); - idx = small_index(nb); - smallbits = gm->smallmap >> idx; - - if((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ - mchunkptr b, p; - idx += ~smallbits & 1; /* Uses next bin if idx empty */ - b = smallbin_at(gm, idx); - p = b->fd; - assert(chunksize(p) == small_index2size(idx)); - unlink_first_small_chunk(gm, b, p, idx); - set_inuse_and_pinuse(gm, p, small_index2size(idx)); - mem = chunk2mem(p); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - else if(nb > gm->dvsize) { - if(smallbits != 0) { /* Use chunk in next nonempty smallbin */ - mchunkptr b, p, r; - size_t rsize; - bindex_t i; - binmap_t leftbits = - (smallbits << idx) & left_bits(idx2bit(idx)); - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - b = smallbin_at(gm, i); - p = b->fd; - assert(chunksize(p) == small_index2size(i)); - unlink_first_small_chunk(gm, b, p, i); - rsize = small_index2size(i) - nb; - /* Fit here cannot be remainderless if 4byte sizes */ - if(SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(gm, p, small_index2size(i)); - else { - set_size_and_pinuse_of_inuse_chunk(gm, p, nb); - r = chunk_plus_offset(p, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(gm, r, rsize); - } - mem = chunk2mem(p); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - else if(gm->treemap != 0 - && (mem = tmalloc_small(gm, nb)) != 0) { - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - } - } else if(bytes >= MAX_REQUEST) - nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ - else { - nb = pad_request(bytes); - if(gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) { - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - } - - if(nb <= gm->dvsize) { - size_t rsize = gm->dvsize - nb; - mchunkptr p = gm->dv; - if(rsize >= MIN_CHUNK_SIZE) { /* split dv */ - mchunkptr r = gm->dv = chunk_plus_offset(p, nb); - gm->dvsize = rsize; - set_size_and_pinuse_of_free_chunk(r, rsize); - set_size_and_pinuse_of_inuse_chunk(gm, p, nb); - } else { /* exhaust dv */ - size_t dvs = gm->dvsize; - gm->dvsize = 0; - gm->dv = 0; - set_inuse_and_pinuse(gm, p, dvs); - } - mem = chunk2mem(p); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - else if(nb < gm->topsize) { /* Split top */ - size_t rsize = gm->topsize -= nb; - mchunkptr p = gm->top; - mchunkptr r = gm->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; - set_size_and_pinuse_of_inuse_chunk(gm, p, nb); - mem = chunk2mem(p); - check_top_chunk(gm, gm->top); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - mem = sys_alloc(gm, nb); - - postaction: - POSTACTION(gm); - return mem; - } - - return 0; -} - -void dlfree(void *mem) -{ - /* - Consolidate freed chunks with preceding or succeeding bordering - free chunks, if they exist, and then place in a bin. Intermixed - with special cases for top, dv, mmapped chunks, and usage errors. - */ - - if(mem != 0) { - mchunkptr p = mem2chunk(mem); -#if FOOTERS - mstate fm = get_mstate_for(p); - if(!ok_magic(fm)) { - USAGE_ERROR_ACTION(fm, p); - return; - } -#else /* FOOTERS */ -#define fm gm -#endif /* FOOTERS */ - if(!PREACTION(fm)) { - check_inuse_chunk(fm, p); - if(RTCHECK(ok_address(fm, p) && ok_cinuse(p))) { - size_t psize = chunksize(p); - mchunkptr next = chunk_plus_offset(p, psize); - if(!pinuse(p)) { - size_t prevsize = p->prev_foot; - if((prevsize & IS_MMAPPED_BIT) != 0) { - prevsize &= ~IS_MMAPPED_BIT; - psize += prevsize + MMAP_FOOT_PAD; - if(CALL_MUNMAP((char *)p - prevsize, psize) == 0) - fm->footprint -= psize; - goto postaction; - } else { - mchunkptr prev = chunk_minus_offset(p, prevsize); - psize += prevsize; - p = prev; - if(RTCHECK(ok_address( - fm, prev))) { /* consolidate backward */ - if(p != fm->dv) { - unlink_chunk(fm, p, prevsize); - } else if((next->head & INUSE_BITS) == INUSE_BITS) { - fm->dvsize = psize; - set_free_with_pinuse(p, psize, next); - goto postaction; - } - } else - goto erroraction; - } - } - - if(RTCHECK(ok_next(p, next) && ok_pinuse(next))) { - if(!cinuse(next)) { /* consolidate forward */ - if(next == fm->top) { - size_t tsize = fm->topsize += psize; - fm->top = p; - p->head = tsize | PINUSE_BIT; - if(p == fm->dv) { - fm->dv = 0; - fm->dvsize = 0; - } - if(should_trim(fm, tsize)) - sys_trim(fm, 0); - goto postaction; - } else if(next == fm->dv) { - size_t dsize = fm->dvsize += psize; - fm->dv = p; - set_size_and_pinuse_of_free_chunk(p, dsize); - goto postaction; - } else { - size_t nsize = chunksize(next); - psize += nsize; - unlink_chunk(fm, next, nsize); - set_size_and_pinuse_of_free_chunk(p, psize); - if(p == fm->dv) { - fm->dvsize = psize; - goto postaction; - } - } - } else - set_free_with_pinuse(p, psize, next); - insert_chunk(fm, p, psize); - check_free_chunk(fm, p); - goto postaction; - } - } - erroraction: - USAGE_ERROR_ACTION(fm, p); - postaction: - POSTACTION(fm); - } - } -#if !FOOTERS -#undef fm -#endif /* FOOTERS */ -} - -void *dlcalloc(size_t n_elements, size_t elem_size) -{ - void *mem; - size_t req = 0; - if(n_elements != 0) { - req = n_elements * elem_size; - if(((n_elements | elem_size) & ~(size_t)0xffff) - && (req / n_elements != elem_size)) - req = MAX_SIZE_T; /* force downstream failure on overflow */ - } - mem = dlmalloc(req); - if(mem != 0 && calloc_must_clear(mem2chunk(mem))) - memset(mem, 0, req); - return mem; -} - -void *dlrealloc(void *oldmem, size_t bytes) -{ - if(oldmem == 0) - return dlmalloc(bytes); -#ifdef REALLOC_ZERO_BYTES_FREES - if(bytes == 0) { - dlfree(oldmem); - return 0; - } -#endif /* REALLOC_ZERO_BYTES_FREES */ - else { -#if !FOOTERS - mstate m = gm; -#else /* FOOTERS */ - mstate m = get_mstate_for(mem2chunk(oldmem)); - if(!ok_magic(m)) { - USAGE_ERROR_ACTION(m, oldmem); - return 0; - } -#endif /* FOOTERS */ - return internal_realloc(m, oldmem, bytes); - } -} - -void *dlmemalign(size_t alignment, size_t bytes) -{ - return internal_memalign(gm, alignment, bytes); -} - -void **dlindependent_calloc(size_t n_elements, size_t elem_size, void *chunks[]) -{ - size_t sz = elem_size; /* serves as 1-element array */ - return ialloc(gm, n_elements, &sz, 3, chunks); -} - -void **dlindependent_comalloc(size_t n_elements, size_t sizes[], void *chunks[]) -{ - return ialloc(gm, n_elements, sizes, 0, chunks); -} - -void *dlvalloc(size_t bytes) -{ - size_t pagesz; - init_mparams(); - pagesz = mparams.page_size; - return dlmemalign(pagesz, bytes); -} - -void *dlpvalloc(size_t bytes) -{ - size_t pagesz; - init_mparams(); - pagesz = mparams.page_size; - return dlmemalign( - pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE)); -} - -int dlmalloc_trim(size_t pad) -{ - int result = 0; - if(!PREACTION(gm)) { - result = sys_trim(gm, pad); - POSTACTION(gm); - } - return result; -} - -size_t dlmalloc_footprint(void) -{ - return gm->footprint; -} - -size_t dlmalloc_max_footprint(void) -{ - return gm->max_footprint; -} - -#if !NO_MALLINFO -struct mallinfo dlmallinfo(void) -{ - return internal_mallinfo(gm); -} -#endif /* NO_MALLINFO */ - -void dlmalloc_stats() -{ - internal_malloc_stats(gm); -} - -size_t dlmalloc_usable_size(void *mem) -{ - if(mem != 0) { - mchunkptr p = mem2chunk(mem); - if(cinuse(p)) - return chunksize(p) - overhead_for(p); - } - return 0; -} - -int dlmallopt(int param_number, int value) -{ - return change_mparam(param_number, value); -} - -#endif /* !ONLY_MSPACES */ - -/* ----------------------------- user mspaces ---------------------------- */ - -#if MSPACES - -static mstate init_user_mstate(char *tbase, size_t tsize) -{ - size_t msize = pad_request(sizeof(struct malloc_state)); - mchunkptr mn; - mchunkptr msp = align_as_chunk(tbase); - mstate m = (mstate)(chunk2mem(msp)); - memset(m, 0, msize); - INITIAL_LOCK(&m->mutex); - msp->head = (msize | PINUSE_BIT | CINUSE_BIT); - m->seg.base = m->least_addr = tbase; - m->seg.size = m->footprint = m->max_footprint = tsize; - m->magic = mparams.magic; - m->mflags = mparams.default_mflags; - disable_contiguous(m); - init_bins(m); - mn = next_chunk(mem2chunk(m)); - init_top(m, mn, (size_t)((tbase + tsize) - (char *)mn) - TOP_FOOT_SIZE); - check_top_chunk(m, m->top); - return m; -} - -mspace create_mspace(size_t capacity, int locked) -{ - mstate m = 0; - size_t msize = pad_request(sizeof(struct malloc_state)); - init_mparams(); /* Ensure pagesize etc initialized */ - - if(capacity < (size_t) - (msize + TOP_FOOT_SIZE + mparams.page_size)) { - size_t rs = ((capacity == 0) ? mparams.granularity - : (capacity + TOP_FOOT_SIZE + msize)); - size_t tsize = granularity_align(rs); - char *tbase = (char *)(CALL_MMAP(tsize)); - if(tbase != CMFAIL) { - m = init_user_mstate(tbase, tsize); - m->seg.sflags = IS_MMAPPED_BIT; - set_lock(m, locked); - } - } - return (mspace)m; -} - -mspace create_mspace_with_base(void *base, size_t capacity, int locked) -{ - mstate m = 0; - size_t msize = pad_request(sizeof(struct malloc_state)); - init_mparams(); /* Ensure pagesize etc initialized */ - - if(capacity > msize + TOP_FOOT_SIZE - && capacity < (size_t) - - (msize + TOP_FOOT_SIZE - + mparams.page_size)) { - m = init_user_mstate((char *)base, capacity); - m->seg.sflags = EXTERN_BIT; - set_lock(m, locked); - } - return (mspace)m; -} - -size_t destroy_mspace(mspace msp) -{ - size_t freed = 0; - mstate ms = (mstate)msp; - if(ok_magic(ms)) { - msegmentptr sp = &ms->seg; - while(sp != 0) { - char *base = sp->base; - size_t size = sp->size; - flag_t flag = sp->sflags; - sp = sp->next; - if((flag & IS_MMAPPED_BIT) && !(flag & EXTERN_BIT) - && CALL_MUNMAP(base, size) == 0) - freed += size; - } - } else { - USAGE_ERROR_ACTION(ms, ms); - } - return freed; -} - -/* - mspace versions of routines are near-clones of the global - versions. This is not so nice but better than the alternatives. -*/ - - -void *mspace_malloc(mspace msp, size_t bytes) -{ - mstate ms = (mstate)msp; - if(!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms, ms); - return 0; - } - if(!PREACTION(ms)) { - void *mem; - size_t nb; - if(bytes <= MAX_SMALL_REQUEST) { - bindex_t idx; - binmap_t smallbits; - nb = (bytes < MIN_REQUEST) ? MIN_CHUNK_SIZE : pad_request(bytes); - idx = small_index(nb); - smallbits = ms->smallmap >> idx; - - if((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ - mchunkptr b, p; - idx += ~smallbits & 1; /* Uses next bin if idx empty */ - b = smallbin_at(ms, idx); - p = b->fd; - assert(chunksize(p) == small_index2size(idx)); - unlink_first_small_chunk(ms, b, p, idx); - set_inuse_and_pinuse(ms, p, small_index2size(idx)); - mem = chunk2mem(p); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - else if(nb > ms->dvsize) { - if(smallbits != 0) { /* Use chunk in next nonempty smallbin */ - mchunkptr b, p, r; - size_t rsize; - bindex_t i; - binmap_t leftbits = - (smallbits << idx) & left_bits(idx2bit(idx)); - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - b = smallbin_at(ms, i); - p = b->fd; - assert(chunksize(p) == small_index2size(i)); - unlink_first_small_chunk(ms, b, p, i); - rsize = small_index2size(i) - nb; - /* Fit here cannot be remainderless if 4byte sizes */ - if(SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(ms, p, small_index2size(i)); - else { - set_size_and_pinuse_of_inuse_chunk(ms, p, nb); - r = chunk_plus_offset(p, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(ms, r, rsize); - } - mem = chunk2mem(p); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - else if(ms->treemap != 0 - && (mem = tmalloc_small(ms, nb)) != 0) { - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - } - } else if(bytes >= MAX_REQUEST) - nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ - else { - nb = pad_request(bytes); - if(ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) { - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - } - - if(nb <= ms->dvsize) { - size_t rsize = ms->dvsize - nb; - mchunkptr p = ms->dv; - if(rsize >= MIN_CHUNK_SIZE) { /* split dv */ - mchunkptr r = ms->dv = chunk_plus_offset(p, nb); - ms->dvsize = rsize; - set_size_and_pinuse_of_free_chunk(r, rsize); - set_size_and_pinuse_of_inuse_chunk(ms, p, nb); - } else { /* exhaust dv */ - size_t dvs = ms->dvsize; - ms->dvsize = 0; - ms->dv = 0; - set_inuse_and_pinuse(ms, p, dvs); - } - mem = chunk2mem(p); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - else if(nb < ms->topsize) { /* Split top */ - size_t rsize = ms->topsize -= nb; - mchunkptr p = ms->top; - mchunkptr r = ms->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; - set_size_and_pinuse_of_inuse_chunk(ms, p, nb); - mem = chunk2mem(p); - check_top_chunk(ms, ms->top); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - /* mem = sys_alloc(ms, nb); */ - mem = 0; - - postaction: - POSTACTION(ms); - return mem; - } - - return 0; -} - -void mspace_free(mspace msp, void *mem) -{ - if(mem != 0) { - mchunkptr p = mem2chunk(mem); -#if FOOTERS - mstate fm = get_mstate_for(p); -#else /* FOOTERS */ - mstate fm = (mstate)msp; -#endif /* FOOTERS */ - if(!ok_magic(fm)) { - USAGE_ERROR_ACTION(fm, p); - return; - } - if(!PREACTION(fm)) { - check_inuse_chunk(fm, p); - if(RTCHECK(ok_address(fm, p) && ok_cinuse(p))) { - size_t psize = chunksize(p); - mchunkptr next = chunk_plus_offset(p, psize); - if(!pinuse(p)) { - size_t prevsize = p->prev_foot; - if((prevsize & IS_MMAPPED_BIT) != 0) { - prevsize &= ~IS_MMAPPED_BIT; - psize += prevsize + MMAP_FOOT_PAD; - if(CALL_MUNMAP((char *)p - prevsize, psize) == 0) - fm->footprint -= psize; - goto postaction; - } else { - mchunkptr prev = chunk_minus_offset(p, prevsize); - psize += prevsize; - p = prev; - if(RTCHECK(ok_address( - fm, prev))) { /* consolidate backward */ - if(p != fm->dv) { - unlink_chunk(fm, p, prevsize); - } else if((next->head & INUSE_BITS) == INUSE_BITS) { - fm->dvsize = psize; - set_free_with_pinuse(p, psize, next); - goto postaction; - } - } else - goto erroraction; - } - } - - if(RTCHECK(ok_next(p, next) && ok_pinuse(next))) { - if(!cinuse(next)) { /* consolidate forward */ - if(next == fm->top) { - size_t tsize = fm->topsize += psize; - fm->top = p; - p->head = tsize | PINUSE_BIT; - if(p == fm->dv) { - fm->dv = 0; - fm->dvsize = 0; - } - if(should_trim(fm, tsize)) - sys_trim(fm, 0); - goto postaction; - } else if(next == fm->dv) { - size_t dsize = fm->dvsize += psize; - fm->dv = p; - set_size_and_pinuse_of_free_chunk(p, dsize); - goto postaction; - } else { - size_t nsize = chunksize(next); - psize += nsize; - unlink_chunk(fm, next, nsize); - set_size_and_pinuse_of_free_chunk(p, psize); - if(p == fm->dv) { - fm->dvsize = psize; - goto postaction; - } - } - } else - set_free_with_pinuse(p, psize, next); - insert_chunk(fm, p, psize); - check_free_chunk(fm, p); - goto postaction; - } - } - erroraction: - USAGE_ERROR_ACTION(fm, p); - postaction: - POSTACTION(fm); - } - } -} - -void *mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) -{ - void *mem; - size_t req = 0; - mstate ms = (mstate)msp; - if(!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms, ms); - return 0; - } - if(n_elements != 0) { - req = n_elements * elem_size; - if(((n_elements | elem_size) & ~(size_t)0xffff) - && (req / n_elements != elem_size)) - req = MAX_SIZE_T; /* force downstream failure on overflow */ - } - mem = internal_malloc(ms, req); - if(mem != 0 && calloc_must_clear(mem2chunk(mem))) - memset(mem, 0, req); - return mem; -} - -void *mspace_realloc(mspace msp, void *oldmem, size_t bytes) -{ - if(oldmem == 0) - return mspace_malloc(msp, bytes); -#ifdef REALLOC_ZERO_BYTES_FREES - if(bytes == 0) { - mspace_free(msp, oldmem); - return 0; - } -#endif /* REALLOC_ZERO_BYTES_FREES */ - else { -#if FOOTERS - mchunkptr p = mem2chunk(oldmem); - mstate ms = get_mstate_for(p); -#else /* FOOTERS */ - mstate ms = (mstate)msp; -#endif /* FOOTERS */ - if(!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms, ms); - return 0; - } - return internal_realloc(ms, oldmem, bytes); - } -} - -void *mspace_memalign(mspace msp, size_t alignment, size_t bytes) -{ - mstate ms = (mstate)msp; - if(!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms, ms); - return 0; - } - return internal_memalign(ms, alignment, bytes); -} - -void **mspace_independent_calloc( - mspace msp, size_t n_elements, size_t elem_size, void *chunks[]) -{ - size_t sz = elem_size; /* serves as 1-element array */ - mstate ms = (mstate)msp; - if(!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms, ms); - return 0; - } - return ialloc(ms, n_elements, &sz, 3, chunks); -} - -void **mspace_independent_comalloc( - mspace msp, size_t n_elements, size_t sizes[], void *chunks[]) -{ - mstate ms = (mstate)msp; - if(!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms, ms); - return 0; - } - return ialloc(ms, n_elements, sizes, 0, chunks); -} - -int mspace_trim(mspace msp, size_t pad) -{ - int result = 0; - mstate ms = (mstate)msp; - if(ok_magic(ms)) { - if(!PREACTION(ms)) { - result = sys_trim(ms, pad); - POSTACTION(ms); - } - } else { - USAGE_ERROR_ACTION(ms, ms); - } - return result; -} - -void mspace_malloc_stats(mspace msp) -{ - mstate ms = (mstate)msp; - if(ok_magic(ms)) { - internal_malloc_stats(ms); - } else { - USAGE_ERROR_ACTION(ms, ms); - } -} - -size_t mspace_footprint(mspace msp) -{ - size_t result; - mstate ms = (mstate)msp; - if(ok_magic(ms)) { - result = ms->footprint; - } - USAGE_ERROR_ACTION(ms, ms); - return result; -} - - -size_t mspace_max_footprint(mspace msp) -{ - size_t result; - mstate ms = (mstate)msp; - if(ok_magic(ms)) { - result = ms->max_footprint; - } - USAGE_ERROR_ACTION(ms, ms); - return result; -} - - -#if !NO_MALLINFO -struct mallinfo mspace_mallinfo(mspace msp) -{ - mstate ms = (mstate)msp; - if(!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms, ms); - } - return internal_mallinfo(ms); -} -#endif /* NO_MALLINFO */ - -int mspace_mallopt(int param_number, int value) -{ - return change_mparam(param_number, value); -} - -#endif /* MSPACES */ - -/* -------------------- Alternative MORECORE functions ------------------- */ - -/* - Guidelines for creating a custom version of MORECORE: - - * For best performance, MORECORE should allocate in multiples of pagesize. - * MORECORE may allocate more memory than requested. (Or even less, - but this will usually result in a malloc failure.) - * MORECORE must not allocate memory when given argument zero, but - instead return one past the end address of memory from previous - nonzero call. - * For best performance, consecutive calls to MORECORE with positive - arguments should return increasing addresses, indicating that - space has been contiguously extended. - * Even though consecutive calls to MORECORE need not return contiguous - addresses, it must be OK for malloc'ed chunks to span multiple - regions in those cases where they do happen to be contiguous. - * MORECORE need not handle negative arguments -- it may instead - just return MFAIL when given negative arguments. - Negative arguments are always multiples of pagesize. MORECORE - must not misinterpret negative args as large positive unsigned - args. You can suppress all such calls from even occurring by defining - MORECORE_CANNOT_TRIM, - - As an example alternative MORECORE, here is a custom allocator - kindly contributed for pre-OSX macOS. It uses virtually but not - necessarily physically contiguous non-paged memory (locked in, - present and won't get swapped out). You can use it by uncommenting - this section, adding some #includes, and setting up the appropriate - defines above: - - #define MORECORE osMoreCore - - There is also a shutdown routine that should somehow be called for - cleanup upon program exit. - - #define MAX_POOL_ENTRIES 100 - #define MINIMUM_MORECORE_SIZE (64 * 1024U) - static int next_os_pool; - void *our_os_pools[MAX_POOL_ENTRIES]; - - void *osMoreCore(int size) - { - void *ptr = 0; - static void *sbrk_top = 0; - - if (size > 0) - { - if (size < MINIMUM_MORECORE_SIZE) - size = MINIMUM_MORECORE_SIZE; - if (CurrentExecutionLevel() == kTaskLevel) - ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0); - if (ptr == 0) - { - return (void *) MFAIL; - } - // save ptrs so they can be freed during cleanup - our_os_pools[next_os_pool] = ptr; - next_os_pool++; - ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK); - sbrk_top = (char *) ptr + size; - return ptr; - } - else if (size < 0) - { - // we don't currently support shrink behavior - return (void *) MFAIL; - } - else - { - return sbrk_top; - } - } - - // cleanup any allocated memory pools - // called as last thing before shutting down driver - - void osCleanupMem(void) - { - void **ptr; - - for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++) - if (*ptr) - { - PoolDeallocate(*ptr); - *ptr = 0; - } - } - -*/ - - -/* ----------------------------------------------------------------------- -History: - V2.8.3 Thu Sep 22 11:16:32 2005 Doug Lea (dl at gee) - * Add max_footprint functions - * Ensure all appropriate literals are size_t - * Fix conditional compilation problem for some #define settings - * Avoid concatenating segments with the one provided - in create_mspace_with_base - * Rename some variables to avoid compiler shadowing warnings - * Use explicit lock initialization. - * Better handling of sbrk interference. - * Simplify and fix segment insertion, trimming and mspace_destroy - * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x - * Thanks especially to Dennis Flanagan for help on these. - - V2.8.2 Sun Jun 12 16:01:10 2005 Doug Lea (dl at gee) - * Fix memalign brace error. - - V2.8.1 Wed Jun 8 16:11:46 2005 Doug Lea (dl at gee) - * Fix improper #endif nesting in C++ - * Add explicit casts needed for C++ - - V2.8.0 Mon May 30 14:09:02 2005 Doug Lea (dl at gee) - * Use trees for large bins - * Support mspaces - * Use segments to unify sbrk-based and mmap-based system allocation, - removing need for emulation on most platforms without sbrk. - * Default safety checks - * Optional footer checks. Thanks to William Robertson for the idea. - * Internal code refactoring - * Incorporate suggestions and platform-specific changes. - Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas, - Aaron Bachmann, Emery Berger, and others. - * Speed up non-fastbin processing enough to remove fastbins. - * Remove useless cfree() to avoid conflicts with other apps. - * Remove internal memcpy, memset. Compilers handle builtins better. - * Remove some options that no one ever used and rename others. - - V2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) - * Fix malloc_state bitmap array misdeclaration - - V2.7.1 Thu Jul 25 10:58:03 2002 Doug Lea (dl at gee) - * Allow tuning of FIRST_SORTED_BIN_SIZE - * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte. - * Better detection and support for non-contiguousness of MORECORE. - Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger - * Bypass most of malloc if no frees. Thanks To Emery Berger. - * Fix freeing of old top non-contiguous chunk im sysmalloc. - * Raised default trim and map thresholds to 256K. - * Fix mmap-related #defines. Thanks to Lubos Lunak. - * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield. - * Branch-free bin calculation - * Default trim and mmap thresholds now 256K. - - V2.7.0 Sun Mar 11 14:14:06 2001 Doug Lea (dl at gee) - * Introduce independent_comalloc and independent_calloc. - Thanks to Michael Pachos for motivation and help. - * Make optional .h file available - * Allow > 2GB requests on 32bit systems. - * new WIN32 sbrk, mmap, munmap, lock code from . - Thanks also to Andreas Mueller , - and Anonymous. - * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for - helping test this.) - * memalign: check alignment arg - * realloc: don't try to shift chunks backwards, since this - leads to more fragmentation in some programs and doesn't - seem to help in any others. - * Collect all cases in malloc requiring system memory into sysmalloc - * Use mmap as backup to sbrk - * Place all internal state in malloc_state - * Introduce fastbins (although similar to 2.5.1) - * Many minor tunings and cosmetic improvements - * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK - * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS - Thanks to Tony E. Bennett and others. - * Include errno.h to support default failure action. - - V2.6.6 Sun Dec 5 07:42:19 1999 Doug Lea (dl at gee) - * return null for negative arguments - * Added Several WIN32 cleanups from Martin C. Fong - * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h' - (e.g. WIN32 platforms) - * Cleanup header file inclusion for WIN32 platforms - * Cleanup code to avoid Microsoft Visual C++ compiler complaints - * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing - memory allocation routines - * Set 'malloc_getpagesize' for WIN32 platforms (needs more work) - * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to - usage of 'assert' in non-WIN32 code - * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to - avoid infinite loop - * Always call 'fREe()' rather than 'free()' - - V2.6.5 Wed Jun 17 15:57:31 1998 Doug Lea (dl at gee) - * Fixed ordering problem with boundary-stamping - - V2.6.3 Sun May 19 08:17:58 1996 Doug Lea (dl at gee) - * Added pvalloc, as recommended by H.J. Liu - * Added 64bit pointer support mainly from Wolfram Gloger - * Added anonymously donated WIN32 sbrk emulation - * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen - * malloc_extend_top: fix mask error that caused wastage after - foreign sbrks - * Add linux mremap support code from HJ Liu - - V2.6.2 Tue Dec 5 06:52:55 1995 Doug Lea (dl at gee) - * Integrated most documentation with the code. - * Add support for mmap, with help from - Wolfram Gloger (Gloger@lrz.uni-muenchen.de). - * Use last_remainder in more cases. - * Pack bins using idea from colin@nyx10.cs.du.edu - * Use ordered bins instead of best-fit threshhold - * Eliminate block-local decls to simplify tracing and debugging. - * Support another case of realloc via move into top - * Fix error occurring when initial sbrk_base not word-aligned. - * Rely on page size for units instead of SBRK_UNIT to - avoid surprises about sbrk alignment conventions. - * Add mallinfo, mallopt. Thanks to Raymond Nijssen - (raymond@es.ele.tue.nl) for the suggestion. - * Add `pad' argument to malloc_trim and top_pad mallopt parameter. - * More precautions for cases where other routines call sbrk, - courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de). - * Added macros etc., allowing use in linux libc from - H.J. Lu (hjl@gnu.ai.mit.edu) - * Inverted this history list - - V2.6.1 Sat Dec 2 14:10:57 1995 Doug Lea (dl at gee) - * Re-tuned and fixed to behave more nicely with V2.6.0 changes. - * Removed all preallocation code since under current scheme - the work required to undo bad preallocations exceeds - the work saved in good cases for most test programs. - * No longer use return list or unconsolidated bins since - no scheme using them consistently outperforms those that don't - given above changes. - * Use best fit for very large chunks to prevent some worst-cases. - * Added some support for debugging - - V2.6.0 Sat Nov 4 07:05:23 1995 Doug Lea (dl at gee) - * Removed footers when chunks are in use. Thanks to - Paul Wilson (wilson@cs.texas.edu) for the suggestion. - - V2.5.4 Wed Nov 1 07:54:51 1995 Doug Lea (dl at gee) - * Added malloc_trim, with help from Wolfram Gloger - (wmglo@Dent.MED.Uni-Muenchen.DE). - - V2.5.3 Tue Apr 26 10:16:01 1994 Doug Lea (dl at g) - - V2.5.2 Tue Apr 5 16:20:40 1994 Doug Lea (dl at g) - * realloc: try to expand in both directions - * malloc: swap order of clean-bin strategy; - * realloc: only conditionally expand backwards - * Try not to scavenge used bins - * Use bin counts as a guide to preallocation - * Occasionally bin return list chunks in first scan - * Add a few optimizations from colin@nyx10.cs.du.edu - - V2.5.1 Sat Aug 14 15:40:43 1993 Doug Lea (dl at g) - * faster bin computation & slightly different binning - * merged all consolidations to one part of malloc proper - (eliminating old malloc_find_space & malloc_clean_bin) - * Scan 2 returns chunks (not just 1) - * Propagate failure in realloc if malloc returns 0 - * Add stuff to allow compilation on non-ANSI compilers - from kpv@research.att.com - - V2.5 Sat Aug 7 07:41:59 1993 Doug Lea (dl at g.oswego.edu) - * removed potential for odd address access in prev_chunk - * removed dependency on getpagesize.h - * misc cosmetics and a bit more internal documentation - * anticosmetics: mangled names in macros to evade debugger strangeness - * tested on sparc, hp-700, dec-mips, rs6000 - with gcc & native cc (hp, dec only) allowing - Detlefs & Zorn comparison study (in SIGPLAN Notices.) - - Trial version Fri Aug 28 13:14:29 1992 Doug Lea (dl at g.oswego.edu) - * Based loosely on libg++-1.2X malloc. (It retains some of the overall - structure of old version, but most details differ.) - -*/ - -void mspace_info(mspace ms, struct mem_info *info) -{ - struct mallinfo mi; - - mi = mspace_mallinfo(ms); - memset(info, 0, sizeof(*info)); - info->total_size = mi.uordblks + mi.fordblks; - info->min_frag = 0; - info->free = mi.fordblks; - info->used = mi.uordblks; - info->real_used = mi.uordblks; - info->max_used = 0; - info->total_frags = 0; -} - - -#endif /* DL_MALLOC */ diff --git a/src/core/mem/dl_malloc.h b/src/core/mem/dl_malloc.h deleted file mode 100644 index f9ff86931..000000000 --- a/src/core/mem/dl_malloc.h +++ /dev/null @@ -1,536 +0,0 @@ -/* - Default header file for malloc-2.8.x, written by Doug Lea - and released to the public domain, as explained at - http://creativecommons.org/licenses/publicdomain. - - last update: Mon Aug 15 08:55:52 2005 Doug Lea (dl at gee) - - This header is for ANSI C/C++ only. You can set any of - the following #defines before including: - - * If USE_DL_PREFIX is defined, it is assumed that malloc.c - was also compiled with this option, so all routines - have names starting with "dl". - - * If HAVE_USR_INCLUDE_MALLOC_H is defined, it is assumed that this - file will be #included AFTER . This is needed only if - your system defines a struct mallinfo that is incompatible with the - standard one declared here. Otherwise, you can include this file - INSTEAD of your system system . At least on ANSI, all - declarations should be compatible with system versions - - * If MSPACES is defined, declarations for mspace versions are included. -*/ - -#ifndef MALLOC_280_H -#define MALLOC_280_H - -#include "dl_config.h" -#include "meminfo.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include /* for size_t */ - -#if !ONLY_MSPACES - -#ifndef USE_DL_PREFIX -#define dlcalloc calloc -#define dlfree free -#define dlmalloc malloc -#define dlmemalign memalign -#define dlrealloc realloc -#define dlvalloc valloc -#define dlpvalloc pvalloc -#define dlmallinfo mallinfo -#define dlmallopt mallopt -#define dlmalloc_trim malloc_trim -#define dlmalloc_stats malloc_stats -#define dlmalloc_usable_size malloc_usable_size -#define dlmalloc_footprint malloc_footprint -#define dlindependent_calloc independent_calloc -#define dlindependent_comalloc independent_comalloc -#endif /* USE_DL_PREFIX */ - - - /* - malloc(size_t n) - Returns a pointer to a newly allocated chunk of at least n bytes, or - null if no space is available, in which case errno is set to ENOMEM - on ANSI C systems. - - If n is zero, malloc returns a minimum-sized chunk. (The minimum - size is 16 bytes on most 32bit systems, and 32 bytes on 64bit - systems.) Note that size_t is an unsigned type, so calls with - arguments that would be negative if signed are interpreted as - requests for huge amounts of space, which will often fail. The - maximum supported value of n differs across systems, but is in all - cases less than the maximum representable value of a size_t. -*/ - void *dlmalloc(size_t); - - /* - free(void* p) - Releases the chunk of memory pointed to by p, that had been previously - allocated using malloc or a related routine such as realloc. - It has no effect if p is null. If p was not malloced or already - freed, free(p) will by default cuase the current program to abort. -*/ - void dlfree(void *); - - /* - calloc(size_t n_elements, size_t element_size); - Returns a pointer to n_elements * element_size bytes, with all locations - set to zero. -*/ - void *dlcalloc(size_t, size_t); - - /* - realloc(void* p, size_t n) - Returns a pointer to a chunk of size n that contains the same data - as does chunk p up to the minimum of (n, p's size) bytes, or null - if no space is available. - - The returned pointer may or may not be the same as p. The algorithm - prefers extending p in most cases when possible, otherwise it - employs the equivalent of a malloc-copy-free sequence. - - If p is null, realloc is equivalent to malloc. - - If space is not available, realloc returns null, errno is set (if on - ANSI) and p is NOT freed. - - if n is for fewer bytes than already held by p, the newly unused - space is lopped off and freed if possible. realloc with a size - argument of zero (re)allocates a minimum-sized chunk. - - The old unix realloc convention of allowing the last-free'd chunk - to be used as an argument to realloc is not supported. -*/ - - void *dlrealloc(void *, size_t); - - /* - memalign(size_t alignment, size_t n); - Returns a pointer to a newly allocated chunk of n bytes, aligned - in accord with the alignment argument. - - The alignment argument should be a power of two. If the argument is - not a power of two, the nearest greater power is used. - 8-byte alignment is guaranteed by normal malloc calls, so don't - bother calling memalign with an argument of 8 or less. - - Overreliance on memalign is a sure way to fragment space. -*/ - void *dlmemalign(size_t, size_t); - - /* - valloc(size_t n); - Equivalent to memalign(pagesize, n), where pagesize is the page - size of the system. If the pagesize is unknown, 4096 is used. -*/ - void *dlvalloc(size_t); - - /* - mallopt(int parameter_number, int parameter_value) - Sets tunable parameters The format is to provide a - (parameter-number, parameter-value) pair. mallopt then sets the - corresponding parameter to the argument value if it can (i.e., so - long as the value is meaningful), and returns 1 if successful else - 0. SVID/XPG/ANSI defines four standard param numbers for mallopt, - normally defined in malloc.h. None of these are use in this malloc, - so setting them has no effect. But this malloc also supports other - options in mallopt: - - Symbol param # default allowed param values - M_TRIM_THRESHOLD -1 2*1024*1024 any (-1U disables trimming) - M_GRANULARITY -2 page size any power of 2 >= page size - M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) -*/ - int dlmallopt(int, int); - -#define M_TRIM_THRESHOLD (-1) -#define M_GRANULARITY (-2) -#define M_MMAP_THRESHOLD (-3) - - - /* - malloc_footprint(); - Returns the number of bytes obtained from the system. The total - number of bytes allocated by malloc, realloc etc., is less than this - value. Unlike mallinfo, this function returns only a precomputed - result, so can be called frequently to monitor memory consumption. - Even if locks are otherwise defined, this function does not use them, - so results might not be up to date. -*/ - size_t dlmalloc_footprint(); - -#if !NO_MALLINFO -/* - mallinfo() - Returns (by copy) a struct containing various summary statistics: - - arena: current total non-mmapped bytes allocated from system - ordblks: the number of free chunks - smblks: always zero. - hblks: current number of mmapped regions - hblkhd: total bytes held in mmapped regions - usmblks: the maximum total allocated space. This will be greater - than current total if trimming has occurred. - fsmblks: always zero - uordblks: current total allocated space (normal or mmapped) - fordblks: total free space - keepcost: the maximum number of bytes that could ideally be released - back to system via malloc_trim. ("ideally" means that - it ignores page restrictions etc.) - - Because these fields are ints, but internal bookkeeping may - be kept as longs, the reported values may wrap around zero and - thus be inaccurate. -*/ -#ifndef HAVE_USR_INCLUDE_MALLOC_H -#ifndef _MALLOC_H -#ifndef MALLINFO_FIELD_TYPE -#define MALLINFO_FIELD_TYPE size_t -#endif /* MALLINFO_FIELD_TYPE */ - struct mallinfo - { - MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ - MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ - MALLINFO_FIELD_TYPE smblks; /* always 0 */ - MALLINFO_FIELD_TYPE hblks; /* always 0 */ - MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ - MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ - MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ - MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ - MALLINFO_FIELD_TYPE fordblks; /* total free space */ - MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ - }; -#endif /* _MALLOC_H */ -#endif /* HAVE_USR_INCLUDE_MALLOC_H */ - - struct mallinfo dlmallinfo(void); -#endif /* NO_MALLINFO */ - - /* - independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); - - independent_calloc is similar to calloc, but instead of returning a - single cleared space, it returns an array of pointers to n_elements - independent elements that can hold contents of size elem_size, each - of which starts out cleared, and can be independently freed, - realloc'ed etc. The elements are guaranteed to be adjacently - allocated (this is not guaranteed to occur with multiple callocs or - mallocs), which may also improve cache locality in some - applications. - - The "chunks" argument is optional (i.e., may be null, which is - probably the most typical usage). If it is null, the returned array - is itself dynamically allocated and should also be freed when it is - no longer needed. Otherwise, the chunks array must be of at least - n_elements in length. It is filled in with the pointers to the - chunks. - - In either case, independent_calloc returns this pointer array, or - null if the allocation failed. If n_elements is zero and "chunks" - is null, it returns a chunk representing an array with zero elements - (which should be freed if not wanted). - - Each element must be individually freed when it is no longer - needed. If you'd like to instead be able to free all at once, you - should instead use regular calloc and assign pointers into this - space to represent elements. (In this case though, you cannot - independently free elements.) - - independent_calloc simplifies and speeds up implementations of many - kinds of pools. It may also be useful when constructing large data - structures that initially have a fixed number of fixed-sized nodes, - but the number is not known at compile time, and some of the nodes - may later need to be freed. For example: - - struct Node { int item; struct Node* next; }; - - struct Node* build_list() { - struct Node** pool; - int n = read_number_of_nodes_needed(); - if (n <= 0) return 0; - pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); - if (pool == 0) die(); - // organize into a linked list... - struct Node* first = pool[0]; - for (i = 0; i < n-1; ++i) - pool[i]->next = pool[i+1]; - free(pool); // Can now free the array (or not, if it is needed later) - return first; - } -*/ - void **dlindependent_calloc(size_t, size_t, void **); - - /* - independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); - - independent_comalloc allocates, all at once, a set of n_elements - chunks with sizes indicated in the "sizes" array. It returns - an array of pointers to these elements, each of which can be - independently freed, realloc'ed etc. The elements are guaranteed to - be adjacently allocated (this is not guaranteed to occur with - multiple callocs or mallocs), which may also improve cache locality - in some applications. - - The "chunks" argument is optional (i.e., may be null). If it is null - the returned array is itself dynamically allocated and should also - be freed when it is no longer needed. Otherwise, the chunks array - must be of at least n_elements in length. It is filled in with the - pointers to the chunks. - - In either case, independent_comalloc returns this pointer array, or - null if the allocation failed. If n_elements is zero and chunks is - null, it returns a chunk representing an array with zero elements - (which should be freed if not wanted). - - Each element must be individually freed when it is no longer - needed. If you'd like to instead be able to free all at once, you - should instead use a single regular malloc, and assign pointers at - particular offsets in the aggregate space. (In this case though, you - cannot independently free elements.) - - independent_comallac differs from independent_calloc in that each - element may have a different size, and also that it does not - automatically clear elements. - - independent_comalloc can be used to speed up allocation in cases - where several structs or objects must always be allocated at the - same time. For example: - - struct Head { ... } - struct Foot { ... } - - void send_message(char* msg) { - int msglen = strlen(msg); - size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; - void* chunks[3]; - if (independent_comalloc(3, sizes, chunks) == 0) - die(); - struct Head* head = (struct Head*)(chunks[0]); - char* body = (char*)(chunks[1]); - struct Foot* foot = (struct Foot*)(chunks[2]); - // ... - } - - In general though, independent_comalloc is worth using only for - larger values of n_elements. For small values, you probably won't - detect enough difference from series of malloc calls to bother. - - Overuse of independent_comalloc can increase overall memory usage, - since it cannot reuse existing noncontiguous small chunks that - might be available for some of the elements. -*/ - void **dlindependent_comalloc(size_t, size_t *, void **); - - - /* - pvalloc(size_t n); - Equivalent to valloc(minimum-page-that-holds(n)), that is, - round up n to nearest pagesize. - */ - void *dlpvalloc(size_t); - - /* - malloc_trim(size_t pad); - - If possible, gives memory back to the system (via negative arguments - to sbrk) if there is unused memory at the `high' end of the malloc - pool or in unused MMAP segments. You can call this after freeing - large blocks of memory to potentially reduce the system-level memory - requirements of a program. However, it cannot guarantee to reduce - memory. Under some allocation patterns, some large free blocks of - memory will be locked between two used chunks, so they cannot be - given back to the system. - - The `pad' argument to malloc_trim represents the amount of free - trailing space to leave untrimmed. If this argument is zero, only - the minimum amount of memory to maintain internal data structures - will be left. Non-zero arguments can be supplied to maintain enough - trailing space to service future expected allocations without having - to re-obtain memory from the system. - - Malloc_trim returns 1 if it actually released any memory, else 0. -*/ - int dlmalloc_trim(size_t); - - /* - malloc_usable_size(void* p); - - Returns the number of bytes you can actually use in - an allocated chunk, which may be more than you requested (although - often not) due to alignment and minimum size constraints. - You can use this many bytes without worrying about - overwriting other allocated objects. This is not a particularly great - programming practice. malloc_usable_size can be more useful in - debugging and assertions, for example: - - p = malloc(n); - assert(malloc_usable_size(p) >= 256); -*/ - size_t dlmalloc_usable_size(void *); - - /* - malloc_stats(); - Prints on stderr the amount of space obtained from the system (both - via sbrk and mmap), the maximum amount (which may be more than - current if malloc_trim and/or munmap got called), and the current - number of bytes allocated via malloc (or realloc, etc) but not yet - freed. Note that this is the number of bytes allocated, not the - number requested. It will be larger than the number requested - because of alignment and bookkeeping overhead. Because it includes - alignment wastage as being in use, this figure may be greater than - zero even when no user-level chunks are allocated. - - The reported current and maximum system memory can be inaccurate if - a program makes other calls to system memory allocation functions - (normally sbrk) outside of malloc. - - malloc_stats prints only the most commonly interesting statistics. - More information can be obtained by calling mallinfo. -*/ - void dlmalloc_stats(); - -#endif /* !ONLY_MSPACES */ - -#if MSPACES - - /* - mspace is an opaque type representing an independent - region of space that supports mspace_malloc, etc. -*/ - typedef void *mspace; - - /* - create_mspace creates and returns a new independent space with the - given initial capacity, or, if 0, the default granularity size. It - returns null if there is no system memory available to create the - space. If argument locked is non-zero, the space uses a separate - lock to control access. The capacity of the space will grow - dynamically as needed to service mspace_malloc requests. You can - control the sizes of incremental increases of this space by - compiling with a different DEFAULT_GRANULARITY or dynamically - setting with mallopt(M_GRANULARITY, value). -*/ - mspace create_mspace(size_t capacity, int locked); - - /* - destroy_mspace destroys the given space, and attempts to return all - of its memory back to the system, returning the total number of - bytes freed. After destruction, the results of access to all memory - used by the space become undefined. -*/ - size_t destroy_mspace(mspace msp); - - /* - create_mspace_with_base uses the memory supplied as the initial base - of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this - space is used for bookkeeping, so the capacity must be at least this - large. (Otherwise 0 is returned.) When this initial space is - exhausted, additional memory will be obtained from the system. - Destroying this space will deallocate all additionally allocated - space (if possible) but not the initial base. -*/ - mspace create_mspace_with_base(void *base, size_t capacity, int locked); - - /* - mspace_malloc behaves as malloc, but operates within - the given space. -*/ - void *mspace_malloc(mspace msp, size_t bytes); - - /* - mspace_free behaves as free, but operates within - the given space. - - If compiled with FOOTERS==1, mspace_free is not actually needed. - free may be called instead of mspace_free because freed chunks from - any space are handled by their originating spaces. -*/ - void mspace_free(mspace msp, void *mem); - - /* - mspace_realloc behaves as realloc, but operates within - the given space. - - If compiled with FOOTERS==1, mspace_realloc is not actually - needed. realloc may be called instead of mspace_realloc because - realloced chunks from any space are handled by their originating - spaces. -*/ - void *mspace_realloc(mspace msp, void *mem, size_t newsize); - - /* - mspace_calloc behaves as calloc, but operates within - the given space. -*/ - void *mspace_calloc(mspace msp, size_t n_elements, size_t elem_size); - - /* - mspace_memalign behaves as memalign, but operates within - the given space. -*/ - void *mspace_memalign(mspace msp, size_t alignment, size_t bytes); - - /* - mspace_independent_calloc behaves as independent_calloc, but - operates within the given space. -*/ - void **mspace_independent_calloc( - mspace msp, size_t n_elements, size_t elem_size, void *chunks[]); - - /* - mspace_independent_comalloc behaves as independent_comalloc, but - operates within the given space. -*/ - void **mspace_independent_comalloc( - mspace msp, size_t n_elements, size_t sizes[], void *chunks[]); - - /* - mspace_footprint() returns the number of bytes obtained from the - system for this space. -*/ - size_t mspace_footprint(mspace msp); - - -#if !NO_MALLINFO - /* - mspace_mallinfo behaves as mallinfo, but reports properties of - the given space. -*/ - struct mallinfo mspace_mallinfo(mspace msp); -#endif /* NO_MALLINFO */ - - /* - mspace_malloc_stats behaves as malloc_stats, but reports - properties of the given space. -*/ - void mspace_malloc_stats(mspace msp); - - /* - mspace_trim behaves as malloc_trim, but - operates within the given space. -*/ - int mspace_trim(mspace msp, size_t pad); - - /* - An alias for mallopt. -*/ - int mspace_mallopt(int, int); - - void mspace_info(mspace ms, struct mem_info *info); - -#endif /* MSPACES */ - -#ifdef __cplusplus -}; /* end of extern "C" */ -#endif - -#endif /* MALLOC_280_H */ diff --git a/src/core/mem/f_malloc.c b/src/core/mem/f_malloc.c index 6bc60bba0..9d71cc43f 100644 --- a/src/core/mem/f_malloc.c +++ b/src/core/mem/f_malloc.c @@ -43,20 +43,19 @@ /* useful macros */ +/** ROUNDTO= 2^k so the following works */ +#define ROUNDTO_MASK (~((unsigned long)ROUNDTO - 1)) +#define ROUNDUP(s) (((s) + (ROUNDTO - 1)) & ROUNDTO_MASK) +#define ROUNDDOWN(s) ((s)&ROUNDTO_MASK) + #define FRAG_NEXT(f) \ ((struct fm_frag *)((char *)(f) + sizeof(struct fm_frag) + (f)->size)) #define FRAG_OVERHEAD (sizeof(struct fm_frag)) + #define INIT_OVERHEAD \ (ROUNDUP(sizeof(struct fm_block)) + 2 * sizeof(struct fm_frag)) - -/** ROUNDTO= 2^k so the following works */ -#define ROUNDTO_MASK (~((unsigned long)ROUNDTO - 1)) -#define ROUNDUP(s) (((s) + (ROUNDTO - 1)) & ROUNDTO_MASK) -#define ROUNDDOWN(s) ((s)&ROUNDTO_MASK) - - /** finds the hash value for s, s=ROUNDTO multiple */ #define GET_HASH(s) \ (((unsigned long)(s) <= F_MALLOC_OPTIMIZE) \ @@ -321,12 +320,28 @@ struct fm_block *fm_malloc_init(char *address, unsigned long size, int type) struct fm_block *qm; unsigned long init_overhead; - /* make address and size multiple of 8*/ + if(sizeof(struct fm_frag) % ROUNDTO != 0) { + LM_ERR("memory fragment align constraints failure (%lu %% %lu = %lu)\n", + sizeof(struct fm_frag), ROUNDTO, + sizeof(struct fm_frag) % ROUNDTO); + return 0; + } + if(sizeof(struct fm_block) % ROUNDTO != 0) { + LM_ERR("memory block align constraints failure (%lu %% %lu = %lu)\n", + sizeof(struct fm_block), ROUNDTO, + sizeof(struct fm_block) % ROUNDTO); + return 0; + } + + /* make address and size multiple of ROUNDTO */ start = (char *)ROUNDUP((unsigned long)address); - LM_DBG("F_OPTIMIZE=%lu, /ROUNDTO=%lu\n", F_MALLOC_OPTIMIZE, - F_MALLOC_OPTIMIZE / ROUNDTO); - LM_DBG("F_HASH_SIZE=%lu, fm_block size=%lu\n", F_HASH_SIZE, - (unsigned long)sizeof(struct fm_block)); + LM_DBG("F_OPTIMIZE=%lu, F_OPTIMIZE/ROUNDTO=%lu, ROUNDTO=%lu\n", + F_MALLOC_OPTIMIZE, F_MALLOC_OPTIMIZE / ROUNDTO, ROUNDTO); + LM_DBG("F_HASH_SIZE=%lu, FM_HASH_BMP_SIZE=%lu, fm_block_size=%lu, " + "fm_block_size %% ROUNDTO=%lu\n", + F_HASH_SIZE, FM_HASH_BMP_SIZE, + (unsigned long)sizeof(struct fm_block), + (unsigned long)sizeof(struct fm_block) % ROUNDTO); LM_DBG("fm_malloc_init(%p, %lu), start=%p\n", address, (unsigned long)size, start); diff --git a/src/core/mem/f_malloc.h b/src/core/mem/f_malloc.h index fda311188..5a9d28ece 100644 --- a/src/core/mem/f_malloc.h +++ b/src/core/mem/f_malloc.h @@ -40,24 +40,26 @@ */ #define F_MALLOC_HASH_BITMAP -#ifdef DBG_F_MALLOC -#if defined(__CPU_sparc64) || defined(__CPU_sparc) -/* tricky, on sun in 32 bits mode long long must be 64 bits aligned - * but long can be 32 bits aligned => malloc should return long long - * aligned memory */ -#define ROUNDTO sizeof(long long) +/** + * ROUNDTO: size to round to, must be = 2^n + * - on sun in 32 bits mode long long must be 64 bits aligned but long + * can be 32 bits aligned => malloc should return multiple of long long + * aligned memory + * - malloc() on gnu/linux: multiple of 8 or 16 on 64-bit systems + * - for simplicity settle for 16 by default + * - sizeof(fm_frag) must be multiple of ROUNDTO! + */ +#ifndef KSR_MEMORY_ALIGN +#define ROUNDTO 16UL #else -#define ROUNDTO \ - sizeof(void *) /* size we round to, must be = 2^n, and - * sizeof(fm_frag) must be multiple of ROUNDTO !*/ -#endif -#else /* DBG_F_MALLOC */ -#define ROUNDTO 8UL +#define ROUNDTO KSR_MEMORY_ALIGN #endif + + #define MIN_FRAG_SIZE ROUNDTO -#define F_MALLOC_OPTIMIZE_FACTOR 14UL /* used below */ +#define F_MALLOC_OPTIMIZE_FACTOR 15UL /* used below */ /** Size to optimize for, (most allocs <= this size), must be 2^k */ #define F_MALLOC_OPTIMIZE (1UL << F_MALLOC_OPTIMIZE_FACTOR) @@ -81,18 +83,18 @@ typedef unsigned long fm_hash_bitmap_t; */ struct fm_frag { - unsigned long size; /* size of fragment */ + unsigned long size; /* size of fragment */ + unsigned long is_free; /* used to detect if fragment is free (when not 0) */ struct fm_frag *next_free; /* next free frag in slot */ - struct fm_frag - *prev_free; /* prev free frag in slot - for faster join/defrag */ - unsigned int is_free; /* used to detect if fragment is free (when not 0) */ + struct fm_frag *prev_free; /* prev free frag in slot - faster join/defrag */ #ifdef DBG_F_MALLOC const char *file; const char *func; const char *mname; unsigned long line; #endif - unsigned int check; + unsigned long reserved1; + unsigned long check; }; struct fm_frag_lnk @@ -107,12 +109,13 @@ struct fm_frag_lnk */ struct fm_block { - int type; + long type; unsigned long size; /** total size */ unsigned long used; /** allocated size*/ unsigned long real_used; /** used + malloc overhead */ unsigned long max_real_used; unsigned long ffrags; + unsigned long reserved1; struct fm_frag *first_frag; struct fm_frag *last_frag; diff --git a/src/core/mem/ll_malloc.c b/src/core/mem/ll_malloc.c deleted file mode 100644 index ff8cc7348..000000000 --- a/src/core/mem/ll_malloc.c +++ /dev/null @@ -1,1115 +0,0 @@ -/* - * shared memory, multi-process safe, pool based, mostly lockless version of - * f_malloc - * - * This file is part of Kamailio, a free SIP server. - * - * Copyright (C) 2007 iptelorg GmbH - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifdef LL_MALLOC - -#include -#include - -#include "ll_malloc.h" -#include "../dprint.h" -#include "../globals.h" -#include "memdbg.h" -#include "../cfg/cfg.h" /* memlog */ - -#define MAX_POOL_FRAGS 10000 /* max fragments per pool hash bucket */ -#define MIN_POOL_FRAGS 10 /* min fragments per pool hash bucket */ - -/*useful macros*/ - -#define FRAG_NEXT(f) \ - ((struct sfm_frag *)((char *)(f) + sizeof(struct sfm_frag) + (f)->size)) - - -/* SF_ROUNDTO= 2^k so the following works */ -#define ROUNDTO_MASK (~((unsigned long)SF_ROUNDTO - 1)) -#define ROUNDUP(s) (((s) + (SF_ROUNDTO - 1)) & ROUNDTO_MASK) -#define ROUNDDOWN(s) ((s)&ROUNDTO_MASK) - -#define FRAG_OVERHEAD (sizeof(struct sfm_frag)) -#define INIT_OVERHEAD \ - (ROUNDUP(sizeof(struct sfm_block)) + sizeof(struct sfm_frag)) - - -/* finds hash if s <=SF_MALLOC_OPTIMIZE */ -#define GET_SMALL_HASH(s) (unsigned long)(s) / SF_ROUNDTO -/* finds hash if s > SF_MALLOC_OPTIMIZE */ -#define GET_BIG_HASH(s) \ - (SF_MALLOC_OPTIMIZE / SF_ROUNDTO + big_hash_idx((s)) \ - - SF_MALLOC_OPTIMIZE_FACTOR + 1) - -/* finds the hash value for s, s=SF_ROUNDTO multiple*/ -#define GET_HASH(s) \ - (((unsigned long)(s) <= SF_MALLOC_OPTIMIZE) ? GET_SMALL_HASH(s) \ - : GET_BIG_HASH(s)) - - -#define UN_HASH_SMALL(h) ((unsigned long)(h)*SF_ROUNDTO) -#define UN_HASH_BIG(h) \ - (1UL << ((unsigned long)(h)-SF_MALLOC_OPTIMIZE / SF_ROUNDTO \ - + SF_MALLOC_OPTIMIZE_FACTOR - 1)) - -#define UN_HASH(h) \ - (((unsigned long)(h) <= (SF_MALLOC_OPTIMIZE / SF_ROUNDTO)) \ - ? UN_HASH_SMALL(h) \ - : UN_HASH_BIG(h)) - -#define BITMAP_BITS (sizeof(((struct sfm_block *)0)->bitmap) * 8) -#define BITMAP_BLOCK_SIZE ((SF_MALLOC_OPTIMIZE / SF_ROUNDTO) / BITMAP_BITS) -/* only for "small" hashes (up to HASH(SF_MALLOC_OPTIMIZE) */ -#define HASH_BIT_POS(h) (((unsigned long)(h)) / BITMAP_BLOCK_SIZE) -#define HASH_TO_BITMAP(h) (1UL << HASH_BIT_POS(h)) -#define BIT_TO_HASH(b) ((b)*BITMAP_BLOCK_SIZE) - - -/* mark/test used/unused frags */ -#define FRAG_MARK_USED(f) -#define FRAG_CLEAR_USED(f) -#define FRAG_WAS_USED(f) (1) - -/* other frag related defines: - * MEM_COALESCE_FRAGS - * MEM_FRAG_AVOIDANCE - */ -#define MEM_FRAG_AVOIDANCE - - -#define SFM_REALLOC_REMALLOC - -/* computes hash number for big buckets*/ -inline static unsigned long big_hash_idx(unsigned long s) -{ - unsigned long idx; - /* s is rounded => s = k*2^n (SF_ROUNDTO=2^n) - * index= i such that 2^i > s >= 2^(i-1) - * - * => index = number of the first non null bit in s*/ - idx = sizeof(long) * 8 - 1; - for(; !(s & (1UL << (sizeof(long) * 8 - 1))); s <<= 1, idx--) - ; - return idx; -} - - -#ifdef DBG_F_MALLOC -#define ST_CHECK_PATTERN 0xf0f0f0f0 -#define END_CHECK_PATTERN1 0xc0c0c0c0 -#define END_CHECK_PATTERN2 0xabcdefed -#endif - - -#ifdef SFM_ONE_LOCK - -#define SFM_MAIN_HASH_LOCK(qm, hash) lock_get(&(qm)->lock) -#define SFM_MAIN_HASH_UNLOCK(qm, hash) lock_release(&(qm)->lock) -#define SFM_POOL_LOCK(p, hash) lock_get(&(p)->lock) -#define SFM_POOL_UNLOCK(p, hash) lock_release(&(p)->lock) - -#warn "degraded performance, only one lock" - -#elif defined SFM_LOCK_PER_BUCKET - -#define SFM_MAIN_HASH_LOCK(qm, hash) lock_get(&(qm)->free_hash[(hash)].lock) -#define SFM_MAIN_HASH_UNLOCK(qm, hash) \ - lock_release(&(qm)->free_hash[(hash)].lock) -#define SFM_POOL_LOCK(p, hash) lock_get(&(p)->pool_hash[(hash)].lock) -#define SFM_POOL_UNLOCK(p, hash) lock_release(&(p)->pool_hash[(hash)].lock) -#else -#error no locks defined -#endif /* SFM_ONE_LOCK/SFM_LOCK_PER_BUCKET */ - -#define SFM_BIG_GET_AND_SPLIT_LOCK(qm) lock_get(&(qm)->get_and_split) -#define SFM_BIG_GET_AND_SPLIT_UNLOCK(qm) lock_release(&(qm)->get_and_split) - -static unsigned long sfm_max_hash = 0; /* maximum hash value (no point in - searching further) */ -static unsigned long pool_id = (unsigned long)-1; - - -/* call for each child */ -int sfm_pool_reset() -{ - pool_id = (unsigned long)-1; - return 0; -} - - -#define sfm_fix_pool_id(qm) \ - do { \ - if(unlikely(pool_id >= SFM_POOLS_NO)) \ - pool_id = ((unsigned)atomic_add(&(qm)->crt_id, 1)) % SFM_POOLS_NO; \ - } while(0) - - -static inline void frag_push(struct sfm_frag **head, struct sfm_frag *frag) -{ - register struct sfm_frag *old; - register struct sfm_frag *crt; - - crt = (void *)atomic_get_long(head); - do { - frag->u.nxt_free = crt; - old = crt; - membar_write_atomic_op(); - crt = (void *)atomic_cmpxchg_long((void *)head, (long)old, (long)frag); - } while(crt != old); -} - - -static inline struct sfm_frag *frag_pop(struct sfm_frag **head) -{ - register struct sfm_frag *old; - register struct sfm_frag *crt; - register struct sfm_frag *nxt; - - crt = (void *)atomic_get_long(head); - do { - /* if circular list, test not needed */ - nxt = crt ? crt->u.nxt_free : 0; - old = crt; - membar_read_atomic_op(); - crt = (void *)atomic_cmpxchg_long((void *)head, (long)old, (long)nxt); - } while(crt != old); - return crt; -} - - -static inline void sfm_pool_insert( - struct sfm_pool *pool, int hash, struct sfm_frag *frag) -{ - unsigned long hash_bit; - - frag_push(&pool->pool_hash[hash].first, frag); - atomic_inc_long((long *)&pool->pool_hash[hash].no); - /* set it only if not already set (avoids an expensive - * cache trashing atomic write op) */ - hash_bit = HASH_TO_BITMAP(hash); - if(!(atomic_get_long((long *)&pool->bitmap) & hash_bit)) - atomic_or_long((long *)&pool->bitmap, hash_bit); -} - - -/* returns 1 if it's ok to add a fragm. to pool p_id @ hash, 0 otherwise */ -static inline int sfm_check_pool( - struct sfm_block *qm, unsigned long p_id, int hash, int split) -{ - /* TODO: come up with something better - * if fragment is some split/rest from an allocation, that is - * >= requested size, accept it, else - * look at misses and current fragments and decide based on them */ - return (p_id < SFM_POOLS_NO) - && (split - || ((qm->pool[p_id].pool_hash[hash].no < MIN_POOL_FRAGS) - || ((qm->pool[p_id].pool_hash[hash].misses - > qm->pool[p_id].pool_hash[hash].no) - && (qm->pool[p_id].pool_hash[hash].no - < MAX_POOL_FRAGS)))); -} - - -/* choose on which pool to add a free'd packet - * return - pool idx or -1 if it should be added to main*/ -static inline unsigned long sfm_choose_pool( - struct sfm_block *qm, struct sfm_frag *frag, int hash, int split) -{ - /* check original pool first */ - if(sfm_check_pool(qm, frag->id, hash, split)) - return frag->id; - else { - /* check if our pool is properly set */ - sfm_fix_pool_id(qm); - /* check if my pool needs some frags */ - if((pool_id != frag->id) && (sfm_check_pool(qm, pool_id, hash, 0))) { - frag->id = pool_id; - return pool_id; - } - } - /* else add it back to main */ - frag->id = (unsigned long)(-1); - return frag->id; -} - - -static inline void sfm_insert_free( - struct sfm_block *qm, struct sfm_frag *frag, int split) -{ - struct sfm_frag **f; - unsigned long p_id; - int hash; - unsigned long hash_bit; - - if(likely(frag->size <= SF_POOL_MAX_SIZE)) { - hash = GET_SMALL_HASH(frag->size); - if(unlikely((p_id = sfm_choose_pool(qm, frag, hash, split)) - == (unsigned long)-1)) { - /* add it back to the "main" hash */ - frag->id = (unsigned long)(-1); /* main hash marker */ - /*insert it here*/ - frag_push(&(qm->free_hash[hash].first), frag); - atomic_inc_long((long *)&qm->free_hash[hash].no); - /* set it only if not already set (avoids an expensive - * cache trashing atomic write op) */ - hash_bit = HASH_TO_BITMAP(hash); - if(!(atomic_get_long((long *)&qm->bitmap) & hash_bit)) - atomic_or_long((long *)&qm->bitmap, hash_bit); - } else { - /* add it to one of the pools pool */ - sfm_pool_insert(&qm->pool[p_id], hash, frag); - } - } else { - hash = GET_BIG_HASH(frag->size); - SFM_MAIN_HASH_LOCK(qm, hash); - f = &(qm->free_hash[hash].first); - for(; *f; f = &((*f)->u.nxt_free)) - if(frag->size <= (*f)->size) - break; - frag->id = (unsigned long)(-1); /* main hash marker */ - /*insert it here*/ - frag->u.nxt_free = *f; - *f = frag; - qm->free_hash[hash].no++; - /* inc. big hash free size ? */ - SFM_MAIN_HASH_UNLOCK(qm, hash); - } -} - - -/* size should be already rounded-up */ -static inline -#ifdef DBG_F_MALLOC - void - sfm_split_frag(struct sfm_block *qm, struct sfm_frag *frag, - unsigned long size, const char *file, const char *func, - unsigned int line) -#else - void - sfm_split_frag( - struct sfm_block *qm, struct sfm_frag *frag, unsigned long size) -#endif -{ - unsigned long rest; - struct sfm_frag *n; - int bigger_rest; - - rest = frag->size - size; -#ifdef MEM_FRAG_AVOIDANCE - if((rest > (FRAG_OVERHEAD + SF_MALLOC_OPTIMIZE)) - || (rest >= (FRAG_OVERHEAD - + size))) { /* the residue fragm. is big enough*/ - bigger_rest = 1; -#else - if(rest > (FRAG_OVERHEAD + SF_MIN_FRAG_SIZE)) { - bigger_rest = rest >= (size + FRAG_OVERHEAD); -#endif - frag->size = size; - /*split the fragment*/ - n = FRAG_NEXT(frag); - n->size = rest - FRAG_OVERHEAD; - n->id = pool_id; - FRAG_CLEAR_USED(n); /* never used */ -#ifdef DBG_F_MALLOC - /* frag created by malloc, mark it*/ - n->file = file; - n->func = "frag. from sfm_malloc"; - n->line = line; - n->check = ST_CHECK_PATTERN; -#endif - /* reinsert n in free list*/ - sfm_insert_free(qm, n, bigger_rest); - } else { - /* we cannot split this fragment any more => alloc all of it*/ - } -} - - -/* init malloc and return a sfm_block*/ -struct sfm_block *sfm_malloc_init(char *address, unsigned long size, int type) -{ - char *start; - char *end; - struct sfm_block *qm; - unsigned long init_overhead; - int r; -#ifdef SFM_LOCK_PER_BUCKET - int i; -#endif - - /* make address and size multiple of 8*/ - start = (char *)ROUNDUP((unsigned long)address); - DBG("sfm_malloc_init: SF_OPTIMIZE=%lu, /SF_ROUNDTO=%lu\n", - SF_MALLOC_OPTIMIZE, SF_MALLOC_OPTIMIZE / SF_ROUNDTO); - DBG("sfm_malloc_init: SF_HASH_SIZE=%lu, sfm_block size=%lu\n", SF_HASH_SIZE, - (long)sizeof(struct sfm_block)); - DBG("sfm_malloc_init(%p, %lu), start=%p\n", address, size, start); - - if(size < start - address) - return 0; - size -= (start - address); - if(size < (SF_MIN_FRAG_SIZE + FRAG_OVERHEAD)) - return 0; - size = ROUNDDOWN(size); - - init_overhead = INIT_OVERHEAD; - - - if(size < init_overhead) { - /* not enough mem to create our control structures !!!*/ - return 0; - } - end = start + size; - qm = (struct sfm_block *)start; - memset(qm, 0, sizeof(struct sfm_block)); - qm->size = size; - qm->type = type; - size -= init_overhead; - - qm->first_frag = - (struct sfm_frag *)(start + ROUNDUP(sizeof(struct sfm_block))); - qm->last_frag = (struct sfm_frag *)(end - sizeof(struct sfm_frag)); - /* init initial fragment*/ - qm->first_frag->size = size; - qm->first_frag->id = (unsigned long)-1; /* not in a pool */ - qm->last_frag->size = 0; - -#ifdef DBG_F_MALLOC - qm->first_frag->check = ST_CHECK_PATTERN; - qm->last_frag->check = END_CHECK_PATTERN1; -#endif - - /* link initial fragment into the free list*/ - - sfm_insert_free(qm, qm->first_frag, 0); - sfm_max_hash = GET_HASH(size); - - /* init locks */ - if(lock_init(&qm->get_and_split) == 0) - goto error; -#ifdef SFM_ONE_LOCK - if(lock_init(&qm->lock) == 0) { - lock_destroy(&qm->get_and_split); - goto error; - } - for(r = 0; r < SFM_POOLS_NO; r++) { - if(lock_init(&qm->pool[r].lock) == 0) { - for(; r > 0; r--) - lock_destroy(&qm->pool[r - 1].lock); - lock_destroy(&qm->lock); - lock_destroy(&qm->get_and_split); - goto error; - } - } -#elif defined(SFM_LOCK_PER_BUCKET) - for(r = 0; r < SF_HASH_SIZE; r++) - if(lock_init(&qm->free_hash[r].lock) == 0) { - for(; r > 0; r--) - lock_destroy(&qm->free_hash[r - 1].lock); - lock_destroy(&qm->get_and_split); - goto error; - } - for(i = 0; i < SFM_POOLS_NO; i++) { - for(r = 0; r < SF_HASH_POOL_SIZE; r++) - if(lock_init(&qm->pool[i].pool_hash[r].lock) == 0) { - for(; r > 0; r--) - lock_destroy(&qm->pool[i].poo_hash[r].lock); - for(; i > 0; i--) { - for(r = 0; r < SF_HASH_POOL_SIZE; r++) - lock_destroy(&qm->pool[i].pool_hash[r].lock); - } - for(r = 0; r < SF_HASH_SIZE; r++) - lock_destroy(&qm->free_hash[r].lock); - lock_destroy(&qm->get_and_split); - goto error; - } - } -#endif - qm->is_init = 1; - return qm; -error: - return 0; -} - - -/* cleanup */ -void sfm_malloc_destroy(struct sfm_block *qm) -{ - int r, i; - /* destroy all the locks */ - if(!qm || !qm->is_init) - return; /* nothing to do */ - lock_destroy(&qm->get_and_split); -#ifdef SFM_ONE_LOCK - lock_destroy(&qm->lock); - for(r = 0; r < SFM_POOLS_NO; r++) { - lock_destroy(&qm->pool[r].lock); - } -#elif defined(SFM_LOCK_PER_BUCKET) - for(r = 0; r < SF_HASH_SIZE; r++) - lock_destroy(&qm->free_hash[r].lock); - for(i = 0; i < SFM_POOLS_NO; i++) { - for(r = 0; r < SF_HASH_POOL_SIZE; r++) - lock_destroy(&qm->pool[i].pool_hash[r].lock); - } -#endif - qm->is_init = 0; -} - - -/* returns next set bit in bitmap, starts at b - * if b is set, returns b - * if not found returns BITMAP_BITS */ -static inline unsigned long _next_set_bit( - unsigned long b, unsigned long *bitmap) -{ - for(; !((1UL << b) & *bitmap) && b < BITMAP_BITS; b++) - ; - return b; -} - -/* returns start of block b and sets *end - * (handles also the "rest" block at the end ) */ -static inline unsigned long _hash_range(unsigned long b, unsigned long *end) -{ - unsigned long s; - - if((unlikely(b >= BITMAP_BITS))) { - s = BIT_TO_HASH(BITMAP_BITS); - *end = SF_HASH_POOL_SIZE; /* last, possible rest block */ - } else { - s = BIT_TO_HASH(b); - *end = s + BITMAP_BLOCK_SIZE; - } - return s; -} - - -#ifdef DBG_F_MALLOC -static inline struct sfm_frag *pool_get_frag(struct sfm_block *qm, - struct sfm_pool *pool, int hash, unisgned long size, const char *file, - const char *func, unsigned int line) -#else -static inline struct sfm_frag *pool_get_frag(struct sfm_block *qm, - struct sfm_pool *pool, int hash, unsigned long size) -#endif -{ - int r; - int next_block; - struct sfm_frag *volatile *f; - struct sfm_frag *frag; - unsigned long b; - unsigned long eob; - - /* special case for r=hash */ - r = hash; - f = &pool->pool_hash[r].first; - - /* detach it from the free list */ - if((frag = frag_pop((struct sfm_frag **)f)) == 0) - goto not_found; -found: - atomic_dec_long((long *)&pool->pool_hash[r].no); - frag->u.nxt_free = 0; /* mark it as 'taken' */ - frag->id = pool_id; -#ifdef DBG_F_MALLOC - sfm_split_frag(qm, frag, size, file, func, line); -#else - sfm_split_frag(qm, frag, size); -#endif - if(&qm->pool[pool_id] == pool) - atomic_inc_long((long *)&pool->hits); - return frag; - -not_found: - atomic_inc_long((long *)&pool->pool_hash[r].misses); - r++; - b = HASH_BIT_POS(r); - - while(r < SF_HASH_POOL_SIZE) { - b = _next_set_bit(b, &pool->bitmap); - next_block = _hash_range(b, &eob); - r = (r < next_block) ? next_block : r; - for(; r < eob; r++) { - f = &pool->pool_hash[r].first; - if((frag = frag_pop((struct sfm_frag **)f)) != 0) - goto found; - atomic_inc_long((long *)&pool->pool_hash[r].misses); - } - b++; - } - atomic_inc_long((long *)&pool->missed); - return 0; -} - - -#ifdef DBG_F_MALLOC -static inline struct sfm_frag *main_get_frag(struct sfm_block *qm, int hash, - unsigned long size, const char *file, const char *func, - unsigned int line) -#else -static inline struct sfm_frag *main_get_frag( - struct sfm_block *qm, int hash, unsigned long size) -#endif -{ - int r; - int next_block; - struct sfm_frag *volatile *f; - struct sfm_frag *frag; - unsigned long b; - unsigned long eob; - - r = hash; - b = HASH_BIT_POS(r); - while(r <= SF_MALLOC_OPTIMIZE / SF_ROUNDTO) { - b = _next_set_bit(b, &qm->bitmap); - next_block = _hash_range(b, &eob); - r = (r < next_block) ? next_block : r; - for(; r < eob; r++) { - f = &qm->free_hash[r].first; - if((frag = frag_pop((struct sfm_frag **)f)) != 0) { - atomic_dec_long((long *)&qm->free_hash[r].no); - frag->u.nxt_free = 0; /* mark it as 'taken' */ - frag->id = pool_id; -#ifdef DBG_F_MALLOC - sfm_split_frag(qm, frag, size, file, func, line); -#else - sfm_split_frag(qm, frag, size); -#endif - return frag; - } - } - b++; - } - /* big fragments */ - SFM_BIG_GET_AND_SPLIT_LOCK(qm); - for(; r <= sfm_max_hash; r++) { - f = &qm->free_hash[r].first; - if(*f) { - SFM_MAIN_HASH_LOCK(qm, r); - if(unlikely((*f) == 0)) { - /* not found */ - SFM_MAIN_HASH_UNLOCK(qm, r); - continue; - } - for(; (*f); f = &((*f)->u.nxt_free)) - if((*f)->size >= size) { - /* found, detach it from the free list*/ - frag = *f; - *f = frag->u.nxt_free; - frag->u.nxt_free = 0; /* mark it as 'taken' */ - qm->free_hash[r].no--; - SFM_MAIN_HASH_UNLOCK(qm, r); - frag->id = pool_id; -#ifdef DBG_F_MALLOC - sfm_split_frag(qm, frag, size, file, func, line); -#else - sfm_split_frag(qm, frag, size); -#endif - SFM_BIG_GET_AND_SPLIT_UNLOCK(qm); - return frag; - }; - SFM_MAIN_HASH_UNLOCK(qm, r); - /* try in a bigger bucket */ - } - } - SFM_BIG_GET_AND_SPLIT_UNLOCK(qm); - return 0; -} - - -#ifdef DBG_F_MALLOC -void *sfm_malloc(struct sfm_block *qm, unsigned long size, const char *file, - const char *func, unsigned int line) -#else -void *sfm_malloc(struct sfm_block *qm, unsigned long size) -#endif -{ - struct sfm_frag *frag; - int hash; - unsigned int i; - -#ifdef DBG_F_MALLOC - MDBG("sfm_malloc(%p, %lu) called from %s: %s(%d)\n", qm, size, file, func, - line); -#endif - /*size must be a multiple of 8*/ - size = ROUNDUP(size); - /* if (size>(qm->size-qm->real_used)) return 0; */ - - /* check if our pool id is set */ - sfm_fix_pool_id(qm); - - /*search for a suitable free frag*/ - if(likely(size <= SF_POOL_MAX_SIZE)) { - hash = GET_SMALL_HASH(size); - /* try first in our pool */ -#ifdef DBG_F_MALLOC - if(likely((frag = pool_get_frag(qm, &qm->pool[pool_id], hash, size, - file, func, line)) - != 0)) - goto found; - /* try in the "main" free hash, go through all the hash */ - if(likely((frag = main_get_frag(qm, hash, size, file, func, line)) - != 0)) - goto found; - /* really low mem , try in other pools */ - for(i = (pool_id + 1); i < (pool_id + SFM_POOLS_NO); i++) { - if((frag = pool_get_frag(qm, &qm->pool[i % SFM_POOLS_NO], hash, - size, file, func, line)) - != 0) - goto found; - } -#else - if(likely((frag = pool_get_frag(qm, &qm->pool[pool_id], hash, size)) - != 0)) - goto found; - /* try in the "main" free hash, go through all the hash */ - if(likely((frag = main_get_frag(qm, hash, size)) != 0)) - goto found; - /* really low mem , try in other pools */ - for(i = (pool_id + 1); i < (pool_id + SFM_POOLS_NO); i++) { - if((frag = pool_get_frag( - qm, &qm->pool[i % SFM_POOLS_NO], hash, size)) - != 0) - goto found; - } -#endif - /* not found, bad! */ - return 0; - } else { - hash = GET_BIG_HASH(size); -#ifdef DBG_F_MALLOC - if((frag = main_get_frag(qm, hash, size, file, func, line)) == 0) - return 0; /* not found, bad! */ -#else - if((frag = main_get_frag(qm, hash, size)) == 0) - return 0; /* not found, bad! */ -#endif - } - -found: - /* we found it!*/ -#ifdef DBG_F_MALLOC - frag->file = file; - frag->func = func; - frag->line = line; - frag->check = ST_CHECK_PATTERN; - MDBG("sfm_malloc(%p, %lu) returns address %p \n", qm, size, - (char *)frag + sizeof(struct sfm_frag)); -#endif - FRAG_MARK_USED(frag); /* mark it as used */ - return (char *)frag + sizeof(struct sfm_frag); -} - - -#ifdef DBG_F_MALLOC -void sfm_free(struct sfm_block *qm, void *p, const char *file, const char *func, - unsigned int line) -#else -void sfm_free(struct sfm_block *qm, void *p) -#endif -{ - struct sfm_frag *f; - -#ifdef DBG_F_MALLOC - MDBG("sfm_free(%p, %p), called from %s: %s(%d)\n", qm, p, file, func, line); - if(p > (void *)qm->last_frag || p < (void *)qm->first_frag) { - LOG(L_CRIT, - "BUG: sfm_free: bad pointer %p (out of memory block!) - " - "aborting\n", - p); - abort(); - } -#endif - if(unlikely(p == 0)) { - LOG(L_WARN, "WARNING: sfm_free: free(0) called\n"); - return; - } - f = (struct sfm_frag *)((char *)p - sizeof(struct sfm_frag)); -#ifdef DBG_F_MALLOC - MDBG("sfm_free: freeing block alloc'ed from %s: %s(%ld)\n", f->file, - f->func, f->line); -#endif -#ifdef DBG_F_MALLOC - f->file = file; - f->func = func; - f->line = line; -#endif - sfm_insert_free(qm, f, 0); -} - - -#ifdef DBG_F_MALLOC -void *sfm_realloc(struct sfm_block *qm, void *p, unsigned long size, - const char *file, const char *func, unsigned int line) -#else -void *sfm_realloc(struct sfm_block *qm, void *p, unsigned long size) -#endif -{ - struct sfm_frag *f; - unsigned long orig_size; - void *ptr; -#ifndef SFM_REALLOC_REMALLOC - struct sfm_frag *n; - struct sfm_frag **pf; - unsigned long diff; - unsigned long p_id; - int hash; - unsigned long n_size; - struct sfm_pool *pool; -#endif - -#ifdef DBG_F_MALLOC - MDBG("sfm_realloc(%p, %p, %lu) called from %s: %s(%d)\n", qm, p, size, file, - func, line); - if((p) && (p > (void *)qm->last_frag || p < (void *)qm->first_frag)) { - LOG(L_CRIT, - "BUG: sfm_free: bad pointer %p (out of memory block!) - " - "aborting\n", - p); - abort(); - } -#endif - if(size == 0) { - if(p) -#ifdef DBG_F_MALLOC - sfm_free(qm, p, file, func, line); -#else - sfm_free(qm, p); -#endif - return 0; - } - if(p == 0) -#ifdef DBG_F_MALLOC - return sfm_malloc(qm, size, file, func, line); -#else - return sfm_malloc(qm, size); -#endif - f = (struct sfm_frag *)((char *)p - sizeof(struct sfm_frag)); -#ifdef DBG_F_MALLOC - MDBG("sfm_realloc: realloc'ing frag %p alloc'ed from %s: %s(%ld)\n", f, - f->file, f->func, f->line); -#endif - size = ROUNDUP(size); - orig_size = f->size; - if(f->size > size) { - /* shrink */ -#ifdef DBG_F_MALLOC - MDBG("sfm_realloc: shrinking from %lu to %lu\n", f->size, size); - sfm_split_frag(qm, f, size, file, "frag. from sfm_realloc", line); -#else - sfm_split_frag(qm, f, size); -#endif - } else if(f->size < size) { - /* grow */ -#ifdef DBG_F_MALLOC - MDBG("sfm_realloc: growing from %lu to %lu\n", f->size, size); -#endif -#ifndef SFM_REALLOC_REMALLOC -/* should set a magic value in list head and in push/pop if magic value => - * lock and wait */ -#error LL_MALLOC realloc not finished yet - diff = size - f->size; - n = FRAG_NEXT(f); - if(((char *)n < (char *)qm->last_frag) && (n->u.nxt_free) - && ((n->size + FRAG_OVERHEAD) >= diff)) { - /* join */ - /* detach n from the free list */ - try_again: - p_id = n->id; - n_size = n->size; - if((unlikely(p_id >= SFM_POOLS_NO))) { - hash = GET_HASH(n_size); - SFM_MAIN_HASH_LOCK(qm, hash); - if(unlikely((n->u.nxt_free == 0) - || ((n->size + FRAG_OVERHEAD) < diff))) { - SFM_MAIN_HASH_UNLOCK(qm, hash); - goto not_found; - } - if(unlikely((n->id != p_id) || (n->size != n_size))) { - /* fragment still free, but changed, either - * moved to another pool or has a diff. size */ - SFM_MAIN_HASH_UNLOCK(qm, hash); - goto try_again; - } - pf = &(qm->free_hash[hash].first); - /* find it */ - for(; (*pf) && (*pf != n); pf = &((*pf)->u.nxt_free)) - ; /*FIXME slow */ - if(*pf == 0) { - SFM_MAIN_HASH_UNLOCK(qm, hash); - /* not found, bad! */ - LOG(L_WARN, - "WARNING: sfm_realloc: could not find %p in " - "free " - "list (hash=%d)\n", - n, hash); - /* somebody is in the process of changing it ? */ - goto not_found; - } - /* detach */ - *pf = n->u.nxt_free; - n->u.nxt_free = 0; /* mark it immediately as detached */ - qm->free_hash[hash].no--; - SFM_MAIN_HASH_UNLOCK(qm, hash); - /* join */ - f->size += n->size + FRAG_OVERHEAD; - /* split it if necessary */ - if(f->size > size) { -#ifdef DBG_F_MALLOC - sfm_split_frag(qm, f, size, file, - "fragm. from " - "sfm_realloc", - line); -#else - sfm_split_frag(qm, f, size); -#endif - } - } else { /* p_id < SFM_POOLS_NO (=> in a pool )*/ - hash = GET_SMALL_HASH(n_size); - pool = &qm->pool[p_id]; - SFM_POOL_LOCK(pool, hash); - if(unlikely((n->u.nxt_free == 0) - || ((n->size + FRAG_OVERHEAD) < diff))) { - SFM_POOL_UNLOCK(pool, hash); - goto not_found; - } - if(unlikely((n->id != p_id) || (n->size != n_size))) { - /* fragment still free, but changed, either - * moved to another pool or has a diff. size */ - SFM_POOL_UNLOCK(pool, hash); - goto try_again; - } - pf = &(pool->pool_hash[hash].first); - /* find it */ - for(; (*pf) && (*pf != n); pf = &((*pf)->u.nxt_free)) - ; /*FIXME slow */ - if(*pf == 0) { - SFM_POOL_UNLOCK(pool, hash); - /* not found, bad! */ - LOG(L_WARN, - "WARNING: sfm_realloc: could not find %p in " - "free " - "list (hash=%d)\n", - n, hash); - /* somebody is in the process of changing it ? */ - goto not_found; - } - /* detach */ - *pf = n->u.nxt_free; - n->u.nxt_free = 0; /* mark it immediately as detached */ - pool->pool_hash[hash].no--; - SFM_POOL_UNLOCK(pool, hash); - /* join */ - f->size += n->size + FRAG_OVERHEAD; - /* split it if necessary */ - if(f->size > size) { -#ifdef DBG_F_MALLOC - sfm_split_frag(qm, f, size, file, - "fragm. from " - "sfm_realloc", - line); -#else - sfm_split_frag(qm, f, size); -#endif - } - } - } else { - not_found: - /* could not join => realloc */ -#else /* SFM_REALLOC_REMALLOC */ - { -#endif /* SFM_REALLOC_REMALLOC */ -#ifdef DBG_F_MALLOC - ptr = sfm_malloc(qm, size, file, func, line); -#else - ptr = sfm_malloc(qm, size); -#endif - if(ptr) { - /* copy, need by libssl */ - memcpy(ptr, p, orig_size); -#ifdef DBG_F_MALLOC - sfm_free(qm, p, file, func, line); -#else - sfm_free(qm, p); -#endif - } - p = ptr; - } - } else { - /* do nothing */ -#ifdef DBG_F_MALLOC - MDBG("sfm_realloc: doing nothing, same size: %lu - %lu\n", f->size, - size); -#endif - } -#ifdef DBG_F_MALLOC - MDBG("sfm_realloc: returning %p\n", p); -#endif - return p; -} - - -void sfm_status(struct sfm_block *qm) -{ - struct sfm_frag *f; - int i, j; - int h; - int unused; - unsigned long size; - int k; - int memlog; - int mem_summary; - -#warning "ll_status doesn't work (might crash if used)" - - memlog = cfg_get(core, core_cfg, memlog); - mem_summary = cfg_get(core, core_cfg, mem_summary); - LOG(memlog, "sfm_status (%p):\n", qm); - if(!qm) - return; - - LOG(memlog, " heap size= %ld\n", qm->size); - - if(mem_summary & 16) - return; - - LOG(memlog, "dumping free list:\n"); - for(h = 0, i = 0, size = 0; h <= sfm_max_hash; h++) { - SFM_MAIN_HASH_LOCK(qm, h); - unused = 0; - for(f = qm->free_hash[h].first, j = 0; f; - size += f->size, f = f->u.nxt_free, i++, j++) { - if(!FRAG_WAS_USED(f)) { - unused++; -#ifdef DBG_F_MALLOC - LOG(memlog, - "unused fragm.: hash = %3d, fragment %p," - " address %p size %lu, created from %s: %s(%ld)\n", - h, f, (char *)f + sizeof(struct sfm_frag), f->size, - f->file, f->func, f->line); -#endif - }; - } - if(j) - LOG(memlog, - "hash = %3d fragments no.: %5d, unused: %5d\n\t\t" - " bucket size: %9lu - %9lu (first %9lu)\n", - h, j, unused, UN_HASH(h), - ((h <= SF_MALLOC_OPTIMIZE / SF_ROUNDTO) ? 1 : 2) - * UN_HASH(h), - qm->free_hash[h].first->size); - if(j != qm->free_hash[h].no) { - LOG(L_CRIT, - "BUG: sfm_status: different free frag. count: %d!=%ld" - " for hash %3d\n", - j, qm->free_hash[h].no, h); - } - SFM_MAIN_HASH_UNLOCK(qm, h); - } - for(k = 0; k < SFM_POOLS_NO; k++) { - for(h = 0; h < SF_HASH_POOL_SIZE; h++) { - SFM_POOL_LOCK(&qm->pool[k], h); - unused = 0; - for(f = qm->pool[k].pool_hash[h].first, j = 0; f; - size += f->size, f = f->u.nxt_free, i++, j++) { - if(!FRAG_WAS_USED(f)) { - unused++; -#ifdef DBG_F_MALLOC - LOG(memlog, - "[%2d] unused fragm.: hash = %3d, fragment %p," - " address %p size %lu, created from %s: " - "%s(%ld)\n", - k h, f, (char *)f + sizeof(struct sfm_frag), - f->size, f->file, f->func, f->line); -#endif - }; - } - if(j) - LOG(memlog, - "[%2d] hash = %3d fragments no.: %5d, unused: " - "%5d\n\t\t bucket size: %9lu - %9lu " - "(first %9lu)\n", - k, h, j, unused, UN_HASH(h), - ((h <= SF_MALLOC_OPTIMIZE / SF_ROUNDTO) ? 1 : 2) - * UN_HASH(h), - qm->pool[k].pool_hash[h].first->size); - if(j != qm->pool[k].pool_hash[h].no) { - LOG(L_CRIT, - "BUG: sfm_status: [%d] different free frag." - " count: %d!=%ld for hash %3d\n", - k, j, qm->pool[k].pool_hash[h].no, h); - } - SFM_POOL_UNLOCK(&qm->pool[k], h); - } - } - LOG(memlog, "TOTAL: %6d free fragments = %6lu free bytes\n", i, size); - LOG(memlog, "-----------------------------\n"); -} - - -/* fills a malloc info structure with info about the block - * if a parameter is not supported, it will be filled with 0 */ -void sfm_info(struct sfm_block *qm, struct mem_info *info) -{ - int r, k; - unsigned long total_frags; - struct sfm_frag *f; - - memset(info, 0, sizeof(*info)); - total_frags = 0; - info->total_size = qm->size; - info->min_frag = SF_MIN_FRAG_SIZE; - /* we'll have to compute it all */ - for(r = 0; r <= SF_MALLOC_OPTIMIZE / SF_ROUNDTO; r++) { - info->free += qm->free_hash[r].no * UN_HASH(r); - total_frags += qm->free_hash[r].no; - } - for(; r <= sfm_max_hash; r++) { - total_frags += qm->free_hash[r].no; - SFM_MAIN_HASH_LOCK(qm, r); - for(f = qm->free_hash[r].first; f; f = f->u.nxt_free) { - info->free += f->size; - } - SFM_MAIN_HASH_UNLOCK(qm, r); - } - for(k = 0; k < SFM_POOLS_NO; k++) { - for(r = 0; r < SF_HASH_POOL_SIZE; r++) { - info->free += qm->pool[k].pool_hash[r].no * UN_HASH(r); - total_frags += qm->pool[k].pool_hash[r].no; - } - } - info->real_used = info->total_size - info->free; - info->used = info->real_used - total_frags * FRAG_OVERHEAD - INIT_OVERHEAD - - FRAG_OVERHEAD; - info->max_used = 0; /* we don't really know */ - info->total_frags = total_frags; -} - - -/* returns how much free memory is available - * on error (not compiled with bookkeeping code) returns (unsigned long)(-1) */ -unsigned long sfm_available(struct sfm_block *qm) -{ - /* we don't know how much free memory we have and it's too expensive - * to compute it */ - return ((unsigned long)-1); -} - -#endif diff --git a/src/core/mem/ll_malloc.h b/src/core/mem/ll_malloc.h deleted file mode 100644 index e58020f3e..000000000 --- a/src/core/mem/ll_malloc.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * shared memory, multi-process safe, pool based, mostly lockless version of - * f_malloc - * - * This file is part of Kamailio, a free SIP server. - * - * Copyright (C) 2007 iptelorg GmbH - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#if !defined(ll_malloc_h) -#define ll_malloc_h - - -#include "meminfo.h" - -#include "../lock_ops.h" -#include "../atomic_ops.h" -#include "../compiler_opt.h" -/* defs*/ - - -#ifdef GEN_LOCK_T_UNLIMITED -#define SFM_LOCK_PER_BUCKET -#else -#define SFM_ONE_LOCK -#endif - -#ifdef DBG_SF_MALLOC -#if defined(__CPU_sparc64) || defined(__CPU_sparc) -/* tricky, on sun in 32 bits mode long long must be 64 bits aligned - * but long can be 32 bits aligned => malloc should return long long - * aligned memory */ -#define SF_ROUNDTO sizeof(long long) -#else -#define SF_ROUNDTO \ - sizeof(void *) /* size we round to, must be = 2^n, and - sizeof(sfm_frag) must be multiple of SF_ROUNDTO !*/ -#endif -#else /* DBG_SF_MALLOC */ -#define SF_ROUNDTO 8UL -#endif -#define SF_MIN_FRAG_SIZE SF_ROUNDTO - -#define SFM_POOLS_NO \ - 4U /* the more the better, but higher initial - mem. consumption */ - -#define SF_MALLOC_OPTIMIZE_FACTOR 14UL /*used below */ -#define SF_MALLOC_OPTIMIZE (1UL << SF_MALLOC_OPTIMIZE_FACTOR) -/* size to optimize for, - (most allocs <= this size), - must be 2^k */ - -#define SF_HASH_POOL_SIZE (SF_MALLOC_OPTIMIZE / SF_ROUNDTO + 1) -#define SF_POOL_MAX_SIZE SF_MALLOC_OPTIMIZE - -#define SF_HASH_SIZE \ - (SF_MALLOC_OPTIMIZE / SF_ROUNDTO \ - + (sizeof(long) * 8 - SF_MALLOC_OPTIMIZE_FACTOR) + 1) - -/* hash structure: - * 0 .... SF_MALLOC_OPTIMIZE/SF_ROUNDTO - small buckets, size increases with - * SF_ROUNDTO from bucket to bucket - * +1 .... end - size = 2^k, big buckets */ - -struct sfm_frag -{ - union - { - struct sfm_frag *nxt_free; - long reserved; - } u; - unsigned long size; - unsigned long id; /* TODO better optimize the size */ - /* pad to SF_ROUNDTO multiple */ - char _pad[((3 * sizeof(long) + SF_ROUNDTO - 1) & ~(SF_ROUNDTO - 1)) - - 3 * sizeof(long)]; -#ifdef DBG_SF_MALLOC - const char *file; - const char *func; - unsigned long line; - unsigned long check; -#endif -}; - -struct sfm_frag_lnk -{ - struct sfm_frag *first; -#ifdef SFM_LOCK_PER_BUCKET - gen_lock_t lock; -#endif - unsigned long no; -}; - -struct sfm_pool_head -{ - struct sfm_frag *first; -#ifdef SFM_LOCK_PER_BUCKET - gen_lock_t lock; -#endif - unsigned long no; - unsigned long misses; -}; - -struct sfm_pool -{ -#ifdef SFM_ONE_LOCK - gen_lock_t lock; -#endif - unsigned long missed; - unsigned long hits; /* debugging only TODO: remove */ - unsigned long bitmap; - struct sfm_pool_head pool_hash[SF_HASH_POOL_SIZE]; -}; - -struct sfm_block -{ -#ifdef SFM_ONE_LOCK - gen_lock_t lock; -#endif - atomic_t crt_id; /* current pool */ - int type; /* type of pool */ - unsigned long size; /* total size */ - /* stats are kept now per bucket */ - struct sfm_frag *first_frag; - struct sfm_frag *last_frag; - unsigned long bitmap; /* only up to SF_MALLOC_OPTIMIZE */ - struct sfm_frag_lnk free_hash[SF_HASH_SIZE]; - struct sfm_pool pool[SFM_POOLS_NO]; - int is_init; - gen_lock_t get_and_split; - char _pad[256]; -}; - - -struct sfm_block *sfm_malloc_init(char *address, unsigned long size, int type); -void sfm_malloc_destroy(struct sfm_block *qm); -int sfm_pool_reset(); - -#ifdef DBG_SF_MALLOC -void *sfm_malloc(struct sfm_block *, unsigned long size, const char *file, - const char *func, unsigned int line); -#else -void *sfm_malloc(struct sfm_block *, unsigned long size); -#endif - -#ifdef DBG_SF_MALLOC -void sfm_free(struct sfm_block *, void *p, const char *file, const char *func, - unsigned int line); -#else -void sfm_free(struct sfm_block *, void *p); -#endif - -#ifdef DBG_SF_MALLOC -void *sfm_realloc(struct sfm_block *, void *p, unsigned long size, - const char *file, const char *func, unsigned int line); -#else -void *sfm_realloc(struct sfm_block *, void *p, unsigned long size); -#endif - -void sfm_status(struct sfm_block *); -void sfm_info(struct sfm_block *, struct mem_info *); - -unsigned long sfm_available(struct sfm_block *); - -#endif diff --git a/src/core/mem/memapi.h b/src/core/mem/memapi.h index b9448b4ac..5e25f0630 100644 --- a/src/core/mem/memapi.h +++ b/src/core/mem/memapi.h @@ -21,6 +21,7 @@ #define _sr_mem_api_ #include +#include #include "src_loc.h" #include "meminfo.h" @@ -50,6 +51,7 @@ typedef void (*sr_shm_glock_f)(void *mbp); typedef void (*sr_shm_gunlock_f)(void *mbp); typedef void (*sr_mem_status_f)(void *mbp); +typedef void (*sr_mem_status_filter_f)(void *qmp, str *fmatch, FILE *fp); typedef void (*sr_mem_info_f)(void *mbp, struct mem_info *info); typedef void (*sr_mem_report_f)(void *mbp, mem_report_t *mrep); typedef unsigned long (*sr_mem_available_f)(void *mbp); @@ -60,6 +62,8 @@ typedef void (*sr_mem_destroy_f)(void); typedef void (*sr_mem_mod_get_stats_f)(void *mbp, void **p); typedef void (*sr_mem_mod_free_stats_f)(void *mbp); +typedef void (*sr_setfunc_f)(void *mbp, void *p, char *func); + /*private memory api*/ typedef struct sr_pkg_api { @@ -81,6 +85,8 @@ typedef struct sr_pkg_api sr_free_f xfree; /*memory status*/ sr_mem_status_f xstatus; + /*memory status with filter*/ + sr_mem_status_filter_f xstatus_filter; /*memory info - internal metrics*/ sr_mem_info_f xinfo; /*memory report - internal report*/ @@ -124,6 +130,8 @@ typedef struct sr_shm_api sr_free_f xfree_unsafe; /*memory status*/ sr_mem_status_f xstatus; + /*memory status with filter*/ + sr_mem_status_filter_f xstatus_filter; /*memory info - internal metrics*/ sr_mem_info_f xinfo; /*memory report - internal report*/ @@ -142,6 +150,8 @@ typedef struct sr_shm_api sr_shm_glock_f xglock; /*memory managing global unlock*/ sr_shm_gunlock_f xgunlock; + /*memory chunk set func pointer*/ + sr_setfunc_f xsetfunc; } sr_shm_api_t; #endif diff --git a/src/core/mem/pkg.c b/src/core/mem/pkg.c index 3ad06ec49..803a68fca 100644 --- a/src/core/mem/pkg.c +++ b/src/core/mem/pkg.c @@ -51,6 +51,7 @@ int pkg_init_api(sr_pkg_api_t *ap) _pkg_root.xrealloc = ap->xrealloc; _pkg_root.xreallocxf = ap->xreallocxf; _pkg_root.xstatus = ap->xstatus; + _pkg_root.xstatus_filter = ap->xstatus_filter; _pkg_root.xinfo = ap->xinfo; _pkg_root.xreport = ap->xreport; _pkg_root.xavailable = ap->xavailable; diff --git a/src/core/mem/pkg.h b/src/core/mem/pkg.h index 9b0e5087d..540ac22ce 100644 --- a/src/core/mem/pkg.h +++ b/src/core/mem/pkg.h @@ -65,6 +65,14 @@ void pkg_print_manager(void); #endif #define pkg_status() _pkg_root.xstatus(_pkg_root.mem_block) +#define pkg_status_filter(fmatch, fp) \ + do { \ + if(_pkg_root.xstatus_filter) { \ + _pkg_root.xstatus_filter(_pkg_root.mem_block, fmatch, fp); \ + } else { \ + LM_ERR("pkg status with filter not implemented\n"); \ + } \ + while(0) #define pkg_info(mi) _pkg_root.xinfo(_pkg_root.mem_block, mi) #define pkg_report(mr) _pkg_root.xreport(_pkg_root.mem_block, mr) #define pkg_available() _pkg_root.xavailable(_pkg_root.mem_block) diff --git a/src/core/mem/q_malloc.c b/src/core/mem/q_malloc.c index a3b9161ca..5850c07a0 100644 --- a/src/core/mem/q_malloc.c +++ b/src/core/mem/q_malloc.c @@ -196,12 +196,30 @@ struct qm_block *qm_malloc_init(char *address, unsigned long size, int type) unsigned long init_overhead; int h; - /* make address and size multiple of 8*/ + if((sizeof(struct qm_frag) % ROUNDTO != 0) + || (sizeof(struct qm_frag_end) % ROUNDTO != 0)) { + LM_ERR("memory fragment align constraints failure (%lu %% %lu = %lu " + "::: %lu %% " + "%lu = %lu)\n", + sizeof(struct qm_frag), ROUNDTO, + sizeof(struct qm_frag) % ROUNDTO, sizeof(struct qm_frag_end), + ROUNDTO, sizeof(struct qm_frag_end) % ROUNDTO); + return 0; + } + if(sizeof(struct qm_block) % ROUNDTO != 0) { + LM_ERR("memory block align constraints failure (%lu %% %lu = %lu)\n", + sizeof(struct qm_block), ROUNDTO, + sizeof(struct qm_block) % ROUNDTO); + return 0; + } + /* make address and size multiple of ROUNDTO */ start = (char *)ROUNDUP((unsigned long)address); - LM_DBG("QM_OPTIMIZE=%lu, /ROUNDTO=%lu\n", QM_MALLOC_OPTIMIZE, - QM_MALLOC_OPTIMIZE / ROUNDTO); - LM_DBG("QM_HASH_SIZE=%lu, qm_block size=%lu\n", QM_HASH_SIZE, - (unsigned long)sizeof(struct qm_block)); + LM_DBG("QM_OPTIMIZE=%lu, QM_OPTIMIZE/ROUNDTO=%lu, ROUNDTO=%lu\n", + QM_MALLOC_OPTIMIZE, QM_MALLOC_OPTIMIZE / ROUNDTO, ROUNDTO); + LM_DBG("QM_HASH_SIZE=%lu, qm_block_size=%lu, qm_block_size %% " + "ROUNDTO=%lu\n", + QM_HASH_SIZE, (unsigned long)sizeof(struct qm_block), + (unsigned long)sizeof(struct qm_block) % ROUNDTO); LM_DBG("qm_malloc_init(%p, %lu), start=%p\n", address, (unsigned long)size, start); if(size < start - address) @@ -387,6 +405,8 @@ void *qm_malloc(void *qmp, size_t size) /*malloc(0) should return a valid pointer according to specs*/ if(unlikely(size == 0)) size = 4; + /*add the value of core parameter that can be set for extra safety*/ + size += ksr_mem_add_size; /*size must be a multiple of 8*/ size = ROUNDUP(size); if(size > (qm->size - qm->real_used)) @@ -569,7 +589,7 @@ void qm_free(void *qmp, void *p) qm_detach_free(qm, next); size += next->size + FRAG_OVERHEAD; qm->real_used -= FRAG_OVERHEAD; - qm->free_hash[GET_HASH(next->size)].no--; /* FIXME slow */ + qm->free_hash[GET_HASH(next->size)].no--; qm->ffrags--; } @@ -585,7 +605,7 @@ void qm_free(void *qmp, void *p) qm_detach_free(qm, prev); size += prev->size + FRAG_OVERHEAD; qm->real_used -= FRAG_OVERHEAD; - qm->free_hash[GET_HASH(prev->size)].no--; /* FIXME slow */ + qm->free_hash[GET_HASH(prev->size)].no--; qm->ffrags--; f = prev; } @@ -664,8 +684,9 @@ void *qm_realloc(void *qmp, void *p, size_t size) abort(); } #endif - /* find first acceptable size */ - size = ROUNDUP(size); + /* find first acceptable size + * - consider the value of core parameter that can be set for extra safety */ + size = ROUNDUP(size + ksr_mem_add_size); if(f->size > size) { orig_size = f->size; /* shrink */ @@ -697,7 +718,7 @@ void *qm_realloc(void *qmp, void *p, size_t size) && ((n->size + FRAG_OVERHEAD) >= diff)) { /* join */ qm_detach_free(qm, n); - qm->free_hash[GET_HASH(n->size)].no--; /*FIXME: slow*/ + qm->free_hash[GET_HASH(n->size)].no--; qm->ffrags--; f->size += n->size + FRAG_OVERHEAD; qm->real_used -= FRAG_OVERHEAD; @@ -715,7 +736,9 @@ void *qm_realloc(void *qmp, void *p, size_t size) qm->real_used += (f->size - orig_size); qm->used += (f->size - orig_size); } else { - /* could not join => realloc */ + /* could not join => realloc + * - qm_malloc adds ksr_mem_add_size */ + size = ROUNDUP(size - ksr_mem_add_size); #ifdef DBG_QM_MALLOC ptr = qm_malloc(qm, size, file, func, line, mname); #else @@ -788,6 +811,30 @@ void *qm_reallocxf(void *qmp, void *p, size_t size) } +void qm_setfunc(void *qmp, void *p, char *func) +{ +#ifndef DBG_QM_MALLOC + LM_ERR("used with invalid compile options\n"); + return; +#else + struct qm_block *qm; + struct qm_frag *f; + + qm = (struct qm_block *)qmp; + + if((p) && (p > (void *)qm->last_frag_end || p < (void *)qm->first_frag)) { + LM_CRIT("BUG: bad pointer %p (out of memory block!) - " + "aborting\n", + p); + abort(); + } + f = (struct qm_frag *)((char *)p - sizeof(struct qm_frag)); + + if(f) + f->func = func; +#endif +} + void qm_check(struct qm_block *qm) { struct qm_frag *f; @@ -946,6 +993,126 @@ void qm_status(void *qmp) } +#ifdef DBG_QM_MALLOC +static void *qm_strnstr(const void *b1, int l1, const void *b2, int l2) +{ + char *sp = (char *)b1; + char *pp = (char *)b2; + char *eos = sp + l1 - l2; + + if(!(b1 && b2 && l1 && l2)) + return NULL; + + while(sp <= eos) { + if(*sp == *pp) + if(memcmp(sp, pp, l2) == 0) + return sp; + + sp++; + } + + return NULL; +} +#endif + +void qm_status_filter(void *qmp, str *fmatch, FILE *fp) +{ + struct qm_block *qm; + struct qm_frag *f; + int i, j; + int h; + int unused; + + qm = (struct qm_block *)qmp; + + fprintf(fp, "block address: %p\n", qm); + if(!qm) + return; + + fprintf(fp, "heap size= %lu\n", qm->size); + fprintf(fp, "used= %lu, used+overhead=%lu, free=%lu\n", qm->used, + qm->real_used, qm->size - qm->real_used); + fprintf(fp, "max used (+overhead)= %lu\n", qm->max_real_used); + + fprintf(fp, "--- allocated fragments:\n"); + for(f = qm->first_frag, i = 0; (char *)f < (char *)qm->last_frag_end; + f = FRAG_NEXT(f), i++) { + if(!f->u.is_free) { +#ifdef DBG_QM_MALLOC + if((fmatch == NULL) || (fmatch->len == 0) + || ((strlen(f->file) >= fmatch->len) + && (qm_strnstr(f->file, strlen(f->file), fmatch->s, + fmatch->len) + != NULL))) { + fprintf(fp, " %3d. %c address=%p frag=%p size=%lu used=%d\n", + i, (f->u.is_free) ? 'A' : 'N', + (char *)f + sizeof(struct qm_frag), f, f->size, + FRAG_WAS_USED(f)); + fprintf(fp, " %s from %s:%ld / %s()\n", + (f->u.is_free) ? "freed" : "alloc'd", f->file, f->line, + f->func); + fprintf(fp, " start check=%lx, end check= %lx, %lx\n", + f->check, FRAG_END(f)->check1, FRAG_END(f)->check2); + if(f->check != ST_CHECK_PATTERN) { + fprintf(fp, " * beginning overwritten(%lx)!\n", + f->check); + } + if((FRAG_END(f)->check1 != END_CHECK_PATTERN1) + || (FRAG_END(f)->check2 != END_CHECK_PATTERN2)) { + fprintf(fp, " * end overwritten(%lx, %lx)!\n", + FRAG_END(f)->check1, FRAG_END(f)->check2); + } + } +#else + fprintf(fp, " %3d. %c address=%p frag=%p size=%lu used=%d\n", i, + (f->u.is_free) ? 'A' : 'N', + (char *)f + sizeof(struct qm_frag), f, f->size, + FRAG_WAS_USED(f)); +#endif + } + } + fprintf(fp, "\n\n--- dumping free list stats:\n"); + for(h = 0, i = 0; h < QM_HASH_SIZE; h++) { + unused = 0; + for(f = qm->free_hash[h].head.u.nxt_free, j = 0; + f != &(qm->free_hash[h].head); f = f->u.nxt_free, i++, j++) { + if(!FRAG_WAS_USED(f)) { + unused++; +#ifdef DBG_QM_MALLOC + if((fmatch == NULL) || (fmatch->len == 0) + || ((strlen(f->file) >= fmatch->len) + && (qm_strnstr(f->file, strlen(f->file), + fmatch->s, fmatch->len) + != NULL))) { + fprintf(fp, + "unused fragm.: hash = %3d, fragment %p," + " address %p size %lu, created from %s:%lu / " + "%s()\n", + h, f, (char *)f + sizeof(struct qm_frag), f->size, + f->file, f->line, f->func); + } +#endif + } + } + + if(j) + fprintf(fp, + "hash= %3d. fragments no.: %5d, unused: %5d\n" + "\t\t bucket size: %9lu - %9ld (first %9lu)\n", + h, j, unused, UN_HASH(h), + ((h <= QM_MALLOC_OPTIMIZE / ROUNDTO) ? 1 : 2) * UN_HASH(h), + qm->free_hash[h].head.u.nxt_free->size); + if(j != qm->free_hash[h].no) { + LOG(L_CRIT, + "--- different free frag. count: %d!=%lu" + " for hash %3d\n", + j, qm->free_hash[h].no, h); + } + } + fprintf(fp, "\n-----------------------------\n"); +} + + /* fills a malloc info structure with info about the block * if a parameter is not supported, it will be filled with 0 */ void qm_info(void *qmp, struct mem_info *info) @@ -1233,6 +1400,7 @@ int qm_malloc_init_pkg_manager(void) ma.xrealloc = qm_realloc; ma.xreallocxf = qm_reallocxf; ma.xstatus = qm_status; + ma.xstatus_filter = qm_status_filter; ma.xinfo = qm_info; ma.xreport = qm_report; ma.xavailable = qm_available; @@ -1420,6 +1588,12 @@ void qm_shm_status(void *qmp) qm_status(qmp); qm_shm_unlock(); } +void qm_shm_status_filter(void *qmp, str *fmatch, FILE *fp) +{ + qm_shm_lock(); + qm_status_filter(qmp, fmatch, fp); + qm_shm_unlock(); +} void qm_shm_info(void *qmp, struct mem_info *info) { qm_shm_lock(); @@ -1498,6 +1672,7 @@ int qm_malloc_init_shm_manager(void) ma.xreallocxf = qm_shm_reallocxf; ma.xresize = qm_shm_resize; ma.xstatus = qm_shm_status; + ma.xstatus_filter = qm_shm_status_filter; ma.xinfo = qm_shm_info; ma.xreport = qm_shm_report; ma.xavailable = qm_shm_available; @@ -1507,6 +1682,7 @@ int qm_malloc_init_shm_manager(void) ma.xfmodstats = qm_shm_mod_free_stats; ma.xglock = qm_shm_glock; ma.xgunlock = qm_shm_gunlock; + ma.xsetfunc = qm_setfunc; if(shm_init_api(&ma) < 0) { LM_ERR("cannot initialize the core shm api\n"); diff --git a/src/core/mem/q_malloc.h b/src/core/mem/q_malloc.h index 71ca3f77d..5b440688a 100644 --- a/src/core/mem/q_malloc.h +++ b/src/core/mem/q_malloc.h @@ -33,33 +33,26 @@ #define DBG_QM_MALLOC #endif -/* defs*/ -#ifdef DBG_QM_MALLOC -#if defined(__CPU_sparc64) || defined(__CPU_sparc) -/* tricky, on sun in 32 bits mode long long must be 64 bits aligned - * but long can be 32 bits aligned => malloc should return long long - * aligned memory */ -#define ROUNDTO sizeof(long long) +/** + * ROUNDTO: size to round to, must be = 2^n + * - on sun in 32 bits mode long long must be 64 bits aligned but long + * can be 32 bits aligned => malloc should return multiple of long long + * aligned memory + * - malloc() on gnu/linux: multiple of 8 or 16 on 64-bit systems + * - for simplicity settle for 16 by default + * - sizeof(qm_frag) and sizeof(qm_frag_end) must be multiple of ROUNDTO! + */ +#ifndef KSR_MEMORY_ALIGN +#define ROUNDTO 16UL #else -#define ROUNDTO \ - sizeof(void *) /* minimum possible ROUNDTO - * ->heavy debugging*/ -#endif -#else /* DBG_QM_MALLOC */ -#define ROUNDTO \ - 16UL /* size we round to, must be = 2^n and also - * sizeof(qm_frag)+sizeof(qm_frag_end) - * must be multiple of ROUNDTO! - */ +#define ROUNDTO KSR_MEMORY_ALIGN #endif -#define MIN_FRAG_SIZE ROUNDTO +#define MIN_FRAG_SIZE ROUNDTO -#define QM_MALLOC_OPTIMIZE_FACTOR 14UL /*used below */ +#define QM_MALLOC_OPTIMIZE_FACTOR 15UL /*used below */ +/* size to optimize for, (most allocs <= this size), must be 2^k */ #define QM_MALLOC_OPTIMIZE ((unsigned long)(1UL << QM_MALLOC_OPTIMIZE_FACTOR)) -/* size to optimize for, - (most allocs <= this size), - must be 2^k */ #define QM_HASH_SIZE \ ((unsigned long)(QM_MALLOC_OPTIMIZE / ROUNDTO \ @@ -70,6 +63,7 @@ * ROUNDTO from bucket to bucket * +1 .... end - size = 2^k, big buckets */ +/* start of QM fragment - its size has to be multiple of ROUNDTO */ struct qm_frag { unsigned long size; @@ -84,9 +78,11 @@ struct qm_frag const char *mname; unsigned long line; unsigned long check; + unsigned long reserved1; #endif }; +/* end of QM fragment - its size has to be multiple of ROUNDTO */ struct qm_frag_end { #ifdef DBG_QM_MALLOC @@ -105,6 +101,7 @@ struct qm_frag_lnk struct qm_frag head; struct qm_frag_end tail; unsigned long no; + unsigned long reserved1; }; @@ -115,7 +112,7 @@ struct qm_frag_lnk struct qm_block { - int type; /* type of memory */ + long type; /* type of memory */ unsigned long size; /* total size */ unsigned long used; /* alloc'ed size*/ unsigned long real_used; /* used+malloc overhead*/ diff --git a/src/core/mem/sf_malloc.c b/src/core/mem/sf_malloc.c deleted file mode 100644 index 932a9c33d..000000000 --- a/src/core/mem/sf_malloc.c +++ /dev/null @@ -1,1118 +0,0 @@ -/* - * shared memory, multi-process safe, pool based version of f_malloc - * - * This file is part of Kamailio, a free SIP server. - * - * Copyright (C) 2007 iptelorg GmbH - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifdef SF_MALLOC - -#include -#include - -#include "sf_malloc.h" -#include "../dprint.h" -#include "../globals.h" -#include "memdbg.h" -#include "../cfg/cfg.h" /* memlog */ - -#define MAX_POOL_FRAGS 10000 /* max fragments per pool hash bucket */ -#define MIN_POOL_FRAGS 10 /* min fragments per pool hash bucket */ - -/*useful macros*/ - -#define FRAG_NEXT(f) \ - ((struct sfm_frag *)((char *)(f) + sizeof(struct sfm_frag) + (f)->size)) - - -/* SF_ROUNDTO= 2^k so the following works */ -#define ROUNDTO_MASK (~((unsigned long)SF_ROUNDTO - 1)) -#define ROUNDUP(s) (((s) + (SF_ROUNDTO - 1)) & ROUNDTO_MASK) -#define ROUNDDOWN(s) ((s)&ROUNDTO_MASK) - -#define FRAG_OVERHEAD (sizeof(struct sfm_frag)) -#define INIT_OVERHEAD \ - (ROUNDUP(sizeof(struct sfm_block)) + sizeof(struct sfm_frag)) - - -/* finds hash if s <=SF_MALLOC_OPTIMIZE */ -#define GET_SMALL_HASH(s) (unsigned long)(s) / SF_ROUNDTO -/* finds hash if s > SF_MALLOC_OPTIMIZE */ -#define GET_BIG_HASH(s) \ - (SF_MALLOC_OPTIMIZE / SF_ROUNDTO + big_hash_idx((s)) \ - - SF_MALLOC_OPTIMIZE_FACTOR + 1) - -/* finds the hash value for s, s=SF_ROUNDTO multiple*/ -#define GET_HASH(s) \ - (((unsigned long)(s) <= SF_MALLOC_OPTIMIZE) ? GET_SMALL_HASH(s) \ - : GET_BIG_HASH(s)) - - -#define UN_HASH_SMALL(h) ((unsigned long)(h)*SF_ROUNDTO) -#define UN_HASH_BIG(h) \ - (1UL << ((unsigned long)(h)-SF_MALLOC_OPTIMIZE / SF_ROUNDTO \ - + SF_MALLOC_OPTIMIZE_FACTOR - 1)) - -#define UN_HASH(h) \ - (((unsigned long)(h) <= (SF_MALLOC_OPTIMIZE / SF_ROUNDTO)) \ - ? UN_HASH_SMALL(h) \ - : UN_HASH_BIG(h)) - -#define BITMAP_BITS (sizeof(((struct sfm_block *)0)->bitmap) * 8) -#define BITMAP_BLOCK_SIZE ((SF_MALLOC_OPTIMIZE / SF_ROUNDTO) / BITMAP_BITS) -/* only for "small" hashes (up to HASH(SF_MALLOC_OPTIMIZE) */ -#define HASH_BIT_POS(h) (((unsigned long)(h)) / BITMAP_BLOCK_SIZE) -#define HASH_TO_BITMAP(h) (1UL << HASH_BIT_POS(h)) -#define BIT_TO_HASH(b) ((b)*BITMAP_BLOCK_SIZE) - - -/* mark/test used/unused frags */ -#define FRAG_MARK_USED(f) -#define FRAG_CLEAR_USED(f) -#define FRAG_WAS_USED(f) (1) - -/* other frag related defines: - * MEM_COALESCE_FRAGS - * MEM_FRAG_AVOIDANCE - */ -#define MEM_FRAG_AVOIDANCE - - -#define SFM_REALLOC_REMALLOC - -/* computes hash number for big buckets*/ -inline static unsigned long big_hash_idx(unsigned long s) -{ - unsigned long idx; - /* s is rounded => s = k*2^n (SF_ROUNDTO=2^n) - * index= i such that 2^i > s >= 2^(i-1) - * - * => index = number of the first non null bit in s*/ - idx = sizeof(long) * 8 - 1; - for(; !(s & (1UL << (sizeof(long) * 8 - 1))); s <<= 1, idx--) - ; - return idx; -} - - -#ifdef DBG_SF_MALLOC -#define ST_CHECK_PATTERN 0xf0f0f0f0 -#define END_CHECK_PATTERN1 0xc0c0c0c0 -#define END_CHECK_PATTERN2 0xabcdefed -#endif - - -#ifdef SFM_ONE_LOCK - -#define SFM_MAIN_HASH_LOCK(qm, hash) lock_get(&(qm)->lock) -#define SFM_MAIN_HASH_UNLOCK(qm, hash) lock_release(&(qm)->lock) -#define SFM_POOL_LOCK(p, hash) lock_get(&(p)->lock) -#define SFM_POOL_UNLOCK(p, hash) lock_release(&(p)->lock) - -#warn "degraded performance, only one lock" - -#elif defined SFM_LOCK_PER_BUCKET - -#define SFM_MAIN_HASH_LOCK(qm, hash) lock_get(&(qm)->free_hash[(hash)].lock) -#define SFM_MAIN_HASH_UNLOCK(qm, hash) \ - lock_release(&(qm)->free_hash[(hash)].lock) -#define SFM_POOL_LOCK(p, hash) lock_get(&(p)->pool_hash[(hash)].lock) -#define SFM_POOL_UNLOCK(p, hash) lock_release(&(p)->pool_hash[(hash)].lock) -#else -#error no locks defined -#endif /* SFM_ONE_LOCK/SFM_LOCK_PER_BUCKET */ - -#define SFM_BIG_GET_AND_SPLIT_LOCK(qm) lock_get(&(qm)->get_and_split) -#define SFM_BIG_GET_AND_SPLIT_UNLOCK(qm) lock_release(&(qm)->get_and_split) - -static unsigned long sfm_max_hash = 0; /* maximum hash value (no point in - searching further) */ -static unsigned long pool_id = (unsigned long)-1; - - -/* call for each child */ -int sfm_pool_reset() -{ - pool_id = (unsigned long)-1; - return 0; -} - - -#define sfm_fix_pool_id(qm) \ - do { \ - if(unlikely(pool_id >= SFM_POOLS_NO)) \ - pool_id = ((unsigned)atomic_add(&(qm)->crt_id, 1)) % SFM_POOLS_NO; \ - } while(0) - - -static inline void frag_push(struct sfm_frag **head, struct sfm_frag *frag) -{ - frag->u.nxt_free = *head; - *head = frag; -} - - -static inline struct sfm_frag *frag_pop(struct sfm_frag **head) -{ - struct sfm_frag *frag; - frag = *head; - *head = frag->u.nxt_free; - return frag; -} - -static inline void sfm_pool_insert( - struct sfm_pool *pool, int hash, struct sfm_frag *frag) -{ - unsigned long hash_bit; - - SFM_POOL_LOCK(pool, hash); - frag_push(&pool->pool_hash[hash].first, frag); - pool->pool_hash[hash].no++; - /* set it only if not already set (avoids an expensive - * cache trashing atomic write op) */ - hash_bit = HASH_TO_BITMAP(hash); - if(!(atomic_get_long((long *)&pool->bitmap) & hash_bit)) - atomic_or_long((long *)&pool->bitmap, hash_bit); - SFM_POOL_UNLOCK(pool, hash); -} - - -/* returns 1 if it's ok to add a fragm. to pool p_id @ hash, 0 otherwise */ -static inline int sfm_check_pool( - struct sfm_block *qm, unsigned long p_id, int hash, int split) -{ - /* TODO: come up with something better - * if fragment is some split/rest from an allocation, that is - * >= requested size, accept it, else - * look at misses and current fragments and decide based on them */ - return (p_id < SFM_POOLS_NO) - && (split - || ((qm->pool[p_id].pool_hash[hash].no < MIN_POOL_FRAGS) - || ((qm->pool[p_id].pool_hash[hash].misses - > qm->pool[p_id].pool_hash[hash].no) - && (qm->pool[p_id].pool_hash[hash].no - < MAX_POOL_FRAGS)))); -} - - -/* choose on which pool to add a free'd packet - * return - pool idx or -1 if it should be added to main*/ -static inline unsigned long sfm_choose_pool( - struct sfm_block *qm, struct sfm_frag *frag, int hash, int split) -{ - /* check original pool first */ - if(sfm_check_pool(qm, frag->id, hash, split)) - return frag->id; - else { - /* check if our pool is properly set */ - sfm_fix_pool_id(qm); - /* check if my pool needs some frags */ - if((pool_id != frag->id) && (sfm_check_pool(qm, pool_id, hash, 0))) { - frag->id = pool_id; - return pool_id; - } - } - /* else add it back to main */ - frag->id = (unsigned long)(-1); - return frag->id; -} - - -static inline void sfm_insert_free( - struct sfm_block *qm, struct sfm_frag *frag, int split) -{ - struct sfm_frag **f; - unsigned long p_id; - int hash; - unsigned long hash_bit; - - if(likely(frag->size <= SF_POOL_MAX_SIZE)) { - hash = GET_SMALL_HASH(frag->size); - if(unlikely((p_id = sfm_choose_pool(qm, frag, hash, split)) - == (unsigned long)-1)) { - /* add it back to the "main" hash */ - SFM_MAIN_HASH_LOCK(qm, hash); - frag->id = (unsigned long)(-1); /* main hash marker */ - /*insert it here*/ - frag_push(&(qm->free_hash[hash].first), frag); - qm->free_hash[hash].no++; - /* set it only if not already set (avoids an expensive - * cache trashing atomic write op) */ - hash_bit = HASH_TO_BITMAP(hash); - if(!(atomic_get_long((long *)&qm->bitmap) & hash_bit)) - atomic_or_long((long *)&qm->bitmap, hash_bit); - SFM_MAIN_HASH_UNLOCK(qm, hash); - } else { - /* add it to one of the pools pool */ - sfm_pool_insert(&qm->pool[p_id], hash, frag); - } - } else { - hash = GET_BIG_HASH(frag->size); - SFM_MAIN_HASH_LOCK(qm, hash); - f = &(qm->free_hash[hash].first); - for(; *f; f = &((*f)->u.nxt_free)) - if(frag->size <= (*f)->size) - break; - frag->id = (unsigned long)(-1); /* main hash marker */ - /*insert it here*/ - frag->u.nxt_free = *f; - *f = frag; - qm->free_hash[hash].no++; - /* inc. big hash free size ? */ - SFM_MAIN_HASH_UNLOCK(qm, hash); - } -} - - -/* size should be already rounded-up */ -static inline -#ifdef DBG_SF_MALLOC - void - sfm_split_frag(struct sfm_block *qm, struct sfm_frag *frag, - unsigned long size, const char *file, const char *func, - unsigned int line) -#else - void - sfm_split_frag( - struct sfm_block *qm, struct sfm_frag *frag, unsigned long size) -#endif -{ - unsigned long rest; - struct sfm_frag *n; - int bigger_rest; - - rest = frag->size - size; -#ifdef MEM_FRAG_AVOIDANCE - if((rest > (FRAG_OVERHEAD + SF_MALLOC_OPTIMIZE)) - || (rest >= (FRAG_OVERHEAD - + size))) { /* the residue fragm. is big enough*/ - bigger_rest = 1; -#else - if(rest > (FRAG_OVERHEAD + SF_MIN_FRAG_SIZE)) { - bigger_rest = rest >= (size + FRAG_OVERHEAD); -#endif - frag->size = size; - /*split the fragment*/ - n = FRAG_NEXT(frag); - n->size = rest - FRAG_OVERHEAD; - n->id = pool_id; - FRAG_CLEAR_USED(n); /* never used */ -#ifdef DBG_SF_MALLOC - /* frag created by malloc, mark it*/ - n->file = file; - n->func = "frag. from sfm_malloc"; - n->line = line; - n->check = ST_CHECK_PATTERN; -#endif - /* reinsert n in free list*/ - sfm_insert_free(qm, n, bigger_rest); - } else { - /* we cannot split this fragment any more => alloc all of it*/ - } -} - - -/* init malloc and return a sfm_block*/ -struct sfm_block *sfm_malloc_init(char *address, unsigned long size, int type) -{ - char *start; - char *end; - struct sfm_block *qm; - unsigned long init_overhead; - int r; -#ifdef SFM_LOCK_PER_BUCKET - int i; -#endif - - /* make address and size multiple of 8*/ - start = (char *)ROUNDUP((unsigned long)address); - LM_DBG("SF_OPTIMIZE=%lu, /SF_ROUNDTO=%lu\n", SF_MALLOC_OPTIMIZE, - SF_MALLOC_OPTIMIZE / SF_ROUNDTO); - LM_DBG("SF_HASH_SIZE=%lu, sfm_block size=%lu\n", SF_HASH_SIZE, - (long)sizeof(struct sfm_block)); - LM_DBG("sfm_malloc_init(%p, %lu), start=%p\n", address, size, start); - - if(size < start - address) - return 0; - size -= (start - address); - if(size < (SF_MIN_FRAG_SIZE + FRAG_OVERHEAD)) - return 0; - size = ROUNDDOWN(size); - - init_overhead = INIT_OVERHEAD; - - if(size < init_overhead) { - /* not enough mem to create our control structures !!!*/ - return 0; - } - end = start + size; - qm = (struct sfm_block *)start; - memset(qm, 0, sizeof(struct sfm_block)); - qm->size = size; - qm->type = type; - size -= init_overhead; - - qm->first_frag = - (struct sfm_frag *)(start + ROUNDUP(sizeof(struct sfm_block))); - qm->last_frag = (struct sfm_frag *)(end - sizeof(struct sfm_frag)); - /* init initial fragment*/ - qm->first_frag->size = size; - qm->first_frag->id = (unsigned long)-1; /* not in a pool */ - qm->last_frag->size = 0; - -#ifdef DBG_SF_MALLOC - qm->first_frag->check = ST_CHECK_PATTERN; - qm->last_frag->check = END_CHECK_PATTERN1; -#endif - - /* link initial fragment into the free list*/ - - sfm_insert_free(qm, qm->first_frag, 0); - sfm_max_hash = GET_HASH(size); - - /* init locks */ - if(lock_init(&qm->get_and_split) == 0) - goto error; -#ifdef SFM_ONE_LOCK - if(lock_init(&qm->lock) == 0) { - lock_destroy(&qm->get_and_split); - goto error; - } - for(r = 0; r < SFM_POOLS_NO; r++) { - if(lock_init(&qm->pool[r].lock) == 0) { - for(; r > 0; r--) - lock_destroy(&qm->pool[r - 1].lock); - lock_destroy(&qm->lock); - lock_destroy(&qm->get_and_split); - goto error; - } - } -#elif defined(SFM_LOCK_PER_BUCKET) - for(r = 0; r < SF_HASH_SIZE; r++) - if(lock_init(&qm->free_hash[r].lock) == 0) { - for(; r > 0; r--) - lock_destroy(&qm->free_hash[r - 1].lock); - lock_destroy(&qm->get_and_split); - goto error; - } - for(i = 0; i < SFM_POOLS_NO; i++) { - for(r = 0; r < SF_HASH_POOL_SIZE; r++) - if(lock_init(&qm->pool[i].pool_hash[r].lock) == 0) { - for(; r > 0; r--) - lock_destroy(&qm->pool[i].poo_hash[r].lock); - for(; i > 0; i--) { - for(r = 0; r < SF_HASH_POOL_SIZE; r++) - lock_destroy(&qm->pool[i].pool_hash[r].lock); - } - for(r = 0; r < SF_HASH_SIZE; r++) - lock_destroy(&qm->free_hash[r].lock); - lock_destroy(&qm->get_and_split); - goto error; - } - } -#endif - qm->is_init = 1; - return qm; -error: - return 0; -} - - -/* cleanup */ -void sfm_malloc_destroy(struct sfm_block *qm) -{ - int r, i; - /* destroy all the locks */ - if(!qm || !qm->is_init) - return; /* nothing to do */ - lock_destroy(&qm->get_and_split); -#ifdef SFM_ONE_LOCK - lock_destroy(&qm->lock); - for(r = 0; r < SFM_POOLS_NO; r++) { - lock_destroy(&qm->pool[r].lock); - } -#elif defined(SFM_LOCK_PER_BUCKET) - for(r = 0; r < SF_HASH_SIZE; r++) - lock_destroy(&qm->free_hash[r].lock); - for(i = 0; i < SFM_POOLS_NO; i++) { - for(r = 0; r < SF_HASH_POOL_SIZE; r++) - lock_destroy(&qm->pool[i].pool_hash[r].lock); - } -#endif - qm->is_init = 0; -} - - -/* returns next set bit in bitmap, starts at b - * if b is set, returns b - * if not found returns BITMAP_BITS */ -static inline unsigned long _next_set_bit( - unsigned long b, unsigned long *bitmap) -{ - for(; !((1UL << b) & *bitmap) && b < BITMAP_BITS; b++) - ; - return b; -} - -/* returns start of block b and sets *end - * (handles also the "rest" block at the end ) */ -static inline unsigned long _hash_range(unsigned long b, unsigned long *end) -{ - unsigned long s; - - if((unlikely(b >= BITMAP_BITS))) { - s = BIT_TO_HASH(BITMAP_BITS); - *end = SF_HASH_POOL_SIZE; /* last, possible rest block */ - } else { - s = BIT_TO_HASH(b); - *end = s + BITMAP_BLOCK_SIZE; - } - return s; -} - - -#ifdef DBG_SF_MALLOC -static inline struct sfm_frag *pool_get_frag(struct sfm_block *qm, - struct sfm_pool *pool, int hash, unsigned long size, const char *file, - const char *func, unsigned int line) -#else -static inline struct sfm_frag *pool_get_frag(struct sfm_block *qm, - struct sfm_pool *pool, int hash, unsigned long size) -#endif -{ - int r; - int next_block; - struct sfm_frag *volatile *f; - struct sfm_frag *frag; - unsigned long b; - unsigned long eob; - - /* special case for r=hash */ - r = hash; - f = &pool->pool_hash[r].first; - if(*f == 0) - goto not_found; - SFM_POOL_LOCK(pool, r); - if(unlikely(*f == 0)) { - SFM_POOL_UNLOCK(pool, r); - goto not_found; - } -found: - /* detach it from the free list*/ - frag = frag_pop((struct sfm_frag **)f); - frag->u.nxt_free = 0; /* mark it as 'taken' */ - frag->id = pool_id; - pool->pool_hash[r].no--; - SFM_POOL_UNLOCK(pool, r); -#ifdef DBG_SF_MALLOC - sfm_split_frag(qm, frag, size, file, func, line); -#else - sfm_split_frag(qm, frag, size); -#endif - if(&qm->pool[pool_id] == pool) - atomic_inc_long((long *)&pool->hits); - return frag; - -not_found: - atomic_inc_long((long *)&pool->pool_hash[r].misses); - r++; - b = HASH_BIT_POS(r); - - while(r < SF_HASH_POOL_SIZE) { - b = _next_set_bit(b, &pool->bitmap); - next_block = _hash_range(b, &eob); - r = (r < next_block) ? next_block : r; - for(; r < eob; r++) { - f = &pool->pool_hash[r].first; - if(*f) { - SFM_POOL_LOCK(pool, r); - if(unlikely(*f == 0)) { - /* not found */ - SFM_POOL_UNLOCK(pool, r); - } else - goto found; - } - atomic_inc_long((long *)&pool->pool_hash[r].misses); - } - b++; - } -#if 0 /* EXPENSIVE BUG CHECK */ - for (r=hash; rpool_hash[r].first; - if (*f){ - SFM_POOL_LOCK(pool, r); - if (unlikely(*f==0)){ - /* not found */ - SFM_POOL_UNLOCK(pool, r); - }else{ - b=_next_set_bit(HASH_BIT_POS(r), &pool->bitmap); - next_block=_hash_range(b, &eob); - BUG("pool_get_frag: found fragm. %d at %d (bit %ld range %ld-%ld), next set bit=%ld" - " bitmap %ld (%p)\n", hash, r, HASH_BIT_POS(r), - next_block, eob, b, pool->bitmap, &pool->bitmap); - goto found; - } - } - } -#endif - atomic_inc_long((long *)&pool->missed); - return 0; -} - - -#ifdef DBG_SF_MALLOC -static inline struct sfm_frag *main_get_frag(struct sfm_block *qm, int hash, - unsigned long size, const char *file, const char *func, - unsigned int line) -#else -static inline struct sfm_frag *main_get_frag( - struct sfm_block *qm, int hash, unsigned long size) -#endif -{ - int r; - int next_block; - struct sfm_frag *volatile *f; - struct sfm_frag *frag; - unsigned long b; - unsigned long eob; - - r = hash; - b = HASH_BIT_POS(r); - while(r <= SF_MALLOC_OPTIMIZE / SF_ROUNDTO) { - b = _next_set_bit(b, &qm->bitmap); - next_block = _hash_range(b, &eob); - r = (r < next_block) ? next_block : r; - for(; r < eob; r++) { - f = &qm->free_hash[r].first; - if(*f) { - SFM_MAIN_HASH_LOCK(qm, r); - if(unlikely(*f == 0)) { - /* not found, somebody stole it */ - SFM_MAIN_HASH_UNLOCK(qm, r); - continue; - } - /* detach it from the free list*/ - frag = frag_pop((struct sfm_frag **)f); - frag->u.nxt_free = 0; /* mark it as 'taken' */ - qm->free_hash[r].no--; - SFM_MAIN_HASH_UNLOCK(qm, r); - frag->id = pool_id; -#ifdef DBG_SF_MALLOC - sfm_split_frag(qm, frag, size, file, func, line); -#else - sfm_split_frag(qm, frag, size); -#endif - return frag; - } - } - b++; - } - /* big fragments */ - SFM_BIG_GET_AND_SPLIT_LOCK(qm); - for(; r <= sfm_max_hash; r++) { - f = &qm->free_hash[r].first; - if(*f) { - SFM_MAIN_HASH_LOCK(qm, r); - if(unlikely((*f) == 0)) { - /* not found */ - SFM_MAIN_HASH_UNLOCK(qm, r); - continue; - } - for(; (*f); f = &((*f)->u.nxt_free)) - if((*f)->size >= size) { - /* found, detach it from the free list*/ - frag = *f; - *f = frag->u.nxt_free; - frag->u.nxt_free = 0; /* mark it as 'taken' */ - qm->free_hash[r].no--; - SFM_MAIN_HASH_UNLOCK(qm, r); - frag->id = pool_id; -#ifdef DBG_SF_MALLOC - sfm_split_frag(qm, frag, size, file, func, line); -#else - sfm_split_frag(qm, frag, size); -#endif - SFM_BIG_GET_AND_SPLIT_UNLOCK(qm); - return frag; - }; - SFM_MAIN_HASH_UNLOCK(qm, r); - /* try in a bigger bucket */ - } - } - SFM_BIG_GET_AND_SPLIT_UNLOCK(qm); - return 0; -} - - -#ifdef DBG_SF_MALLOC -void *sfm_malloc(struct sfm_block *qm, unsigned long size, const char *file, - const char *func, unsigned int line) -#else -void *sfm_malloc(struct sfm_block *qm, unsigned long size) -#endif -{ - struct sfm_frag *frag; - int hash; - unsigned int i; - -#ifdef DBG_SF_MALLOC - MDBG("sfm_malloc(%p, %lu) called from %s: %s(%d)\n", qm, size, file, func, - line); -#endif - /*size must be a multiple of 8*/ - size = ROUNDUP(size); - /* if (size>(qm->size-qm->real_used)) return 0; */ - - /* check if our pool id is set */ - sfm_fix_pool_id(qm); - - /*search for a suitable free frag*/ - if(likely(size <= SF_POOL_MAX_SIZE)) { - hash = GET_SMALL_HASH(size); -/* try first in our pool */ -#ifdef DBG_SF_MALLOC - if(likely((frag = pool_get_frag(qm, &qm->pool[pool_id], hash, size, - file, func, line)) - != 0)) - goto found; - /* try in the "main" free hash, go through all the hash */ - if(likely((frag = main_get_frag(qm, hash, size, file, func, line)) - != 0)) - goto found; - /* really low mem , try in other pools */ - for(i = (pool_id + 1); i < (pool_id + SFM_POOLS_NO); i++) { - if((frag = pool_get_frag(qm, &qm->pool[i % SFM_POOLS_NO], hash, - size, file, func, line)) - != 0) - goto found; - } -#else - if(likely((frag = pool_get_frag(qm, &qm->pool[pool_id], hash, size)) - != 0)) - goto found; - /* try in the "main" free hash, go through all the hash */ - if(likely((frag = main_get_frag(qm, hash, size)) != 0)) - goto found; - /* really low mem , try in other pools */ - for(i = (pool_id + 1); i < (pool_id + SFM_POOLS_NO); i++) { - if((frag = pool_get_frag( - qm, &qm->pool[i % SFM_POOLS_NO], hash, size)) - != 0) - goto found; - } -#endif - /* not found, bad! */ - return 0; - } else { - hash = GET_BIG_HASH(size); -#ifdef DBG_SF_MALLOC - if((frag = main_get_frag(qm, hash, size, file, func, line)) == 0) - return 0; /* not found, bad! */ -#else - if((frag = main_get_frag(qm, hash, size)) == 0) - return 0; /* not found, bad! */ -#endif - } - -found: -/* we found it!*/ -#ifdef DBG_SF_MALLOC - frag->file = file; - frag->func = func; - frag->line = line; - frag->check = ST_CHECK_PATTERN; - MDBG("sfm_malloc(%p, %lu) returns address %p \n", qm, size, - (char *)frag + sizeof(struct sfm_frag)); -#endif - FRAG_MARK_USED(frag); /* mark it as used */ - return (char *)frag + sizeof(struct sfm_frag); -} - - -#ifdef DBG_SF_MALLOC -void sfm_free(struct sfm_block *qm, void *p, const char *file, const char *func, - unsigned int line) -#else -void sfm_free(struct sfm_block *qm, void *p) -#endif -{ - struct sfm_frag *f; - -#ifdef DBG_SF_MALLOC - MDBG("sfm_free(%p, %p), called from %s: %s(%d)\n", qm, p, file, func, line); - if(p > (void *)qm->last_frag || p < (void *)qm->first_frag) { - LM_CRIT("BUG: bad pointer %p (out of memory block!) - " - "aborting\n", - p); - abort(); - } -#endif - if(unlikely(p == 0)) { - LM_WARN("WARNING: free(0) called\n"); - return; - } - f = (struct sfm_frag *)((char *)p - sizeof(struct sfm_frag)); -#ifdef DBG_SF_MALLOC - MDBG("sfm_free: freeing block alloc'ed from %s: %s(%ld)\n", f->file, - f->func, f->line); -#endif -#ifdef DBG_SF_MALLOC - f->file = file; - f->func = func; - f->line = line; -#endif - sfm_insert_free(qm, f, 0); -} - - -#ifdef DBG_SF_MALLOC -void *sfm_realloc(struct sfm_block *qm, void *p, unsigned long size, - const char *file, const char *func, unsigned int line) -#else -void *sfm_realloc(struct sfm_block *qm, void *p, unsigned long size) -#endif -{ - struct sfm_frag *f; - unsigned long orig_size; - void *ptr; -#ifndef SFM_REALLOC_REMALLOC - struct sfm_frag *n; - struct sfm_frag **pf; - unsigned long diff; - unsigned long p_id; - int hash; - unsigned long n_size; - struct sfm_pool *pool; -#endif - -#ifdef DBG_SF_MALLOC - MDBG("sfm_realloc(%p, %p, %lu) called from %s: %s(%d)\n", qm, p, size, file, - func, line); - if((p) && (p > (void *)qm->last_frag || p < (void *)qm->first_frag)) { - LM_CRIT("BUG: bad pointer %p (out of memory block!) - " - "aborting\n", - p); - abort(); - } -#endif - if(size == 0) { - if(p) -#ifdef DBG_SF_MALLOC - sfm_free(qm, p, file, func, line); -#else - sfm_free(qm, p); -#endif - return 0; - } - if(p == 0) -#ifdef DBG_SF_MALLOC - return sfm_malloc(qm, size, file, func, line); -#else - return sfm_malloc(qm, size); -#endif - f = (struct sfm_frag *)((char *)p - sizeof(struct sfm_frag)); -#ifdef DBG_SF_MALLOC - MDBG("sfm_realloc: realloc'ing frag %p alloc'ed from %s: %s(%ld)\n", f, - f->file, f->func, f->line); -#endif - size = ROUNDUP(size); - orig_size = f->size; - if(f->size > size) { -/* shrink */ -#ifdef DBG_SF_MALLOC - MDBG("sfm_realloc: shrinking from %lu to %lu\n", f->size, size); - sfm_split_frag(qm, f, size, file, "frag. from sfm_realloc", line); -#else - sfm_split_frag(qm, f, size); -#endif - } else if(f->size < size) { -/* grow */ -#ifdef DBG_SF_MALLOC - MDBG("sfm_realloc: growing from %lu to %lu\n", f->size, size); -#endif -#ifndef SFM_REALLOC_REMALLOC - diff = size - f->size; - n = FRAG_NEXT(f); - if(((char *)n < (char *)qm->last_frag) && (n->u.nxt_free) - && ((n->size + FRAG_OVERHEAD) >= diff)) { - /* join */ - /* detach n from the free list */ - try_again: - p_id = n->id; - n_size = n->size; - if((unlikely(p_id >= SFM_POOLS_NO))) { - hash = GET_HASH(n_size); - SFM_MAIN_HASH_LOCK(qm, hash); - if(unlikely((n->u.nxt_free == 0) - || ((n->size + FRAG_OVERHEAD) < diff))) { - SFM_MAIN_HASH_UNLOCK(qm, hash); - goto not_found; - } - if(unlikely((n->id != p_id) || (n->size != n_size))) { - /* fragment still free, but changed, either - * moved to another pool or has a diff. size */ - SFM_MAIN_HASH_UNLOCK(qm, hash); - goto try_again; - } - pf = &(qm->free_hash[hash].first); - /* find it */ - for(; (*pf) && (*pf != n); pf = &((*pf)->u.nxt_free)) - ; /*FIXME slow */ - if(*pf == 0) { - SFM_MAIN_HASH_UNLOCK(qm, hash); - /* not found, bad! */ - LM_WARN("could not find %p in free list (hash=%d)\n", n, - hash); - /* somebody is in the process of changing it ? */ - goto not_found; - } - /* detach */ - *pf = n->u.nxt_free; - n->u.nxt_free = 0; /* mark it immediately as detached */ - qm->free_hash[hash].no--; - SFM_MAIN_HASH_UNLOCK(qm, hash); - /* join */ - f->size += n->size + FRAG_OVERHEAD; - /* split it if necessary */ - if(f->size > size) { -#ifdef DBG_SF_MALLOC - sfm_split_frag(qm, f, size, file, - "fragm. from " - "sfm_realloc", - line); -#else - sfm_split_frag(qm, f, size); -#endif - } - } else { /* p_id < SFM_POOLS_NO (=> in a pool )*/ - hash = GET_SMALL_HASH(n_size); - pool = &qm->pool[p_id]; - SFM_POOL_LOCK(pool, hash); - if(unlikely((n->u.nxt_free == 0) - || ((n->size + FRAG_OVERHEAD) < diff))) { - SFM_POOL_UNLOCK(pool, hash); - goto not_found; - } - if(unlikely((n->id != p_id) || (n->size != n_size))) { - /* fragment still free, but changed, either - * moved to another pool or has a diff. size */ - SFM_POOL_UNLOCK(pool, hash); - goto try_again; - } - pf = &(pool->pool_hash[hash].first); - /* find it */ - for(; (*pf) && (*pf != n); pf = &((*pf)->u.nxt_free)) - ; /*FIXME slow */ - if(*pf == 0) { - SFM_POOL_UNLOCK(pool, hash); - /* not found, bad! */ - LM_WARN("could not find %p in free list (hash=%d)\n", n, - hash); - /* somebody is in the process of changing it ? */ - goto not_found; - } - /* detach */ - *pf = n->u.nxt_free; - n->u.nxt_free = 0; /* mark it immediately as detached */ - pool->pool_hash[hash].no--; - SFM_POOL_UNLOCK(pool, hash); - /* join */ - f->size += n->size + FRAG_OVERHEAD; - /* split it if necessary */ - if(f->size > size) { -#ifdef DBG_SF_MALLOC - sfm_split_frag(qm, f, size, file, - "fragm. from " - "sfm_realloc", - line); -#else - sfm_split_frag(qm, f, size); -#endif - } - } - } else { - not_found: -/* could not join => realloc */ -#else /* SFM_REALLOC_REMALLOC */ - { -#endif /* SFM_REALLOC_REMALLOC */ -#ifdef DBG_SF_MALLOC - ptr = sfm_malloc(qm, size, file, func, line); -#else - ptr = sfm_malloc(qm, size); -#endif - if(ptr) { - /* copy, need by libssl */ - memcpy(ptr, p, orig_size); -#ifdef DBG_SF_MALLOC - sfm_free(qm, p, file, func, line); -#else - sfm_free(qm, p); -#endif - } - p = ptr; - } - } else { -/* do nothing */ -#ifdef DBG_SF_MALLOC - MDBG("doing nothing, same size: %lu - %lu\n", f->size, size); -#endif - } -#ifdef DBG_SF_MALLOC - MDBG("returning pointer value %p\n", p); -#endif - return p; -} - - -void sfm_status(struct sfm_block *qm) -{ - struct sfm_frag *f; - int i, j; - int h; - int unused; - unsigned long size; - int k; - int memlog; - - memlog = cfg_get(core, core_cfg, memlog); - LOG(memlog, "sfm_status (%p):\n", qm); - if(!qm) - return; - - LOG(memlog, " heap size= %ld\n", qm->size); - LOG(memlog, "dumping free list:\n"); - for(h = 0, i = 0, size = 0; h <= sfm_max_hash; h++) { - SFM_MAIN_HASH_LOCK(qm, h); - unused = 0; - for(f = qm->free_hash[h].first, j = 0; f; - size += f->size, f = f->u.nxt_free, i++, j++) { - if(!FRAG_WAS_USED(f)) { - unused++; -#ifdef DBG_SF_MALLOC - LOG(memlog, - "unused fragm.: hash = %3d, fragment %p," - " address %p size %lu, created from %s: %s(%ld)\n", - h, f, (char *)f + sizeof(struct sfm_frag), f->size, - f->file, f->func, f->line); -#endif - }; - } - if(j) - LOG(memlog, - "hash = %3d fragments no.: %5d, unused: %5d\n\t\t" - " bucket size: %9lu - %9lu (first %9lu)\n", - h, j, unused, UN_HASH(h), - ((h <= SF_MALLOC_OPTIMIZE / SF_ROUNDTO) ? 1 : 2) - * UN_HASH(h), - qm->free_hash[h].first->size); - if(j != qm->free_hash[h].no) { - LM_CRIT("BUG: different free frag. count: %d!=%ld" - " for hash %3d\n", - j, qm->free_hash[h].no, h); - } - SFM_MAIN_HASH_UNLOCK(qm, h); - } - for(k = 0; k < SFM_POOLS_NO; k++) { - for(h = 0; h < SF_HASH_POOL_SIZE; h++) { - SFM_POOL_LOCK(&qm->pool[k], h); - unused = 0; - for(f = qm->pool[k].pool_hash[h].first, j = 0; f; - size += f->size, f = f->u.nxt_free, i++, j++) { - if(!FRAG_WAS_USED(f)) { - unused++; -#ifdef DBG_SF_MALLOC - LOG(memlog, - "[%2d] unused fragm.: hash = %3d, fragment %p," - " address %p size %lu, created from %s: " - "%s(%ld)\n", - k, h, f, (char *)f + sizeof(struct sfm_frag), - f->size, f->file, f->func, f->line); -#endif - }; - } - if(j) - LOG(memlog, - "[%2d] hash = %3d fragments no.: %5d, unused: " - "%5d\n\t\t bucket size: %9lu - %9lu " - "(first %9lu)\n", - k, h, j, unused, UN_HASH(h), - ((h <= SF_MALLOC_OPTIMIZE / SF_ROUNDTO) ? 1 : 2) - * UN_HASH(h), - qm->pool[k].pool_hash[h].first->size); - if(j != qm->pool[k].pool_hash[h].no) { - LOG(L_CRIT, - "BUG: sfm_status: [%d] different free frag." - " count: %d!=%ld for hash %3d\n", - k, j, qm->pool[k].pool_hash[h].no, h); - } - SFM_POOL_UNLOCK(&qm->pool[k], h); - } - } - LOG(memlog, "TOTAL: %6d free fragments = %6lu free bytes\n", i, size); - LOG(memlog, "-----------------------------\n"); -} - - -/* fills a malloc info structure with info about the block - * if a parameter is not supported, it will be filled with 0 */ -void sfm_info(struct sfm_block *qm, struct mem_info *info) -{ - int r, k; - unsigned long total_frags; - struct sfm_frag *f; - - memset(info, 0, sizeof(*info)); - total_frags = 0; - info->total_size = qm->size; - info->min_frag = SF_MIN_FRAG_SIZE; - /* we'll have to compute it all */ - for(r = 0; r <= SF_MALLOC_OPTIMIZE / SF_ROUNDTO; r++) { - info->free += qm->free_hash[r].no * UN_HASH(r); - total_frags += qm->free_hash[r].no; - } - for(; r <= sfm_max_hash; r++) { - total_frags += qm->free_hash[r].no; - SFM_MAIN_HASH_LOCK(qm, r); - for(f = qm->free_hash[r].first; f; f = f->u.nxt_free) { - info->free += f->size; - } - SFM_MAIN_HASH_UNLOCK(qm, r); - } - for(k = 0; k < SFM_POOLS_NO; k++) { - for(r = 0; r < SF_HASH_POOL_SIZE; r++) { - info->free += qm->pool[k].pool_hash[r].no * UN_HASH(r); - total_frags += qm->pool[k].pool_hash[r].no; - } - } - info->real_used = info->total_size - info->free; - info->used = info->real_used - total_frags * FRAG_OVERHEAD - INIT_OVERHEAD - - FRAG_OVERHEAD; - info->max_used = 0; /* we don't really know */ - info->total_frags = total_frags; -} - - -/* returns how much free memory is available - * on error (not compiled with bookkeeping code) returns (unsigned long)(-1) */ -unsigned long sfm_available(struct sfm_block *qm) -{ - /* we don't know how much free memory we have and it's too expensive - * to compute it */ - return ((unsigned long)-1); -} - -#endif \ No newline at end of file diff --git a/src/core/mem/sf_malloc.h b/src/core/mem/sf_malloc.h deleted file mode 100644 index 618ead5bd..000000000 --- a/src/core/mem/sf_malloc.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * shared memory, multi-process safe, pool based version of f_malloc - * - * This file is part of Kamailio, a free SIP server. - * - * Copyright (C) 2007 iptelorg GmbH - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifdef SF_MALLOC - -#if !defined(sf_malloc_h) -#define sf_malloc_h - -#include "meminfo.h" - -#include "../lock_ops.h" -#include "../atomic_ops.h" -#include "../compiler_opt.h" -/* defs*/ - -#ifdef DBG_SR_MEMORY -#define DBG_SF_MALLOC -#endif - -#ifdef GEN_LOCK_T_UNLIMITED -#define SFM_LOCK_PER_BUCKET -#else -#define SFM_ONE_LOCK -#endif - -#ifdef DBG_SF_MALLOC -#if defined(__CPU_sparc64) || defined(__CPU_sparc) -/* tricky, on sun in 32 bits mode long long must be 64 bits aligned - * but long can be 32 bits aligned => malloc should return long long - * aligned memory */ -#define SF_ROUNDTO sizeof(long long) -#else -#define SF_ROUNDTO \ - sizeof(void *) /* size we round to, must be = 2^n, - * and sizeof(sfm_frag) must be multiple of SF_ROUNDTO !*/ -#endif -#else /* DBG_SF_MALLOC */ -#define SF_ROUNDTO 8UL -#endif -#define SF_MIN_FRAG_SIZE SF_ROUNDTO - -#define SFM_POOLS_NO \ - 4U /* the more the better, but higher initial - * mem. consumption */ - -#define SF_MALLOC_OPTIMIZE_FACTOR 14UL /*used below */ -#define SF_MALLOC_OPTIMIZE (1UL << SF_MALLOC_OPTIMIZE_FACTOR) -/* size to optimize for, - (most allocs <= this size), - must be 2^k */ - -#define SF_HASH_POOL_SIZE (SF_MALLOC_OPTIMIZE / SF_ROUNDTO + 1) -#define SF_POOL_MAX_SIZE SF_MALLOC_OPTIMIZE - -#define SF_HASH_SIZE \ - (SF_MALLOC_OPTIMIZE / SF_ROUNDTO \ - + (sizeof(long) * 8 - SF_MALLOC_OPTIMIZE_FACTOR) + 1) - -/* hash structure: - * 0 .... SF_MALLOC_OPTIMIZE/SF_ROUNDTO - small buckets, size increases with - * SF_ROUNDTO from bucket to bucket - * +1 .... end - size = 2^k, big buckets */ - -struct sfm_frag -{ - union - { - struct sfm_frag *nxt_free; - long reserved; - } u; - unsigned long size; - unsigned long id; /* TODO better optimize the size */ - /* pad to SF_ROUNDTO multiple */ - char _pad[((3 * sizeof(long) + SF_ROUNDTO - 1) & ~(SF_ROUNDTO - 1)) - - 3 * sizeof(long)]; -#ifdef DBG_SF_MALLOC - const char *file; - const char *func; - unsigned long line; - unsigned long check; -#endif -}; - -struct sfm_frag_lnk -{ - struct sfm_frag *first; -#ifdef SFM_LOCK_PER_BUCKET - gen_lock_t lock; -#endif - unsigned long no; -}; - -struct sfm_pool_head -{ - struct sfm_frag *first; -#ifdef SFM_LOCK_PER_BUCKET - gen_lock_t lock; -#endif - unsigned long no; - unsigned long misses; -}; - -struct sfm_pool -{ -#ifdef SFM_ONE_LOCK - gen_lock_t lock; -#endif - unsigned long missed; - unsigned long hits; /* debugging only TODO: remove */ - unsigned long bitmap; - struct sfm_pool_head pool_hash[SF_HASH_POOL_SIZE]; -}; - -struct sfm_block -{ -#ifdef SFM_ONE_LOCK - gen_lock_t lock; -#endif - atomic_t crt_id; /* current pool */ - int type; - unsigned long size; /* total size */ - /* stats are kept now per bucket */ - struct sfm_frag *first_frag; - struct sfm_frag *last_frag; - unsigned long bitmap; /* only up to SF_MALLOC_OPTIMIZE */ - struct sfm_frag_lnk free_hash[SF_HASH_SIZE]; - struct sfm_pool pool[SFM_POOLS_NO]; - int is_init; - gen_lock_t get_and_split; - char _pad[256]; -}; - - -struct sfm_block *sfm_malloc_init(char *address, unsigned long size, int type); -void sfm_malloc_destroy(struct sfm_block *qm); -int sfm_pool_reset(); - -#ifdef DBG_SF_MALLOC -void *sfm_malloc(struct sfm_block *, unsigned long size, const char *file, - const char *func, unsigned int line); -#else -void *sfm_malloc(struct sfm_block *, unsigned long size); -#endif - -#ifdef DBG_SF_MALLOC -void *sfm_mallocxz(struct sfm_block *, unsigned long size, const char *file, - const char *func, unsigned int line); -#else -void *sfm_mallocxz(struct sfm_block *, unsigned long size); -#endif - -#ifdef DBG_SF_MALLOC -void sfm_free(struct sfm_block *, void *p, const char *file, const char *func, - unsigned int line); -#else -void sfm_free(struct sfm_block *, void *p); -#endif - -#ifdef DBG_SF_MALLOC -void *sfm_realloc(struct sfm_block *, void *p, unsigned long size, - const char *file, const char *func, unsigned int line); -#else -void *sfm_realloc(struct sfm_block *, void *p, unsigned long size); -#endif - -#ifdef DBG_SF_MALLOC -void *sfm_reallocxf(struct sfm_block *, void *p, unsigned long size, - const char *file, const char *func, unsigned int line); -#else -void *sfm_reallocxf(struct sfm_block *, void *p, unsigned long size); -#endif - -void sfm_status(struct sfm_block *); -void sfm_info(struct sfm_block *, struct mem_info *); - -unsigned long sfm_available(struct sfm_block *); - -#endif - -#endif \ No newline at end of file diff --git a/src/core/mem/shm.c b/src/core/mem/shm.c index 75f2dde27..f321fff72 100644 --- a/src/core/mem/shm.c +++ b/src/core/mem/shm.c @@ -242,6 +242,7 @@ int shm_init_api(sr_shm_api_t *ap) _shm_root.xreallocxf = ap->xreallocxf; _shm_root.xresize = ap->xresize; _shm_root.xstatus = ap->xstatus; + _shm_root.xstatus_filter = ap->xstatus_filter; _shm_root.xinfo = ap->xinfo; _shm_root.xreport = ap->xreport; _shm_root.xavailable = ap->xavailable; @@ -251,6 +252,7 @@ int shm_init_api(sr_shm_api_t *ap) _shm_root.xfmodstats = ap->xfmodstats; _shm_root.xglock = ap->xglock; _shm_root.xgunlock = ap->xgunlock; + _shm_root.xsetfunc = ap->xsetfunc; return 0; } diff --git a/src/core/mem/shm.h b/src/core/mem/shm.h index 3813d9840..8d4d0d95e 100644 --- a/src/core/mem/shm.h +++ b/src/core/mem/shm.h @@ -53,6 +53,8 @@ extern sr_shm_api_t _shm_root; #define shm_mallocxz(s) \ _shm_root.xmallocxz(_shm_root.mem_block, (s), _SRC_LOC_, _SRC_FUNCTION_, \ _SRC_LINE_, _SRC_MODULE_) +#define shm_mallocxp(s, loc, fname, nline, mname) \ + _shm_root.xmalloc(_shm_root.mem_block, (s), loc, fname, nline, mname) #define shm_malloc_unsafe(s) \ _shm_root.xmalloc_unsafe(_shm_root.mem_block, (s), _SRC_LOC_, \ _SRC_FUNCTION_, _SRC_LINE_, _SRC_MODULE_) @@ -62,6 +64,8 @@ extern sr_shm_api_t _shm_root; #define shm_reallocxf(p, s) \ _shm_root.xreallocxf(_shm_root.mem_block, (p), (s), _SRC_LOC_, \ _SRC_FUNCTION_, _SRC_LINE_, _SRC_MODULE_) +#define shm_reallocxp(p, s, loc, fname, nline, mname) \ + _shm_root.xrealloc(_shm_root.mem_block, (p), (s), loc, fname, nline, mname) #define shm_resize(p, s) \ _shm_root.xresize(_shm_root.mem_block, (p), (s), _SRC_LOC_, \ _SRC_FUNCTION_, _SRC_LINE_, _SRC_MODULE_) @@ -83,6 +87,14 @@ extern sr_shm_api_t _shm_root; #endif #define shm_status() _shm_root.xstatus(_shm_root.mem_block) +#define shm_status_filter(fmatch, fp) \ + do { \ + if(_shm_root.xstatus_filter) { \ + _shm_root.xstatus_filter(_shm_root.mem_block, fmatch, fp); \ + } else { \ + LM_ERR("shm status with filter not implemented\n"); \ + } \ + } while(0) #define shm_info(mi) _shm_root.xinfo(_shm_root.mem_block, mi) #define shm_report(mr) _shm_root.xreport(_shm_root.mem_block, mr) #define shm_available() _shm_root.xavailable(_shm_root.mem_block) @@ -93,6 +105,14 @@ extern sr_shm_api_t _shm_root; #define shm_global_lock() _shm_root.xglock(_shm_root.mem_block) #define shm_global_unlock() _shm_root.xgunlock(_shm_root.mem_block) +#define shm_setfunc(p, f) \ + do { \ + if(_shm_root.xsetfunc) { \ + _shm_root.xsetfunc(_shm_root.mem_block, (p), (f)); \ + } else { \ + LM_ERR("xsetfunc not implemented\n"); \ + } \ + } while(0) void *shm_core_get_pool(void); int shm_init_api(sr_shm_api_t *ap); diff --git a/src/core/mod_fix.c b/src/core/mod_fix.c index ecd870c0c..10be56098 100644 --- a/src/core/mod_fix.c +++ b/src/core/mod_fix.c @@ -843,6 +843,38 @@ int fixup_free_ssi(void **param, int param_no) } } +/** + * + */ +int fixup_sii(void **param, int param_no) +{ + switch(param_no) { + case 1: + return fixup_spve_null(param, 1); + case 2: + case 3: + return fixup_igp_null(param, 1); + default: + return E_UNSPEC; + } +} + +/** + * + */ +int fixup_free_sii(void **param, int param_no) +{ + switch(param_no) { + case 1: + return fixup_free_spve_null(param, 1); + case 2: + case 3: + return fixup_free_igp_null(param, 1); + default: + return E_UNSPEC; + } +} + /** * */ diff --git a/src/core/mod_fix.h b/src/core/mod_fix.h index a76d64f0c..3143f0604 100644 --- a/src/core/mod_fix.h +++ b/src/core/mod_fix.h @@ -168,6 +168,9 @@ int fixup_free_igp_regexp(void **param, int param_no); int fixup_ssi(void **param, int param_no); int fixup_free_ssi(void **param, int param_no); +int fixup_sii(void **param, int param_no); +int fixup_free_sii(void **param, int param_no); + int fixup_sssi(void **param, int param_no); int fixup_free_sssi(void **param, int param_no); diff --git a/src/core/modparam.c b/src/core/modparam.c index cf7957a16..b48d9e824 100644 --- a/src/core/modparam.c +++ b/src/core/modparam.c @@ -72,7 +72,7 @@ int set_mod_param_regex(char *regex, char *name, modparam_t type, void *val) { struct sr_module *t; regex_t preg; - int mod_found, len; + int mod_found, len, len_param; char *reg; void *ptr, *val2; modparam_t param_type; @@ -143,15 +143,16 @@ int set_mod_param_regex(char *regex, char *name, modparam_t type, void *val) } else { switch(PARAM_TYPE_MASK(param_type)) { case PARAM_STRING: - *((char **)ptr) = - pkg_malloc(strlen((char *)val2) + 1); + len_param = strlen((char *)val2); + *((char **)ptr) = pkg_malloc(len_param + 1); if(!*((char **)ptr)) { PKG_MEM_ERROR; regfree(&preg); pkg_free(reg); return -1; } - strcpy(*((char **)ptr), (char *)val2); + strncpy(*((char **)ptr), (char *)val2, len_param); + (*((char **)ptr))[len_param] = '\0'; break; case PARAM_STR: diff --git a/src/core/msg_translator.c b/src/core/msg_translator.c index 44524379b..acd591186 100644 --- a/src/core/msg_translator.c +++ b/src/core/msg_translator.c @@ -114,6 +114,7 @@ extern int version_len; str _ksr_xavp_via_params = STR_NULL; str _ksr_xavp_via_fields = STR_NULL; +str _ksr_xavp_via_reply_params = STR_NULL; int ksr_local_rport = 0; /** per process fixup function for global_req_flags. @@ -547,11 +548,15 @@ static inline int lumps_len( int new_len; struct lump *t; struct lump *r; - str *send_address_str; - str *send_port_str; + str *send_address_str = NULL; + str *send_port_str = NULL; + int send_proto_id = PROTO_NONE; + int send_af = 0; str *recv_address_str = NULL; str *recv_port_str = NULL; int recv_port_no = 0; + int recv_proto_id = PROTO_NONE; + int recv_af = 0; struct socket_info *send_sock; @@ -595,19 +600,17 @@ static inline int lumps_len( case SUBST_RCV_IP: \ if(msg->rcv.bind_address && STR_WITHVAL(recv_address_str)) { \ new_len += recv_address_str->len; \ - if(msg->rcv.bind_address->address.af != AF_INET) \ + if(recv_af == AF_INET6) \ new_len += 2; \ } else { \ - /* FIXME */ \ - LM_CRIT("FIXME: null bind_address\n"); \ + LM_CRIT("rcv ip - null bind_address\n"); \ }; \ break; \ case SUBST_RCV_PORT: \ if(msg->rcv.bind_address && STR_WITHVAL(recv_port_str)) { \ new_len += recv_port_str->len; \ } else { \ - /* FIXME */ \ - LM_CRIT("FIXME: null bind_address\n"); \ + LM_CRIT(" rcv port - null bind_address\n"); \ }; \ break; \ case SUBST_RCV_PROTO: \ @@ -637,16 +640,14 @@ static inline int lumps_len( msg->rcv.bind_address->proto); \ } \ } else { \ - /* FIXME */ \ - LM_CRIT("FIXME: null bind_address\n"); \ + LM_CRIT("null bind_address\n"); \ }; \ break; \ case SUBST_RCV_ALL: \ case SUBST_RCV_ALL_EX: \ if(msg->rcv.bind_address && STR_WITHVAL(recv_address_str)) { \ new_len += recv_address_str->len; \ - if((msg->rcv.bind_address->address.af == AF_INET6) \ - && (recv_address_str->s[0] != '[') \ + if((recv_af == AF_INET6) && (recv_address_str->s[0] != '[') \ && (memchr(recv_address_str->s, ':', \ recv_address_str->len) \ != NULL)) \ @@ -656,7 +657,7 @@ static inline int lumps_len( new_len += 1 + recv_port_str->len; \ } \ /*add;transport=xxx*/ \ - switch(msg->rcv.bind_address->proto) { \ + switch(recv_proto_id) { \ case PROTO_NONE: \ case PROTO_UDP: \ break; /* udp is the default */ \ @@ -672,6 +673,10 @@ static inline int lumps_len( break; \ } \ break; \ + case PROTO_WS: \ + case PROTO_WSS: \ + new_len += TRANSPORT_PARAM_LEN + 2; \ + break; \ case PROTO_SCTP: \ new_len += TRANSPORT_PARAM_LEN + 4; \ break; \ @@ -686,25 +691,23 @@ static inline int lumps_len( } \ RCVCOMP_LUMP_LEN \ } else { \ - /* FIXME */ \ - LM_CRIT("FIXME: null bind_address\n"); \ + LM_CRIT("null bind_address\n"); \ }; \ break; \ case SUBST_SND_IP: \ if(send_sock) { \ new_len += send_address_str->len; \ - if(send_sock->address.af == AF_INET6 \ - && send_address_str->s[0] != '[') \ + if(send_af == AF_INET6 && send_address_str->s[0] != '[') \ new_len += 2; \ } else { \ - LM_CRIT("FIXME: null send_sock\n"); \ + LM_CRIT("null send_sock\n"); \ }; \ break; \ case SUBST_SND_PORT: \ if(send_sock) { \ new_len += send_port_str->len; \ } else { \ - LM_CRIT("FIXME: null send_sock\n"); \ + LM_CRIT("null send_sock\n"); \ }; \ break; \ case SUBST_SND_PROTO: \ @@ -733,15 +736,14 @@ static inline int lumps_len( LM_CRIT("unknown proto %d\n", send_sock->proto); \ } \ } else { \ - LM_CRIT("FIXME: null send_sock\n"); \ + LM_CRIT("null send_sock\n"); \ }; \ break; \ case SUBST_SND_ALL: \ case SUBST_SND_ALL_EX: \ if(send_sock) { \ new_len += send_address_str->len; \ - if((send_sock->address.af == AF_INET6) \ - && (send_address_str->s[0] != '[') \ + if((send_af == AF_INET6) && (send_address_str->s[0] != '[') \ && (memchr(send_address_str->s, ':', \ send_address_str->len) \ != NULL)) \ @@ -752,7 +754,7 @@ static inline int lumps_len( new_len += 1 + send_port_str->len; \ } \ /*add;transport=xxx*/ \ - switch(send_sock->proto) { \ + switch(send_proto_id) { \ case PROTO_NONE: \ case PROTO_UDP: \ break; /* udp is the default */ \ @@ -768,6 +770,10 @@ static inline int lumps_len( break; \ } \ break; \ + case PROTO_WS: \ + case PROTO_WSS: \ + new_len += TRANSPORT_PARAM_LEN + 2; \ + break; \ case PROTO_SCTP: \ new_len += TRANSPORT_PARAM_LEN + 4; \ break; \ @@ -780,8 +786,7 @@ static inline int lumps_len( } \ SENDCOMP_LUMP_LEN \ } else { \ - /* FIXME */ \ - LM_CRIT("FIXME: null send_sock\n"); \ + LM_CRIT("null send_sock\n"); \ }; \ break; \ case SUBST_NOP: /* do nothing */ \ @@ -798,24 +803,39 @@ static inline int lumps_len( s_offset = 0; new_len = 0; /* init send_address_str & send_port_str */ - if(send_sock && send_sock->useinfo.name.len > 0) + if(send_sock && send_sock->useinfo.name.len > 0) { send_address_str = &(send_sock->useinfo.name); - else if(msg->set_global_address.len) + send_af = send_sock->useinfo.af; + } else if(msg->set_global_address.len) { send_address_str = &(msg->set_global_address); - else + if(send_sock) { + send_af = send_sock->address.af; + } + } else if(send_sock) { send_address_str = &(send_sock->address_str); + send_af = send_sock->address.af; + } if(send_sock && send_sock->useinfo.port_no > 0) send_port_str = &(send_sock->useinfo.port_no_str); else if(msg->set_global_port.len) send_port_str = &(msg->set_global_port); else send_port_str = &(send_sock->port_no_str); + if(send_sock) { + if(send_sock->useinfo.proto != PROTO_NONE) + send_proto_id = send_sock->useinfo.proto; + else + send_proto_id = send_sock->proto; + } /* init recv_address_str, recv_port_str & recv_port_no */ if(msg->rcv.bind_address) { - if(msg->rcv.bind_address->useinfo.name.len > 0) + if(msg->rcv.bind_address->useinfo.name.len > 0) { recv_address_str = &(msg->rcv.bind_address->useinfo.name); - else + recv_af = msg->rcv.bind_address->useinfo.af; + } else { recv_address_str = &(msg->rcv.bind_address->address_str); + recv_af = msg->rcv.bind_address->address.af; + } if(msg->rcv.bind_address->useinfo.port_no > 0) { recv_port_str = &(msg->rcv.bind_address->useinfo.port_no_str); recv_port_no = msg->rcv.bind_address->useinfo.port_no; @@ -823,6 +843,11 @@ static inline int lumps_len( recv_port_str = &(msg->rcv.bind_address->port_no_str); recv_port_no = msg->rcv.bind_address->port_no; } + if(msg->rcv.bind_address->useinfo.proto != PROTO_NONE) { + recv_proto_id = msg->rcv.bind_address->useinfo.proto; + } else { + recv_proto_id = msg->rcv.bind_address->proto; + } } for(t = lumps; t; t = t->next) { @@ -924,11 +949,15 @@ void process_lumps(struct sip_msg *msg, struct lump *lumps, char *new_buf, int size; int offset; int s_offset; - str *send_address_str; - str *send_port_str; + str *send_address_str = NULL; + str *send_port_str = NULL; + int send_proto_id = PROTO_NONE; + int send_af = 0; str *recv_address_str = NULL; str *recv_port_str = NULL; int recv_port_no = 0; + int recv_proto_id = PROTO_NONE; + int recv_af = 0; struct socket_info *send_sock; #ifdef USE_COMP @@ -978,320 +1007,322 @@ void process_lumps(struct sip_msg *msg, struct lump *lumps, char *new_buf, #define SENDCOMP_PARAM_ADD #endif /* USE_COMP */ -#define SUBST_LUMP(subst_l) \ - switch((subst_l)->u.subst) { \ - case SUBST_RCV_IP: \ - if(msg->rcv.bind_address && STR_WITHVAL(recv_address_str)) { \ - if(msg->rcv.bind_address->address.af != AF_INET) { \ - new_buf[offset] = '['; \ - offset++; \ - } \ - memcpy(new_buf + offset, recv_address_str->s, \ - recv_address_str->len); \ - offset += recv_address_str->len; \ - if(msg->rcv.bind_address->address.af != AF_INET) { \ - new_buf[offset] = ']'; \ - offset++; \ - } \ - } else { \ - /*FIXME*/ \ - LM_CRIT("FIXME: null bind_address\n"); \ - }; \ - break; \ - case SUBST_RCV_PORT: \ - if(msg->rcv.bind_address && STR_WITHVAL(recv_port_str)) { \ - memcpy(new_buf + offset, recv_port_str->s, \ - recv_port_str->len); \ - offset += recv_port_str->len; \ - } else { \ - /*FIXME*/ \ - LM_CRIT("FIXME: null bind_address\n"); \ - }; \ - break; \ - case SUBST_RCV_ALL: \ - case SUBST_RCV_ALL_EX: \ - if(msg->rcv.bind_address && STR_WITHVAL(recv_address_str)) { \ - /* address */ \ - if((msg->rcv.bind_address->address.af == AF_INET6) \ - && (recv_address_str->s[0] != '[') \ - && (memchr(recv_address_str->s, ':', \ - recv_address_str->len) \ - != NULL)) { \ - new_buf[offset] = '['; \ - offset++; \ - } \ - memcpy(new_buf + offset, recv_address_str->s, \ - recv_address_str->len); \ - offset += recv_address_str->len; \ - if((msg->rcv.bind_address->address.af == AF_INET6) \ - && (recv_address_str->s[0] != '[') \ - && (memchr(recv_address_str->s, ':', \ - recv_address_str->len) \ - != NULL)) { \ - new_buf[offset] = ']'; \ - offset++; \ - } \ - /* :port */ \ - if(recv_port_no != SIP_PORT && STR_WITHVAL(recv_port_str)) { \ - new_buf[offset] = ':'; \ - offset++; \ - memcpy(new_buf + offset, recv_port_str->s, \ - recv_port_str->len); \ - offset += recv_port_str->len; \ - } \ - switch(msg->rcv.bind_address->proto) { \ - case PROTO_NONE: \ - case PROTO_UDP: \ - break; /* nothing to do, udp is default*/ \ - case PROTO_TCP: \ - memcpy(new_buf + offset, TRANSPORT_PARAM, \ - TRANSPORT_PARAM_LEN); \ - offset += TRANSPORT_PARAM_LEN; \ - if(msg->rcv.proto == PROTO_WS) { \ - memcpy(new_buf + offset, "ws", 2); \ - offset += 2; \ - } else { \ - memcpy(new_buf + offset, "tcp", 3); \ - offset += 3; \ - } \ - break; \ - case PROTO_TLS: \ - memcpy(new_buf + offset, TRANSPORT_PARAM, \ - TRANSPORT_PARAM_LEN); \ - offset += TRANSPORT_PARAM_LEN; \ - if(msg->rcv.proto == PROTO_WS \ - || msg->rcv.proto == PROTO_WSS) { \ - memcpy(new_buf + offset, "ws", 2); \ - offset += 2; \ - } else { \ - memcpy(new_buf + offset, "tls", 3); \ - offset += 3; \ - } \ - break; \ - case PROTO_SCTP: \ - memcpy(new_buf + offset, TRANSPORT_PARAM, \ - TRANSPORT_PARAM_LEN); \ - offset += TRANSPORT_PARAM_LEN; \ - memcpy(new_buf + offset, "sctp", 4); \ - offset += 4; \ - break; \ - default: \ - LM_CRIT("unknown proto %d\n", \ - msg->rcv.bind_address->proto); \ - } \ - if((subst_l)->u.subst == SUBST_RCV_ALL_EX \ - && msg->rcv.bind_address->sockname.len > 0) { \ - memcpy(new_buf + offset, SOCKNAME_PARAM, \ - SOCKNAME_PARAM_LEN); \ - offset += SOCKNAME_PARAM_LEN; \ - memcpy(new_buf + offset, \ - msg->rcv.bind_address->sockname.s, \ - msg->rcv.bind_address->sockname.len); \ - offset += msg->rcv.bind_address->sockname.len; \ - } \ - RCVCOMP_PARAM_ADD \ - } else { \ - /*FIXME*/ \ - LM_CRIT("FIXME: null bind_address\n"); \ - }; \ - break; \ - case SUBST_SND_IP: \ - if(send_sock) { \ - if((send_sock->address.af != AF_INET) \ - && (send_address_str->s[0] != '[')) { \ - new_buf[offset] = '['; \ - offset++; \ - } \ - memcpy(new_buf + offset, send_address_str->s, \ - send_address_str->len); \ - offset += send_address_str->len; \ - if((send_sock->address.af != AF_INET) \ - && (send_address_str->s[0] != '[')) { \ - new_buf[offset] = ']'; \ - offset++; \ - } \ - } else { \ - /*FIXME*/ \ - LM_CRIT("FIXME: null send_sock\n"); \ - }; \ - break; \ - case SUBST_SND_PORT: \ - if(send_sock) { \ - memcpy(new_buf + offset, send_port_str->s, \ - send_port_str->len); \ - offset += send_port_str->len; \ - } else { \ - /*FIXME*/ \ - LM_CRIT("FIXME: null send_sock\n"); \ - }; \ - break; \ - case SUBST_SND_ALL: \ - case SUBST_SND_ALL_EX: \ - if(send_sock) { \ - /* address */ \ - if((send_sock->address.af == AF_INET6) \ - && (send_address_str->s[0] != '[') \ - && (memchr(send_address_str->s, ':', \ - send_address_str->len) \ - != NULL)) { \ - new_buf[offset] = '['; \ - offset++; \ - } \ - memcpy(new_buf + offset, send_address_str->s, \ - send_address_str->len); \ - offset += send_address_str->len; \ - if((send_sock->address.af == AF_INET6) \ - && (send_address_str->s[0] != '[') \ - && (memchr(send_address_str->s, ':', \ - send_address_str->len) \ - != NULL)) { \ - new_buf[offset] = ']'; \ - offset++; \ - } \ - /* :port */ \ - if((send_sock->port_no != SIP_PORT) \ - || (send_port_str != &(send_sock->port_no_str))) { \ - new_buf[offset] = ':'; \ - offset++; \ - memcpy(new_buf + offset, send_port_str->s, \ - send_port_str->len); \ - offset += send_port_str->len; \ - } \ - switch(send_sock->proto) { \ - case PROTO_NONE: \ - case PROTO_UDP: \ - break; /* nothing to do, udp is default*/ \ - case PROTO_TCP: \ - memcpy(new_buf + offset, TRANSPORT_PARAM, \ - TRANSPORT_PARAM_LEN); \ - offset += TRANSPORT_PARAM_LEN; \ - if(send_info->proto == PROTO_WS) { \ - memcpy(new_buf + offset, "ws", 2); \ - offset += 2; \ - } else { \ - memcpy(new_buf + offset, "tcp", 3); \ - offset += 3; \ - } \ - break; \ - case PROTO_TLS: \ - memcpy(new_buf + offset, TRANSPORT_PARAM, \ - TRANSPORT_PARAM_LEN); \ - offset += TRANSPORT_PARAM_LEN; \ - if(send_info->proto == PROTO_WS \ - || send_info->proto == PROTO_WSS) { \ - memcpy(new_buf + offset, "ws", 2); \ - offset += 2; \ - } else { \ - memcpy(new_buf + offset, "tls", 3); \ - offset += 3; \ - } \ - break; \ - case PROTO_SCTP: \ - memcpy(new_buf + offset, TRANSPORT_PARAM, \ - TRANSPORT_PARAM_LEN); \ - offset += TRANSPORT_PARAM_LEN; \ - memcpy(new_buf + offset, "sctp", 4); \ - offset += 4; \ - break; \ - default: \ - LM_CRIT("unknown proto %d\n", send_sock->proto); \ - } \ - if((subst_l)->u.subst == SUBST_SND_ALL_EX \ - && send_sock->sockname.len > 0) { \ - memcpy(new_buf + offset, SOCKNAME_PARAM, \ - SOCKNAME_PARAM_LEN); \ - offset += SOCKNAME_PARAM_LEN; \ - memcpy(new_buf + offset, send_sock->sockname.s, \ - send_sock->sockname.len); \ - offset += send_sock->sockname.len; \ - } \ - SENDCOMP_PARAM_ADD \ - } else { \ - /*FIXME*/ \ - LM_CRIT("FIXME: null bind_address\n"); \ - }; \ - break; \ - case SUBST_RCV_PROTO: \ - if(msg->rcv.bind_address) { \ - switch(msg->rcv.bind_address->proto) { \ - case PROTO_NONE: \ - case PROTO_UDP: \ - memcpy(new_buf + offset, "udp", 3); \ - offset += 3; \ - break; \ - case PROTO_TCP: \ - if(msg->rcv.proto == PROTO_WS) { \ - memcpy(new_buf + offset, "ws", 2); \ - offset += 2; \ - } else { \ - memcpy(new_buf + offset, "tcp", 3); \ - offset += 3; \ - } \ - break; \ - case PROTO_TLS: \ - if(msg->rcv.proto == PROTO_WS \ - || msg->rcv.proto == PROTO_WSS) { \ - memcpy(new_buf + offset, "ws", 2); \ - offset += 2; \ - } else { \ - memcpy(new_buf + offset, "tls", 3); \ - offset += 3; \ - } \ - break; \ - case PROTO_SCTP: \ - memcpy(new_buf + offset, "sctp", 4); \ - offset += 4; \ - break; \ - default: \ - LM_CRIT("unknown proto %d\n", \ - msg->rcv.bind_address->proto); \ - } \ - } else { \ - /*FIXME*/ \ - LM_CRIT("FIXME: null send_sock \n"); \ - }; \ - break; \ - case SUBST_SND_PROTO: \ - if(send_sock) { \ - switch(send_sock->proto) { \ - case PROTO_NONE: \ - case PROTO_UDP: \ - memcpy(new_buf + offset, "udp", 3); \ - offset += 3; \ - break; \ - case PROTO_TCP: \ - if(send_info->proto == PROTO_WS) { \ - memcpy(new_buf + offset, "ws", 2); \ - offset += 2; \ - } else { \ - memcpy(new_buf + offset, "tcp", 3); \ - offset += 3; \ - } \ - break; \ - case PROTO_TLS: \ - if(send_info->proto == PROTO_WS \ - || send_info->proto == PROTO_WSS) { \ - memcpy(new_buf + offset, "ws", 2); \ - offset += 2; \ - } else { \ - memcpy(new_buf + offset, "tls", 3); \ - offset += 3; \ - } \ - break; \ - case PROTO_SCTP: \ - memcpy(new_buf + offset, "sctp", 4); \ - offset += 4; \ - break; \ - default: \ - LM_CRIT("unknown proto %d\n", send_sock->proto); \ - } \ - } else { \ - /*FIXME*/ \ - LM_CRIT("FIXME: null send_sock \n"); \ - }; \ - break; \ - default: \ - LM_CRIT("unknown subst type %d\n", (subst_l)->u.subst); \ +#define SUBST_LUMP(subst_l) \ + switch((subst_l)->u.subst) { \ + case SUBST_RCV_IP: \ + if(msg->rcv.bind_address && STR_WITHVAL(recv_address_str)) { \ + if(recv_af == AF_INET6) { \ + new_buf[offset] = '['; \ + offset++; \ + } \ + memcpy(new_buf + offset, recv_address_str->s, \ + recv_address_str->len); \ + offset += recv_address_str->len; \ + if(recv_af == AF_INET6) { \ + new_buf[offset] = ']'; \ + offset++; \ + } \ + } else { \ + LM_CRIT("null bind_address\n"); \ + }; \ + break; \ + case SUBST_RCV_PORT: \ + if(msg->rcv.bind_address && STR_WITHVAL(recv_port_str)) { \ + memcpy(new_buf + offset, recv_port_str->s, \ + recv_port_str->len); \ + offset += recv_port_str->len; \ + } else { \ + LM_CRIT("null bind_address\n"); \ + }; \ + break; \ + case SUBST_RCV_ALL: \ + case SUBST_RCV_ALL_EX: \ + if(msg->rcv.bind_address && STR_WITHVAL(recv_address_str)) { \ + /* address */ \ + if((recv_af == AF_INET6) && (recv_address_str->s[0] != '[') \ + && (memchr(recv_address_str->s, ':', \ + recv_address_str->len) \ + != NULL)) { \ + new_buf[offset] = '['; \ + offset++; \ + } \ + memcpy(new_buf + offset, recv_address_str->s, \ + recv_address_str->len); \ + offset += recv_address_str->len; \ + if((recv_af == AF_INET6) && (recv_address_str->s[0] != '[') \ + && (memchr(recv_address_str->s, ':', \ + recv_address_str->len) \ + != NULL)) { \ + new_buf[offset] = ']'; \ + offset++; \ + } \ + /* :port */ \ + if(recv_port_no != SIP_PORT && STR_WITHVAL(recv_port_str)) { \ + new_buf[offset] = ':'; \ + offset++; \ + memcpy(new_buf + offset, recv_port_str->s, \ + recv_port_str->len); \ + offset += recv_port_str->len; \ + } \ + switch(recv_proto_id) { \ + case PROTO_NONE: \ + case PROTO_UDP: \ + break; /* nothing to do, udp is default*/ \ + case PROTO_TCP: \ + memcpy(new_buf + offset, TRANSPORT_PARAM, \ + TRANSPORT_PARAM_LEN); \ + offset += TRANSPORT_PARAM_LEN; \ + if(msg->rcv.proto == PROTO_WS) { \ + memcpy(new_buf + offset, "ws", 2); \ + offset += 2; \ + } else { \ + memcpy(new_buf + offset, "tcp", 3); \ + offset += 3; \ + } \ + break; \ + case PROTO_TLS: \ + memcpy(new_buf + offset, TRANSPORT_PARAM, \ + TRANSPORT_PARAM_LEN); \ + offset += TRANSPORT_PARAM_LEN; \ + if(msg->rcv.proto == PROTO_WS \ + || msg->rcv.proto == PROTO_WSS) { \ + memcpy(new_buf + offset, "ws", 2); \ + offset += 2; \ + } else { \ + memcpy(new_buf + offset, "tls", 3); \ + offset += 3; \ + } \ + break; \ + case PROTO_WS: \ + case PROTO_WSS: \ + memcpy(new_buf + offset, TRANSPORT_PARAM, \ + TRANSPORT_PARAM_LEN); \ + offset += TRANSPORT_PARAM_LEN; \ + memcpy(new_buf + offset, "ws", 2); \ + offset += 2; \ + break; \ + case PROTO_SCTP: \ + memcpy(new_buf + offset, TRANSPORT_PARAM, \ + TRANSPORT_PARAM_LEN); \ + offset += TRANSPORT_PARAM_LEN; \ + memcpy(new_buf + offset, "sctp", 4); \ + offset += 4; \ + break; \ + default: \ + LM_CRIT("unknown proto %d\n", \ + msg->rcv.bind_address->proto); \ + } \ + if((subst_l)->u.subst == SUBST_RCV_ALL_EX \ + && msg->rcv.bind_address->sockname.len > 0) { \ + memcpy(new_buf + offset, SOCKNAME_PARAM, \ + SOCKNAME_PARAM_LEN); \ + offset += SOCKNAME_PARAM_LEN; \ + memcpy(new_buf + offset, \ + msg->rcv.bind_address->sockname.s, \ + msg->rcv.bind_address->sockname.len); \ + offset += msg->rcv.bind_address->sockname.len; \ + } \ + RCVCOMP_PARAM_ADD \ + } else { \ + LM_CRIT("null bind_address\n"); \ + }; \ + break; \ + case SUBST_SND_IP: \ + if(send_sock) { \ + if((send_af == AF_INET6) && (send_address_str->s[0] != '[')) { \ + new_buf[offset] = '['; \ + offset++; \ + } \ + memcpy(new_buf + offset, send_address_str->s, \ + send_address_str->len); \ + offset += send_address_str->len; \ + if((send_af == AF_INET6) && (send_address_str->s[0] != '[')) { \ + new_buf[offset] = ']'; \ + offset++; \ + } \ + } else { \ + LM_CRIT("null send_sock\n"); \ + }; \ + break; \ + case SUBST_SND_PORT: \ + if(send_sock) { \ + memcpy(new_buf + offset, send_port_str->s, \ + send_port_str->len); \ + offset += send_port_str->len; \ + } else { \ + LM_CRIT("null send_sock\n"); \ + }; \ + break; \ + case SUBST_SND_ALL: \ + case SUBST_SND_ALL_EX: \ + if(send_sock) { \ + /* address */ \ + if((send_af == AF_INET6) && (send_address_str->s[0] != '[') \ + && (memchr(send_address_str->s, ':', \ + send_address_str->len) \ + != NULL)) { \ + new_buf[offset] = '['; \ + offset++; \ + } \ + memcpy(new_buf + offset, send_address_str->s, \ + send_address_str->len); \ + offset += send_address_str->len; \ + if((send_af == AF_INET6) && (send_address_str->s[0] != '[') \ + && (memchr(send_address_str->s, ':', \ + send_address_str->len) \ + != NULL)) { \ + new_buf[offset] = ']'; \ + offset++; \ + } \ + /* :port */ \ + if((send_sock->port_no != SIP_PORT) \ + || (send_port_str != &(send_sock->port_no_str))) { \ + new_buf[offset] = ':'; \ + offset++; \ + memcpy(new_buf + offset, send_port_str->s, \ + send_port_str->len); \ + offset += send_port_str->len; \ + } \ + switch(send_proto_id) { \ + case PROTO_NONE: \ + case PROTO_UDP: \ + break; /* nothing to do, udp is default*/ \ + case PROTO_TCP: \ + memcpy(new_buf + offset, TRANSPORT_PARAM, \ + TRANSPORT_PARAM_LEN); \ + offset += TRANSPORT_PARAM_LEN; \ + if(send_info->proto == PROTO_WS) { \ + memcpy(new_buf + offset, "ws", 2); \ + offset += 2; \ + } else { \ + memcpy(new_buf + offset, "tcp", 3); \ + offset += 3; \ + } \ + break; \ + case PROTO_TLS: \ + memcpy(new_buf + offset, TRANSPORT_PARAM, \ + TRANSPORT_PARAM_LEN); \ + offset += TRANSPORT_PARAM_LEN; \ + if(send_info->proto == PROTO_WS \ + || send_info->proto == PROTO_WSS) { \ + memcpy(new_buf + offset, "ws", 2); \ + offset += 2; \ + } else { \ + memcpy(new_buf + offset, "tls", 3); \ + offset += 3; \ + } \ + break; \ + case PROTO_WS: \ + case PROTO_WSS: \ + memcpy(new_buf + offset, TRANSPORT_PARAM, \ + TRANSPORT_PARAM_LEN); \ + offset += TRANSPORT_PARAM_LEN; \ + memcpy(new_buf + offset, "ws", 2); \ + offset += 2; \ + break; \ + case PROTO_SCTP: \ + memcpy(new_buf + offset, TRANSPORT_PARAM, \ + TRANSPORT_PARAM_LEN); \ + offset += TRANSPORT_PARAM_LEN; \ + memcpy(new_buf + offset, "sctp", 4); \ + offset += 4; \ + break; \ + default: \ + LM_CRIT("unknown proto %d\n", send_sock->proto); \ + } \ + if((subst_l)->u.subst == SUBST_SND_ALL_EX \ + && send_sock->sockname.len > 0) { \ + memcpy(new_buf + offset, SOCKNAME_PARAM, \ + SOCKNAME_PARAM_LEN); \ + offset += SOCKNAME_PARAM_LEN; \ + memcpy(new_buf + offset, send_sock->sockname.s, \ + send_sock->sockname.len); \ + offset += send_sock->sockname.len; \ + } \ + SENDCOMP_PARAM_ADD \ + } else { \ + LM_CRIT("null bind_address\n"); \ + }; \ + break; \ + case SUBST_RCV_PROTO: \ + if(msg->rcv.bind_address) { \ + switch(msg->rcv.bind_address->proto) { \ + case PROTO_NONE: \ + case PROTO_UDP: \ + memcpy(new_buf + offset, "udp", 3); \ + offset += 3; \ + break; \ + case PROTO_TCP: \ + if(msg->rcv.proto == PROTO_WS) { \ + memcpy(new_buf + offset, "ws", 2); \ + offset += 2; \ + } else { \ + memcpy(new_buf + offset, "tcp", 3); \ + offset += 3; \ + } \ + break; \ + case PROTO_TLS: \ + if(msg->rcv.proto == PROTO_WS \ + || msg->rcv.proto == PROTO_WSS) { \ + memcpy(new_buf + offset, "ws", 2); \ + offset += 2; \ + } else { \ + memcpy(new_buf + offset, "tls", 3); \ + offset += 3; \ + } \ + break; \ + case PROTO_SCTP: \ + memcpy(new_buf + offset, "sctp", 4); \ + offset += 4; \ + break; \ + default: \ + LM_CRIT("unknown proto %d\n", \ + msg->rcv.bind_address->proto); \ + } \ + } else { \ + LM_CRIT("null send_sock\n"); \ + }; \ + break; \ + case SUBST_SND_PROTO: \ + if(send_sock) { \ + switch(send_sock->proto) { \ + case PROTO_NONE: \ + case PROTO_UDP: \ + memcpy(new_buf + offset, "udp", 3); \ + offset += 3; \ + break; \ + case PROTO_TCP: \ + if(send_info->proto == PROTO_WS) { \ + memcpy(new_buf + offset, "ws", 2); \ + offset += 2; \ + } else { \ + memcpy(new_buf + offset, "tcp", 3); \ + offset += 3; \ + } \ + break; \ + case PROTO_TLS: \ + if(send_info->proto == PROTO_WS \ + || send_info->proto == PROTO_WSS) { \ + memcpy(new_buf + offset, "ws", 2); \ + offset += 2; \ + } else { \ + memcpy(new_buf + offset, "tls", 3); \ + offset += 3; \ + } \ + break; \ + case PROTO_SCTP: \ + memcpy(new_buf + offset, "sctp", 4); \ + offset += 4; \ + break; \ + default: \ + LM_CRIT("unknown proto %d\n", send_sock->proto); \ + } \ + } else { \ + LM_CRIT("null send_sock\n"); \ + }; \ + break; \ + default: \ + LM_CRIT("unknown subst type %d\n", (subst_l)->u.subst); \ } if(send_info) { @@ -1300,33 +1331,39 @@ void process_lumps(struct sip_msg *msg, struct lump *lumps, char *new_buf, send_sock = 0; } /* init send_address_str & send_port_str */ - if(msg->set_global_address.len) - send_address_str = &(msg->set_global_address); - else - send_address_str = &(send_sock->address_str); - if(msg->set_global_port.len) - send_port_str = &(msg->set_global_port); - else - send_port_str = &(send_sock->port_no_str); - /* init send_address_str & send_port_str */ - if(send_sock && send_sock->useinfo.name.len > 0) + if(send_sock && send_sock->useinfo.name.len > 0) { send_address_str = &(send_sock->useinfo.name); - else if(msg->set_global_address.len) + send_af = send_sock->useinfo.af; + } else if(msg->set_global_address.len) { send_address_str = &(msg->set_global_address); - else + if(send_sock) { + send_af = send_sock->address.af; + } + } else if(send_sock) { send_address_str = &(send_sock->address_str); + send_af = send_sock->address.af; + } if(send_sock && send_sock->useinfo.port_no > 0) send_port_str = &(send_sock->useinfo.port_no_str); else if(msg->set_global_port.len) send_port_str = &(msg->set_global_port); else send_port_str = &(send_sock->port_no_str); + if(send_sock) { + if(send_sock->useinfo.proto != PROTO_NONE) + send_proto_id = send_sock->useinfo.proto; + else + send_proto_id = send_sock->proto; + } /* init recv_address_str, recv_port_str & recv_port_no */ if(msg->rcv.bind_address) { - if(msg->rcv.bind_address->useinfo.name.len > 0) + if(msg->rcv.bind_address->useinfo.name.len > 0) { recv_address_str = &(msg->rcv.bind_address->useinfo.name); - else + recv_af = msg->rcv.bind_address->useinfo.af; + } else { recv_address_str = &(msg->rcv.bind_address->address_str); + recv_af = msg->rcv.bind_address->address.af; + } if(msg->rcv.bind_address->useinfo.port_no > 0) { recv_port_str = &(msg->rcv.bind_address->useinfo.port_no_str); recv_port_no = msg->rcv.bind_address->useinfo.port_no; @@ -1334,6 +1371,11 @@ void process_lumps(struct sip_msg *msg, struct lump *lumps, char *new_buf, recv_port_str = &(msg->rcv.bind_address->port_no_str); recv_port_no = msg->rcv.bind_address->port_no; } + if(msg->rcv.bind_address->useinfo.proto != PROTO_NONE) { + recv_proto_id = msg->rcv.bind_address->useinfo.proto; + } else { + recv_proto_id = msg->rcv.bind_address->proto; + } } orig = msg->buf; @@ -2319,6 +2361,9 @@ char *generate_res_buf_from_sip_res( unsigned offset, s_offset, via_offset; char *buf; unsigned int len; + str xparams; + str sdup; + sr_lump_t *anchor; buf = msg->buf; len = msg->len; @@ -2338,6 +2383,33 @@ char *generate_res_buf_from_sip_res( } } + /* test and add xavp via reply params */ + if(msg && msg->via2 && (msg->msg_flags & FL_ADD_XAVP_VIA_REPLY_PARAMS) + && _ksr_xavp_via_reply_params.len > 0) { + xparams.s = pv_get_buffer(); + xparams.len = xavp_serialize_fields_style(&_ksr_xavp_via_reply_params, + 1, xparams.s, pv_get_buffer_size()); + if(xparams.len > 0) { + LM_DBG("adding via reply xavp params\n"); + anchor = anchor_lump(msg, + msg->via2->params.s + msg->via2->params.len - msg->buf, 0, + 0); + if(anchor == NULL) { + LM_ERR("unable to get the anchor\n"); + goto error; + } + if(pkg_str_dup(&sdup, &xparams) < 0) { + PKG_MEM_ERROR; + goto error; + } + if(insert_new_lump_after(anchor, sdup.s, sdup.len, 0) == 0) { + LM_ERR("unable to add via reply xavp params\n"); + pkg_free(sdup.s); + goto error; + } + } + } + /* Calculate message body difference and adjust * Content-Length */ @@ -2356,9 +2428,8 @@ char *generate_res_buf_from_sip_res( } } - new_len = - len + body_delta + lumps_len(msg, msg->add_rm, 0); /*FIXME: we don't - know the send sock */ + /* note: unknow the send sock */ + new_len = len + body_delta + lumps_len(msg, msg->add_rm, 0); LM_DBG("old size: %d, new size: %d\n", len, new_len); new_buf = (char *)pkg_malloc(new_len + 1); /* +1 is for debugging @@ -2369,9 +2440,9 @@ char *generate_res_buf_from_sip_res( } new_buf[new_len] = 0; /* debug: print the message */ offset = s_offset = 0; - /*FIXME: no send sock*/ - process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, 0, - FLAG_MSG_ALL); /*FIXME:*/ + /* note: no send sock*/ + process_lumps( + msg, msg->add_rm, new_buf, &offset, &s_offset, 0, FLAG_MSG_ALL); process_lumps( msg, msg->body_lumps, new_buf, &offset, &s_offset, 0, FLAG_MSG_ALL); /* copy the rest of the message */ @@ -2415,6 +2486,7 @@ char *build_res_buf_from_sip_req(unsigned int code, str *text, str *new_tag, char *totags; int httpreq; char *pvia; + str xparams = STR_NULL; body = 0; buf = 0; @@ -2456,6 +2528,17 @@ char *build_res_buf_from_sip_req(unsigned int code, str *text, str *new_tag, len -= msg->via1->rport->size + 1; /* include ';' */ } + /* test and add xavp via reply params */ + if((msg->msg_flags & FL_ADD_XAVP_VIA_REPLY_PARAMS) + && _ksr_xavp_via_reply_params.len > 0) { + xparams.s = pv_get_buffer(); + xparams.len = xavp_serialize_fields_style(&_ksr_xavp_via_reply_params, + 1, xparams.s, pv_get_buffer_size()); + if(xparams.len > 0) { + len += xparams.len; /* starting ';' included */ + } + } + /* first line */ len += msg->first_line.u.request.version.len + 1 /*space*/ + 3 /*code*/ + 1 /*space*/ + text->len @@ -2588,6 +2671,9 @@ char *build_res_buf_from_sip_req(unsigned int code, str *text, str *new_tag, append_str_trans(p, hdr->name.s, (hdr->body.s + hdr->body.len) - hdr->name.s, msg); } + if(xparams.len > 0) { + append_str(p, xparams.s, xparams.len); + } append_str(p, CRLF, CRLF_LEN); /* if is HTTP, replace Via with Sia * - HTTP Via format is different than SIP Via @@ -2768,7 +2854,7 @@ int branch_builder(unsigned int hash_index, } -/* uses only the send_info->send_socket, send_info->proto and +/* uses only the send_info->send_socket, send_info->proto, send_info->id and * send_info->comp (so that a send_info used for sending can be passed * to this function w/o changes and the correct via will be built) */ char *via_builder(unsigned int *len, sip_msg_t *msg, @@ -2787,6 +2873,7 @@ char *via_builder(unsigned int *len, sip_msg_t *msg, char *comp_name; #endif /* USE_COMP */ int port; + int proto; struct ip_addr ip; union sockaddr_union *from = NULL; union sockaddr_union local_addr; @@ -2830,7 +2917,23 @@ char *via_builder(unsigned int *len, sip_msg_t *msg, else port_str = &(send_sock->port_no_str); } - + proto = PROTO_NONE; + if(msg && (msg->msg_flags & FL_USE_XAVP_VIA_FIELDS) + && _ksr_xavp_via_fields.len > 0) { + xname.s = "proto"; + xname.len = 5; + rxavp = xavp_get_child_with_sval(&_ksr_xavp_via_fields, &xname); + if(rxavp != NULL) { + proto = get_valid_proto_id(&rxavp->val.v.s); + } + } + if(proto == PROTO_NONE) { + if(send_sock->useinfo.proto != PROTO_NONE) { + proto = send_sock->useinfo.proto; + } else { + proto = send_info->proto; + } + } comp_len = comp_name_len = 0; #ifdef USE_COMP comp_name = 0; @@ -2853,7 +2956,7 @@ char *via_builder(unsigned int *len, sip_msg_t *msg, } #endif /* USE_COMP */ - via_prefix_len = MY_VIA_LEN + (send_info->proto == PROTO_SCTP); + via_prefix_len = MY_VIA_LEN + (proto == PROTO_SCTP); max_len = via_prefix_len + address_str->len /* space in MY_VIA */ + 2 /* just in case it is a v6 address ... [ ] */ + 1 /*':'*/ + port_str->len @@ -2872,15 +2975,15 @@ char *via_builder(unsigned int *len, sip_msg_t *msg, via_len = via_prefix_len + address_str->len; /*space included in MY_VIA*/ memcpy(line_buf, MY_VIA, MY_VIA_LEN); - if(send_info->proto == PROTO_UDP) { + if(proto == PROTO_UDP) { /* do nothing */ - } else if(send_info->proto == PROTO_TCP) { + } else if(proto == PROTO_TCP) { memcpy(line_buf + MY_VIA_LEN - 4, "TCP ", 4); - } else if(send_info->proto == PROTO_TLS) { + } else if(proto == PROTO_TLS) { memcpy(line_buf + MY_VIA_LEN - 4, "TLS ", 4); - } else if(send_info->proto == PROTO_SCTP) { + } else if(proto == PROTO_SCTP) { memcpy(line_buf + MY_VIA_LEN - 4, "SCTP ", 5); - } else if(send_info->proto == PROTO_WS) { + } else if(proto == PROTO_WS) { if(unlikely(send_info->send_flags.f & SND_F_FORCE_SOCKET && send_info->send_sock)) { local_addr = send_info->send_sock->su; @@ -2919,10 +3022,10 @@ char *via_builder(unsigned int *len, sip_msg_t *msg, return 0; } tcpconn_put(con); - } else if(send_info->proto == PROTO_WSS) { + } else if(proto == PROTO_WSS) { memcpy(line_buf + MY_VIA_LEN - 4, "WSS ", 4); } else { - LM_CRIT("unknown proto %d\n", send_info->proto); + LM_CRIT("unknown proto %d\n", proto); pkg_free(line_buf); return 0; } diff --git a/src/core/onsend.c b/src/core/onsend.c index a4d81781d..84186cd67 100644 --- a/src/core/onsend.c +++ b/src/core/onsend.c @@ -87,7 +87,18 @@ int run_onsend(sip_msg_t *orig_msg, dest_info_t *dst, char *buf, int len) orig_msg->fwd_send_flags = fwd_snd_flags_bak; orig_msg->rpl_send_flags = rpl_snd_flags_bak; exec_post_script_cb(orig_msg, ONSEND_CB_TYPE); - if((ret == 0) && !(ra_ctx.run_flags & DROP_R_F)) { + /* - handle drop action with flag DROP_R_F + * KEMI case (python,lua,jsdt) + * ret = 1 always + * Native case: + * ret = 1 success + * ret = 0 drop the message + */ + if(ra_ctx.run_flags & DROP_R_F) { + ret = 0; + } else if(ret == 0) { + /* native case where run_actions return 0 + * but DROP_R_F is not set */ ret = 1; } } else { diff --git a/src/core/parser/contact/contact.c b/src/core/parser/contact/contact.c index 3c66a2082..dd522a6cd 100644 --- a/src/core/parser/contact/contact.c +++ b/src/core/parser/contact/contact.c @@ -208,6 +208,18 @@ static inline int skip_name(str *_s) return -1; } +static inline void contact_append(contact_t **head, contact_t *node) +{ + contact_t *ptr = *head; + if(*head == NULL) { + *head = node; + return; + } + while(ptr->next != NULL) { + ptr = ptr->next; + } + ptr->next = node; +} /* * Parse contacts in a Contact HF @@ -298,8 +310,7 @@ int parse_contacts(str *_s, contact_t **_c) _s->len--; trim_leading(_s); - c->next = *_c; - *_c = c; + contact_append(_c, c); c = NULL; if(_s->len == 0) { @@ -318,8 +329,8 @@ error: ok: c->len = _s->s - c->name.s; - c->next = *_c; - *_c = c; + contact_append(_c, c); + c = NULL; return 0; } diff --git a/src/core/parser/hf.c b/src/core/parser/hf.c index d1ed5c1bb..c71f0d899 100644 --- a/src/core/parser/hf.c +++ b/src/core/parser/hf.c @@ -40,6 +40,7 @@ #include "parse_expires.h" #include "parse_sipifmatch.h" #include "parse_rr.h" +#include "parse_diversion.h" #include "parse_subscription_state.h" #include "contact/parse_contact.h" #include "parse_disposition.h" @@ -87,7 +88,7 @@ void clean_hdr_field(struct hdr_field *const hf) break; case HDR_DIVERSION_T: - free_to(hf->parsed); + free_diversion_body((diversion_body_t *)(hf->parsed)); break; case HDR_EVENT_T: diff --git a/src/core/parser/msg_parser.c b/src/core/parser/msg_parser.c index fdc4a8443..a85048730 100644 --- a/src/core/parser/msg_parser.c +++ b/src/core/parser/msg_parser.c @@ -63,7 +63,7 @@ /* number of via's encountered */ int via_cnt; /* global request flags */ -unsigned int global_req_flags = 0; +msg_flags_t global_req_flags = 0; int ksr_sip_parser_mode = KSR_SIP_PARSER_MODE_STRICT; @@ -1341,31 +1341,33 @@ int get_rcv_socket_uri(sip_msg_t *m, int tmode, str *uri, int atype) char *p; str ip, port; int len; - str proto; + int af; + str proto = STR_NULL; if(!uri || !m || !m->rcv.bind_address) { ERR("invalid parameter value\n"); return -1; } - if(tmode == 0) { - switch(m->rcv.proto) { - case PROTO_NONE: - case PROTO_UDP: - proto.s = - 0; /* Do not add transport parameter, UDP is default */ - proto.len = 0; - break; - default: - if(get_valid_proto_string(m->rcv.proto, 1, 0, &proto) < 0) { - ERR("unknown transport protocol\n"); - return -1; - } - } + if((tmode == 0) + && (m->rcv.proto == PROTO_NONE || m->rcv.proto == PROTO_UDP)) { + /* do not add transport parameter, UDP is default */ + proto.s = NULL; + proto.len = 0; } else { - if(get_valid_proto_string(m->rcv.proto, 1, 0, &proto) < 0) { - ERR("unknown transport protocol\n"); - return -1; + if(atype == 0 || m->rcv.bind_address->useinfo.address_str.len <= 0 + || m->rcv.bind_address->useinfo.proto == PROTO_NONE) { + if(get_valid_proto_string(m->rcv.proto, 1, 0, &proto) < 0) { + ERR("unknown transport protocol\n"); + return -1; + } + } else { + if(get_valid_proto_string( + m->rcv.bind_address->useinfo.proto, 1, 0, &proto) + < 0) { + ERR("unknown transport protocol\n"); + return -1; + } } } @@ -1384,8 +1386,13 @@ int get_rcv_socket_uri(sip_msg_t *m, int tmode, str *uri, int atype) port.s = m->rcv.bind_address->useinfo.port_no_str.s; port.len = m->rcv.bind_address->useinfo.port_no_str.len; } + if(atype == 1 && m->rcv.bind_address->useinfo.address_str.len > 0) { + af = m->rcv.bind_address->useinfo.af; + } else { + af = m->rcv.src_ip.af; + } - len = 4 + ip.len + 2 * (m->rcv.src_ip.af == AF_INET6) + 1 + port.len; + len = 4 + ip.len + 2 * (af == AF_INET6) + 1 + port.len; if(proto.s) { len += TRANSPORT_PARAM_LEN; len += proto.len; @@ -1400,11 +1407,11 @@ int get_rcv_socket_uri(sip_msg_t *m, int tmode, str *uri, int atype) memcpy(p, "sip:", 4); p += 4; - if(m->rcv.src_ip.af == AF_INET6) + if(af == AF_INET6) *p++ = '['; memcpy(p, ip.s, ip.len); p += ip.len; - if(m->rcv.src_ip.af == AF_INET6) + if(af == AF_INET6) *p++ = ']'; *p++ = ':'; diff --git a/src/core/parser/msg_parser.h b/src/core/parser/msg_parser.h index b9dc0260f..45e7eb1a7 100644 --- a/src/core/parser/msg_parser.h +++ b/src/core/parser/msg_parser.h @@ -118,6 +118,8 @@ typedef enum request_method #define FL_ROUTE_ADDR (1 << 25) /*!< request has Route address for next hop */ #define FL_USE_OTCPID \ (1 << 26) /*!< request to be routed using outbound tcp con id */ +#define FL_ADD_XAVP_VIA_REPLY_PARAMS \ + (1 << 27) /*!< add xavp fields to first (previous sip node) via params */ /* WARNING: Value (1 << 28) is reserved for use in kamailio call_control * module (flag FL_USE_CALL_CONTROL )! */ @@ -131,6 +133,9 @@ typedef enum request_method /* WARNING: Value (1 << 31) is reserved for use in kamailio * nat_traversal module (flag FL_DO_KEEPALIVE)! */ +#define FL_FINAL_REPLY (1ULL << 32) /* local final reply sent */ +#define FL_DELAYED_REPLY (1ULL << 33) /* local reply sending delayed */ + #define FL_MTU_FB_MASK (FL_MTU_TCP_FB | FL_MTU_TLS_FB | FL_MTU_SCTP_FB) @@ -232,6 +237,8 @@ enum _uri_flags }; /* bit fields */ typedef enum _uri_flags uri_flags; +typedef unsigned long long msg_flags_t; + /*! \brief The SIP uri object */ struct sip_uri { @@ -421,7 +428,7 @@ typedef struct sip_msg unsigned int hash_index; /*!< index to TM hash table; stored in core to avoid unnecessary calculations */ - unsigned int msg_flags; /*!< internal flags used by core */ + msg_flags_t msg_flags; /*!< internal flags used by core */ flag_t flags; /*!< config flags */ flag_t xflags[KSR_XFLAGS_SIZE]; /*!< config extended flags */ str set_global_address; @@ -445,7 +452,7 @@ typedef struct sip_msg * runing failure handlers - see modules/tm/t_reply.c */ } sip_msg_t; -/*! \brief pointer to a fakes message which was never received ; +/*! \brief pointer to a faked message which was never received ; (when this message is "relayed", it is generated out of the original request) */ @@ -457,7 +464,7 @@ extern int via_cnt; * a flag value is checked, e.g.: * if ((msg->msg_flags|global_req_flags) & FL_XXX) ... */ -extern unsigned int global_req_flags; +extern msg_flags_t global_req_flags; int parse_msg( diff --git a/src/core/parser/parse_diversion.c b/src/core/parser/parse_diversion.c index 804dfdb6b..557950052 100644 --- a/src/core/parser/parse_diversion.c +++ b/src/core/parser/parse_diversion.c @@ -31,6 +31,7 @@ #include "../dprint.h" #include "../ut.h" #include "../mem/mem.h" +#include "parse_diversion.h" #include "parse_from.h" #include "parse_to.h" #include "msg_parser.h" @@ -44,49 +45,187 @@ * * limitations: it parses only the first occurrence */ -int parse_diversion_header(struct sip_msg *msg) +#define NUM_DIVERSION_BODIES 10 +int parse_diversion_body(char *buf, int len, diversion_body_t **body) { - struct to_body *diversion_b; + static to_body_t uri_b[NUM_DIVERSION_BODIES]; /* Temporary storage */ + int num_uri = 0; + int body_len = 0; + char *tmp; + int i; + to_param_t *params; + + memset(uri_b, 0, NUM_DIVERSION_BODIES * sizeof(to_body_t)); + + tmp = parse_addr_spec(buf, buf + len, &uri_b[num_uri], 1); + if(uri_b[num_uri].error == PARSE_ERROR) { + LM_ERR("Error parsing Diversion body %u '%.*s'\n", num_uri, len, buf); + return -1; + } - if(!msg->diversion && (parse_headers(msg, HDR_DIVERSION_F, 0) == -1)) { - goto error; + /* id.body should contain all info including uri and params */ + body_len = uri_b[num_uri].body.len; + + /* Loop over all params */ + params = uri_b[num_uri].param_lst; + while(params) { + body_len += + params->name.len + params->value.len + 2; // 2 for '=' and ';' + params = params->next; } - if(!msg->diversion) { - /* header not found */ + uri_b[num_uri].body.len = body_len; + + num_uri++; + while(*tmp == ',' && (num_uri < NUM_DIVERSION_BODIES)) { + tmp++; + while(tmp < buf + len && (*tmp == ' ' || *tmp == '\t')) + tmp++; + + if(tmp >= buf + len) { + LM_ERR("no content after comma when parsing Diversion body %u " + "'%.*s'\n", + num_uri, len, buf); + // Free params already allocated + while(num_uri >= 0) { + free_to_params(&uri_b[num_uri]); + num_uri--; + } + return -1; + } + + if((tmp < buf + len - 1 && *tmp == '\n') + || (tmp < buf + len - 2 && *tmp == '\r' + && *(tmp + 1) == '\n')) { + if(*tmp == '\n') { + tmp++; + } else { + tmp += 2; + } + if(*tmp != ' ' && *tmp != '\t') { + // TODO: Check if this is the correct error message + LM_ERR("no space after EOL when parsing Diversion body %u " + "'%.*s'\n", + num_uri, len, buf); + // Free params already allocated + while(num_uri >= 0) { + free_to_params(&uri_b[num_uri]); + num_uri--; + } + return -1; + } + tmp++; + } + /* Parse next body */ + tmp = parse_addr_spec(tmp, buf + len, &uri_b[num_uri], 1); + if(uri_b[num_uri].error == PARSE_ERROR) { + LM_ERR("Error parsing Diversion body %u '%.*s'\n", num_uri, len, + buf); + // Free params already allocated + while(num_uri >= 0) { + free_to_params(&uri_b[num_uri]); + num_uri--; + } + return -1; + } + + /* id.body should contain all info including uri and params */ + body_len = uri_b[num_uri].body.len; + + /* Loop over all params */ + params = uri_b[num_uri].param_lst; + while(params) { + body_len += params->name.len + params->value.len + + 2; /* 2 for '=' and ';' */ + params = params->next; + } + + uri_b[num_uri].body.len = body_len; + + num_uri++; + } + if(num_uri >= NUM_DIVERSION_BODIES) { + LM_WARN("Too many bodies in Diversion header '%.*s'\n", len, buf); + LM_WARN("Ignoring bodies beyond %u\n", NUM_DIVERSION_BODIES); + } + *body = pkg_malloc(sizeof(diversion_body_t) + num_uri * sizeof(to_body_t)); + if(*body == NULL) { + PKG_MEM_ERROR; return -1; } + memset(*body, 0, sizeof(diversion_body_t)); + (*body)->id = (to_body_t *)((char *)(*body) + sizeof(diversion_body_t)); + (*body)->num_ids = num_uri; + for(i = 0; i < num_uri; i++) { + memcpy(&(*body)->id[i], &uri_b[i], sizeof(to_body_t)); + } + return 0; +} +int parse_diversion_header(struct sip_msg *msg) +{ + diversion_body_t *diversion_b; + diversion_body_t **prev_diversion_body; + hdr_field_t *hf; + void **vp; + + if(!msg->diversion) { + if(parse_headers(msg, HDR_DIVERSION_F, 0) < 0) { + LM_ERR("Error parsing Diversion header\n"); + return -1; + } + + if(!msg->diversion) { + /* Diversion header not found */ + LM_DBG("Diversion header not found\n"); + return -1; + } + } /* maybe the header is already parsed! */ if(msg->diversion->parsed) return 0; - /* bad luck! :-( - we have to parse it */ - /* first, get some memory */ - diversion_b = pkg_malloc(sizeof(struct to_body)); - if(diversion_b == 0) { - PKG_MEM_ERROR; - goto error; + vp = &msg->diversion->parsed; + /* Set it as the first header in the list */ + prev_diversion_body = (diversion_body_t **)vp; + + /* Loop through all the Diversion headers */ + for(hf = msg->diversion; hf != NULL; hf = next_sibling_hdr(hf)) { + if(parse_diversion_body(hf->body.s, hf->body.len, &diversion_b) < 0) { + LM_ERR("Error parsing Diversion header\n"); + return -1; + } + + hf->parsed = (void *)diversion_b; + *prev_diversion_body = diversion_b; + prev_diversion_body = &diversion_b->next; + + if(parse_headers(msg, HDR_DIVERSION_F, 1) < 0) { + LM_ERR("Error looking for subsequent Diversion header\n"); + return -1; + } } + return 0; +} - /* now parse it!! */ - memset(diversion_b, 0, sizeof(struct to_body)); - parse_addr_spec(msg->diversion->body.s, - msg->diversion->body.s + msg->diversion->body.len + 1, diversion_b, - 1); - if(diversion_b->error == PARSE_ERROR) { - LM_ERR("bad diversion header\n"); - free_to(diversion_b); - goto error; +int free_diversion_body(diversion_body_t *div_b) +{ + int i; + + if(div_b == NULL) { + return -1; } - msg->diversion->parsed = diversion_b; + for(i = 0; i < div_b->num_ids; i++) { + /* Free to_body pointer parameters */ + if(div_b->id[i].param_lst) { + free_to_params(&(div_b->id[i])); + } + } + pkg_free(div_b); return 0; -error: - return -1; } - /*! \brief * Get the value of a given diversion parameter */ @@ -99,7 +238,9 @@ str *get_diversion_param(struct sip_msg *msg, str *name) return 0; } - params = ((struct to_body *)(msg->diversion->parsed))->param_lst; + to_body_t *diversion = + get_diversion(msg)->id; /* This returns the first entry */ + params = diversion->param_lst; while(params) { if((params->name.len == name->len) diff --git a/src/core/parser/parse_diversion.h b/src/core/parser/parse_diversion.h index 271219eba..8aba7d8f1 100644 --- a/src/core/parser/parse_diversion.h +++ b/src/core/parser/parse_diversion.h @@ -29,10 +29,21 @@ #define PARSE_DIVERSION_H #include "msg_parser.h" +#include "parse_addr_spec.h" + +/*! \brief + * Structure representing a Diversion header + */ +typedef struct diversion_body +{ + to_body_t *id; + int num_ids; + struct diversion_body *next; /*!< Next Diversion in the list */ +} diversion_body_t; /*! \brief casting macro for accessing Diversion body */ -#define get_diversion(p_msg) ((struct to_body *)(p_msg)->diversion->parsed) +#define get_diversion(p_msg) ((diversion_body_t *)(p_msg)->diversion->parsed) /*! \brief @@ -45,4 +56,9 @@ int parse_diversion_header(struct sip_msg *msg); */ str *get_diversion_param(struct sip_msg *msg, str *name); +/*! \brief + * Free the memory allocated for a Diversion header + */ +int free_diversion_body(diversion_body_t *div_b); + #endif /* PARSE_DIVERSION_H */ diff --git a/src/core/parser/parse_rr.c b/src/core/parser/parse_rr.c index f6fce793f..362f30b15 100644 --- a/src/core/parser/parse_rr.c +++ b/src/core/parser/parse_rr.c @@ -444,20 +444,28 @@ int print_rr_body( i = (nb_recs == NULL) ? 0 : *nb_recs; while(i < n) { - memcpy(cp, route[i].s, route[i].len); - cp += route[i].len; - if(++i < n) - *(cp++) = ','; + if(route[i].s != NULL) { + memcpy(cp, route[i].s, route[i].len); + cp += route[i].len; + if(++i < n) + *(cp++) = ','; + } else { + i++; + } } } else { i = (nb_recs == NULL) ? n - 1 : (n - *nb_recs - 1); while(i >= 0) { - memcpy(cp, route[i].s, route[i].len); - cp += route[i].len; - if(i-- > 0) - *(cp++) = ','; + if(route[i].s != NULL) { + memcpy(cp, route[i].s, route[i].len); + cp += route[i].len; + if(i-- > 0) + *(cp++) = ','; + } else { + i--; + } } } oroute->len = cp - start; diff --git a/src/core/parser/parse_via.c b/src/core/parser/parse_via.c index 8eb5b763e..f924e3dc5 100644 --- a/src/core/parser/parse_via.c +++ b/src/core/parser/parse_via.c @@ -1090,7 +1090,7 @@ find_value: state = F_COMP_VALUE; break; /* '=' in any other COMP value state is an error, - * and it will be catched by the default branch */ + * and it will be caught by the default branch */ #endif case P_STRING: break; @@ -1162,10 +1162,18 @@ find_value: case ',': switch(state) { case P_VALUE: + if(param->flags & VIA_PARAM_F_QUOTED) { + /* inside a quoted value */ + break; + } param->value.len = tmp - param->value.s; state = F_VIA; goto endofvalue; case P_STRING: + if(param->flags & VIA_PARAM_F_QUOTED) { + /* inside a quoted value */ + break; + } case F_LF: case F_CR: case F_CRLF: @@ -1217,6 +1225,7 @@ find_value: case F_VALUE: state = P_STRING; param->value.s = tmp + 1; + param->flags |= VIA_PARAM_F_QUOTED; break; case P_STRING: state = L_PARAM; @@ -2695,11 +2704,11 @@ endofpacket: if(vb->params.s != NULL && vb->params.len == 0 && vb->last_param != NULL) { if(vb->last_param->name.len > 0) { if(vb->last_param->value.len > 0) { - vb->params.len = vb->last_param->value.s - + vb->last_param->value.len - vb->params.s; + vb->params.len = vb->last_param->value.s + vb->last_param->value.len + - vb->params.s; } else { - vb->params.len = vb->last_param->name.s - + vb->last_param->name.len - vb->params.s; + vb->params.len = vb->last_param->name.s + vb->last_param->name.len + - vb->params.s; } } } @@ -2720,11 +2729,11 @@ nextvia: if(vb->params.s != NULL && vb->params.len == 0 && vb->last_param != NULL) { if(vb->last_param->name.len > 0) { if(vb->last_param->value.len > 0) { - vb->params.len = vb->last_param->value.s - + vb->last_param->value.len - vb->params.s; + vb->params.len = vb->last_param->value.s + vb->last_param->value.len + - vb->params.s; } else { - vb->params.len = vb->last_param->name.s - + vb->last_param->name.len - vb->params.s; + vb->params.len = vb->last_param->name.s + vb->last_param->name.len + - vb->params.s; } } } @@ -2840,3 +2849,46 @@ int parse_via_header(struct sip_msg *msg, int n, struct via_body **q) } else return -1; } + + +/* + * Parse/link Via overload-control parameters + */ +int parse_via_oc(struct sip_msg *msg, struct via_body *vbp, via_oc_t *ocp) +{ + via_param_t *vp; + + if(vbp == NULL || ocp == NULL) { + return -1; + } + memset(ocp, 0, sizeof(via_oc_t)); + + for(vp = vbp->param_lst; vp != NULL; vp = vp->next) { + if(vp->name.len == 2 && strncasecmp(vp->name.s, "oc", 2) == 0) { + if(vp->value.len > 0) { + ocp->oc = 2; + ocp->ocval.len = vp->value.len; + ocp->ocval.s = vp->value.s; + } else { + ocp->oc = 1; + } + } else if(vp->name.len == 7 + && strncasecmp(vp->name.s, "oc-algo", 7) == 0) { + if(vp->value.len > 0) { + ocp->algo.len = vp->value.len; + ocp->algo.s = vp->value.s; + } + } else if(vp->name.len == 11 + && strncasecmp(vp->name.s, "oc-validity", 11) == 0) { + if(vp->value.len > 0) { + str2ulong(&vp->value, &ocp->validity); + } + } else if(vp->name.len == 6 + && strncasecmp(vp->name.s, "oc-seq", 6) == 0) { + if(vp->value.len > 0) { + str2int(&vp->value, &ocp->seq); + } + } + } + return 0; +} diff --git a/src/core/parser/parse_via.h b/src/core/parser/parse_via.h index 4cd17ca3e..beda386cf 100644 --- a/src/core/parser/parse_via.h +++ b/src/core/parser/parse_via.h @@ -53,9 +53,12 @@ enum }; +#define VIA_PARAM_F_QUOTED (1) + typedef struct via_param { int type; /* Type of the parameter */ + unsigned int flags; /* Flags for the parameter */ str name; /* Name of the parameter */ str value; /* Value of the parameter */ char *start; /* Pointer to param start, just after ';', @@ -66,6 +69,16 @@ typedef struct via_param } via_param_t; +/* RFC7339 - overload control */ +typedef struct via_oc +{ + int oc; + str ocval; + str algo; + unsigned long validity; + unsigned int seq; +} via_oc_t; + /* Format: name/version/transport host:port;params comment */ /* WARNING: keep in sync with tm/sip_msg.c via_body_cloner */ typedef struct via_body @@ -123,5 +136,9 @@ void free_via_list(struct via_body *vb); */ int parse_via_header(struct sip_msg *msg, int n, struct via_body **q); +/* + * Parse/link Via overload-control parameters + */ +int parse_via_oc(struct sip_msg *msg, struct via_body *vbp, via_oc_t *ocp); #endif /* PARSE_VIA_H */ diff --git a/src/core/ppcfg.c b/src/core/ppcfg.c index 262a7931c..d77a23788 100644 --- a/src/core/ppcfg.c +++ b/src/core/ppcfg.c @@ -510,6 +510,8 @@ char *pp_defexp_eval(char *exval, int exlen, int qmode) LM_DBG("expression string result: [%s]\n", result->param.stz.sval); sval.s = result->param.stz.sval; sval.len = strlen(result->param.stz.sval); + } else { + goto done; } if(qmode == 1) { diff --git a/src/core/proxy.c b/src/core/proxy.c index 7b6aa0fcd..77868ef6f 100644 --- a/src/core/proxy.c +++ b/src/core/proxy.c @@ -220,7 +220,6 @@ error: return 0; } -/* FIXME - we should use the same error logic as in HOSTENT_CPY */ #define MK_PROXY(name, port, protocol, p_malloc, p_free, he_cpy) \ do { \ struct proxy_l *p; \ diff --git a/src/core/proxy.h b/src/core/proxy.h index b3702c954..1e775e671 100644 --- a/src/core/proxy.h +++ b/src/core/proxy.h @@ -93,4 +93,4 @@ inline static void proxy_mark(struct proxy_l *p, int err) } -#endif \ No newline at end of file +#endif diff --git a/src/core/pv_core.c b/src/core/pv_core.c index 48232b4c2..c889f7572 100644 --- a/src/core/pv_core.c +++ b/src/core/pv_core.c @@ -39,8 +39,6 @@ extern int _last_returned_code; static int pv_get_retcode(struct sip_msg *msg, pv_param_t *p, pv_value_t *res) { - /* FIXME: as soon as PVs support script context, use it instead of the - * return in global variable hack */ return pv_get_sintval(msg, p, res, _last_returned_code); } diff --git a/src/core/pvapi.c b/src/core/pvapi.c index 37a872b95..34d0a9bcb 100644 --- a/src/core/pvapi.c +++ b/src/core/pvapi.c @@ -90,6 +90,38 @@ pv_cache_t **pv_cache_get_table(void) return NULL; } +static void pv_cache_dump(int level) +{ + int i; + pv_cache_t *pvi = NULL; + + if(_pv_cache_set == 0) { + LM_DBG("PV cache not initialized\n"); + return; + } + + for(i = 0; i < PV_CACHE_SIZE; i++) { + pvi = _pv_cache[i]; + while(pvi) { + LOG(level, "pvar [%.*s] found in cache[%d]\n", pvi->pvname.len, + pvi->pvname.s, i); + pvi = pvi->next; + } + } +} + +/* Dumps pv cache. + * Per-child process callback that is called + * when pv_cache_dump cfg var is changed. + */ +void pv_cache_dump_cb(str *gname, str *name) +{ + if(cfg_get(core, core_cfg, pv_cache_dump) == my_pid()) { + pv_cache_dump(cfg_get(core, core_cfg, memlog)); + cfg_get(core, core_cfg, pv_cache_dump) = 0; + } +} + /** * @brief Check if a char is valid according to the PV syntax * @param c checked char @@ -1997,7 +2029,7 @@ void pv_destroy_api(void) * - buffer to print PVs */ static char **_pv_print_buffer = NULL; -#define PV_DEFAULT_PRINT_BUFFER_SIZE 8192 /* 8kB */ +#define PV_DEFAULT_PRINT_BUFFER_SIZE 32768 /* 32kB */ static int _pv_print_buffer_size = PV_DEFAULT_PRINT_BUFFER_SIZE; static int _pv_print_buffer_size_active = 0; /* 6 mod params + 4 direct usage from mods */ diff --git a/src/core/pvapi.h b/src/core/pvapi.h index 729bcf307..9cea1a803 100644 --- a/src/core/pvapi.h +++ b/src/core/pvapi.h @@ -22,6 +22,7 @@ #ifndef __pvapi_h__ #define __pvapi_h__ +#include "str.h" int pv_init_api(void); void pv_destroy_api(void); @@ -34,6 +35,7 @@ int pv_get_buffer_size(void); int pv_get_buffer_slots(void); void pv_set_buffer_size(int n); void pv_set_buffer_slots(int n); +void pv_cache_dump_cb(str *gname, str *name); #endif /*__pvapi_h__*/ diff --git a/src/core/raw_sock.c b/src/core/raw_sock.c index 0e0faddfc..dcf3708a0 100644 --- a/src/core/raw_sock.c +++ b/src/core/raw_sock.c @@ -164,7 +164,7 @@ int raw_socket(int proto, struct ip_addr *ip, str *iface, int iphdr_incl) goto error; #endif /* SO_BINDTODEVICE */ } - /* FIXME: probe_max_receive_buffer(sock) missing */ + /* note: probe_max_receive_buffer(sock) missing */ if(ip) { init_su(&su, ip, 0); if(bind(sock, &su.s, sockaddru_len(su)) == -1) { @@ -323,8 +323,6 @@ int raw_udp4_recv(int rsock, char **buf, int len, union sockaddr_union *from, *buf = *buf + sizeof(struct ip); } - /* FIXME: if initial buffer is aligned, one could skip the memcpy - and directly cast ip and udphdr pointer to the memory */ memcpy(&iph, *buf, sizeof(struct ip)); udph_start = *buf + iph.ip_hl * 4; udp_payload = udph_start + sizeof(struct udphdr); diff --git a/src/core/resolve.c b/src/core/resolve.c index b6ee85926..6d581f491 100644 --- a/src/core/resolve.c +++ b/src/core/resolve.c @@ -1526,8 +1526,8 @@ size_t create_srv_pref_list(char *proto, struct dns_srv_proto *list) if(naptr_proto_supported(i) == 0) { continue; } else { - list[i - 1].proto_pref = tmp.proto_pref; - list[i - 1].proto = i; + list[list_len].proto_pref = tmp.proto_pref; + list[list_len].proto = i; list_len++; } }; diff --git a/src/core/route_struct.c b/src/core/route_struct.c index 654e588be..fa43b498e 100644 --- a/src/core/route_struct.c +++ b/src/core/route_struct.c @@ -561,11 +561,12 @@ void print_actions(struct action *a) */ struct action *get_action_from_param(void **param, int param_no) { - struct action *ac, ac2; - action_u_t *au, au2; + cfg_action_t *ac; + action_u_t *au; /* param points to au->u.string, get pointer to au */ - au = (void *)((char *)param - ((char *)&au2.u.string - (char *)&au2)); + au = ksr_container_of(param, action_u_t, u.string); au = au - 1 - param_no; - ac = (void *)((char *)au - ((char *)&ac2.val - (char *)&ac2)); + /* au points to ac->val, get pointer to ac */ + ac = ksr_container_of(au, cfg_action_t, val); return ac; } diff --git a/src/core/rthreads.h b/src/core/rthreads.h new file mode 100644 index 000000000..56d68cef2 --- /dev/null +++ b/src/core/rthreads.h @@ -0,0 +1,294 @@ +/* + * Copyright (C) 2024 Chan Shih-Ping + * + * This file is part of Kamailio, a free SIP server. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * A set of helpers to run functions in threads. + * + * This is not a thread pool implementation - + * - it runs functions in a run-once thread to avoid + * creating thread-locals in the calling thread. + * + * Primary use case: to init libssl in a separate thread + */ +#include + +#include "./globals.h" +/* + * prototype: void *fn(void *arg) { ... } + */ +typedef void *(*_thread_proto)(void *); + +#ifndef KSR_RTHREAD_SKIP_P +static void *run_threadP(_thread_proto fn, void *arg) +{ +#ifdef USE_TLS + pthread_t tid; + void *ret = NULL; + + if(likely(ksr_tls_threads_mode == 0 || ksr_tls_threads_mode == 2 + || (ksr_tls_threads_mode == 1 && process_no > 0))) { + return fn(arg); + } + + pthread_create(&tid, NULL, fn, arg); + pthread_join(tid, &ret); + + return ret; +#else + return fn(arg); +#endif /* USE_TLS */ +} +#endif + +/* + * prototype: void *fn(void *arg1, int arg2) { ... } + */ +#ifdef KSR_RTHREAD_NEED_PI +typedef void *(*_thread_protoPI)(void *, int); +struct _thread_argsPI +{ + _thread_protoPI fn; + void *tptr; + int tint; +}; +static void *run_thread_wrapPI(struct _thread_argsPI *args) +{ + return (*args->fn)(args->tptr, args->tint); +} + +static void *run_threadPI(_thread_protoPI fn, void *arg1, int arg2) +{ +#ifdef USE_TLS + pthread_t tid; + void *ret = NULL; + + if(likely(ksr_tls_threads_mode == 0 || ksr_tls_threads_mode == 2 + || (ksr_tls_threads_mode == 1 && process_no > 0))) { + return fn(arg1, arg2); + } + + pthread_create(&tid, NULL, (_thread_proto)&run_thread_wrapPI, + &(struct _thread_argsPI){fn, arg1, arg2}); + pthread_join(tid, &ret); + + return ret; +#else + return fn(arg1, arg2); +#endif +} +#endif + +/* + * prototype: void fn(void) { ... } + */ +#ifdef KSR_RTHREAD_NEED_V +typedef void (*_thread_protoV)(void); +struct _thread_argsV +{ + _thread_protoV fn; +}; +static void *run_thread_wrapV(struct _thread_argsV *args) +{ + (*args->fn)(); + return NULL; +} + +static void run_threadV(_thread_protoV fn) +{ +#ifdef USE_TLS + pthread_t tid; + + if(likely(ksr_tls_threads_mode == 0 || ksr_tls_threads_mode == 2 + || (ksr_tls_threads_mode == 1 && process_no > 0))) { + fn(); + return; + } + + pthread_create(&tid, NULL, (_thread_proto)run_thread_wrapV, + &(struct _thread_argsV){fn}); + pthread_join(tid, NULL); +#else + fn(); +#endif +} +#endif + +/* + * prototype: int fn(void *, void *) { ... } + */ +#ifdef KSR_RTHREAD_NEED_4PP +typedef int (*_thread_proto4PP)(void *, void *); +struct _thread_args4PP +{ + _thread_proto4PP fn; + void *arg1; + void *arg2; + int *ret; +}; +static void *run_thread_wrap4PP(struct _thread_args4PP *args) +{ + *args->ret = (*args->fn)(args->arg1, args->arg2); + return NULL; +} + +static int run_thread4PP(_thread_proto4PP fn, void *arg1, void *arg2) +{ +#ifdef USE_TLS + pthread_t tid; + int ret = 0; + + if(likely(ksr_tls_threads_mode == 0 || ksr_tls_threads_mode == 2 + || (ksr_tls_threads_mode == 1 && process_no > 0))) { + return fn(arg1, arg2); + } + pthread_create(&tid, NULL, (_thread_proto)run_thread_wrap4PP, + &(struct _thread_args4PP){fn, arg1, arg2, &ret}); + pthread_join(tid, NULL); + + return ret; +#else + return fn(arg1, arg2); +#endif +} +#endif + +/* + * prototype: void fn(void *) { ... } + */ +#ifdef KSR_RTHREAD_NEED_0P +typedef void (*_thread_proto0P)(void *); +struct _thread_args0P +{ + _thread_proto0P fn; + void *arg1; +}; +static void *run_thread_wrap0P(struct _thread_args0P *args) +{ + (*args->fn)(args->arg1); + return NULL; +} + +static void run_thread0P(_thread_proto0P fn, void *arg1) +{ +#ifdef USE_TLS + pthread_t tid; + + if(likely(ksr_tls_threads_mode == 0 || ksr_tls_threads_mode == 2 + || (ksr_tls_threads_mode == 1 && process_no > 0))) { + fn(arg1); + return; + } + pthread_create(&tid, NULL, (_thread_proto)run_thread_wrap0P, + &(struct _thread_args0P){fn, arg1}); + pthread_join(tid, NULL); +#else + fn(arg1) +#endif +} +#endif + +/* + * prototype: + * db_unixodbc_query(const db1_con_t *_h, const db_key_t *_k, + * const db_op_t *_op, const db_val_t *_v, const db_key_t *_c, + * const int _n, const int _nc, const db_key_t _o, db1_res_t **_r) + */ +#ifdef KSR_RTHREAD_NEED_4P5I2P2 +typedef int (*_thread_proto4P5I2P2)( + void *, void *, void *, void *, void *, int, int, void *, void *); +struct _thread_args4P5I2P2 +{ + _thread_proto4P5I2P2 fn; + void *arg1; + void *arg2; + void *arg3; + void *arg4; + void *arg5; + int arg6; + int arg7; + void *arg8; + void *arg9; + int *ret; +}; +static void *run_thread_wrap4P5I2P2(struct _thread_args4P5I2P2 *args) +{ + *args->ret = (*args->fn)(args->arg1, args->arg2, args->arg3, args->arg4, + args->arg5, args->arg6, args->arg7, args->arg8, args->arg9); + return NULL; +} + +static int run_thread4P5I2P2(_thread_proto4P5I2P2 fn, void *arg1, void *arg2, + void *arg3, void *arg4, void *arg5, int arg6, int arg7, void *arg8, + void *arg9) +{ +#ifdef USE_TLS + pthread_t tid; + int ret = 0; + + if(likely(ksr_tls_threads_mode == 0 || ksr_tls_threads_mode == 2 + || (ksr_tls_threads_mode == 1 && process_no > 0))) { + return fn(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + } + pthread_create(&tid, NULL, (_thread_proto)run_thread_wrap4P5I2P2, + &(struct _thread_args4P5I2P2){fn, arg1, arg2, arg3, arg4, arg5, + arg6, arg7, arg8, arg9, &ret}); + pthread_join(tid, NULL); + return ret; +#else + return fn(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); +#endif +} +#endif + +/* + * prototype: CURLcode curl_global_init(long flags) { ... } + */ +#ifdef KSR_RTHREAD_NEED_4L +typedef int (*_thread_proto4L)(long); +struct _thread_args4L +{ + _thread_proto4L fn; + long arg1; + int *ret; +}; +static void *run_thread_wrap4L(struct _thread_args4L *args) +{ + *args->ret = (*args->fn)(args->arg1); + return NULL; +} + +static int run_thread4L(_thread_proto4L fn, long arg1) +{ +#ifdef USE_TLS + pthread_t tid; + int ret = 0; + + if(likely(ksr_tls_threads_mode == 0 || ksr_tls_threads_mode == 2 + || (ksr_tls_threads_mode == 1 && process_no > 0))) { + return fn(arg1); + } + pthread_create(&tid, NULL, (_thread_proto)run_thread_wrap4L, + &(struct _thread_args4L){fn, arg1, &ret}); + pthread_join(tid, NULL); + + return ret; +#else + return fn(arg1) +#endif +} +#endif diff --git a/src/core/select_core.c b/src/core/select_core.c index 12b884ead..57dad2f78 100644 --- a/src/core/select_core.c +++ b/src/core/select_core.c @@ -1387,7 +1387,7 @@ int select_ip_port(str *res, select_t *s, struct sip_msg *msg) if(param & SEL_PROTO) { switch(msg->rcv.proto) { case PROTO_NONE: - proto_str.s = 0; + proto_str.s = ""; proto_str.len = 0; break; @@ -1411,6 +1411,16 @@ int select_ip_port(str *res, select_t *s, struct sip_msg *msg) proto_str.len = 4; break; + case PROTO_WS: + proto_str.s = "ws"; + proto_str.len = 2; + break; + + case PROTO_WSS: + proto_str.s = "wss"; + proto_str.len = 3; + break; + default: LM_ERR("Unknown transport protocol\n"); return -1; diff --git a/src/core/socket_info.c b/src/core/socket_info.c index 2b9996f93..ab59df73d 100644 --- a/src/core/socket_info.c +++ b/src/core/socket_info.c @@ -289,8 +289,8 @@ error: * allocates a si and a si->name in new pkg memory */ static inline struct socket_info *new_sock_info(char *name, struct name_lst *addr_l, unsigned short port, unsigned short proto, - char *usename, unsigned short useport, char *sockname, - enum si_flags flags) + unsigned short useproto, char *usename, unsigned short useport, + char *sockname, enum si_flags flags) { struct socket_info *si; struct name_lst *n; @@ -332,14 +332,21 @@ static inline struct socket_info *new_sock_info(char *name, si->useinfo.name.s = (char *)pkg_malloc(si->useinfo.name.len + 1); if(si->useinfo.name.s == 0) goto error; - strcpy(si->useinfo.name.s, usename); + strncpy(si->useinfo.name.s, usename, si->useinfo.name.len + 1); if(usename[0] == '[' && usename[si->useinfo.name.len - 1] == ']') { si->useinfo.address_str.len = si->useinfo.name.len - 2; p = si->useinfo.name.s + 1; + si->useinfo.af = AF_INET6; } else { + ip_addr_t *ipv = NULL; + ipv = str2ipx(&si->useinfo.name); + if(ipv != NULL) { + si->useinfo.af = ipv->af; + } si->useinfo.address_str.len = si->useinfo.name.len; p = si->useinfo.name.s; } + si->useinfo.proto = (useproto != PROTO_NONE) ? useproto : proto; si->useinfo.address_str.s = (char *)pkg_malloc(si->useinfo.address_str.len + 1); if(si->useinfo.address_str.s == NULL) @@ -354,7 +361,7 @@ static inline struct socket_info *new_sock_info(char *name, (char *)pkg_malloc(si->useinfo.port_no_str.len + 1); if(si->useinfo.port_no_str.s == NULL) goto error; - strcpy(si->useinfo.port_no_str.s, p); + strncpy(si->useinfo.port_no_str.s, p, si->useinfo.port_no_str.len); si->useinfo.port_no = useport; he = resolvehost(si->useinfo.name.s); @@ -457,7 +464,11 @@ int socketinfo2str(char *s, int *len, struct socket_info *si, int mode) str proto; int l; - proto.s = get_valid_proto_name(si->proto); + if(si->useinfo.proto != PROTO_NONE) { + proto.s = get_valid_proto_name(si->useinfo.proto); + } else { + proto.s = get_valid_proto_name(si->proto); + } proto.len = strlen(proto.s); if(mode == 1) @@ -1068,14 +1079,14 @@ found: /* append a new sock_info structure to the corresponding list * return new sock info on success, 0 on error */ static struct socket_info *new_sock2list(char *name, struct name_lst *addr_l, - unsigned short port, unsigned short proto, char *usename, - unsigned short useport, char *sockname, enum si_flags flags, - struct socket_info **list) + unsigned short port, unsigned short proto, unsigned short useproto, + char *usename, unsigned short useport, char *sockname, + enum si_flags flags, struct socket_info **list) { struct socket_info *si; /* allocates si and si->name in new pkg memory */ - si = new_sock_info( - name, addr_l, port, proto, usename, useport, sockname, flags); + si = new_sock_info(name, addr_l, port, proto, useproto, usename, useport, + sockname, flags); if(si == 0) { LM_ERR("new_sock_info failed\n"); goto error; @@ -1087,14 +1098,15 @@ static struct socket_info *new_sock2list(char *name, struct name_lst *addr_l, #ifdef USE_MCAST if(mcast != 0) { si->mcast.len = strlen(mcast); - si->mcast.s = (char *)pkg_malloc(si->mcast.len + 1); + si->mcast.s = (char *)pkg_mallocxz(si->mcast.len + 1); if(si->mcast.s == 0) { PKG_MEM_ERROR; + si->mcast.len = 0; pkg_free(si->name.s); pkg_free(si); return 0; } - strcpy(si->mcast.s, mcast); + memcpy(si->mcast.s, mcast, si->mcast.len); mcast = 0; } #endif /* USE_MCAST */ @@ -1109,13 +1121,13 @@ error: * return new sock info on success, 0 on error */ static struct socket_info *new_sock2list_after(char *name, struct name_lst *addr_l, unsigned short port, unsigned short proto, - char *usename, unsigned short useport, char *sockname, - enum si_flags flags, struct socket_info *after) + unsigned short useproto, char *usename, unsigned short useport, + char *sockname, enum si_flags flags, struct socket_info *after) { struct socket_info *si; - si = new_sock_info( - name, addr_l, port, proto, usename, useport, sockname, flags); + si = new_sock_info(name, addr_l, port, proto, useproto, usename, useport, + sockname, flags); if(si == 0) { LM_ERR("new_sock_info failed\n"); goto error; @@ -1130,8 +1142,9 @@ error: /* adds a sock_info structure to the corresponding proto list * return last new socket info structur on success, NULL on error */ socket_info_t *add_listen_socket_info(char *name, struct name_lst *addr_l, - unsigned short port, unsigned short proto, char *usename, - unsigned short useport, char *sockname, enum si_flags flags) + unsigned short port, unsigned short proto, unsigned short useproto, + char *usename, unsigned short useport, char *sockname, + enum si_flags flags) { socket_info_t *newsi = NULL; socket_info_t **list = NULL; @@ -1162,8 +1175,8 @@ socket_info_t *add_listen_socket_info(char *name, struct name_lst *addr_l, c_port = port; } if(c_proto != PROTO_SCTP) { - newsi = new_sock2list(name, 0, c_port, c_proto, usename, useport, - sockname, flags & ~SI_IS_MHOMED, list); + newsi = new_sock2list(name, 0, c_port, c_proto, useproto, usename, + useport, sockname, flags & ~SI_IS_MHOMED, list); if(newsi == 0) { LM_ERR("new_sock2list failed\n"); goto error; @@ -1171,16 +1184,17 @@ socket_info_t *add_listen_socket_info(char *name, struct name_lst *addr_l, /* add the other addresses in the list as separate sockets * since only SCTP can bind to multiple addresses */ for(a_l = addr_l; a_l; a_l = a_l->next) { - if(new_sock2list(a_l->name, 0, c_port, c_proto, usename, - useport, sockname, flags & ~SI_IS_MHOMED, list) + if(new_sock2list(a_l->name, 0, c_port, c_proto, useproto, + usename, useport, sockname, flags & ~SI_IS_MHOMED, + list) == 0) { LM_ERR("new_sock2list failed\n"); goto error; } } } else { - newsi = new_sock2list(name, addr_l, c_port, c_proto, usename, - useport, sockname, flags, list); + newsi = new_sock2list(name, addr_l, c_port, c_proto, useproto, + usename, useport, sockname, flags, list); if(newsi == 0) { LM_ERR("new_sock2list failed\n"); goto error; @@ -1196,11 +1210,12 @@ error: /* adds a sock_info structure to the corresponding proto list * return 0 on success, -1 on error */ int add_listen_advertise_iface_name(char *name, struct name_lst *addr_l, - unsigned short port, unsigned short proto, char *usename, - unsigned short useport, char *sockname, enum si_flags flags) + unsigned short port, unsigned short proto, unsigned short useproto, + char *usename, unsigned short useport, char *sockname, + enum si_flags flags) { - if(add_listen_socket_info( - name, addr_l, port, proto, usename, useport, sockname, flags) + if(add_listen_socket_info(name, addr_l, port, proto, useproto, usename, + useport, sockname, flags) == NULL) { return -1; } @@ -1210,11 +1225,11 @@ int add_listen_advertise_iface_name(char *name, struct name_lst *addr_l, /* adds a sock_info structure to the corresponding proto list * return 0 on success, -1 on error */ int add_listen_advertise_iface(char *name, struct name_lst *addr_l, - unsigned short port, unsigned short proto, char *usename, - unsigned short useport, enum si_flags flags) + unsigned short port, unsigned short proto, unsigned short useproto, + char *usename, unsigned short useport, enum si_flags flags) { return add_listen_advertise_iface_name( - name, addr_l, port, proto, usename, useport, NULL, flags); + name, addr_l, port, proto, useproto, usename, useport, NULL, flags); } /* adds a sock_info structure to the corresponding proto list @@ -1223,7 +1238,7 @@ int add_listen_iface(char *name, struct name_lst *addr_l, unsigned short port, unsigned short proto, enum si_flags flags) { return add_listen_advertise_iface_name( - name, addr_l, port, proto, 0, 0, 0, flags); + name, addr_l, port, proto, 0, 0, 0, 0, flags); } /* adds a sock_info structure to the corresponding proto list @@ -1233,7 +1248,7 @@ int add_listen_iface_name(char *name, struct name_lst *addr_l, enum si_flags flags) { return add_listen_advertise_iface_name( - name, addr_l, port, proto, 0, 0, sockname, flags); + name, addr_l, port, proto, 0, 0, 0, sockname, flags); } int add_listen_socket(socket_attrs_t *sa) @@ -1249,8 +1264,8 @@ int add_listen_socket(socket_attrs_t *sa) addr_l.name = sa->bindaddr.s; newsi = add_listen_socket_info(sa->bindaddr.s, &addr_l, sa->bindport, - sa->bindproto, sa->useaddr.s, sa->useport, sa->sockname.s, - sa->sflags); + sa->bindproto, sa->useproto, sa->useaddr.s, sa->useport, + sa->sockname.s, sa->sflags); return (newsi != NULL) ? 0 : -1; } @@ -1810,14 +1825,14 @@ error: * return 0 on success, -1 on error */ static int addr_info_to_si_lst(struct addr_info *ai_lst, unsigned short port, - char proto, char *usename, unsigned short useport, char *sockname, - enum si_flags flags, struct socket_info **list) + char proto, char useproto, char *usename, unsigned short useport, + char *sockname, enum si_flags flags, struct socket_info **list) { struct addr_info *ail; for(ail = ai_lst; ail; ail = ail->next) { - if(new_sock2list(ail->name.s, 0, port, proto, usename, useport, - sockname, ail->flags | flags, list) + if(new_sock2list(ail->name.s, 0, port, proto, useproto, usename, + useport, sockname, ail->flags | flags, list) == 0) return -1; } @@ -1830,15 +1845,16 @@ static int addr_info_to_si_lst(struct addr_info *ai_lst, unsigned short port, * return 0 on success, -1 on error */ static int addr_info_to_si_lst_after(struct addr_info *ai_lst, - unsigned short port, char proto, char *usename, unsigned short useport, - char *sockname, enum si_flags flags, struct socket_info *el) + unsigned short port, char proto, char useproto, char *usename, + unsigned short useport, char *sockname, enum si_flags flags, + struct socket_info *el) { struct addr_info *ail; struct socket_info *new_si; for(ail = ai_lst; ail; ail = ail->next) { - if((new_si = new_sock2list_after(ail->name.s, 0, port, proto, usename, - useport, sockname, ail->flags | flags, el)) + if((new_si = new_sock2list_after(ail->name.s, 0, port, proto, useproto, + usename, useport, sockname, ail->flags | flags, el)) == 0) return -1; el = new_si; @@ -1879,8 +1895,9 @@ static int fix_socket_list(struct socket_info **list, int *type_flags) != -1) { if(si->flags & SI_IS_MHOMED) { if((new_si = new_sock2list_after(ai_lst->name.s, 0, si->port_no, - si->proto, si->useinfo.name.s, si->useinfo.port_no, - si->sockname.s, ai_lst->flags | si->flags, si)) + si->proto, si->useinfo.proto, si->useinfo.name.s, + si->useinfo.port_no, si->sockname.s, + ai_lst->flags | si->flags, si)) == 0) break; ail = ai_lst; @@ -1904,8 +1921,8 @@ static int fix_socket_list(struct socket_info **list, int *type_flags) } else { /* add all addr. as separate interfaces */ if(addr_info_to_si_lst_after(ai_lst, si->port_no, si->proto, - si->useinfo.name.s, si->useinfo.port_no, - si->sockname.s, si->flags, si) + si->useinfo.proto, si->useinfo.name.s, + si->useinfo.port_no, si->sockname.s, si->flags, si) != 0) goto error; /* ai_lst not needed anymore */ @@ -2067,7 +2084,7 @@ static int fix_socket_list(struct socket_info **list, int *type_flags) ail = ail_next; continue; } - /* 2. check if the extra addresses contain a duplicates for + /* 2. check if the extra addresses contain a duplicate for * other addresses in the same list */ for(tmp_ail = ail->next; tmp_ail;) { tmp_ail_next = tmp_ail->next; @@ -2231,14 +2248,13 @@ int fix_all_socket_lists() 0, AF_INET6, 0, PROTO_UDP, &ai_lst) == 0) #else - && (!auto_bind_ipv6 - || add_interfaces( - 0, AF_INET6, 0, PROTO_UDP, &ai_lst) - == 0) /* add_interface does not work for IPv6 on Linux */ + && (!auto_bind_ipv6 + || add_interfaces(0, AF_INET6, 0, PROTO_UDP, &ai_lst) + == 0) /* add_interface does not work for IPv6 on Linux */ #endif /* __OS_linux */ ) && (addr_info_to_si_lst( - ai_lst, 0, PROTO_UDP, 0, 0, 0, 0, &udp_listen) + ai_lst, 0, PROTO_UDP, 0, 0, 0, 0, 0, &udp_listen) == 0)) { free_addr_info_lst(&ai_lst); ai_lst = 0; @@ -2252,14 +2268,14 @@ int fix_all_socket_lists() PROTO_TCP, &ai_lst) != 0) #else - || (auto_bind_ipv6 - && add_interfaces(0, AF_INET6, 0, - PROTO_TCP, &ai_lst) - != 0) + || (auto_bind_ipv6 + && add_interfaces(0, AF_INET6, 0, PROTO_TCP, + &ai_lst) + != 0) #endif /* __OS_linux */ ) || (addr_info_to_si_lst(ai_lst, 0, PROTO_TCP, 0, 0, 0, - 0, &tcp_listen) + 0, 0, &tcp_listen) != 0)) goto error; free_addr_info_lst(&ai_lst); @@ -2274,14 +2290,14 @@ int fix_all_socket_lists() &ai_lst) != 0) #else - || (auto_bind_ipv6 - && add_interfaces(0, AF_INET6, 0, - PROTO_TLS, &ai_lst) - != 0) + || (auto_bind_ipv6 + && add_interfaces(0, AF_INET6, 0, + PROTO_TLS, &ai_lst) + != 0) #endif /* __OS_linux */ ) || (addr_info_to_si_lst(ai_lst, 0, PROTO_TLS, 0, 0, - 0, 0, &tls_listen) + 0, 0, 0, &tls_listen) != 0)) goto error; } @@ -2299,14 +2315,14 @@ int fix_all_socket_lists() PROTO_SCTP, &ai_lst) != 0) #else - || (auto_bind_ipv6 - && add_interfaces(0, AF_INET6, 0, - PROTO_SCTP, &ai_lst) - != 0) + || (auto_bind_ipv6 + && add_interfaces(0, AF_INET6, 0, PROTO_SCTP, + &ai_lst) + != 0) #endif /* __OS_linux */ ) || (addr_info_to_si_lst(ai_lst, 0, PROTO_SCTP, 0, 0, 0, - 0, &sctp_listen) + 0, 0, &sctp_listen) != 0)) goto error; free_addr_info_lst(&ai_lst); @@ -2421,8 +2437,9 @@ void print_all_socket_lists() printf(" name %s", si->sockname.s); } if(si->useinfo.name.s) { - printf(" advertise %s:%d", si->useinfo.name.s, - si->useinfo.port_no); + printf(" advertise %s:%s:%d", + get_valid_proto_name(si->useinfo.proto), + si->useinfo.name.s, si->useinfo.port_no); } printf("\n"); } diff --git a/src/core/socket_info.h b/src/core/socket_info.h index c45769be8..df6fbb836 100644 --- a/src/core/socket_info.h +++ b/src/core/socket_info.h @@ -84,11 +84,12 @@ int add_listen_iface_name(char *name, struct name_lst *addr_l, unsigned short port, unsigned short proto, char *sockname, enum si_flags flags); int add_listen_advertise_iface(char *name, struct name_lst *nlst, - unsigned short port, unsigned short proto, char *useaddr, - unsigned short useport, enum si_flags flags); + unsigned short port, unsigned short proto, unsigned short useproto, + char *useaddr, unsigned short useport, enum si_flags flags); int add_listen_advertise_iface_name(char *name, struct name_lst *nlst, - unsigned short port, unsigned short proto, char *useaddr, - unsigned short useport, char *sockname, enum si_flags flags); + unsigned short port, unsigned short proto, unsigned short useproto, + char *useaddr, unsigned short useport, char *sockname, + enum si_flags flags); int fix_all_socket_lists(void); void print_all_socket_lists(void); void print_aliases(void); diff --git a/src/core/sr_module.c b/src/core/sr_module.c index 2c5b4f185..d67e7e44a 100644 --- a/src/core/sr_module.c +++ b/src/core/sr_module.c @@ -326,8 +326,7 @@ static int register_module(module_exports_t *e, char *path, void *handle) LM_ERR("too long module name: %s\n", mod->exports.name); goto error; } - strcpy(defmod, "MOD_"); - strcat(defmod, mod->exports.name); + snprintf(defmod, 64, "MOD_%s", mod->exports.name); pp_define_set_type(KSR_PPDEF_DEFINE); if(pp_define(strlen(defmod), defmod) < 0) { LM_ERR("unable to set cfg define for module: %s\n", mod->exports.name); @@ -402,6 +401,7 @@ int ksr_locate_module(char *mod_path, char **new_path) { struct stat stat_buf; str modname; + str modfile; char *mdir; char *nxt_mdir; char *path; @@ -412,11 +412,14 @@ int ksr_locate_module(char *mod_path, char **new_path) *new_path = NULL; path = mod_path; path_type = 0; - modname.s = path; - modname.len = strlen(mod_path); - if(modname.len > 3 && strcmp(modname.s + modname.len - 3, ".so") == 0) { + modfile.s = path; + modfile.len = strlen(mod_path); + modname.s = modfile.s; + if(modfile.len > 3 && strcmp(modfile.s + modfile.len - 3, ".so") == 0) { path_type = 1; - modname.len -= 3; + modname.len = modfile.len - 3; + } else { + modname.len = modfile.len; } if(!strchr(path, '/')) path_type |= 2; @@ -445,9 +448,12 @@ int ksr_locate_module(char *mod_path, char **new_path) len++; } path[len] = 0; - strcat(path, modname.s); - if(!(path_type & 1)) + if(path_type & 1) { + strncat(path, modfile.s, modfile.len); + } else { + strncat(path, modname.s, modname.len); strcat(path, ".so"); + } if(stat(path, &stat_buf) == -1) { LM_DBG("module file not found <%s>\n", path); @@ -470,9 +476,12 @@ int ksr_locate_module(char *mod_path, char **new_path) path[len] = 0; strncat(path, modname.s, modname.len); strcat(path, "/"); - strcat(path, modname.s); - if(!(path_type & 1)) + if(path_type & 1) { + strncat(path, modfile.s, modfile.len); + } else { + strncat(path, modname.s, modname.len); strcat(path, ".so"); + } if(stat(path, &stat_buf) == -1) { LM_DBG("module file not found <%s>\n", path); @@ -503,7 +512,7 @@ int ksr_locate_module(char *mod_path, char **new_path) len++; } path[len] = 0; - strcat(path, mod_path); + strncat(path, mod_path, strlen(mod_path)); if(stat(path, &stat_buf) == -1) { LM_DBG("module file not found <%s>\n", path); @@ -1083,7 +1092,7 @@ action_u_t *fixup_get_param( { action_u_t *a; /* cur_param points to a->u.string, get pointer to a */ - a = (void *)((char *)cur_param - offsetof(action_u_t, u.string)); + a = (action_u_t *)((char *)cur_param - offsetof(action_u_t, u.string)); return a + required_param_no - cur_param_no; } @@ -1105,7 +1114,7 @@ int fixup_get_param_count(void **cur_param, int cur_param_no) action_param_type *fixup_get_param_ptype(void **param) { action_u_t *a; - a = (void *)((char *)param - offsetof(action_u_t, u.string)); + a = (action_u_t *)((char *)param - offsetof(action_u_t, u.string)); return &a->type; } diff --git a/src/core/tcp_main.c b/src/core/tcp_main.c index 2ad2fafbe..757329a85 100644 --- a/src/core/tcp_main.c +++ b/src/core/tcp_main.c @@ -1169,6 +1169,10 @@ int tcp_connection_limit_srcip(union sockaddr_union *srcaddr, int limit) int n; int i; + if(limit <= 0) { + return 0; + } + n = 0; su2ip_addr(&src_ip, srcaddr); TCPCONN_LOCK; @@ -2064,15 +2068,15 @@ int tcp_send(struct dest_info *dst, union sockaddr_union *from, const char *buf, struct tcp_connection *c; struct ip_addr ip; int port; - int fd; + int fd = -1; long response[2]; int n; ticks_t con_lifetime; int try_local_port; #ifdef USE_TLS - const char *rest_buf; - const char *t_buf; - unsigned rest_len, t_len; + const char *rest_buf = NULL; + const char *t_buf = NULL; + unsigned rest_len = 0, t_len = 0; long resp; snd_flags_t t_send_flags; #endif /* USE_TLS */ @@ -3256,6 +3260,18 @@ int tcp_init(struct socket_info *sock_info) } #endif init_sock_keepalive(sock_info->socket); +#ifdef HAVE_TCP_USER_TIMEOUT + if((optval = TICKS_TO_S(cfg_get(tcp, tcp_cfg, send_timeout)))) { + optval *= 1000; + if(setsockopt(sock_info->socket, IPPROTO_TCP, TCP_USER_TIMEOUT, &optval, + sizeof(optval)) + < 0) { + LM_WARN("failed to set TCP_USER_TIMEOUT: %s\n", strerror(errno)); + } else { + LM_INFO("Set TCP_USER_TIMEOUT=%d ms\n", optval); + } + } +#endif if(bind(sock_info->socket, &addr->s, sockaddru_len(*addr)) == -1) { LM_ERR("bind(%x, %p, %d) on %s:%d : %s\n", sock_info->socket, &addr->s, (unsigned)sockaddru_len(*addr), sock_info->address_str.s, @@ -3536,6 +3552,7 @@ static void destroy_send_fd_queues(void) } +#ifdef SEND_FD_QUEUE inline static int send_fd_queue_add( struct tcp_send_fd_q *q, int unix_sock, struct tcp_connection *t) { @@ -3573,7 +3590,7 @@ inline static int send_fd_queue_add( error: return -1; } - +#endif inline static void send_fd_queue_run(struct tcp_send_fd_q *q) { @@ -4361,7 +4378,6 @@ inline static int send2child(struct tcp_connection *tcpconn) tcpconn->s) <= 0)) { if((errno == EAGAIN) || (errno == EWOULDBLOCK)) { - /* FIXME: remove after debugging */ LM_CRIT("tcp child %d, socket %d: queue full, %d requests queued " "(total handled %d)\n", idx, tcp_children[idx].unix_sock, min_busy, @@ -4544,23 +4560,7 @@ inline static int handle_tcpconn_ev( int empty_q; int bytes; #endif /* TCP_ASYNC */ - /* is refcnt!=0 really necessary? - * No, in fact it's a bug: I can have the following situation: a send only - * tcp connection used by n processes simultaneously => refcnt = n. In - * the same time I can have a read event and this situation is perfectly - * valid. -- andrei - */ -#if 0 - if ((tcpconn->refcnt!=0)){ - /* FIXME: might be valid for sigio_rt iff fd flags are not cleared - * (there is a short window in which it could generate a sig - * that would be catched by tcp_main) */ - LM_CRIT("handle_tcpconn_ev: io event on referenced" - " tcpconn (%p), refcnt=%d, fd=%d\n", - tcpconn, tcpconn->refcnt, tcpconn->s); - return -1; - } -#endif + /* pass it to child, so remove it from the io watch list and the local * timer */ #ifdef TCP_ASYNC @@ -4615,7 +4615,7 @@ inline static int handle_tcpconn_ev( (void)dst_blocklist_su(BLST_ERR_SEND, tcpconn->rcv.proto, &tcpconn->rcv.src_su, &tcpconn->send_flags, 0); #endif /* USE_DST_BLOCKLIST */ - TCP_STATS_CON_RESET(); /* FIXME: it could != RST */ + TCP_STATS_CON_RESET(); /* note: it could != RST */ } } if(unlikely(!tcpconn_try_unhash(tcpconn))) { @@ -5493,11 +5493,11 @@ void tcp_timer_check_connections(unsigned int ticks, void *param) cidset = 0; if(con->state == S_CONN_OK) { if(con->req.tvrstart.tv_sec > 0) { - tvdiff = 1000000 + tvdiff = 1000000LL * (tvnow.tv_sec - con->req.tvrstart.tv_sec) + (tvnow.tv_usec - con->req.tvrstart.tv_usec); - if(tvdiff >= ksr_tcp_msg_read_timeout * 1000000) { + if(tvdiff >= 1000000LL * ksr_tcp_msg_read_timeout) { LM_DBG("n: %d - connection id: %d - message " "reading timeout: %lld\n", n, con->id, tvdiff); diff --git a/src/core/tcp_options.h b/src/core/tcp_options.h index d5a628a11..84c551e2a 100644 --- a/src/core/tcp_options.h +++ b/src/core/tcp_options.h @@ -68,6 +68,13 @@ #endif /* __OS_ */ #endif /* NO_TCP_LINGER2 */ +/* tcp user_timeout */ +#ifndef NO_TCP_USER_TIMEOUT +#ifdef __OS_linux +#define HAVE_TCP_USER_TIMEOUT +#endif /* __OS_ */ +#endif /* NO_TCP_LINGER2 */ + /* keepalive */ #ifndef NO_TCP_KEEPALIVE #define HAVE_SO_KEEPALIVE diff --git a/src/core/tcp_read.c b/src/core/tcp_read.c index 042881ee9..8fa6566c1 100644 --- a/src/core/tcp_read.c +++ b/src/core/tcp_read.c @@ -834,7 +834,8 @@ int tcp_read_headers(struct tcp_connection *c, rd_conn_flags_t *read_flags) r->state = H_CONT_LEN_BODY_PARSE; r->content_len = (*p - '0'); break; - /*FIXME: content length on different lines ! */ + /* note: review case of content-length + * on different lines */ crlf_default_skip_case; } p++; @@ -856,7 +857,7 @@ int tcp_read_headers(struct tcp_connection *c, rd_conn_flags_t *read_flags) break; case '\r': case ' ': - case '\t': /* FIXME: check if line contains only WS */ + case '\t': if(r->content_len < 0) { LM_ERR("bad Content-Length header value %d in" " state %d\n", @@ -1595,14 +1596,7 @@ again: #endif /* rcv.bind_address should always be !=0 */ bind_address = con->rcv.bind_address; - /* just for debugging use sendipv4 as receiving socket FIXME*/ - /* - if (con->rcv.dst_ip.af==AF_INET6){ - bind_address=sendipv6_tcp; - }else{ - bind_address=sendipv4_tcp; - } - */ + con->rcv.proto_reserved1 = con->id; /* copy the id */ c = *req->parsed; /* ugly hack: zero term the msg & save the previous char, req->parsed should be ok diff --git a/src/core/tcp_stats.h b/src/core/tcp_stats.h index 213f5e764..385895c39 100644 --- a/src/core/tcp_stats.h +++ b/src/core/tcp_stats.h @@ -101,7 +101,7 @@ void tcp_stats_destroy(void); #define TCP_STATS_CON_RESET() counter_inc(tcp_cnts_h.con_reset) /** called each time a send operation fails due to a timeout. - * FIXME: it works only in async mode (in sync. mode a send might timeout + * - note: it works only in async mode (in sync. mode a send might timeout * but the stats won't be increased). */ #define TCP_STATS_SEND_TIMEOUT() counter_inc(tcp_cnts_h.send_timeout) diff --git a/src/core/timer.c b/src/core/timer.c index fbfbf7877..1da85c2ec 100644 --- a/src/core/timer.c +++ b/src/core/timer.c @@ -823,7 +823,7 @@ inline static void timer_list_expire(ticks_t t, struct timer_head *h */ while(h->next != (struct timer_ln *)h) { tl = h->next; -#ifdef TIMER_DEBUG /* FIXME: replace w/ EXTRA_DEBUG */ +#ifdef TIMER_DEBUG if(tl == 0) { LM_CRIT("timer_list_expire: tl=%p, h=%p {%p, %p}\n", tl, h, h->next, h->prev); diff --git a/src/core/timer_proc.c b/src/core/timer_proc.c index 0b04cf651..55bd98dab 100644 --- a/src/core/timer_proc.c +++ b/src/core/timer_proc.c @@ -29,6 +29,7 @@ #include "pt.h" #include "ut.h" #include "mem/shm_mem.h" +#include "sr_module.h" #include @@ -76,6 +77,9 @@ int fork_basic_timer(int child_id, char *desc, int make_sock, timer_function *f, if(cfg_child_init()) return -1; for(;;) { + if(unlikely(ksr_shutdown_phase() != 0)) { + return 0; + } sleep(interval); cfg_update(); f(get_ticks(), param); /* ticks in s for compatibility with old @@ -99,6 +103,9 @@ int fork_basic_timer_w(int child_id, char *desc, int make_sock, if(cfg_child_init()) return -1; for(;;) { + if(unlikely(ksr_shutdown_phase() != 0)) { + return 0; + } sleep(interval); cfg_update(); f(get_ticks(), worker, @@ -141,6 +148,9 @@ int fork_basic_utimer(int child_id, char *desc, int make_sock, if(cfg_child_init()) return -1; for(;;) { + if(unlikely(ksr_shutdown_phase() != 0)) { + return 0; + } sleep_us(uinterval); cfg_update(); ts = get_ticks_raw(); @@ -165,6 +175,9 @@ int fork_basic_utimer_w(int child_id, char *desc, int make_sock, if(cfg_child_init()) return -1; for(;;) { + if(unlikely(ksr_shutdown_phase() != 0)) { + return 0; + } sleep_us(uinterval); cfg_update(); ts = get_ticks_raw(); @@ -273,6 +286,9 @@ int fork_sync_timer(int child_id, char *desc, int make_sock, timer_function *f, if(cfg_child_init()) return -1; for(;;) { + if(unlikely(ksr_shutdown_phase() != 0)) { + return 0; + } if(ts2 > interval) sleep_us(1000); /* 1 millisecond sleep to catch up */ else @@ -324,6 +340,9 @@ int fork_sync_utimer(int child_id, char *desc, int make_sock, if(cfg_child_init()) return -1; for(;;) { + if(unlikely(ksr_shutdown_phase() != 0)) { + return 0; + } if(ts2 > uinterval) sleep_us(1); else diff --git a/src/core/udp_server.c b/src/core/udp_server.c index bbb870312..7e01dd8c2 100644 --- a/src/core/udp_server.c +++ b/src/core/udp_server.c @@ -237,6 +237,107 @@ int probe_max_receive_buffer(int udp_sock) /* EoJKU */ } +int probe_max_send_buffer(int udp_sock) +{ + int optval; + int ioptval; + unsigned int ioptvallen; + int foptval; + unsigned int foptvallen; + int voptval; + unsigned int voptvallen; + int phase = 0; + + /* jku: try to increase buffer size as much as we can */ + ioptvallen = sizeof(ioptval); + if(getsockopt( + udp_sock, SOL_SOCKET, SO_SNDBUF, (void *)&ioptval, &ioptvallen) + == -1) { + LM_ERR("fd: %d getsockopt: %s\n", udp_sock, strerror(errno)); + return -1; + } + if(ioptval == 0) { + LM_DBG("SO_SNDBUF initially set to 0 for fd %d; resetting to %d\n", + udp_sock, BUFFER_INCREMENT); + ioptval = BUFFER_INCREMENT; + } else + LM_INFO("SO_SNDBUF is initially %d for fd %d\n", ioptval, udp_sock); + for(optval = ioptval;;) { + /* increase size; double in initial phase, add linearly later */ + if(phase == 0) + optval <<= 1; + else + optval += BUFFER_INCREMENT; + if(optval > maxsndbuffer) { + if(phase == 1) + break; + else { + phase = 1; + optval >>= 1; + continue; + } + } + if(ksr_verbose_startup) + LM_DBG("trying SO_SNDBUF: %d on fd: %d\n", optval, udp_sock); + if(setsockopt(udp_sock, SOL_SOCKET, SO_SNDBUF, (void *)&optval, + sizeof(optval)) + == -1) { + /* Solaris returns -1 if asked size too big; Linux ignores */ + LM_DBG("SOL_SOCKET failed for val %d on fd %d, phase %d: %s\n", + optval, udp_sock, phase, strerror(errno)); + /* if setting buffer size failed and still in the aggressive + phase, try less aggressively; otherwise give up + */ + if(phase == 0) { + phase = 1; + optval >>= 1; + continue; + } else + break; + } + /* verify if change has taken effect */ + /* Linux note -- otherwise I would never know that; funny thing: Linux + doubles size for which we asked in setsockopt + */ + voptvallen = sizeof(voptval); + if(getsockopt(udp_sock, SOL_SOCKET, SO_SNDBUF, (void *)&voptval, + &voptvallen) + == -1) { + LM_ERR("fd: %d getsockopt: %s\n", udp_sock, strerror(errno)); + return -1; + } else { + if(ksr_verbose_startup) + LM_DBG("setting SO_SNDBUF on fd %d; val=%d, verify=%d\n", + udp_sock, optval, voptval); + if(voptval < optval) { + LM_DBG("setting SO_SNDBUF on fd %d has no effect\n", udp_sock); + /* if setting buffer size failed and still in the aggressive + phase, try less aggressively; otherwise give up + */ + if(phase == 0) { + phase = 1; + optval >>= 1; + continue; + } else + break; + } + } + + } /* for ... */ + foptvallen = sizeof(foptval); + if(getsockopt( + udp_sock, SOL_SOCKET, SO_SNDBUF, (void *)&foptval, &foptvallen) + == -1) { + LM_ERR("fd: %d getsockopt: %s\n", udp_sock, strerror(errno)); + return -1; + } + LM_INFO("SO_SNDBUF is finally %d on fd %d\n", foptval, udp_sock); + + return 0; + + /* EoJKU */ +} + #ifdef USE_MCAST @@ -490,6 +591,9 @@ int udp_init(struct socket_info *sock_info) if(probe_max_receive_buffer(sock_info->socket) == -1) goto error; + if(probe_max_send_buffer(sock_info->socket) == -1) + goto error; + if(bind(sock_info->socket, &addr->s, sockaddru_len(*addr)) == -1) { LM_ERR("bind(%x, %p, %d) on %s: %s\n", sock_info->socket, &addr->s, (unsigned)sockaddru_len(*addr), sock_info->address_str.s, diff --git a/src/core/udp_server.h b/src/core/udp_server.h index 176b541bb..1ab5e1900 100644 --- a/src/core/udp_server.h +++ b/src/core/udp_server.h @@ -32,6 +32,7 @@ #include "ip_addr.h" #define MAX_RECV_BUFFER_SIZE 256 * 1024 +#define MAX_SEND_BUFFER_SIZE 256 * 1024 #define BUFFER_INCREMENT 2048 diff --git a/src/core/usr_avp.c b/src/core/usr_avp.c index 1adb8fdb8..d31ed6687 100644 --- a/src/core/usr_avp.c +++ b/src/core/usr_avp.c @@ -598,9 +598,7 @@ avp_t *search_avp_by_index( return 0; } -/* FIXME */ /********* free functions ********/ - void destroy_avp(avp_t *avp_del) { int i; diff --git a/src/core/usr_avp.h b/src/core/usr_avp.h index ae44b7b29..f75d54561 100644 --- a/src/core/usr_avp.h +++ b/src/core/usr_avp.h @@ -123,7 +123,6 @@ typedef struct search_state avp_id_t id; avp_name_t name; avp_t *avp; /* Current AVP */ - // regex_t* search_re; /* Compiled regular expression */ } avp_search_state_t; /* avp aliases structs*/ diff --git a/src/core/ut.h b/src/core/ut.h index 8e2e4f0d8..ff8d964e5 100644 --- a/src/core/ut.h +++ b/src/core/ut.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -143,6 +144,8 @@ #define is_in_str(p, in) (p < in->s + in->len && *p) +#define ksr_container_of(ptr, type, member) \ + ((type *)((char *)(ptr)-offsetof(type, member))) /* links a value to a msgid */ struct msgid_var diff --git a/src/core/utils/snexpr.h b/src/core/utils/snexpr.h index 559aa7915..5b159a256 100644 --- a/src/core/utils/snexpr.h +++ b/src/core/utils/snexpr.h @@ -62,7 +62,7 @@ extern "C" if(*length + 1 > *cap) { void *ptr; int n = (*cap == 0) ? 1 : *cap << 1; - ptr = realloc(*buf, n * memsz); + ptr = realloc(*buf, (size_t)n * memsz); if(ptr == NULL) { return -1; /* allocation failed */ } @@ -1254,10 +1254,10 @@ extern "C" sne_vec_free(&arg.args); goto cleanup; /* first argument is not a variable */ } - struct snexpr_var *v; - for(v = vars->head; v; v = v->next) { - if(v == u->param.var.vref) { - struct macro m = {v->name, arg.args}; + struct snexpr_var *v1; + for(v1 = vars->head; v1; v1 = v1->next) { + if(v1 == u->param.var.vref) { + struct macro m = {v1->name, arg.args}; sne_vec_push(¯os, m); break; } @@ -1284,9 +1284,9 @@ extern "C" char varname[14]; snprintf(varname, sizeof(varname) - 1, "$%d", (j + 1)); - struct snexpr_var *v = snexpr_var_find( + struct snexpr_var *v1 = snexpr_var_find( vars, varname, strlen(varname)); - struct snexpr ev = snexpr_varref(v); + struct snexpr ev = snexpr_varref(v1); struct snexpr assign = snexpr_binary(SNE_OP_ASSIGN, ev, sne_vec_nth(&arg.args, j)); @@ -1409,10 +1409,10 @@ extern "C" cleanup: sne_vec_foreach(¯os, m, i) { - struct snexpr e; - sne_vec_foreach(&m.body, e, j) + struct snexpr e1; + sne_vec_foreach(&m.body, e1, j) { - snexpr_destroy_args(&e); + snexpr_destroy_args(&e1); } sne_vec_free(&m.body); } diff --git a/src/core/xavp.c b/src/core/xavp.c index 4381ad1d4..21a819708 100644 --- a/src/core/xavp.c +++ b/src/core/xavp.c @@ -1105,19 +1105,23 @@ int xavp_set_child_sval(str *rname, str *cname, str *sval) } /** - * serialize the values in subfields of an xavp in name=value; format + * serialize the values in subfields of an xavp in name=value format styles * - rname - name of the root list xavp + * - mode - 0 - style is 'name=value;', 1 - style is ';name=value' * - obuf - buffer were to write the output * - olen - the size of obuf * return: 0 - not found; -1 - error; >0 - length of output */ -int xavp_serialize_fields(str *rname, char *obuf, int olen) +int xavp_serialize_fields_style(str *rname, int mode, char *obuf, int olen) { sr_xavp_t *ravp = NULL; sr_xavp_t *avp = NULL; str ostr; int rlen; + char *pr = ""; + char *sf = ""; + char *qs = ""; ravp = xavp_get(rname, NULL); if(ravp == NULL || ravp->val.type != SR_XTYPE_XAVP) { @@ -1125,6 +1129,17 @@ int xavp_serialize_fields(str *rname, char *obuf, int olen) return 0; } + if(mode & XAVP_PRINT_SCPR) { + pr = ";"; + sf = ""; + } else { + pr = ""; + sf = ";"; + } + if(mode & XAVP_PRINT_QVAL) { + qs = "\""; + } + rlen = 0; ostr.s = obuf; avp = ravp->val.v.xavp; @@ -1132,27 +1147,38 @@ int xavp_serialize_fields(str *rname, char *obuf, int olen) switch(avp->val.type) { case SR_XTYPE_LONG: LM_DBG(" XAVP long int value: %ld\n", avp->val.v.l); - ostr.len = snprintf(ostr.s, olen - rlen, "%.*s=%lu;", + ostr.len = snprintf(ostr.s, olen - rlen, "%s%.*s=%lu%s", pr, + avp->name.len, avp->name.s, (unsigned long)avp->val.v.l, + sf); + if(ostr.len <= 0 || ostr.len >= olen - rlen) { + LM_ERR("failed to serialize long int value (%d/%d)\n", + ostr.len, olen - rlen); + return -1; + } + break; + case SR_XTYPE_LLONG: + LM_DBG(" XAVP long long int value: %lld\n", avp->val.v.ll); + ostr.len = snprintf(ostr.s, olen - rlen, "%s%.*s=%llu%s", pr, avp->name.len, avp->name.s, - (unsigned long)avp->val.v.l); + (unsigned long long)avp->val.v.ll, sf); if(ostr.len <= 0 || ostr.len >= olen - rlen) { - LM_ERR("failed to serialize int value (%d/%d\n", ostr.len, - olen - rlen); + LM_ERR("failed to serialize long long value (%d/%d)\n", + ostr.len, olen - rlen); return -1; } break; case SR_XTYPE_STR: LM_DBG(" XAVP str value: %s\n", avp->val.v.s.s); if(avp->val.v.s.len == 0) { - ostr.len = snprintf(ostr.s, olen - rlen, "%.*s;", - avp->name.len, avp->name.s); + ostr.len = snprintf(ostr.s, olen - rlen, "%s%.*s%s", pr, + avp->name.len, avp->name.s, sf); } else { - ostr.len = snprintf(ostr.s, olen - rlen, "%.*s=%.*s;", - avp->name.len, avp->name.s, avp->val.v.s.len, - avp->val.v.s.s); + ostr.len = snprintf(ostr.s, olen - rlen, + "%s%.*s=%s%.*s%s%s", pr, avp->name.len, avp->name.s, + qs, avp->val.v.s.len, avp->val.v.s.s, qs, sf); } if(ostr.len <= 0 || ostr.len >= olen - rlen) { - LM_ERR("failed to serialize int value (%d/%d\n", ostr.len, + LM_ERR("failed to serialize str value (%d/%d)\n", ostr.len, olen - rlen); return -1; } @@ -1171,6 +1197,19 @@ int xavp_serialize_fields(str *rname, char *obuf, int olen) return rlen; } +/** + * serialize the values in subfields of an xavp in 'name=value;' format + * - rname - name of the root list xavp + * - obuf - buffer were to write the output + * - olen - the size of obuf + * return: 0 - not found; -1 - error; >0 - length of output + */ + +int xavp_serialize_fields(str *rname, char *obuf, int olen) +{ + return xavp_serialize_fields_style(rname, 0, obuf, olen); +} + /** * */ @@ -1607,8 +1646,19 @@ int xavu_serialize_fields(str *rname, char *obuf, int olen) avu->name.len, avu->name.s, (unsigned long)avu->val.v.l); if(ostr.len <= 0 || ostr.len >= olen - rlen) { - LM_ERR("failed to serialize int value (%d/%d\n", ostr.len, - olen - rlen); + LM_ERR("failed to serialize long int value (%d/%d\n", + ostr.len, olen - rlen); + return -1; + } + break; + case SR_XTYPE_LLONG: + LM_DBG(" XAVP long long int value: %lld\n", avu->val.v.ll); + ostr.len = snprintf(ostr.s, olen - rlen, "%.*s=%llu;", + avu->name.len, avu->name.s, + (unsigned long long)avu->val.v.ll); + if(ostr.len <= 0 || ostr.len >= olen - rlen) { + LM_ERR("failed to serialize long long value (%d/%d\n", + ostr.len, olen - rlen); return -1; } break; @@ -2571,8 +2621,19 @@ int xavi_serialize_fields(str *rname, char *obuf, int olen) avi->name.len, avi->name.s, (unsigned long)avi->val.v.l); if(ostr.len <= 0 || ostr.len >= olen - rlen) { - LM_ERR("failed to serialize int value (%d/%d\n", ostr.len, - olen - rlen); + LM_ERR("failed to serialize long int value (%d/%d\n", + ostr.len, olen - rlen); + return -1; + } + break; + case SR_XTYPE_LLONG: + LM_DBG(" XAVP long long int value: %lld\n", avi->val.v.ll); + ostr.len = snprintf(ostr.s, olen - rlen, "%.*s=%llu;", + avi->name.len, avi->name.s, + (unsigned long long)avi->val.v.ll); + if(ostr.len <= 0 || ostr.len >= olen - rlen) { + LM_ERR("failed to serialize long long value (%d/%d\n", + ostr.len, olen - rlen); return -1; } break; diff --git a/src/core/xavp.h b/src/core/xavp.h index c1aa7d8c6..b9131c2d2 100644 --- a/src/core/xavp.h +++ b/src/core/xavp.h @@ -115,6 +115,10 @@ sr_xavp_t *xavp_get_child_with_ival(str *rname, str *cname); sr_xavp_t *xavp_get_child_with_sval(str *rname, str *cname); int xavp_serialize_fields(str *rname, char *obuf, int olen); +#define XAVP_PRINT_SCPR 1 /* semicolon prefix */ +#define XAVP_PRINT_QVAL 2 /* quote string param values */ +int xavp_serialize_fields_style(str *rname, int mode, char *obuf, int olen); + int xavp_set_child_ival(str *rname, str *cname, long ival); int xavp_set_child_sval(str *rname, str *cname, str *sval); diff --git a/src/lib/cds/dbid.c b/src/lib/cds/dbid.c index 5eb2ab20e..fc4a47deb 100644 --- a/src/lib/cds/dbid.c +++ b/src/lib/cds/dbid.c @@ -9,7 +9,6 @@ void generate_dbid_ptr(dbid_t dst, void *data_ptr) { /* TODO: add cluster distinctive member */ - /* FIXME: replace sprintf by something more effective */ snprintf(dst, MAX_DBID_LEN, "%px%xx%x", data_ptr, (int)time(NULL), rand()); } @@ -26,7 +25,6 @@ void generate_dbid(dbid_t dst) } /* TODO: add cluster distinctive member */ - /* FIXME: replace sprintf by something more effective */ snprintf(dst, MAX_DBID_LEN, "%xy%xy%xy%x", my_pid, cntr++, (int)time(NULL), rand()); } diff --git a/src/lib/cds/simple_profile.c b/src/lib/cds/simple_profile.c index f166ec8b0..f20211776 100644 --- a/src/lib/cds/simple_profile.c +++ b/src/lib/cds/simple_profile.c @@ -4,9 +4,6 @@ #include #include -/* FIXME: only for testing */ -/*#include "dprint.h"*/ - #define trace_signal SIGTRAP typedef void (*_sig_t)(int); diff --git a/src/lib/cds/sstr.c b/src/lib/cds/sstr.c index 5b065fdcb..a342fbb26 100644 --- a/src/lib/cds/sstr.c +++ b/src/lib/cds/sstr.c @@ -263,7 +263,6 @@ char *str_strchr(const str_t *s, char c) char *str_str(const str_t *s, const str_t *search_for) { int i, j; - /* FIXME: reimplement using better algorithm */ if(is_str_empty(search_for)) return s->s; diff --git a/src/lib/presence/notifier_domain.c b/src/lib/presence/notifier_domain.c index 56773d13c..8f03828c1 100644 --- a/src/lib/presence/notifier_domain.c +++ b/src/lib/presence/notifier_domain.c @@ -223,33 +223,6 @@ static void free_subscription(qsa_subscription_t *s) cds_free(s); } -/*static void add_server_subscription(notifier_t *n, qsa_subscription_t *s) -{ - server_subscription_t server_s; - - server_s.notifier_data = NULL; - if (n->subscribe(n, &s->record_id, s, &server_s.notifier_data) == 0) { - server_s.notifier = n; - vector_add(&s->server_subscriptions, &server_s); - } - else ERROR_LOG("subscription not accepted by notifier %p\n", n); -} - -static void remove_notifier_from_subscription(qsa_subscription_t *s, notifier_t *n) -{ - int cnt,i; - - cnt = vector_size(&s->server_subscriptions); - for (i = 0; i < cnt; i++) { - ss = vector_get_ptr(&s->server_subscriptions, i); - if (!ss) continue; - / * FIXME: call n->unsubscribe ??? - * NO this is called from unregister which is initiated - * by the notifier (may be synchronized there!) * / - if (ss->notifier == n) ss->notifier = NULL; / * "zombie" * / - } -} -*/ /* -------- Domain initialization/destruction functions -------- */ diff --git a/src/lib/presence/pidf.c b/src/lib/presence/pidf.c index d875ce974..3f00314a5 100644 --- a/src/lib/presence/pidf.c +++ b/src/lib/presence/pidf.c @@ -170,9 +170,9 @@ static void doc_add_presentity( DEBUG_LOG("doc_add_presentity()\n"); if(use_cpim_pidf_ns) - dstr_append_zt( - buf, "properties, "id")); @@ -433,7 +433,7 @@ static int read_tuple(xmlNode *tuple, presence_tuple_info_t **dst, } else if(cmp_node(n, "status", ns) >= 0) { /* skip, already processed */ } else if(cmp_node(n, "timestamp", ns) >= 0) { - /* FIXME: process */ + /* TODO: process */ } else { /* PIDF extensions - only from non-PIDF namespace? */ res = read_extension(n, &ex, doc); if((res == 0) && ex) diff --git a/src/lib/srdb1/db_ut.c b/src/lib/srdb1/db_ut.c index c7a888704..9975672ae 100644 --- a/src/lib/srdb1/db_ut.c +++ b/src/lib/srdb1/db_ut.c @@ -610,11 +610,16 @@ int db_val2pv_spec(struct sip_msg *msg, db_val_t *dbval, pv_spec_t *pvs) pv.rs.len = LL_LEN; db_longlong2str(dbval->val.ll_val, ll_buf, &pv.rs.len); pv.rs.s = ll_buf; - /* if it fits, also store as 32 bit integer*/ - if(!((unsigned long long)dbval->val.ll_val - & 0xffffffff00000000ULL)) { + /* if it fits, also store as long number */ + if(sizeof(long long) == sizeof(long)) { pv.flags |= PV_VAL_INT | PV_TYPE_INT; - pv.ri = (int)dbval->val.ll_val; + pv.ri = (long)dbval->val.ll_val; + } else { + if(dbval->val.ll_val >= LONG_MIN + && dbval->val.ll_val <= LONG_MAX) { + pv.flags |= PV_VAL_INT | PV_TYPE_INT; + pv.ri = (long)dbval->val.ll_val; + } } break; default: diff --git a/src/lib/srdb2/db_cmd.c b/src/lib/srdb2/db_cmd.c index 2782f4dc7..9ba1d22ee 100644 --- a/src/lib/srdb2/db_cmd.c +++ b/src/lib/srdb2/db_cmd.c @@ -58,7 +58,7 @@ db_cmd_t *db_cmd(enum db_cmd_type type, db_ctx_t *ctx, char *table, newp->type = type; - /** FIXME: it is not clear now that this is necessary + /** NOTE: it is not clear now that this is necessary * when we have match and value separate arrays */ if(result) { newp->result = db_fld_copy(result); @@ -78,7 +78,7 @@ db_cmd_t *db_cmd(enum db_cmd_type type, db_ctx_t *ctx, char *table, goto err; } - /* FIXME: This should be redesigned so that we do not need to connect + /* NOTE: This should be redesigned so that we do not need to connect * connections in context before commands are created, this takes splitting * the command initialization sequence in two steps, one would be creating * all the data structures and the second would be checking corresponding @@ -242,7 +242,6 @@ int db_exec(db_res_t **res, db_cmd_t *cmd) return -1; } - /* FIXME */ db_payload_idx = 0; ret = cmd->exec[0](r, cmd); if(ret < 0) { diff --git a/src/lib/srdb2/db_gen.h b/src/lib/srdb2/db_gen.h index eca24c760..f8dd483b8 100644 --- a/src/lib/srdb2/db_gen.h +++ b/src/lib/srdb2/db_gen.h @@ -95,7 +95,7 @@ extern "C" */ /* - * FIXME: We should find some other way of doing this than just copying + * NOTE: We should find some other way of doing this than just copying * and pasting the code from STAILQ_FOREACH */ #define DBLIST_FOREACH(var, head) \ @@ -111,7 +111,7 @@ extern "C" */ /* - * FIXME: We should find some other way of doing this than just copying + * NOTE: We should find some other way of doing this than just copying * and pasting the code from STAILQ_FOREACH_SAFE */ #define DBLIST_FOREACH_SAFE(var, head, tvar) \ diff --git a/src/lib/trie/dtrie.c b/src/lib/trie/dtrie.c index 4de2ecf41..448a4cb01 100644 --- a/src/lib/trie/dtrie.c +++ b/src/lib/trie/dtrie.c @@ -127,7 +127,8 @@ int dtrie_insert(struct dtrie_node_t *root, const char *number, const unsigned int numberlen, void *data, const unsigned int branches) { struct dtrie_node_t *node = root; - unsigned char digit, i = 0; + unsigned char digit; + unsigned i = 0; if(root == NULL) return -1; @@ -242,7 +243,8 @@ void **dtrie_longest_match(struct dtrie_node_t *root, const char *number, const unsigned int branches) { struct dtrie_node_t *node = root; - unsigned char digit, i = 0; + unsigned char digit; + unsigned int i = 0; void **ret = NULL; if(root == NULL) diff --git a/src/lib/xcap/common_policy.c b/src/lib/xcap/common_policy.c index a7d33d95d..0f887aa7c 100644 --- a/src/lib/xcap/common_policy.c +++ b/src/lib/xcap/common_policy.c @@ -175,7 +175,7 @@ int is_rule_for_uri(cp_rule_t *rule, const str_t *uri) if(!rule) return 0; if(!rule->conditions) - return 1; /* FIXME: ??? */ + return 1; id = rule->conditions->identity; if(!id) return 0; diff --git a/src/lib/xcap/parse_common_rules.c b/src/lib/xcap/parse_common_rules.c index 0e46ace71..ca3f4599c 100644 --- a/src/lib/xcap/parse_common_rules.c +++ b/src/lib/xcap/parse_common_rules.c @@ -211,13 +211,11 @@ static int read_conditions(xmlNode *cn, cp_conditions_t **dst) while(n) { if(n->type == XML_ELEMENT_NODE) { if(cmp_node(n, "validity", common_policy_ns) >= 0) { - /* FIXME: free existing validity */ res = read_validity(n, &(*dst)->validity); if(res != 0) break; } else { if(cmp_node(n, "identity", common_policy_ns) >= 0) { - /* FIXME: free existing identity */ res = read_identity(n, &(*dst)->identity); if(res != 0) break; diff --git a/src/lib/xcap/resource_list.c b/src/lib/xcap/resource_list.c index cb7d11105..928c133df 100644 --- a/src/lib/xcap/resource_list.c +++ b/src/lib/xcap/resource_list.c @@ -169,9 +169,9 @@ void free_traversed_list(traversed_list_t *list) /* ------- helper functions (doing flat list) ------- */ +/* absolute uri from ref (RFC 3986, section 5.2) */ static char *relative2absolute_uri(const str_t *xcap_root, const char *relative) { - /* FIXME: do absolute uri from ref (RFC 3986, section 5.2) */ int len; int root_len = 0; int rel_len = 0; diff --git a/src/lib/xcap/xcap_client.c b/src/lib/xcap/xcap_client.c index c633f3c7f..2fe6e41d1 100644 --- a/src/lib/xcap/xcap_client.c +++ b/src/lib/xcap/xcap_client.c @@ -284,13 +284,8 @@ int xcap_query( /* follow redirects (needed for apache mod_speling - case insesitive names) */ curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1); - /* curl_easy_setopt(handle, CURLOPT_TCP_NODELAY, 1); - curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, 10);*/ - /* Accept headers */ - res = curl_easy_perform(handle); - /* curl_easy_cleanup(handle); */ /* FIXME: experimental */ } else ERROR_LOG("can't initialize curl handle\n"); if(res == 0) { diff --git a/src/main.c b/src/main.c index 8e34285fd..c7e98e1b4 100644 --- a/src/main.c +++ b/src/main.c @@ -31,7 +31,9 @@ */ #ifdef KSR_PTHREAD_MUTEX_SHARED +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include #endif @@ -167,11 +169,13 @@ Options:\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\ + default is no.\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 OS UDP receive buffer size which will not be exceeded by\n\ auto-probing-and-increase procedure even if OS allows\n\ + -B nr Maximum OS UDP send buffer size which will not be exceeded by\n\ + auto-probing-and-increase procedure even if OS allows\n\ -c Check configuration file for syntax errors\n\ --cfg-print Print configuration file evaluating includes and ifdefs\n\ -d Debugging level control (multiple -d to increase the level from 0)\n\ @@ -262,9 +266,10 @@ void print_ct_constants(void) /* printf("SHM_MEM_SIZE %dMB, ", SHM_MEM_SIZE); */ - printf("MAX_RECV_BUFFER_SIZE %d," + printf("MAX_RECV_BUFFER_SIZE %d, MAX_SEND_BUFFER_SIZE %d," " MAX_URI_SIZE %d, BUF_SIZE %d, DEFAULT PKG_SIZE %uMB\n", - MAX_RECV_BUFFER_SIZE, MAX_URI_SIZE, BUF_SIZE, PKG_MEM_SIZE); + MAX_RECV_BUFFER_SIZE, MAX_SEND_BUFFER_SIZE, MAX_URI_SIZE, BUF_SIZE, + PKG_MEM_SIZE); #ifdef USE_TCP printf("poll method support: %s.\n", poll_support); #endif @@ -279,6 +284,7 @@ void print_internals(void) printf(" Default paths to modules: %s\n", MODS_DIR); printf(" Compile flags: %s\n", ver_flags); printf(" MAX_RECV_BUFFER_SIZE=%d\n", MAX_RECV_BUFFER_SIZE); + printf(" MAX_SEND_BUFFER_SIZE=%d\n", MAX_SEND_BUFFER_SIZE); printf(" MAX_URI_SIZE=%d\n", MAX_URI_SIZE); printf(" BUF_SIZE=%d\n", BUF_SIZE); printf(" DEFAULT PKG_SIZE=%uMB\n", PKG_MEM_SIZE); @@ -306,7 +312,13 @@ char *mods_dir = MODS_DIR; /* search path for dyn. loadable modules */ int mods_dir_cmd = 0; /* mods dir path set in command lin e*/ char *cfg_file = 0; -unsigned int maxbuffer = MAX_RECV_BUFFER_SIZE; /* maximum buffer size we do +unsigned int maxbuffer = + MAX_RECV_BUFFER_SIZE; /* maximum receive buffer size we do + not want to exceed during the + auto-probing procedure; may + be re-configured */ +unsigned int maxsndbuffer = + MAX_SEND_BUFFER_SIZE; /* maximum send buffer size we do not want to exceed during the auto-probing procedure; may be re-configured */ @@ -326,8 +338,9 @@ int tcp_disable = 0; /* 1 if tcp is disabled */ int tls_disable = 0; /* tls enabled by default */ #else int tls_disable = 1; /* tls disabled by default */ -#endif /* CORE_TLS */ -#endif /* USE_TLS */ +#endif /* CORE_TLS */ +int ksr_tls_threads_mode = 0; /* threads execution mode for tls with libssl */ +#endif /* USE_TLS */ #ifdef USE_SCTP int sctp_children_no = 0; int sctp_disable = 2; /* 1 if sctp is disabled, 2 if auto mode, 0 enabled */ @@ -363,7 +376,7 @@ int timerlog = L_WARN; good for trouble-shooting */ int sip_warning = 0; -/* should localy-generated messages include server's signature? +/* should locally-generated messages include server's signature? be default yes, good for trouble-shooting */ int server_signature = 1; @@ -409,7 +422,7 @@ int open_files_limit = -1; /* don't touch it by default */ /* memory options */ int shm_force_alloc = 0; /* force immediate (on startup) page allocation - (by writting 0 in the pages), useful if + (by writing 0 in the pages), useful if mlock_pages is also 1 */ int mlock_pages = 0; /* default off, try to disable swapping */ @@ -454,7 +467,7 @@ struct socket_info *sctp_listen = 0; #endif struct socket_info *bind_address = 0; /* pointer to the crt. proc. listening address*/ -struct socket_info *sendipv4; /* ipv4 socket to use when msg. comes from ipv6*/ +struct socket_info *sendipv4; /* ipv4 socket to use when msg comes from ipv6 */ struct socket_info *sendipv6; /* same as above for ipv6 */ #ifdef USE_RAW_SOCKS int raw_udp4_send_sock = -1; /* raw socket used for sending udp4 packets */ @@ -536,7 +549,8 @@ char *sr_memmng_shm = NULL; static int *_sr_instance_started = NULL; int ksr_cfg_print_mode = 0; -int ksr_atexit_mode = 1; +int ksr_atexit_mode = 0; +int ksr_mem_add_size = 0; int ksr_wait_worker1_mode = 0; int ksr_wait_worker1_time = 4000000; @@ -1064,7 +1078,7 @@ static void free_name_lst(struct name_lst *lst) /* parse h and returns a name lst (flags are set to SI_IS_MHOMED if - * h contains more then one name or contains a name surrounded by '(' ')' ) + * h contains more than one name or contains a name surrounded by '(' ')' ) * valid formats: "hostname" * "(hostname, hostname1, hostname2)" * "(hostname hostname1 hostname2)" @@ -1148,7 +1162,7 @@ error: * where proto= udp|tcp|tls|sctp * @param s - string (like above) * @param host - will be filled with the host part - * Note: for multi-homing it wil contain all the addresses + * Note: for multi-homing it will contain all the addresses * (e.g.: "sctp:(1.2.3.4, 5.6.7.8)" => host="(1.2.3.4, 5.6.7.8)") * @param hlen - will be filled with the length of the host part. * @param port - will be filled with the port if present or 0 if it's not. @@ -1226,7 +1240,7 @@ int parse_phostport(char *s, char **host, int *hlen, int *port, int *proto) *host = first + 1; *hlen = (int)(p - *host); } else { - /* valid port => its host:port */ + /* valid port => it is host:port */ *proto = 0; *host = s; *hlen = (int)(first - *host); @@ -1254,7 +1268,7 @@ error_port: * where proto= udp|tcp|tls|sctp * @param s - string (like above) * @param host - will be filled with the host part - * Note: for multi-homing it wil contain all the addresses + * Note: for multi-homing it will contain all the addresses * (e.g.: "sctp:(1.2.3.4, 5.6.7.8)" => host="(1.2.3.4, 5.6.7.8)") * @param hlen - will be filled with the length of the host part. * @param port - will be filled with the port if present or 0 if it's not. @@ -1279,7 +1293,7 @@ static struct name_lst *parse_phostport_mh( * determine the default path to the configuration file if the user did not * specify one using the command line option. If \c cfg_file contains an * absolute pathname then it is cloned unmodified, if it contains a relative - * pathanme than the value returned by \c getcwd function will be added at the + * pathname then the value returned by \c getcwd function will be added at the * beginning. This function must be run before changing its current working * directory to / (in daemon mode). * @return Zero on success, negative number @@ -2069,8 +2083,9 @@ int main(int argc, char **argv) int c, r; char *tmp; int tmp_len; - int port; - int proto; + int port = 5060; + int proto = PROTO_NONE; + int aproto = PROTO_NONE; char *ahost = NULL; int aport = 0; char *options; @@ -2082,6 +2097,7 @@ int main(int argc, char **argv) struct name_lst *n_lst; char *p; struct stat st = {0}; + long l1 = 0; #define KSR_TBUF_SIZE 512 char tbuf[KSR_TBUF_SIZE]; @@ -2140,12 +2156,12 @@ int main(int argc, char **argv) log_init(); /* command line options */ - options = ":f:cm:M:dVIhEeb:l:L:n:vKrRDTN:W:w:t:u:g:P:G:SQ:O:a:A:x:X:Y:"; + options = ":f:cm:M:dVIhEeb:B:l:L:n:vKrRDTN:W:w:t:u:g:P:G:SQ:O:a:A:x:X:Y:"; /* Handle special command line arguments, that must be treated before - * intializing the various subsystem or before parsing other arguments: + * initializing the various subsystem or before parsing other arguments: * - get the startup debug and log_stderr values - * - look if pkg mem size is overriden on the command line (-M) and get - * the new value here (before intializing pkg_mem). + * - look if pkg mem size is overridden on the command line (-M) and get + * the new value here (before initializing pkg_mem). * - look if there is a -h, e.g. -f -h construction won't be caught * later */ @@ -2169,12 +2185,20 @@ int main(int argc, char **argv) fprintf(stderr, "bad private mem size\n"); goto error; } - pkg_mem_size = strtol(optarg, &tmp, 10) * 1024 * 1024; + l1 = strtol(optarg, &tmp, 10); if(tmp && (*tmp)) { fprintf(stderr, "bad private mem size number: -M %s\n", optarg); goto error; - }; + } + /* safety check for upper limit of 1TB */ + if(l1 <= 0 || l1 > 1024L * 1024) { + fprintf(stderr, + "out of limits private mem size number: -M %s\n", + optarg); + goto error; + } + pkg_mem_size = 1024UL * 1024 * l1; break; case 'x': sr_memmng_shm = optarg; @@ -2303,11 +2327,18 @@ int main(int argc, char **argv) fprintf(stderr, "bad shared mem size\n"); goto error; } - shm_mem_size = strtol(optarg, &tmp, 10) * 1024 * 1024; + l1 = strtol(optarg, &tmp, 10); if(tmp && (*tmp)) { fprintf(stderr, "bad shmem size number: -m %s\n", optarg); goto error; - }; + } + /* safety check for upper limit of 16TB */ + if(l1 <= 0 || l1 > 16L * 1024 * 1024) { + fprintf(stderr, "out of limits shmem size number: -m %s\n", + optarg); + goto error; + } + shm_mem_size = 1024UL * 1024 * l1; LM_INFO("shared memory: %ld bytes\n", shm_mem_size); break; case 'd': @@ -2382,6 +2413,7 @@ int main(int argc, char **argv) } break; case 'b': + case 'B': case 'l': case 'n': case 'K': @@ -2670,6 +2702,18 @@ int main(int argc, char **argv) goto error; } break; + case 'B': + if(optarg == NULL) { + fprintf(stderr, "bad -B parameter\n"); + goto error; + } + maxsndbuffer = strtol(optarg, &tmp, 10); + if(tmp && (*tmp)) { + fprintf(stderr, "bad max buffer size number: -B %s\n", + optarg); + goto error; + } + break; case 'T': #ifdef USE_TCP tcp_disable = 1; @@ -2707,7 +2751,7 @@ int main(int argc, char **argv) *p = '\0'; p++; tmp_len = 0; - if(parse_phostport(p, &ahost, &tmp_len, &aport, &proto) + if(parse_phostport(p, &ahost, &tmp_len, &aport, &aproto) < 0) { fprintf(stderr, "listen value with invalid advertise: %s\n", @@ -2730,7 +2774,7 @@ int main(int argc, char **argv) } /* add a new addr. to our address list */ if(add_listen_advertise_iface(n_lst->name, n_lst->next, port, - proto, ahost, aport, n_lst->flags) + proto, aproto, ahost, aport, n_lst->flags) != 0) { fprintf(stderr, "failed to add new listen address: %s\n", optarg); @@ -2991,7 +3035,7 @@ int main(int argc, char **argv) ksr_sockets_index(); if(default_core_cfg.dns_try_ipv6 && !(socket_types & SOCKET_T_IPV6)) { /* if we are not listening on any ipv6 address => no point - * to try to resovle ipv6 addresses */ + * to try to resolve ipv6 addresses */ default_core_cfg.dns_try_ipv6 = 0; } /* print all the listen addresses */ @@ -3239,7 +3283,7 @@ error: #ifdef KSR_PTHREAD_MUTEX_SHARED /** - * code to set PTHREAD_PROCESS_SHARED attribute for phtread mutex to cope + * code to set PTHREAD_PROCESS_SHARED attribute for pthread mutex to cope * with libssl 1.1+ thread-only mutex initialization */ diff --git a/src/modules/acc/README b/src/modules/acc/README index 2235d73aa..666f8844a 100644 --- a/src/modules/acc/README +++ b/src/modules/acc/README @@ -1478,9 +1478,11 @@ Chapter 2. Frequently Asked Questions First at all check if your question was already answered on one of our mailing lists: * User Mailing List - - https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users + https://lists.kamailio.org/mailman3/postorius/lists/sr-users.lists. + kamailio.org/ * Developer Mailing List - - https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-dev + https://lists.kamailio.org/mailman3/postorius/lists/sr-dev.lists.ka + mailio.org/ E-mails regarding any stable Kamailio release should be sent to and e-mails regarding development diff --git a/src/modules/acc/acc_cdr.c b/src/modules/acc/acc_cdr.c index 4ec019f1f..4c003e0ec 100644 --- a/src/modules/acc/acc_cdr.c +++ b/src/modules/acc/acc_cdr.c @@ -113,10 +113,10 @@ int cdr_core2strar(struct dlg_cell *dlg, str *values, int *unused, char *types) /* cleanup already allocated memory and * return that we didn't do anything */ for(i = i - 1; i >= 0; i--) { - if(NULL != values[i].s) { + if(NULL != values[i].s && types[i] != TYPE_NULL) { pkg_free(values[i].s); - values[i].s = NULL; } + values[i].s = NULL; } return 0; } diff --git a/src/modules/acc/acc_extra.c b/src/modules/acc/acc_extra.c index 255057a99..a84f02bbe 100644 --- a/src/modules/acc/acc_extra.c +++ b/src/modules/acc/acc_extra.c @@ -127,8 +127,10 @@ struct acc_extra *parse_acc_extra(char *extra_str) foo = s; while(*s && !isspace((int)*s) && EQUAL != *s) s++; - if(*s == 0) + if(*s == 0) { + LM_ERR("unexpected end of string\n"); goto parse_error; + } if(*s == EQUAL) { extra->name.len = (s++) - foo; } else { @@ -136,8 +138,10 @@ struct acc_extra *parse_acc_extra(char *extra_str) /* skip spaces */ while(*s && isspace((int)*s)) s++; - if(*s != EQUAL) + if(*s != EQUAL) { + LM_ERR("unexpected char '%c' instead of '='\n", *s); goto parse_error; + } s++; } extra->name.s = foo; @@ -149,15 +153,19 @@ struct acc_extra *parse_acc_extra(char *extra_str) /* get value type */ stmp.s = s; stmp.len = strlen(s); - if((foo = pv_parse_spec(&stmp, &extra->spec)) == 0) + if((foo = pv_parse_spec(&stmp, &extra->spec)) == 0) { + LM_ERR("failed to parse variable name\n"); goto parse_error; + } s = foo; /* skip spaces */ while(*s && isspace((int)*s)) s++; - if(*s && (*(s++) != SEPARATOR || *s == 0)) + if(*s && (*(s++) != SEPARATOR || *s == 0)) { + LM_ERR("unexpected char at end of name=var group\n"); goto parse_error; + } } /* go throught all extras and make the names null terminated */ diff --git a/src/modules/acc_json/README b/src/modules/acc_json/README index bdcc5e689..6d15e77b3 100644 --- a/src/modules/acc_json/README +++ b/src/modules/acc_json/README @@ -43,7 +43,7 @@ Julien Chavanton 3.10. acc_log_level (integer) 3.11. cdr_enable (int) 3.12. cdr_extra (str) - 3.13. cdr_json_pre_encoded_prefix (string) + 3.13. cdr_pre_encoded_prefix (string) 3.14. cdr_expired_dlg_enable (str) 3.15. cdr_output_mqueue (integer) 3.16. cdr_output_syslog (integer) @@ -64,7 +64,7 @@ Julien Chavanton 1.10. acc_log_level example 1.11. cdr_enable example 1.12. cdr_extra example - 1.13. cdr_json_pre_encoded_prefix example + 1.13. cdr_pre_encoded_prefix example 1.14. cdr_expired_dlg_enable example 1.15. cdr_output_mqueue usage example 1.16. cdr_log_facility example @@ -94,7 +94,7 @@ Chapter 1. Admin Guide 3.10. acc_log_level (integer) 3.11. cdr_enable (int) 3.12. cdr_extra (str) - 3.13. cdr_json_pre_encoded_prefix (string) + 3.13. cdr_pre_encoded_prefix (string) 3.14. cdr_expired_dlg_enable (str) 3.15. cdr_output_mqueue (integer) 3.16. cdr_output_syslog (integer) @@ -144,7 +144,7 @@ Chapter 1. Admin Guide 3.10. acc_log_level (integer) 3.11. cdr_enable (int) 3.12. cdr_extra (str) - 3.13. cdr_json_pre_encoded_prefix (string) + 3.13. cdr_pre_encoded_prefix (string) 3.14. cdr_expired_dlg_enable (str) 3.15. cdr_output_mqueue (integer) 3.16. cdr_output_syslog (integer) @@ -350,17 +350,17 @@ modparam("acc_json", "cdr_enable", 1) modparam("acc_json", "cdr_extra", "ci=$dlg_var(call_id);ft=$dlg_var(from_tag)") ... -3.13. cdr_json_pre_encoded_prefix (string) +3.13. cdr_pre_encoded_prefix (string) Prefix to identify values that will be considered to be already json encoded. Default value is NULL. - Example 1.13. cdr_json_pre_encoded_prefix example + Example 1.13. cdr_pre_encoded_prefix example ... modparam("acc_json", "cdr_extra", "json_data=$avp(json_data);") -modparam("acc_json", "cdr_json_pre_encoded_prefix", "json_") +modparam("acc_json", "cdr_pre_encoded_prefix", "json_") ... $avp(json_data) = '{"b":2, "c":3}'; ... diff --git a/src/modules/acc_json/doc/acc_json_admin.xml b/src/modules/acc_json/doc/acc_json_admin.xml index a31118f88..08bb113d0 100644 --- a/src/modules/acc_json/doc/acc_json_admin.xml +++ b/src/modules/acc_json/doc/acc_json_admin.xml @@ -366,8 +366,8 @@ modparam("acc_json", "cdr_extra", "ci=$dlg_var(call_id);ft=$dlg_var(from_tag)")
-
- <varname>cdr_json_pre_encoded_prefix</varname> (string) +
+ <varname>cdr_pre_encoded_prefix</varname> (string) Prefix to identify values that will be considered to be already json encoded. @@ -375,11 +375,11 @@ modparam("acc_json", "cdr_extra", "ci=$dlg_var(call_id);ft=$dlg_var(from_tag)") Default value is NULL. - cdr_json_pre_encoded_prefix example + cdr_pre_encoded_prefix example ... modparam("acc_json", "cdr_extra", "json_data=$avp(json_data);") -modparam("acc_json", "cdr_json_pre_encoded_prefix", "json_") +modparam("acc_json", "cdr_pre_encoded_prefix", "json_") ... $avp(json_data) = '{"b":2, "c":3}'; ... diff --git a/src/modules/app_jsdt/app_jsdt_api.c b/src/modules/app_jsdt/app_jsdt_api.c index 8ad015c89..68dc38f1b 100644 --- a/src/modules/app_jsdt/app_jsdt_api.c +++ b/src/modules/app_jsdt/app_jsdt_api.c @@ -1072,23 +1072,42 @@ duk_ret_t cb_resolve_module(duk_context *JJ) const char *parent_id = duk_get_string(JJ, 1); char requested_path[PATH_MAX]; + char resolved_id[PATH_MAX]; + char *ptr = NULL; + + if(requested_id == NULL) { + return duk_generic_error(JJ, "Invalid parameter"); + } + if(strlen(requested_id) >= PATH_MAX) { + return duk_generic_error(JJ, "Parameter too long"); + } + requested_path[0] = '\0'; if(requested_id[0] == '/') { // absolute strcpy(requested_path, requested_id); } else if(strncmp(requested_id, "./", 2) || strncmp(requested_id, "../", 3)) { - if(strlen(parent_id)) { + if(parent_id != NULL && strlen(parent_id) > 0) { + if(strlen(parent_id) >= PATH_MAX) { + return duk_generic_error(JJ, "Second parameter too long"); + } // relative to parent strcpy(requested_path, parent_id); } else { + if(strlen(_sr_jsdt_load_file.s) >= PATH_MAX) { + return duk_generic_error(JJ, "Load file path too long"); + } // no parent so relative to jsdt_load_file strcpy(requested_path, _sr_jsdt_load_file.s); } - char *ptr = strrchr(requested_path, '/'); + ptr = strrchr(requested_path, '/'); if(ptr) { ptr++; *ptr = '\0'; } + if(strlen(requested_path) + strlen(requested_id) >= PATH_MAX) { + return duk_generic_error(JJ, "Path too long"); + } strcat(requested_path, requested_id); } else { LM_INFO("cb_resolve_module - TODO resolve pathless module names"); @@ -1096,9 +1115,11 @@ duk_ret_t cb_resolve_module(duk_context *JJ) } // if missing add .js ext if(strcmp(strrchr(requested_path, '\0') - 3, ".js")) { + if(strlen(requested_path) + 3 >= PATH_MAX) { + return duk_generic_error(JJ, "Path too long"); + } strcat(requested_path, ".js"); } - char resolved_id[PATH_MAX]; if(realpath(requested_path, resolved_id)) { duk_push_string(JJ, resolved_id); return 1; /*nrets*/ diff --git a/src/modules/app_lua/app_lua_api.c b/src/modules/app_lua/app_lua_api.c index 2be3bdd09..78e238437 100644 --- a/src/modules/app_lua/app_lua_api.c +++ b/src/modules/app_lua/app_lua_api.c @@ -448,7 +448,7 @@ int lua_sr_reload_script(int pos) lock_set_release(sr_lua_locks, i); } } else { - if(pos >= 0 && pos < len) { + if(pos < len) { lock_set_get(sr_lua_locks, pos); sr_lua_script_ver->version[pos] += 1; lock_set_release(sr_lua_locks, pos); diff --git a/src/modules/app_lua/app_lua_mod.c b/src/modules/app_lua/app_lua_mod.c index e99191724..a041ebecb 100644 --- a/src/modules/app_lua/app_lua_mod.c +++ b/src/modules/app_lua/app_lua_mod.c @@ -118,7 +118,8 @@ int sr_kemi_config_engine_lua( ret = app_lua_run_ex(msg, rname->s, (rparam && rparam->s) ? rparam->s : NULL, NULL, NULL, 0); } else { - ret = app_lua_run_ex(msg, "ksr_request_route", NULL, NULL, NULL, 1); + ret = app_lua_run_ex( + msg, kemi_request_route_callback.s, NULL, NULL, NULL, 1); } } else if(rtype == CORE_ONREPLY_ROUTE) { if(kemi_reply_route_callback.len > 0) { diff --git a/src/modules/app_perl/README b/src/modules/app_perl/README index 23b8b6917..23d82129c 100644 --- a/src/modules/app_perl/README +++ b/src/modules/app_perl/README @@ -1715,9 +1715,11 @@ Chapter 4. Frequently Asked Questions First at all check if your question was already answered on one of our mailing lists: * User Mailing List - - https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users + https://lists.kamailio.org/mailman3/postorius/lists/sr-users.lists. + kamailio.org/ * Developer Mailing List - - https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-dev + https://lists.kamailio.org/mailman3/postorius/lists/sr-dev.lists.ka + mailio.org/ E-mails regarding any stable Kamailio release should be sent to and e-mails regarding development diff --git a/src/modules/app_python/apy_kemi.c b/src/modules/app_python/apy_kemi.c index d163a792c..c9addc760 100644 --- a/src/modules/app_python/apy_kemi.c +++ b/src/modules/app_python/apy_kemi.c @@ -60,7 +60,7 @@ int sr_kemi_config_engine_python( ret = apy_exec( msg, rname->s, (rparam && rparam->s) ? rparam->s : NULL, 0); } else { - ret = apy_exec(msg, "ksr_request_route", NULL, 1); + ret = apy_exec(msg, kemi_request_route_callback.s, NULL, 1); } } else if(rtype == CORE_ONREPLY_ROUTE) { if(kemi_reply_route_callback.len > 0) { diff --git a/src/modules/app_python3/apy_kemi.c b/src/modules/app_python3/apy_kemi.c index 7e66d27d4..718d8eced 100644 --- a/src/modules/app_python3/apy_kemi.c +++ b/src/modules/app_python3/apy_kemi.c @@ -63,7 +63,7 @@ int sr_kemi_config_engine_python( ret = apy_exec( msg, rname->s, (rparam && rparam->s) ? rparam->s : NULL, 0); } else { - ret = apy_exec(msg, "ksr_request_route", NULL, 1); + ret = apy_exec(msg, kemi_request_route_callback.s, NULL, 1); } } else if(rtype == CORE_ONREPLY_ROUTE) { if(kemi_reply_route_callback.len > 0) { diff --git a/src/modules/app_python3/python_exec.c b/src/modules/app_python3/python_exec.c index f57a876dc..beab9a978 100644 --- a/src/modules/app_python3/python_exec.c +++ b/src/modules/app_python3/python_exec.c @@ -71,6 +71,9 @@ int apy_exec(sip_msg_t *_msg, char *fname, char *fparam, int emode) PyGILState_STATE gstate; int locked = 0; + /* clear error state */ + PyErr_Clear(); + if(lock_try(_sr_python_reload_lock) == 0) { if(_sr_python_reload_version && *_sr_python_reload_version != _sr_python_local_version) { @@ -92,11 +95,13 @@ int apy_exec(sip_msg_t *_msg, char *fname, char *fparam, int emode) pFunc = PyObject_GetAttrString(_sr_apy_handler_obj, fname); if(pFunc == NULL || !PyCallable_Check(pFunc)) { if(emode == 1) { - LM_ERR("%s not found or is not callable\n", fname); + LM_ERR("%s not found or is not callable (%p)\n", fname, pFunc); } else { - LM_DBG("%s not found or is not callable\n", fname); + LM_DBG("%s not found or is not callable (%p)\n", fname, pFunc); + } + if(pFunc) { + Py_XDECREF(pFunc); } - Py_XDECREF(pFunc); _sr_apy_env.msg = bmsg; if(emode == 1) { goto err; @@ -161,6 +166,8 @@ int apy_exec(sip_msg_t *_msg, char *fname, char *fparam, int emode) Py_DECREF(pResult); _sr_apy_env.msg = bmsg; err: + /* clear error state */ + PyErr_Clear(); PY_GIL_RELEASE; LOCK_RELEASE; return rval; diff --git a/src/modules/app_python3s/apy3s_kemi.c b/src/modules/app_python3s/apy3s_kemi.c index 9130a84f9..38c67b9e1 100644 --- a/src/modules/app_python3s/apy3s_kemi.c +++ b/src/modules/app_python3s/apy3s_kemi.c @@ -76,6 +76,9 @@ int apy3s_exec_func(sip_msg_t *_msg, char *fname, char *fparam, int emode) return -1; } + /* clear error state */ + PyErr_Clear(); + if(lock_try(_sr_python_reload_lock) == 0) { if(_sr_python_reload_version && *_sr_python_reload_version != _sr_python_local_version) { @@ -98,11 +101,13 @@ int apy3s_exec_func(sip_msg_t *_msg, char *fname, char *fparam, int emode) if(pFunc == NULL || !PyCallable_Check(pFunc)) { if(emode == 1) { - LM_ERR("%s not found or is not callable\n", fname); + LM_ERR("%s not found or is not callable (%p)\n", fname, pFunc); } else { - LM_DBG("%s not found or is not callable\n", fname); + LM_DBG("%s not found or is not callable (%p)\n", fname, pFunc); + } + if(pFunc) { + Py_XDECREF(pFunc); } - Py_XDECREF(pFunc); _sr_apy_env.msg = bmsg; if(emode == 1) { goto error; @@ -157,6 +162,8 @@ error: if(locked) { lock_release(_sr_python_reload_lock); } + /* clear error state */ + PyErr_Clear(); return rval; } @@ -175,7 +182,7 @@ int sr_kemi_config_engine_python( ret = apy3s_exec_func( msg, rname->s, (rparam && rparam->s) ? rparam->s : NULL, 0); } else { - ret = apy3s_exec_func(msg, "ksr_request_route", NULL, 1); + ret = apy3s_exec_func(msg, kemi_request_route_callback.s, NULL, 1); } } else if(rtype == CORE_ONREPLY_ROUTE) { if(kemi_reply_route_callback.len > 0) { diff --git a/src/modules/app_sqlang/Makefile b/src/modules/app_sqlang/Makefile deleted file mode 100644 index e7f06a7a7..000000000 --- a/src/modules/app_sqlang/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -# -# app_sqlang module makefile -# -# WARNING: do not run this directly, it should be run by the main Makefile - -include ../../Makefile.defs -auto_gen= -NAME=app_sqlang.so - -DEFS+=-I./squirrel/include -LIBS += -L. -lsquirrel -lsqstdlib -lstdc++ - -MKSQLANG= -SQMARCH64= - -SQLANGARCHBSZ= $(shell echo $(ARCH) | sed -e 's/.*64.*/64b/') -ifeq ($(SQLANGARCHBSZ),64b) - MKSQLANG=sq64 -endif - -ifeq ($(ARCH), x86_64) - SQMARCH64=-m64 -endif - -ifeq ($(ARCH), sparc64) - SQMARCH64=-m64 -endif - -ifeq ($(ARCH), arm6) - SQMARCH64="-march=armv6" -endif - -ifeq ($(ARCH), aarch64) - SQMARCH64= -endif - -ifeq ($(ARCH), mips64) - SQMARCH64=-mips64 -endif - -include ../../Makefile.modules - -libsquirrel.a: - $(MAKE) -C ./squirrel/squirrel SQMARCH64="$(SQMARCH64)" CC_EXTRA_FLAGS="-fPIC" \ - OUT="../../libsquirrel.a" $(MKSQLANG) - -libsqstdlib.a: - $(MAKE) -C ./squirrel/sqstdlib SQMARCH64="$(SQMARCH64)" CC_EXTRA_FLAGS="-fPIC" \ - OUT="../../libsqstdlib.a" $(MKSQLANG) - -app_sqlang.so: libsquirrel.a libsqstdlib.a diff --git a/src/modules/app_sqlang/README b/src/modules/app_sqlang/README deleted file mode 100644 index c95692610..000000000 --- a/src/modules/app_sqlang/README +++ /dev/null @@ -1,259 +0,0 @@ -app_sqlang Module - -Daniel-Constantin Mierla - - asipto.com - -Edited by - -Daniel-Constantin Mierla - - - - Copyright © 2017 Daniel-Constantin Mierla (asipto.com) - __________________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1. Overview - 2. Dependencies - - 2.1. Kamailio Modules - 2.2. External Libraries or Applications - - 3. Parameters - - 3.1. load (str) - - 4. Functions - - 4.1. sqlang_dofile(path) - 4.2. sqlang_dostring(script) - 4.3. sqlang_run(function [, params]) - 4.4. sqlang_runstring(script) - - 5. RPC Commands - - 5.1. app_sqlang.reload - 5.2. app_sqlang.api_list - - 6. Example of usage - - List of Examples - - 1.1. Set load parameter - 1.2. sqlang_dofile usage - 1.3. sqlang_dostring usage - 1.4. sqlang_run usage - 1.5. sqlang_runstring usage - -Chapter 1. Admin Guide - - Table of Contents - - 1. Overview - 2. Dependencies - - 2.1. Kamailio Modules - 2.2. External Libraries or Applications - - 3. Parameters - - 3.1. load (str) - - 4. Functions - - 4.1. sqlang_dofile(path) - 4.2. sqlang_dostring(script) - 4.3. sqlang_run(function [, params]) - 4.4. sqlang_runstring(script) - - 5. RPC Commands - - 5.1. app_sqlang.reload - 5.2. app_sqlang.api_list - - 6. Example of usage - -1. Overview - - This module allows executing Squirrel Language (SQLang) scripts from - config file. It exports all KEMI functions to SQLang in order to access - the current processed SIP message. These functions are within SQLang - object 'KSR' (a table object). - - It includes the Squirrel Language engine - (http://www.squirrel-lang.org). Exported API from SIP router to SQLang - is documented in the dokuwiki. - - The module has two SQLang contexts: - * first is used for functions sqlang_dofile() and sqlang_dostring(). - * second is used for function sqlan_run() and parameter 'load'. - Therefore sqlang_run() cannot execute functions from scripts loaded - via sqlang_dofile() in config. This is kind of caching mode, - avoiding reading file every time, but you must be sure you do not - have something that is executed by default and requires access to - SIP message. This environment is also used by KEMI framework for - the config SIP routing functions. - -2. Dependencies - - 2.1. Kamailio Modules - 2.2. External Libraries or Applications - -2.1. Kamailio Modules - - The following modules must be loaded before this module: - * none. - -2.2. External Libraries or Applications - - The following libraries or applications must be installed before - running Kamailio with this module loaded: - * none - -3. Parameters - - 3.1. load (str) - -3.1. load (str) - - Set the path to the SQLang file to be loaded at startup. Then you can - use sqlang_run(function, params) to execute a function from the script - at runtime. If you use it for KEMI configuration, then it has to - include the required functions. - - Default value is “null”. - - Example 1.1. Set load parameter -... -modparam("app_sqlang", "load", "/usr/local/etc/kamailio/sqlang/myscript.sq") -... - -4. Functions - - 4.1. sqlang_dofile(path) - 4.2. sqlang_dostring(script) - 4.3. sqlang_run(function [, params]) - 4.4. sqlang_runstring(script) - -4.1. sqlang_dofile(path) - - Note: not implemented yet. - - Execute the SQLang script stored in 'path'. The parameter can be a - string with pseudo-variables evaluated at runtime. - - Example 1.2. sqlang_dofile usage -... -sqlang_dofile("/usr/local/etc/kamailio/sqlang/myscript.sq"); -... - -4.2. sqlang_dostring(script) - - Note: not implemented yet. - - Execute the Squirrel script stored in parameter. The parameter can be a - string with pseudo-variables. - - Example 1.3. sqlang_dostring usage -... -if(!sqlang_dostring('KSR.dbg("test message\n")')) -{ - xdbg("SCRIPT: failed to execute squirrel script!\n"); -} -... - -4.3. sqlang_run(function [, params]) - - Execute the Squirrel function 'func' giving params as parameters. There - can be up to 3 string parameters. The function must exist in the script - loaded at startup via parameter 'load'. Parameters can be strings with - pseudo-variables that are evaluated at runtime. - - Example 1.4. sqlang_run usage -... -if(!sqlang_run("sqlang_append_fu_to_reply")) -{ - xdbg("SCRIPT: failed to execute squirrel function!\n"); -} -... -sqlang_run("sqlang_funcx", "$rU", "2"); -... - -4.4. sqlang_runstring(script) - - Note: not implemented yet. - - Execute the SQLang script stored in parameter. The parameter can be a - string with pseudo-variables. The script is executed in JS context - specific to loaded JS files at startup. - - Example 1.5. sqlang_runstring usage -... -if(!sqlang_runstring('KSR.dbg("Hello World from $fU\n")')) -{ - xdbg("failed to execute squirrel script!\n"); -} -... - -5. RPC Commands - - 5.1. app_sqlang.reload - 5.2. app_sqlang.api_list - -5.1. app_sqlang.reload - - Marks the need to reload the SQLang script pointed by 'load' parameter. - The actual reload is done by every working process when the next call - to sqlang_run() function or KEMI config is executed. - - Name: app_sqlang.reload - - Parameters: none - - Example: -... -kamcmd app_sqlang.reload -... - -5.2. app_sqlang.api_list - - List the functions available via Kemi framework. - - Name: app_sqlang.api_list - - Parameters: none - - Example: -... -kamcmd app_sqlang.api_list -... - -6. Example of usage - - Create your SQLang script and stored on file system, say: - '/usr/local/etc/kamailio/sqlang/myscript.sq'. -... -function sr_append_fu_to_reply() -{ - KSR.hdr.append_to_reply("P-From: " + KSR.pv.get("$fu") + "\r\n"); -} -... - - Load the script via parameter 'load' and execute function via - sqlang_run(...). -... -modparam("app_sqlang", "load", "/usr/local/etc/kamailio/sqlang/myscript.sq") -... -request_route { - ... - if(!sqlang_run("sr_append_fu_to_reply")) - { - xdbg("SCRIPT: failed to execute squirrel function!\n"); - } - ... -} -... diff --git a/src/modules/app_sqlang/app_sqlang_api.c b/src/modules/app_sqlang/app_sqlang_api.c deleted file mode 100644 index c85f0b097..000000000 --- a/src/modules/app_sqlang/app_sqlang_api.c +++ /dev/null @@ -1,1288 +0,0 @@ -/** - * Copyright (C) 2017 Daniel-Constantin Mierla (asipto.com) - * - * This file is part of Kamailio, a free SIP server. - * - * This file 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 - * - * - * This file 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 - * - */ - -#include -#include -#include -#include -#include - -#include "../../core/dprint.h" -#include "../../core/pvar.h" -#include "../../core/sr_module.h" -#include "../../core/mem/shm.h" -#include "../../core/rpc.h" -#include "../../core/rpc_lookup.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "app_sqlang_kemi_export.h" -#include "app_sqlang_api.h" - -#define SRSQLANG_FALSE 0 -#define SRSQLANG_TRUE 1 - -void sqlang_sr_kemi_register_libs(HSQUIRRELVM J); - -typedef struct _sr_sqlang_env -{ - HSQUIRRELVM J; - int J_exit; - HSQUIRRELVM JJ; - int JJ_exit; - sip_msg_t *msg; - unsigned int flags; - unsigned int nload; /* number of scripts loaded */ -} sr_sqlang_env_t; - -static sr_sqlang_env_t _sr_J_env = {0}; - -str _sr_sqlang_load_file = STR_NULL; - -static int *_sr_sqlang_reload_version = NULL; -static int _sr_sqlang_local_version = 0; - -/** - * - */ -sr_sqlang_env_t *sqlang_sr_env_get(void) -{ - return &_sr_J_env; -} - -/** - * - */ -int sqlang_sr_initialized(void) -{ - if(_sr_J_env.J == NULL) - return 0; - - return 1; -} - -/** - * - */ -#define SQLANG_SR_EXIT_THROW_STR "~~ksr~exit~~" -#define SQLANG_SR_EXIT_EXEC_STR "throw '" SQLANG_SR_EXIT_THROW_STR "';" - -static str _sr_kemi_sqlang_exit_string = str_init(SQLANG_SR_EXIT_THROW_STR); - -/** - * - */ -str *sr_kemi_sqlang_exit_string_get(void) -{ - return &_sr_kemi_sqlang_exit_string; -} - -/** - * - */ -int app_sqlang_return_int(HSQUIRRELVM J, int v) -{ - sq_pushinteger(J, v); - return 1; -} - -/** - * - */ -int app_sqlang_return_error(HSQUIRRELVM J) -{ - sq_pushinteger(J, -1); - return 1; -} - -/** - * - */ -int app_sqlang_return_boolean(HSQUIRRELVM J, int b) -{ - if(b == SRSQLANG_FALSE) - sq_pushbool(J, SRSQLANG_FALSE); - else - sq_pushbool(J, SRSQLANG_TRUE); - return 1; -} - -/** - * - */ -int app_sqlang_return_false(HSQUIRRELVM J) -{ - sq_pushbool(J, SRSQLANG_FALSE); - return 1; -} - -/** - * - */ -int app_sqlang_return_true(HSQUIRRELVM J) -{ - sq_pushbool(J, SRSQLANG_TRUE); - return 1; -} - -/** - * - */ -int sr_kemi_sqlang_return_int(HSQUIRRELVM J, sr_kemi_t *ket, int rc) -{ - if(ket->rtype == SR_KEMIP_INT) { - sq_pushinteger(J, rc); - return 1; - } - if(ket->rtype == SR_KEMIP_BOOL && rc != SR_KEMI_FALSE) { - return app_sqlang_return_true(J); - } - return app_sqlang_return_false(J); -} - -static char *sqlang_to_string(HSQUIRRELVM J, int idx) -{ - const SQChar *s = NULL; - if(idx >= 0) { - sq_getstring(J, idx + 2, &s); - } else { - sq_getstring(J, idx, &s); - } - return (char *)s; -} - -static int sqlang_to_int(HSQUIRRELVM J, int idx) -{ - SQInteger i = 0; - - if(idx >= 0) { - sq_getinteger(J, idx + 2, &i); - } else { - sq_getinteger(J, idx, &i); - } - return (int)i; -} - -static long sqlang_to_long(HSQUIRRELVM J, int idx) -{ - SQFloat i = 0; - - if(idx >= 0) { - sq_getfloat(J, idx + 2, &i); - } else { - sq_getfloat(J, idx, &i); - } - return (long)i; -} - -static int sqlang_gettop(HSQUIRRELVM J) -{ - return (sq_gettop(J) - 1); -} - -static void sqlang_pushstring(HSQUIRRELVM J, char *s) -{ - if(s == NULL) { - sq_pushnull(J); - return; - } - sq_pushstring(J, (const SQChar *)s, (SQInteger)strlen(s)); -} - -static void sqlang_pushlstring(HSQUIRRELVM J, char *s, int l) -{ - if(s == NULL) { - sq_pushnull(J); - return; - } - sq_pushstring(J, (const SQChar *)s, (SQInteger)l); -} - -#if 0 -static int sqlang_isnumber(HSQUIRRELVM J, int idx) -{ - if(idx>=0) { - idx += 2; - } - - if(sq_gettype(J, idx)==OT_INTEGER) - return 1; - return 0; -} -#endif - -static int sqlang_isstring(HSQUIRRELVM J, int idx) -{ - if(idx >= 0) { - idx += 2; - } - - if(sq_gettype(J, idx) == OT_STRING) - return 1; - return 0; -} - -static int sqlang_isfunction(HSQUIRRELVM J, int idx) -{ - if(idx >= 0) { - idx += 2; - } - - switch(sq_gettype(J, idx)) { - case OT_CLOSURE: - case OT_NATIVECLOSURE: - return 1; - default: - return 0; - } -} - -#if 0 -static char* sqlang_safe_tostring(HSQUIRRELVM J, int idx) -{ - const SQChar *s = NULL; - - if(idx>=0) { - idx += 2; - } - if(sqlang_isstring(J, idx)) { - sq_getstring(J, idx, &s); - } - return (s)?(char*)s:"Error on sqlang"; -} -#endif - -static int sqlang_gettype(HSQUIRRELVM J, int idx) -{ - if(idx >= 0) { - idx += 2; - } - - return (int)sq_gettype(J, idx); -} - -/** - * - */ -static SQInteger sqlang_sr_exit(HSQUIRRELVM J) -{ - if(_sr_J_env.JJ == J) { - _sr_J_env.JJ_exit = 1; - } else { - _sr_J_env.J_exit = 1; - } - return sq_throwerror(J, _SC("~~ksr~exit~~")); -} - -/** - * - */ -static SQInteger sqlang_sr_drop(HSQUIRRELVM J) -{ - if(_sr_J_env.JJ == J) { - _sr_J_env.JJ_exit = 1; - } else { - _sr_J_env.J_exit = 1; - } - sr_kemi_core_set_drop(NULL); - return sq_throwerror(J, _SC("~~ksr~exit~~")); -} - - -/** - * - */ -static SQInteger sqlang_sr_modf(HSQUIRRELVM J) -{ - int ret; - char *sqlangv[MAX_ACTIONS]; - char *argv[MAX_ACTIONS]; - int argc; - int i; - int mod_type; - struct run_act_ctx ra_ctx; - struct action *act; - ksr_cmd_export_t *expf; - sr_sqlang_env_t *env_J; - - ret = 1; - act = NULL; - argc = 0; - memset(sqlangv, 0, MAX_ACTIONS * sizeof(char *)); - memset(argv, 0, MAX_ACTIONS * sizeof(char *)); - env_J = sqlang_sr_env_get(); - if(env_J->msg == NULL) - goto error; - - argc = sqlang_gettop(J); - if(argc == 0) { - LM_ERR("name of module function not provided\n"); - goto error; - } - if(argc >= MAX_ACTIONS) { - LM_ERR("too many parameters\n"); - goto error; - } - /* first is function name, then parameters */ - for(i = 0; i < argc; i++) { - if(!sqlang_isstring(J, i)) { - LM_ERR("invalid parameter type (%d)\n", i); - goto error; - } - sqlangv[i] = (char *)sqlang_to_string(J, i); - } - LM_ERR("request to execute cfg function '%s'\n", sqlangv[0]); - /* pkg copy only parameters */ - for(i = 1; i < MAX_ACTIONS; i++) { - if(sqlangv[i] != NULL) { - argv[i] = (char *)pkg_malloc(strlen(sqlangv[i]) + 1); - if(argv[i] == NULL) { - PKG_MEM_ERROR; - goto error; - } - strcpy(argv[i], sqlangv[i]); - } - } - - expf = find_export_record(sqlangv[0], argc - 1, 0); - if(expf == NULL) { - LM_ERR("function '%s' is not available\n", sqlangv[0]); - goto error; - } - /* check fixups */ - if(expf->fixup != NULL && expf->free_fixup == NULL) { - LM_ERR("function '%s' has fixup - cannot be used\n", sqlangv[0]); - goto error; - } - switch(expf->param_no) { - case 0: - mod_type = MODULE0_T; - break; - case 1: - mod_type = MODULE1_T; - break; - case 2: - mod_type = MODULE2_T; - break; - case 3: - mod_type = MODULE3_T; - break; - case 4: - mod_type = MODULE4_T; - break; - case 5: - mod_type = MODULE5_T; - break; - case 6: - mod_type = MODULE6_T; - break; - case VAR_PARAM_NO: - mod_type = MODULEX_T; - break; - default: - LM_ERR("unknown/bad definition for function '%s' (%d params)\n", - sqlangv[0], expf->param_no); - goto error; - } - - act = mk_action(mod_type, argc + 1 /* number of (type, value) pairs */, - MODEXP_ST, expf, /* function */ - NUMBER_ST, argc - 1, /* parameter number */ - STRING_ST, argv[1], /* param. 1 */ - STRING_ST, argv[2], /* param. 2 */ - STRING_ST, argv[3], /* param. 3 */ - STRING_ST, argv[4], /* param. 4 */ - STRING_ST, argv[5], /* param. 5 */ - STRING_ST, argv[6] /* param. 6 */ - ); - - if(act == NULL) { - LM_ERR("action structure could not be created for '%s'\n", sqlangv[0]); - goto error; - } - - /* handle fixups */ - if(expf->fixup) { - if(argc == 1) { - /* no parameters */ - if(expf->fixup(0, 0) < 0) { - LM_ERR("Error in fixup (0) for '%s'\n", sqlangv[0]); - goto error; - } - } else { - for(i = 1; i < argc; i++) { - if(expf->fixup(&(act->val[i + 1].u.data), i) < 0) { - LM_ERR("Error in fixup (%d) for '%s'\n", i, sqlangv[0]); - goto error; - } - act->val[i + 1].type = MODFIXUP_ST; - } - } - } - init_run_actions_ctx(&ra_ctx); - ret = do_action(&ra_ctx, act, env_J->msg); - - /* free fixups */ - if(expf->fixup) { - for(i = 1; i < argc; i++) { - if((act->val[i + 1].type == MODFIXUP_ST) - && (act->val[i + 1].u.data)) { - expf->free_fixup(&(act->val[i + 1].u.data), i); - } - } - } - pkg_free(act); - for(i = 0; i < MAX_ACTIONS; i++) { - if(argv[i] != NULL) - pkg_free(argv[i]); - argv[i] = 0; - } - sq_pushinteger(J, ret); - return 1; - -error: - if(act != NULL) - pkg_free(act); - for(i = 0; i < MAX_ACTIONS; i++) { - if(argv[i] != NULL) - pkg_free(argv[i]); - argv[i] = 0; - } - sq_pushinteger(J, -1); - return 1; -} - - -const SQRegFunction _sr_kemi_x_J_Map[] = { - {"exit", sqlang_sr_exit, 1 /* 0 args */, NULL}, - {"drop", sqlang_sr_drop, 1 /* 0 args */, NULL}, - {"modf", sqlang_sr_modf, 0 /* var args */, NULL}, {NULL, NULL, 0}}; - -/** - * - */ -void sqlang_errorfunc(HSQUIRRELVM J, const SQChar *fmt, ...) -{ - char ebuf[4096]; - va_list ap; - - if(_sr_J_env.JJ == J) { - if(_sr_J_env.JJ_exit == 1) { - LM_DBG("exception on ksr exit (JJ)\n"); - return; - } - } else { - if(_sr_J_env.J_exit == 1) { - LM_DBG("exception on ksr exit (J)\n"); - return; - } - } - - ebuf[0] = '\0'; - va_start(ap, fmt); - vsnprintf(ebuf, 4094, fmt, ap); - va_end(ap); - LM_ERR("SQLang error: %s\n", ebuf); -} - -/** - * - */ -void sqlang_printfunc(HSQUIRRELVM SQ_UNUSED_ARG(J), const SQChar *fmt, ...) -{ - char ebuf[4096]; - va_list ap; - - ebuf[0] = '\0'; - va_start(ap, fmt); - vsnprintf(ebuf, 4094, fmt, ap); - va_end(ap); - LM_INFO("SQLang info: %s\n", ebuf); -} - -/** - * - */ -void sqlang_debughook(HSQUIRRELVM J, SQInteger type, const SQChar *sourcename, - SQInteger line, const SQChar *funcname) -{ - LM_ERR("SQLang: %s:%d - %s(...) [type %d]\n", (char *)sourcename, (int)line, - (char *)funcname, (int)type); -} - -/** - * load a JS file into context - */ -static int sqlang_load_file(HSQUIRRELVM J, const char *filename) -{ - if(!SQ_SUCCEEDED(sqstd_dofile(J, _SC(filename), 0, 1))) { - /* prints syntax errors if any */ - LM_ERR("failed to load file: %s\n", filename); - return -1; - } - LM_DBG("loaded file: %s\n", filename); - return 0; -#if 0 - FILE *f; - size_t len; -#define SQLANG_SCRIPT_MAX_SIZE 128 * 1024 - char buf[SQLANG_SCRIPT_MAX_SIZE]; - - f = fopen(filename, "rb"); - if (f) { - len = fread((void *) buf, 1, sizeof(buf)-1, f); - fclose(f); - if(len>0) { - buf[len] = '\0'; - if(!SQ_SUCCEEDED(sq_compilebuffer(J, buf, len, - _SC(filename), SQTrue))) { - LM_ERR("failed to compile: %s\n", filename); - return -1; - } - } else { - LM_ERR("empty content in %s\n", filename); - return -1; - } - } else { - LM_ERR("cannot open file: %s\n", filename); - return -1; - } - return 0; -#endif -} - -/** - * - */ -int sqlang_sr_init_mod(void) -{ - if(_sr_sqlang_reload_version == NULL) { - _sr_sqlang_reload_version = (int *)shm_malloc(sizeof(int)); - if(_sr_sqlang_reload_version == NULL) { - SHM_MEM_ERROR_FMT("reload version\n"); - ; - return -1; - } - *_sr_sqlang_reload_version = 0; - } - memset(&_sr_J_env, 0, sizeof(sr_sqlang_env_t)); - - return 0; -} - -/** - * - */ -int sqlang_kemi_load_script(void) -{ - if(sqlang_load_file(_sr_J_env.JJ, _sr_sqlang_load_file.s) < 0) { - LM_ERR("failed to load sqlang script file: %.*s\n", - _sr_sqlang_load_file.len, _sr_sqlang_load_file.s); - return -1; - } - return 0; -} -/** - * - */ -int sqlang_sr_init_child(void) -{ - memset(&_sr_J_env, 0, sizeof(sr_sqlang_env_t)); - _sr_J_env.J = sq_open(1024); - if(_sr_J_env.J == NULL) { - LM_ERR("cannot create SQlang context (exec)\n"); - return -1; - } - sq_pushroottable(_sr_J_env.J); - /*sets the print functions*/ - sq_setprintfunc(_sr_J_env.J, sqlang_printfunc, sqlang_errorfunc); - //sq_setnativedebughook(_sr_J_env.J, sqlang_debughook); - sq_enabledebuginfo(_sr_J_env.J, 1); - - sqstd_register_bloblib(_sr_J_env.J); - sqstd_register_iolib(_sr_J_env.J); - sqstd_register_systemlib(_sr_J_env.J); - sqstd_register_mathlib(_sr_J_env.J); - sqstd_register_stringlib(_sr_J_env.J); - sqstd_seterrorhandlers(_sr_J_env.J); - - sqlang_sr_kemi_register_libs(_sr_J_env.J); - if(_sr_sqlang_load_file.s != NULL && _sr_sqlang_load_file.len > 0) { - _sr_J_env.JJ = sq_open(1024); - if(_sr_J_env.JJ == NULL) { - LM_ERR("cannot create load SQLang context (load)\n"); - return -1; - } - sq_pushroottable(_sr_J_env.JJ); - LM_DBG("*** sqlang top index now is: %d\n", - (int)sqlang_gettop(_sr_J_env.JJ)); - /*sets the print functions*/ - sq_setprintfunc(_sr_J_env.JJ, sqlang_printfunc, sqlang_errorfunc); - //sq_setnativedebughook(_sr_J_env.JJ, sqlang_debughook); - sq_enabledebuginfo(_sr_J_env.JJ, 1); - - sqstd_register_bloblib(_sr_J_env.JJ); - sqstd_register_iolib(_sr_J_env.JJ); - sqstd_register_systemlib(_sr_J_env.JJ); - sqstd_register_mathlib(_sr_J_env.JJ); - sqstd_register_stringlib(_sr_J_env.JJ); - sqstd_seterrorhandlers(_sr_J_env.JJ); - - sqlang_sr_kemi_register_libs(_sr_J_env.JJ); - LM_DBG("loading sqlang script file: %.*s\n", _sr_sqlang_load_file.len, - _sr_sqlang_load_file.s); - if(sqlang_kemi_load_script() < 0) { - return -1; - } - } - LM_DBG("JS initialized!\n"); - return 0; -} - -/** - * - */ -void sqlang_sr_destroy(void) -{ - if(_sr_J_env.J != NULL) { - sq_close(_sr_J_env.J); - _sr_J_env.J = NULL; - } - if(_sr_J_env.JJ != NULL) { - sq_close(_sr_J_env.JJ); - _sr_J_env.JJ = NULL; - } - memset(&_sr_J_env, 0, sizeof(sr_sqlang_env_t)); -} - -/** - * - */ -int sqlang_kemi_reload_script(void) -{ - int v; - if(_sr_sqlang_load_file.s == NULL && _sr_sqlang_load_file.len <= 0) { - LM_WARN("script file path not provided\n"); - return -1; - } - if(_sr_sqlang_reload_version == NULL) { - LM_WARN("reload not enabled\n"); - return -1; - } - if(_sr_J_env.JJ == NULL) { - LM_ERR("load JS context not created\n"); - return -1; - } - - v = *_sr_sqlang_reload_version; - if(v == _sr_sqlang_local_version) { - /* same version */ - return 0; - } - LM_DBG("reloading sqlang script file: %.*s (%d => %d)\n", - _sr_sqlang_load_file.len, _sr_sqlang_load_file.s, - _sr_sqlang_local_version, v); - sqlang_kemi_load_script(); - _sr_sqlang_local_version = v; - return 0; -} - - -/** - * - */ -int app_sqlang_run_ex( - sip_msg_t *msg, char *func, char *p1, char *p2, char *p3, int emode) -{ - int n; - int ret; - int top; - sip_msg_t *bmsg; - SQInteger rv; - - if(_sr_J_env.JJ == NULL) { - LM_ERR("sqlang loading state not initialized (call: %s)\n", func); - return -1; - } - /* check the script version loaded */ - sqlang_kemi_reload_script(); - - top = sqlang_gettop(_sr_J_env.JJ); - - LM_DBG("sqlang top index is: %d\n", top); - sq_pushroottable(_sr_J_env.JJ); /* pushes the global table */ - sq_pushstring(_sr_J_env.JJ, _SC(func), -1); - if(!SQ_SUCCEEDED(sq_get(_sr_J_env.JJ, -2))) { - /* failed to gets the func field from the global table */ - sq_settop(_sr_J_env.JJ, - (top <= 0) ? 1 : top); /* restores the original stack size */ - LM_ERR("sqlang failed to find symbol (call: %s)\n", func); - return -1; - } - - if(!sqlang_isfunction(_sr_J_env.JJ, -1)) { - LM_ERR("no such function [%s] in sqlang scripts\n", func); - LM_ERR("top stack type [%d]\n", sqlang_gettype(_sr_J_env.JJ, -1)); - } - /* push the 'this' (in this case is the global table) */ - sq_pushroottable(_sr_J_env.JJ); - n = 1; - if(p1 != NULL) { - sqlang_pushstring(_sr_J_env.JJ, p1); - n++; - if(p2 != NULL) { - sqlang_pushstring(_sr_J_env.JJ, p2); - n++; - if(p3 != NULL) { - sqlang_pushstring(_sr_J_env.JJ, p3); - n++; - } - } - } - LM_DBG("executing sqlang function: [[%s]] (n: %d)\n", func, n); - bmsg = _sr_J_env.msg; - _sr_J_env.msg = msg; - _sr_J_env.JJ_exit = 0; - /* call the function */ - rv = sq_call(_sr_J_env.JJ, n, SQFalse, SQTrue); - if(SQ_SUCCEEDED(rv)) { - ret = 1; - } else { - if(_sr_J_env.JJ_exit == 0) { - LM_ERR("failed to execute the func: %s (%d)\n", func, (int)rv); - sqstd_printcallstack(_sr_J_env.JJ); - ret = -1; - } else { - LM_DBG("script execution exit\n"); - ret = 1; - } - } - _sr_J_env.msg = bmsg; - _sr_J_env.JJ_exit = 0; - sq_settop(_sr_J_env.JJ, - (top <= 0) ? 1 : top); /* restores the original stack size */ - - return ret; -} - -/** - * - */ -int app_sqlang_run(sip_msg_t *msg, char *func, char *p1, char *p2, char *p3) -{ - return app_sqlang_run_ex(msg, func, p1, p2, p3, 1); -} - -/** - * - */ -int app_sqlang_runstring(sip_msg_t *msg, char *script) -{ -#if 0 - int ret; - sip_msg_t *bmsg; - - if(_sr_J_env.JJ==NULL) { - LM_ERR("sqlang loading state not initialized (call: %s)\n", script); - return -1; - } - - sqlang_kemi_reload_script(); - - LM_DBG("running sqlang string: [[%s]]\n", script); - LM_DBG("sqlang top index is: %d\n", sqlang_gettop(_sr_J_env.JJ)); - bmsg = _sr_J_env.msg; - _sr_J_env.msg = msg; - sqlang_pushstring(_sr_J_env.JJ, script); - ret = duk_peval(_sr_J_env.JJ); - if(ret != 0) { - LM_ERR("JS failed running: %s\n", sqlang_safe_tostring(_sr_J_env.JJ, -1)); - } - duk_pop(_sr_J_env.JJ); /* ignore result */ - - _sr_J_env.msg = bmsg; - return (ret==0)?1:-1; -#endif - LM_ERR("not implemented\n"); - return -1; -} - -/** - * - */ -int app_sqlang_dostring(sip_msg_t *msg, char *script) -{ -#if 0 - int ret; - sip_msg_t *bmsg; - - LM_DBG("executing sqlang string: [[%s]]\n", script); - LM_DBG("JS top index is: %d\n", sqlang_gettop(_sr_J_env.J)); - bmsg = _sr_J_env.msg; - _sr_J_env.msg = msg; - sqlang_pushstring(_sr_J_env.J, script); - ret = duk_peval(_sr_J_env.J); - if(ret != 0) { - LM_ERR("JS failed running: %s\n", sqlang_safe_tostring(_sr_J_env.J, -1)); - } - duk_pop(_sr_J_env.J); /* ignore result */ - _sr_J_env.msg = bmsg; - return (ret==0)?1:-1; -#endif - LM_ERR("not implemented\n"); - return -1; -} - -/** - * - */ -int app_sqlang_dofile(sip_msg_t *msg, char *script) -{ -#if 0 - int ret; - sip_msg_t *bmsg; - - LM_DBG("executing sqlang file: [[%s]]\n", script); - LM_DBG("JS top index is: %d\n", sqlang_gettop(_sr_J_env.J)); - bmsg = _sr_J_env.msg; - _sr_J_env.msg = msg; - if(sqlang_load_file(_sr_J_env.J, script)<0) { - LM_ERR("failed to load sqlang script file: %s\n", script); - return -1; - } - ret = duk_peval(_sr_J_env.J); - if(ret != 0) { - LM_ERR("JS failed running: %s\n", sqlang_safe_tostring(_sr_J_env.J, -1)); - } - duk_pop(_sr_J_env.J); /* ignore result */ - - _sr_J_env.msg = bmsg; - return (ret==0)?1:-1; -#endif - LM_ERR("not implemented\n"); - return -1; -} - -/** - * - */ -int sr_kemi_sqlang_return_xval( - HSQUIRRELVM J, sr_kemi_t *ket, sr_kemi_xval_t *rx) -{ - switch(rx->vtype) { - case SR_KEMIP_NONE: - return 0; - case SR_KEMIP_INT: - sq_pushinteger(J, (SQInteger)rx->v.n); - return 1; - case SR_KEMIP_LONG: - sq_pushfloat(J, (SQFloat)rx->v.l); - return 1; - case SR_KEMIP_STR: - sqlang_pushlstring(J, rx->v.s.s, rx->v.s.len); - return 1; - case SR_KEMIP_BOOL: - if(rx->v.n != SR_KEMI_FALSE) { - sq_pushbool(J, SRSQLANG_TRUE); - } else { - sq_pushbool(J, SRSQLANG_FALSE); - } - return 1; - case SR_KEMIP_ARRAY: - LM_ERR("unsupported return type: array\n"); - sr_kemi_xval_free(rx); - sqlang_pushstring(J, NULL); - return 1; - case SR_KEMIP_DICT: - LM_ERR("unsupported return type: map\n"); - sr_kemi_xval_free(rx); - sqlang_pushstring(J, NULL); - return 1; - case SR_KEMIP_XVAL: - /* unknown content - return false */ - sq_pushbool(J, SRSQLANG_FALSE); - return 1; - case SR_KEMIP_NULL: - sqlang_pushstring(J, NULL); - return 1; - default: - /* unknown type - return false */ - sq_pushbool(J, SRSQLANG_FALSE); - return 1; - } -} - -/** - * - */ -int sr_kemi_sqlang_exec_func_ex(HSQUIRRELVM J, sr_kemi_t *ket) -{ - int i; - int argc; - int ret; - str *fname; - str *mname; - sr_kemi_xval_t vps[SR_KEMI_PARAMS_MAX]; - sr_sqlang_env_t *env_J; - sr_kemi_xval_t *xret; - - env_J = sqlang_sr_env_get(); - - if(env_J == NULL || env_J->msg == NULL || ket == NULL) { - LM_ERR("invalid JS environment attributes or parameters\n"); - return app_sqlang_return_false(J); - } - - fname = &ket->fname; - mname = &ket->mname; - - argc = sqlang_gettop(J); - if(argc == 0 && ket->ptypes[0] == SR_KEMIP_NONE) { - if(ket->rtype == SR_KEMIP_XVAL) { - xret = ((sr_kemi_xfm_f)(ket->func))(env_J->msg); - return sr_kemi_sqlang_return_xval(J, ket, xret); - } else { - ret = ((sr_kemi_fm_f)(ket->func))(env_J->msg); - return sr_kemi_sqlang_return_int(J, ket, ret); - } - } - if(argc == 0 && ket->ptypes[0] != SR_KEMIP_NONE) { - LM_ERR("invalid number of parameters for: %.*s.%.*s\n", mname->len, - mname->s, fname->len, fname->s); - return app_sqlang_return_false(J); - } - - if(argc > SR_KEMI_PARAMS_MAX) { - LM_ERR("too many parameters for: %.*s.%.*s\n", mname->len, mname->s, - fname->len, fname->s); - return app_sqlang_return_false(J); - } - - memset(vps, 0, SR_KEMI_PARAMS_MAX * sizeof(sr_kemi_xval_t)); - for(i = 0; i < SR_KEMI_PARAMS_MAX; i++) { - if(ket->ptypes[i] == SR_KEMIP_NONE) { - break; - } else if(ket->ptypes[i] == SR_KEMIP_STR) { - vps[i].vtype = SR_KEMIP_STR; - vps[i].v.s.s = (char *)sqlang_to_string(J, i); - vps[i].v.s.len = strlen(vps[i].v.s.s); - LM_DBG("param[%d] for: %.*s is str: %.*s\n", i, fname->len, - fname->s, vps[i].v.s.len, vps[i].v.s.s); - } else if(ket->ptypes[i] == SR_KEMIP_INT) { - vps[i].vtype = SR_KEMIP_INT; - vps[i].v.n = sqlang_to_int(J, i); - LM_DBG("param[%d] for: %.*s is int: %d\n", i, fname->len, fname->s, - vps[i].v.n); - } else if(ket->ptypes[i] == SR_KEMIP_LONG) { - vps[i].vtype = SR_KEMIP_LONG; - vps[i].v.l = sqlang_to_long(J, i); - LM_DBG("param[%d] for: %.*s is long int: %ld\n", i, fname->len, - fname->s, vps[i].v.l); - } else { - LM_ERR("unknown parameter type %d (%d)\n", ket->ptypes[i], i); - return app_sqlang_return_false(J); - } - } - xret = sr_kemi_exec_func(ket, env_J->msg, i, vps); - return sr_kemi_sqlang_return_xval(J, ket, xret); -} - -/** - * - */ -int sr_kemi_sqlang_exec_func(HSQUIRRELVM J, int eidx) -{ - sr_kemi_t *ket; - int ret; - struct timeval tvb = {0}, tve = {0}; - struct timezone tz; - unsigned int tdiff; - - ket = sr_kemi_sqlang_export_get(eidx); - - if(unlikely(cfg_get(core, core_cfg, latency_limit_action) > 0) - && is_printable(cfg_get(core, core_cfg, latency_log))) { - gettimeofday(&tvb, &tz); - } - - ret = sr_kemi_sqlang_exec_func_ex(J, ket); - - if(unlikely(cfg_get(core, core_cfg, latency_limit_action) > 0) - && is_printable(cfg_get(core, core_cfg, latency_log))) { - gettimeofday(&tve, &tz); - tdiff = (tve.tv_sec - tvb.tv_sec) * 1000000 - + (tve.tv_usec - tvb.tv_usec); - if(tdiff >= cfg_get(core, core_cfg, latency_limit_action)) { - LOG(cfg_get(core, core_cfg, latency_log), - "alert - action KSR.%s%s%s(...)" - " took too long [%u us]\n", - (ket->mname.len > 0) ? ket->mname.s : "", - (ket->mname.len > 0) ? "." : "", ket->fname.s, tdiff); - } - } - - return ret; -} - -/** - * - */ -SQRegFunction *_sr_J_KSRMethods = NULL; -#define SR_SQLANG_KSR_MODULES_SIZE 256 -#define SR_SQLANG_KSR_METHODS_SIZE \ - (SR_KEMI_SQLANG_EXPORT_SIZE + SR_SQLANG_KSR_MODULES_SIZE) - - -/** - * - */ -SQInteger sqlang_register_global_func(HSQUIRRELVM J, SQFUNCTION f, char *fname) -{ - sq_pushstring(J, fname, -1); - sq_newclosure(J, f, 0); /* create a new function */ - sq_newslot(J, -3, SQFalse); - return 0; -} - -/** - * - */ -SQInteger sqlang_open_KSR(HSQUIRRELVM J) -{ - SQRegFunction *_sr_crt_J_KSRMethods = NULL; - sr_kemi_module_t *emods = NULL; - int emods_size = 0; - int i; - int k; - int n; - char mname[128]; - char malias[256]; - - _sr_J_KSRMethods = - malloc(SR_SQLANG_KSR_METHODS_SIZE * sizeof(SQRegFunction)); - if(_sr_J_KSRMethods == NULL) { - SYS_MEM_ERROR; - return 0; - } - memset(_sr_J_KSRMethods, 0, - SR_SQLANG_KSR_METHODS_SIZE * sizeof(SQRegFunction)); - - emods_size = sr_kemi_modules_size_get(); - emods = sr_kemi_modules_get(); - - n = 0; - _sr_crt_J_KSRMethods = _sr_J_KSRMethods; - if(emods_size == 0 || emods[0].kexp == NULL) { - LM_ERR("no kemi exports registered\n"); - return 0; - } - - sq_pushroottable(J); /* stack[1] */ - sq_pushstring(J, "KSR", -1); /* stack[2] */ - sq_newtable(J); /* stack[3] */ - - for(i = 0; emods[0].kexp[i].func != NULL; i++) { - LM_DBG("exporting KSR.%s(...)\n", emods[0].kexp[i].fname.s); - _sr_crt_J_KSRMethods[i].name = emods[0].kexp[i].fname.s; - _sr_crt_J_KSRMethods[i].f = - sr_kemi_sqlang_export_associate(&emods[0].kexp[i]); - if(_sr_crt_J_KSRMethods[i].f == NULL) { - LM_ERR("failed to associate kemi function with sqlang export\n"); - free(_sr_J_KSRMethods); - _sr_J_KSRMethods = NULL; - goto error; - } - _sr_crt_J_KSRMethods[i].nparamscheck = 0; - snprintf(malias, 254, "%s", emods[0].kexp[i].fname.s); - sqlang_register_global_func(J, _sr_crt_J_KSRMethods[i].f, malias); - n++; - } - - /* special modules */ - sq_pushstring(J, "x", -1); /* stack[4] */ - sq_newtable(J); /* stack[5] */ - i = 0; - while(_sr_kemi_x_J_Map[i].name != 0) { - snprintf(malias, 254, "%s", _sr_kemi_x_J_Map[i].name); - sqlang_register_global_func(J, _sr_kemi_x_J_Map[i].f, malias); - i++; - } - sq_newslot(J, -3, SQFalse); - - /* registered kemi modules */ - if(emods_size > 1) { - for(k = 1; k < emods_size; k++) { - n++; - _sr_crt_J_KSRMethods = _sr_J_KSRMethods + n; - snprintf(mname, 128, "%s", emods[k].kexp[0].mname.s); - sq_pushstring(J, mname, -1); /* stack[4] */ - sq_newtable(J); /* stack[5] */ - for(i = 0; emods[k].kexp[i].func != NULL; i++) { - LM_DBG("exporting %s.%s(...)\n", mname, - emods[k].kexp[i].fname.s); - _sr_crt_J_KSRMethods[i].name = emods[k].kexp[i].fname.s; - _sr_crt_J_KSRMethods[i].f = - sr_kemi_sqlang_export_associate(&emods[k].kexp[i]); - if(_sr_crt_J_KSRMethods[i].f == NULL) { - LM_ERR("failed to associate kemi function with func " - "export\n"); - free(_sr_J_KSRMethods); - _sr_J_KSRMethods = NULL; - goto error; - } - _sr_crt_J_KSRMethods[i].nparamscheck = 0; - snprintf(malias, 256, "%s", _sr_crt_J_KSRMethods[i].name); - sqlang_register_global_func( - J, _sr_crt_J_KSRMethods[i].f, malias); - n++; - } - sq_newslot(J, -3, SQFalse); - - LM_DBG("initializing kemi sub-module: %s (%s)\n", mname, - emods[k].kexp[0].mname.s); - } - } - sq_newslot(J, -3, SQFalse); - sq_pop(J, 1); /* pops the root table */ - LM_DBG("module 'KSR' has been initialized\n"); - return 1; -error: - sq_pop(J, 1); /* pops the root table */ - return 0; -} - -/** - * - */ -void sqlang_sr_kemi_register_libs(HSQUIRRELVM J) -{ - int ret; - - ret = sqlang_open_KSR(J); - - LM_INFO("initialized KSR module with return code: %d\n", ret); -} - -static const char *app_sqlang_rpc_reload_doc[2] = {"Reload sqlang file", 0}; - - -static void app_sqlang_rpc_reload(rpc_t *rpc, void *ctx) -{ - int v; - void *vh; - - if(_sr_sqlang_load_file.s == NULL && _sr_sqlang_load_file.len <= 0) { - LM_WARN("script file path not provided\n"); - rpc->fault(ctx, 500, "No script file"); - return; - } - if(_sr_sqlang_reload_version == NULL) { - LM_WARN("reload not enabled\n"); - rpc->fault(ctx, 500, "Reload not enabled"); - return; - } - - v = *_sr_sqlang_reload_version; - LM_INFO("marking for reload sqlang script file: %.*s (%d => %d)\n", - _sr_sqlang_load_file.len, _sr_sqlang_load_file.s, - _sr_sqlang_local_version, v); - *_sr_sqlang_reload_version += 1; - - if(rpc->add(ctx, "{", &vh) < 0) { - rpc->fault(ctx, 500, "Server error"); - return; - } - rpc->struct_add(vh, "dd", "old", v, "new", *_sr_sqlang_reload_version); -} - -static const char *app_sqlang_rpc_api_list_doc[2] = { - "List kemi exports to sqlang", 0}; - -static void app_sqlang_rpc_api_list(rpc_t *rpc, void *ctx) -{ - int i; - int n; - sr_kemi_t *ket; - void *th; - void *sh; - void *ih; - - if(rpc->add(ctx, "{", &th) < 0) { - rpc->fault(ctx, 500, "Internal error root reply"); - return; - } - n = 0; - for(i = 0; i < SR_KEMI_SQLANG_EXPORT_SIZE; i++) { - ket = sr_kemi_sqlang_export_get(i); - if(ket == NULL) - continue; - n++; - } - - if(rpc->struct_add(th, "d[", "msize", n, "methods", &ih) < 0) { - rpc->fault(ctx, 500, "Internal error array structure"); - return; - } - for(i = 0; i < SR_KEMI_SQLANG_EXPORT_SIZE; i++) { - ket = sr_kemi_sqlang_export_get(i); - if(ket == NULL) - continue; - if(rpc->struct_add(ih, "{", "func", &sh) < 0) { - rpc->fault(ctx, 500, "Internal error internal structure"); - return; - } - if(rpc->struct_add(sh, "SSSS", "ret", - sr_kemi_param_map_get_name(ket->rtype), "module", - &ket->mname, "name", &ket->fname, "params", - sr_kemi_param_map_get_params(ket->ptypes)) - < 0) { - LM_ERR("failed to add the structure with attributes (%d)\n", i); - rpc->fault(ctx, 500, "Internal error creating dest struct"); - return; - } - } -} - -rpc_export_t app_sqlang_rpc_cmds[] = { - {"app_sqlang.reload", app_sqlang_rpc_reload, app_sqlang_rpc_reload_doc, - 0}, - {"app_sqlang.api_list", app_sqlang_rpc_api_list, - app_sqlang_rpc_api_list_doc, 0}, - {0, 0, 0, 0}}; - -/** - * register RPC commands - */ -int app_sqlang_init_rpc(void) -{ - if(rpc_register_array(app_sqlang_rpc_cmds) != 0) { - LM_ERR("failed to register RPC commands\n"); - return -1; - } - return 0; -} diff --git a/src/modules/app_sqlang/app_sqlang_api.h b/src/modules/app_sqlang/app_sqlang_api.h deleted file mode 100644 index 7a1a92910..000000000 --- a/src/modules/app_sqlang/app_sqlang_api.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright (C) 2017 Daniel-Constantin Mierla (asipto.com) - * - * This file is part of Kamailio, a free SIP server. - * - * This file 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 - * - * - * This file 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 _APP_SQLANG_API_H_ -#define _APP_SQLANG_API_H_ - -#include - -#include "../../core/parser/msg_parser.h" - -int sqlang_sr_init_mod(void); -int sqlang_sr_init_child(void); -void sqlang_sr_destroy(void); - -int sqlang_sr_initialized(void); - -int sr_kemi_sqlang_exec_func(HSQUIRRELVM J, int eidx); - -int app_sqlang_run_ex( - sip_msg_t *msg, char *func, char *p1, char *p2, char *p3, int emode); -int app_sqlang_run(sip_msg_t *msg, char *func, char *p1, char *p2, char *p3); -int app_sqlang_runstring(sip_msg_t *msg, char *script); -int app_sqlang_dostring(sip_msg_t *msg, char *script); -int app_sqlang_dofile(sip_msg_t *msg, char *script); - -int app_sqlang_init_rpc(void); -#endif diff --git a/src/modules/app_sqlang/app_sqlang_kemi_export.c b/src/modules/app_sqlang/app_sqlang_kemi_export.c deleted file mode 100644 index 6a58266f8..000000000 --- a/src/modules/app_sqlang/app_sqlang_kemi_export.c +++ /dev/null @@ -1,9279 +0,0 @@ -/** - * Copyright (C) 2016 Daniel-Constantin Mierla (asipto.com) - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -/** - * this file is generated - do not edit - */ - -#include -#include -#include - -#include "../../core/dprint.h" - -#include "app_sqlang_api.h" -#include "app_sqlang_kemi_export.h" - - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_0(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 0); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_2(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 2); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_3(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 3); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_4(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 4); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_5(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 5); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_6(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 6); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_7(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 7); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_8(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 8); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_9(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 9); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_10(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 10); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_11(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 11); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_12(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 12); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_13(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 13); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_14(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 14); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_15(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 15); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_16(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 16); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_17(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 17); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_18(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 18); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_19(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 19); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_20(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 20); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_21(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 21); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_22(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 22); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_23(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 23); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_24(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 24); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_25(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 25); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_26(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 26); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_27(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 27); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_28(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 28); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_29(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 29); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_30(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 30); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_31(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 31); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_32(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 32); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_33(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 33); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_34(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 34); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_35(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 35); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_36(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 36); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_37(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 37); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_38(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 38); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_39(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 39); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_40(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 40); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_41(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 41); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_42(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 42); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_43(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 43); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_44(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 44); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_45(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 45); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_46(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 46); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_47(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 47); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_48(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 48); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_49(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 49); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_50(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 50); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_51(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 51); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_52(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 52); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_53(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 53); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_54(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 54); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_55(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 55); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_56(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 56); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_57(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 57); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_58(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 58); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_59(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 59); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_60(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 60); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_61(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 61); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_62(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 62); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_63(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 63); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_64(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 64); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_65(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 65); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_66(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 66); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_67(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 67); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_68(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 68); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_69(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 69); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_70(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 70); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_71(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 71); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_72(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 72); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_73(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 73); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_74(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 74); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_75(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 75); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_76(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 76); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_77(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 77); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_78(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 78); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_79(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 79); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_80(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 80); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_81(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 81); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_82(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 82); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_83(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 83); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_84(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 84); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_85(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 85); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_86(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 86); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_87(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 87); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_88(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 88); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_89(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 89); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_90(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 90); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_91(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 91); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_92(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 92); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_93(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 93); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_94(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 94); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_95(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 95); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_96(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 96); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_97(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 97); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_98(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 98); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_99(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 99); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_100(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 100); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_101(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 101); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_102(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 102); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_103(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 103); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_104(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 104); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_105(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 105); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_106(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 106); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_107(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 107); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_108(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 108); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_109(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 109); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_110(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 110); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_111(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 111); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_112(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 112); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_113(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 113); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_114(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 114); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_115(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 115); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_116(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 116); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_117(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 117); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_118(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 118); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_119(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 119); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_120(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 120); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_121(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 121); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_122(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 122); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_123(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 123); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_124(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 124); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_125(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 125); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_126(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 126); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_127(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 127); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_128(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 128); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_129(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 129); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_130(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 130); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_131(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 131); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_132(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 132); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_133(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 133); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_134(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 134); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_135(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 135); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_136(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 136); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_137(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 137); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_138(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 138); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_139(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 139); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_140(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 140); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_141(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 141); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_142(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 142); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_143(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 143); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_144(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 144); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_145(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 145); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_146(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 146); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_147(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 147); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_148(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 148); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_149(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 149); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_150(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 150); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_151(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 151); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_152(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 152); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_153(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 153); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_154(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 154); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_155(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 155); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_156(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 156); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_157(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 157); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_158(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 158); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_159(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 159); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_160(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 160); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_161(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 161); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_162(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 162); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_163(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 163); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_164(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 164); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_165(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 165); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_166(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 166); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_167(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 167); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_168(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 168); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_169(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 169); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_170(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 170); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_171(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 171); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_172(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 172); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_173(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 173); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_174(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 174); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_175(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 175); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_176(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 176); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_177(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 177); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_178(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 178); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_179(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 179); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_180(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 180); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_181(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 181); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_182(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 182); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_183(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 183); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_184(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 184); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_185(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 185); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_186(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 186); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_187(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 187); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_188(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 188); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_189(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 189); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_190(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 190); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_191(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 191); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_192(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 192); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_193(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 193); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_194(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 194); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_195(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 195); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_196(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 196); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_197(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 197); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_198(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 198); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_199(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 199); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_200(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 200); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_201(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 201); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_202(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 202); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_203(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 203); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_204(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 204); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_205(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 205); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_206(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 206); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_207(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 207); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_208(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 208); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_209(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 209); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_210(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 210); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_211(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 211); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_212(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 212); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_213(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 213); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_214(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 214); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_215(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 215); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_216(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 216); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_217(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 217); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_218(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 218); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_219(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 219); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_220(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 220); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_221(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 221); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_222(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 222); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_223(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 223); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_224(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 224); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_225(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 225); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_226(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 226); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_227(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 227); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_228(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 228); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_229(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 229); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_230(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 230); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_231(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 231); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_232(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 232); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_233(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 233); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_234(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 234); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_235(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 235); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_236(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 236); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_237(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 237); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_238(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 238); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_239(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 239); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_240(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 240); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_241(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 241); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_242(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 242); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_243(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 243); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_244(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 244); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_245(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 245); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_246(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 246); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_247(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 247); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_248(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 248); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_249(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 249); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_250(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 250); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_251(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 251); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_252(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 252); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_253(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 253); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_254(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 254); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_255(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 255); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_256(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 256); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_257(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 257); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_258(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 258); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_259(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 259); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_260(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 260); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_261(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 261); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_262(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 262); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_263(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 263); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_264(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 264); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_265(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 265); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_266(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 266); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_267(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 267); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_268(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 268); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_269(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 269); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_270(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 270); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_271(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 271); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_272(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 272); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_273(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 273); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_274(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 274); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_275(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 275); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_276(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 276); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_277(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 277); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_278(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 278); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_279(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 279); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_280(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 280); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_281(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 281); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_282(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 282); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_283(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 283); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_284(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 284); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_285(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 285); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_286(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 286); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_287(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 287); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_288(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 288); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_289(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 289); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_290(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 290); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_291(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 291); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_292(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 292); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_293(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 293); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_294(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 294); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_295(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 295); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_296(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 296); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_297(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 297); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_298(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 298); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_299(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 299); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_300(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 300); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_301(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 301); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_302(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 302); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_303(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 303); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_304(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 304); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_305(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 305); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_306(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 306); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_307(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 307); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_308(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 308); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_309(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 309); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_310(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 310); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_311(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 311); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_312(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 312); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_313(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 313); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_314(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 314); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_315(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 315); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_316(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 316); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_317(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 317); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_318(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 318); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_319(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 319); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_320(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 320); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_321(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 321); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_322(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 322); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_323(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 323); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_324(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 324); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_325(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 325); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_326(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 326); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_327(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 327); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_328(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 328); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_329(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 329); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_330(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 330); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_331(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 331); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_332(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 332); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_333(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 333); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_334(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 334); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_335(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 335); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_336(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 336); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_337(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 337); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_338(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 338); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_339(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 339); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_340(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 340); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_341(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 341); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_342(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 342); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_343(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 343); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_344(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 344); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_345(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 345); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_346(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 346); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_347(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 347); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_348(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 348); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_349(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 349); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_350(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 350); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_351(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 351); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_352(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 352); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_353(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 353); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_354(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 354); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_355(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 355); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_356(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 356); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_357(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 357); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_358(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 358); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_359(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 359); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_360(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 360); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_361(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 361); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_362(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 362); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_363(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 363); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_364(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 364); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_365(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 365); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_366(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 366); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_367(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 367); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_368(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 368); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_369(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 369); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_370(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 370); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_371(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 371); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_372(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 372); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_373(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 373); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_374(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 374); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_375(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 375); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_376(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 376); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_377(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 377); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_378(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 378); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_379(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 379); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_380(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 380); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_381(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 381); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_382(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 382); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_383(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 383); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_384(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 384); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_385(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 385); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_386(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 386); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_387(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 387); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_388(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 388); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_389(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 389); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_390(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 390); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_391(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 391); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_392(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 392); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_393(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 393); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_394(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 394); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_395(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 395); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_396(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 396); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_397(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 397); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_398(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 398); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_399(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 399); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_400(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 400); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_401(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 401); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_402(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 402); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_403(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 403); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_404(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 404); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_405(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 405); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_406(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 406); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_407(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 407); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_408(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 408); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_409(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 409); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_410(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 410); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_411(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 411); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_412(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 412); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_413(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 413); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_414(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 414); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_415(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 415); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_416(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 416); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_417(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 417); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_418(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 418); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_419(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 419); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_420(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 420); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_421(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 421); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_422(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 422); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_423(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 423); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_424(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 424); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_425(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 425); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_426(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 426); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_427(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 427); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_428(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 428); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_429(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 429); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_430(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 430); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_431(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 431); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_432(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 432); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_433(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 433); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_434(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 434); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_435(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 435); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_436(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 436); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_437(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 437); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_438(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 438); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_439(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 439); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_440(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 440); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_441(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 441); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_442(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 442); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_443(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 443); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_444(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 444); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_445(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 445); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_446(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 446); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_447(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 447); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_448(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 448); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_449(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 449); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_450(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 450); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_451(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 451); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_452(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 452); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_453(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 453); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_454(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 454); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_455(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 455); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_456(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 456); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_457(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 457); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_458(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 458); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_459(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 459); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_460(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 460); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_461(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 461); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_462(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 462); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_463(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 463); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_464(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 464); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_465(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 465); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_466(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 466); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_467(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 467); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_468(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 468); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_469(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 469); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_470(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 470); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_471(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 471); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_472(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 472); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_473(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 473); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_474(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 474); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_475(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 475); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_476(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 476); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_477(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 477); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_478(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 478); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_479(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 479); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_480(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 480); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_481(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 481); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_482(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 482); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_483(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 483); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_484(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 484); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_485(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 485); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_486(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 486); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_487(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 487); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_488(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 488); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_489(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 489); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_490(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 490); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_491(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 491); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_492(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 492); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_493(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 493); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_494(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 494); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_495(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 495); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_496(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 496); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_497(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 497); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_498(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 498); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_499(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 499); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_500(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 500); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_501(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 501); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_502(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 502); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_503(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 503); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_504(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 504); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_505(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 505); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_506(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 506); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_507(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 507); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_508(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 508); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_509(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 509); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_510(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 510); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_511(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 511); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_512(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 512); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_513(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 513); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_514(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 514); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_515(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 515); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_516(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 516); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_517(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 517); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_518(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 518); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_519(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 519); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_520(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 520); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_521(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 521); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_522(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 522); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_523(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 523); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_524(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 524); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_525(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 525); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_526(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 526); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_527(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 527); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_528(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 528); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_529(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 529); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_530(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 530); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_531(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 531); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_532(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 532); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_533(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 533); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_534(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 534); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_535(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 535); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_536(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 536); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_537(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 537); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_538(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 538); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_539(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 539); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_540(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 540); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_541(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 541); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_542(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 542); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_543(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 543); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_544(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 544); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_545(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 545); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_546(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 546); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_547(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 547); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_548(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 548); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_549(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 549); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_550(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 550); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_551(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 551); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_552(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 552); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_553(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 553); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_554(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 554); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_555(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 555); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_556(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 556); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_557(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 557); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_558(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 558); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_559(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 559); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_560(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 560); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_561(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 561); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_562(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 562); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_563(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 563); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_564(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 564); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_565(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 565); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_566(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 566); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_567(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 567); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_568(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 568); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_569(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 569); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_570(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 570); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_571(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 571); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_572(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 572); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_573(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 573); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_574(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 574); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_575(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 575); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_576(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 576); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_577(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 577); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_578(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 578); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_579(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 579); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_580(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 580); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_581(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 581); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_582(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 582); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_583(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 583); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_584(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 584); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_585(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 585); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_586(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 586); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_587(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 587); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_588(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 588); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_589(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 589); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_590(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 590); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_591(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 591); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_592(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 592); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_593(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 593); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_594(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 594); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_595(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 595); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_596(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 596); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_597(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 597); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_598(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 598); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_599(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 599); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_600(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 600); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_601(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 601); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_602(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 602); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_603(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 603); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_604(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 604); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_605(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 605); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_606(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 606); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_607(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 607); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_608(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 608); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_609(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 609); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_610(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 610); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_611(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 611); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_612(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 612); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_613(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 613); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_614(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 614); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_615(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 615); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_616(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 616); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_617(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 617); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_618(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 618); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_619(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 619); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_620(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 620); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_621(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 621); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_622(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 622); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_623(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 623); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_624(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 624); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_625(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 625); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_626(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 626); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_627(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 627); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_628(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 628); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_629(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 629); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_630(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 630); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_631(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 631); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_632(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 632); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_633(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 633); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_634(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 634); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_635(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 635); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_636(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 636); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_637(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 637); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_638(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 638); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_639(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 639); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_640(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 640); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_641(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 641); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_642(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 642); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_643(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 643); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_644(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 644); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_645(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 645); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_646(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 646); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_647(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 647); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_648(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 648); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_649(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 649); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_650(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 650); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_651(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 651); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_652(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 652); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_653(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 653); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_654(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 654); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_655(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 655); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_656(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 656); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_657(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 657); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_658(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 658); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_659(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 659); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_660(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 660); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_661(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 661); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_662(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 662); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_663(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 663); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_664(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 664); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_665(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 665); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_666(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 666); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_667(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 667); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_668(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 668); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_669(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 669); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_670(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 670); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_671(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 671); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_672(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 672); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_673(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 673); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_674(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 674); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_675(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 675); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_676(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 676); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_677(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 677); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_678(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 678); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_679(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 679); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_680(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 680); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_681(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 681); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_682(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 682); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_683(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 683); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_684(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 684); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_685(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 685); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_686(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 686); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_687(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 687); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_688(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 688); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_689(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 689); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_690(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 690); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_691(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 691); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_692(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 692); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_693(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 693); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_694(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 694); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_695(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 695); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_696(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 696); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_697(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 697); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_698(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 698); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_699(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 699); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_700(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 700); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_701(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 701); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_702(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 702); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_703(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 703); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_704(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 704); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_705(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 705); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_706(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 706); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_707(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 707); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_708(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 708); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_709(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 709); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_710(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 710); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_711(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 711); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_712(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 712); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_713(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 713); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_714(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 714); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_715(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 715); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_716(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 716); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_717(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 717); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_718(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 718); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_719(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 719); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_720(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 720); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_721(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 721); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_722(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 722); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_723(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 723); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_724(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 724); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_725(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 725); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_726(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 726); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_727(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 727); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_728(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 728); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_729(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 729); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_730(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 730); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_731(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 731); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_732(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 732); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_733(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 733); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_734(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 734); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_735(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 735); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_736(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 736); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_737(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 737); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_738(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 738); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_739(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 739); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_740(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 740); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_741(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 741); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_742(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 742); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_743(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 743); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_744(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 744); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_745(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 745); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_746(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 746); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_747(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 747); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_748(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 748); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_749(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 749); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_750(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 750); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_751(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 751); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_752(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 752); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_753(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 753); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_754(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 754); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_755(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 755); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_756(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 756); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_757(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 757); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_758(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 758); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_759(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 759); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_760(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 760); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_761(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 761); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_762(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 762); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_763(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 763); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_764(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 764); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_765(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 765); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_766(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 766); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_767(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 767); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_768(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 768); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_769(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 769); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_770(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 770); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_771(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 771); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_772(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 772); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_773(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 773); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_774(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 774); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_775(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 775); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_776(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 776); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_777(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 777); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_778(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 778); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_779(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 779); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_780(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 780); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_781(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 781); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_782(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 782); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_783(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 783); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_784(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 784); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_785(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 785); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_786(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 786); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_787(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 787); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_788(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 788); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_789(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 789); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_790(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 790); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_791(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 791); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_792(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 792); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_793(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 793); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_794(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 794); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_795(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 795); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_796(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 796); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_797(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 797); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_798(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 798); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_799(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 799); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_800(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 800); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_801(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 801); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_802(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 802); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_803(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 803); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_804(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 804); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_805(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 805); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_806(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 806); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_807(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 807); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_808(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 808); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_809(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 809); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_810(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 810); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_811(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 811); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_812(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 812); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_813(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 813); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_814(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 814); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_815(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 815); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_816(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 816); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_817(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 817); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_818(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 818); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_819(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 819); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_820(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 820); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_821(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 821); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_822(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 822); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_823(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 823); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_824(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 824); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_825(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 825); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_826(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 826); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_827(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 827); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_828(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 828); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_829(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 829); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_830(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 830); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_831(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 831); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_832(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 832); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_833(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 833); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_834(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 834); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_835(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 835); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_836(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 836); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_837(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 837); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_838(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 838); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_839(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 839); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_840(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 840); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_841(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 841); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_842(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 842); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_843(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 843); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_844(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 844); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_845(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 845); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_846(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 846); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_847(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 847); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_848(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 848); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_849(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 849); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_850(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 850); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_851(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 851); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_852(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 852); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_853(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 853); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_854(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 854); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_855(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 855); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_856(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 856); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_857(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 857); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_858(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 858); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_859(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 859); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_860(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 860); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_861(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 861); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_862(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 862); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_863(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 863); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_864(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 864); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_865(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 865); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_866(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 866); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_867(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 867); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_868(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 868); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_869(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 869); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_870(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 870); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_871(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 871); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_872(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 872); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_873(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 873); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_874(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 874); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_875(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 875); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_876(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 876); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_877(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 877); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_878(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 878); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_879(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 879); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_880(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 880); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_881(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 881); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_882(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 882); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_883(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 883); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_884(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 884); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_885(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 885); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_886(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 886); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_887(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 887); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_888(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 888); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_889(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 889); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_890(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 890); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_891(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 891); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_892(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 892); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_893(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 893); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_894(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 894); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_895(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 895); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_896(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 896); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_897(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 897); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_898(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 898); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_899(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 899); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_900(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 900); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_901(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 901); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_902(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 902); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_903(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 903); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_904(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 904); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_905(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 905); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_906(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 906); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_907(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 907); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_908(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 908); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_909(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 909); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_910(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 910); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_911(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 911); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_912(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 912); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_913(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 913); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_914(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 914); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_915(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 915); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_916(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 916); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_917(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 917); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_918(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 918); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_919(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 919); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_920(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 920); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_921(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 921); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_922(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 922); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_923(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 923); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_924(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 924); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_925(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 925); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_926(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 926); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_927(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 927); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_928(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 928); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_929(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 929); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_930(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 930); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_931(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 931); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_932(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 932); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_933(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 933); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_934(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 934); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_935(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 935); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_936(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 936); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_937(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 937); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_938(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 938); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_939(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 939); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_940(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 940); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_941(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 941); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_942(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 942); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_943(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 943); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_944(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 944); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_945(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 945); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_946(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 946); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_947(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 947); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_948(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 948); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_949(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 949); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_950(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 950); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_951(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 951); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_952(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 952); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_953(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 953); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_954(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 954); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_955(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 955); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_956(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 956); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_957(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 957); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_958(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 958); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_959(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 959); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_960(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 960); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_961(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 961); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_962(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 962); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_963(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 963); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_964(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 964); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_965(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 965); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_966(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 966); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_967(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 967); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_968(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 968); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_969(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 969); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_970(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 970); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_971(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 971); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_972(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 972); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_973(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 973); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_974(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 974); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_975(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 975); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_976(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 976); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_977(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 977); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_978(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 978); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_979(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 979); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_980(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 980); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_981(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 981); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_982(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 982); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_983(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 983); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_984(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 984); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_985(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 985); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_986(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 986); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_987(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 987); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_988(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 988); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_989(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 989); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_990(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 990); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_991(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 991); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_992(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 992); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_993(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 993); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_994(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 994); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_995(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 995); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_996(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 996); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_997(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 997); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_998(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 998); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_999(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 999); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1000(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1000); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1001(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1001); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1002(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1002); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1003(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1003); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1004(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1004); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1005(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1005); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1006(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1006); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1007(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1007); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1008(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1008); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1009(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1009); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1010(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1010); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1011(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1011); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1012(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1012); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1013(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1013); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1014(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1014); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1015(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1015); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1016(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1016); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1017(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1017); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1018(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1018); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1019(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1019); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1020(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1020); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1021(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1021); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1022(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1022); -} - -/** - * - */ -static SQInteger sr_kemi_sqlang_exec_func_1023(HSQUIRRELVM J) -{ - return sr_kemi_sqlang_exec_func(J, 1023); -} - -/** - * - */ -static sr_kemi_sqlang_export_t _sr_kemi_sqlang_export_list[] = { - {sr_kemi_sqlang_exec_func_0, NULL}, {sr_kemi_sqlang_exec_func_1, NULL}, - {sr_kemi_sqlang_exec_func_2, NULL}, {sr_kemi_sqlang_exec_func_3, NULL}, - {sr_kemi_sqlang_exec_func_4, NULL}, {sr_kemi_sqlang_exec_func_5, NULL}, - {sr_kemi_sqlang_exec_func_6, NULL}, {sr_kemi_sqlang_exec_func_7, NULL}, - {sr_kemi_sqlang_exec_func_8, NULL}, {sr_kemi_sqlang_exec_func_9, NULL}, - {sr_kemi_sqlang_exec_func_10, NULL}, - {sr_kemi_sqlang_exec_func_11, NULL}, - {sr_kemi_sqlang_exec_func_12, NULL}, - {sr_kemi_sqlang_exec_func_13, NULL}, - {sr_kemi_sqlang_exec_func_14, NULL}, - {sr_kemi_sqlang_exec_func_15, NULL}, - {sr_kemi_sqlang_exec_func_16, NULL}, - {sr_kemi_sqlang_exec_func_17, NULL}, - {sr_kemi_sqlang_exec_func_18, NULL}, - {sr_kemi_sqlang_exec_func_19, NULL}, - {sr_kemi_sqlang_exec_func_20, NULL}, - {sr_kemi_sqlang_exec_func_21, NULL}, - {sr_kemi_sqlang_exec_func_22, NULL}, - {sr_kemi_sqlang_exec_func_23, NULL}, - {sr_kemi_sqlang_exec_func_24, NULL}, - {sr_kemi_sqlang_exec_func_25, NULL}, - {sr_kemi_sqlang_exec_func_26, NULL}, - {sr_kemi_sqlang_exec_func_27, NULL}, - {sr_kemi_sqlang_exec_func_28, NULL}, - {sr_kemi_sqlang_exec_func_29, NULL}, - {sr_kemi_sqlang_exec_func_30, NULL}, - {sr_kemi_sqlang_exec_func_31, NULL}, - {sr_kemi_sqlang_exec_func_32, NULL}, - {sr_kemi_sqlang_exec_func_33, NULL}, - {sr_kemi_sqlang_exec_func_34, NULL}, - {sr_kemi_sqlang_exec_func_35, NULL}, - {sr_kemi_sqlang_exec_func_36, NULL}, - {sr_kemi_sqlang_exec_func_37, NULL}, - {sr_kemi_sqlang_exec_func_38, NULL}, - {sr_kemi_sqlang_exec_func_39, NULL}, - {sr_kemi_sqlang_exec_func_40, NULL}, - {sr_kemi_sqlang_exec_func_41, NULL}, - {sr_kemi_sqlang_exec_func_42, NULL}, - {sr_kemi_sqlang_exec_func_43, NULL}, - {sr_kemi_sqlang_exec_func_44, NULL}, - {sr_kemi_sqlang_exec_func_45, NULL}, - {sr_kemi_sqlang_exec_func_46, NULL}, - {sr_kemi_sqlang_exec_func_47, NULL}, - {sr_kemi_sqlang_exec_func_48, NULL}, - {sr_kemi_sqlang_exec_func_49, NULL}, - {sr_kemi_sqlang_exec_func_50, NULL}, - {sr_kemi_sqlang_exec_func_51, NULL}, - {sr_kemi_sqlang_exec_func_52, NULL}, - {sr_kemi_sqlang_exec_func_53, NULL}, - {sr_kemi_sqlang_exec_func_54, NULL}, - {sr_kemi_sqlang_exec_func_55, NULL}, - {sr_kemi_sqlang_exec_func_56, NULL}, - {sr_kemi_sqlang_exec_func_57, NULL}, - {sr_kemi_sqlang_exec_func_58, NULL}, - {sr_kemi_sqlang_exec_func_59, NULL}, - {sr_kemi_sqlang_exec_func_60, NULL}, - {sr_kemi_sqlang_exec_func_61, NULL}, - {sr_kemi_sqlang_exec_func_62, NULL}, - {sr_kemi_sqlang_exec_func_63, NULL}, - {sr_kemi_sqlang_exec_func_64, NULL}, - {sr_kemi_sqlang_exec_func_65, NULL}, - {sr_kemi_sqlang_exec_func_66, NULL}, - {sr_kemi_sqlang_exec_func_67, NULL}, - {sr_kemi_sqlang_exec_func_68, NULL}, - {sr_kemi_sqlang_exec_func_69, NULL}, - {sr_kemi_sqlang_exec_func_70, NULL}, - {sr_kemi_sqlang_exec_func_71, NULL}, - {sr_kemi_sqlang_exec_func_72, NULL}, - {sr_kemi_sqlang_exec_func_73, NULL}, - {sr_kemi_sqlang_exec_func_74, NULL}, - {sr_kemi_sqlang_exec_func_75, NULL}, - {sr_kemi_sqlang_exec_func_76, NULL}, - {sr_kemi_sqlang_exec_func_77, NULL}, - {sr_kemi_sqlang_exec_func_78, NULL}, - {sr_kemi_sqlang_exec_func_79, NULL}, - {sr_kemi_sqlang_exec_func_80, NULL}, - {sr_kemi_sqlang_exec_func_81, NULL}, - {sr_kemi_sqlang_exec_func_82, NULL}, - {sr_kemi_sqlang_exec_func_83, NULL}, - {sr_kemi_sqlang_exec_func_84, NULL}, - {sr_kemi_sqlang_exec_func_85, NULL}, - {sr_kemi_sqlang_exec_func_86, NULL}, - {sr_kemi_sqlang_exec_func_87, NULL}, - {sr_kemi_sqlang_exec_func_88, NULL}, - {sr_kemi_sqlang_exec_func_89, NULL}, - {sr_kemi_sqlang_exec_func_90, NULL}, - {sr_kemi_sqlang_exec_func_91, NULL}, - {sr_kemi_sqlang_exec_func_92, NULL}, - {sr_kemi_sqlang_exec_func_93, NULL}, - {sr_kemi_sqlang_exec_func_94, NULL}, - {sr_kemi_sqlang_exec_func_95, NULL}, - {sr_kemi_sqlang_exec_func_96, NULL}, - {sr_kemi_sqlang_exec_func_97, NULL}, - {sr_kemi_sqlang_exec_func_98, NULL}, - {sr_kemi_sqlang_exec_func_99, NULL}, - {sr_kemi_sqlang_exec_func_100, NULL}, - {sr_kemi_sqlang_exec_func_101, NULL}, - {sr_kemi_sqlang_exec_func_102, NULL}, - {sr_kemi_sqlang_exec_func_103, NULL}, - {sr_kemi_sqlang_exec_func_104, NULL}, - {sr_kemi_sqlang_exec_func_105, NULL}, - {sr_kemi_sqlang_exec_func_106, NULL}, - {sr_kemi_sqlang_exec_func_107, NULL}, - {sr_kemi_sqlang_exec_func_108, NULL}, - {sr_kemi_sqlang_exec_func_109, NULL}, - {sr_kemi_sqlang_exec_func_110, NULL}, - {sr_kemi_sqlang_exec_func_111, NULL}, - {sr_kemi_sqlang_exec_func_112, NULL}, - {sr_kemi_sqlang_exec_func_113, NULL}, - {sr_kemi_sqlang_exec_func_114, NULL}, - {sr_kemi_sqlang_exec_func_115, NULL}, - {sr_kemi_sqlang_exec_func_116, NULL}, - {sr_kemi_sqlang_exec_func_117, NULL}, - {sr_kemi_sqlang_exec_func_118, NULL}, - {sr_kemi_sqlang_exec_func_119, NULL}, - {sr_kemi_sqlang_exec_func_120, NULL}, - {sr_kemi_sqlang_exec_func_121, NULL}, - {sr_kemi_sqlang_exec_func_122, NULL}, - {sr_kemi_sqlang_exec_func_123, NULL}, - {sr_kemi_sqlang_exec_func_124, NULL}, - {sr_kemi_sqlang_exec_func_125, NULL}, - {sr_kemi_sqlang_exec_func_126, NULL}, - {sr_kemi_sqlang_exec_func_127, NULL}, - {sr_kemi_sqlang_exec_func_128, NULL}, - {sr_kemi_sqlang_exec_func_129, NULL}, - {sr_kemi_sqlang_exec_func_130, NULL}, - {sr_kemi_sqlang_exec_func_131, NULL}, - {sr_kemi_sqlang_exec_func_132, NULL}, - {sr_kemi_sqlang_exec_func_133, NULL}, - {sr_kemi_sqlang_exec_func_134, NULL}, - {sr_kemi_sqlang_exec_func_135, NULL}, - {sr_kemi_sqlang_exec_func_136, NULL}, - {sr_kemi_sqlang_exec_func_137, NULL}, - {sr_kemi_sqlang_exec_func_138, NULL}, - {sr_kemi_sqlang_exec_func_139, NULL}, - {sr_kemi_sqlang_exec_func_140, NULL}, - {sr_kemi_sqlang_exec_func_141, NULL}, - {sr_kemi_sqlang_exec_func_142, NULL}, - {sr_kemi_sqlang_exec_func_143, NULL}, - {sr_kemi_sqlang_exec_func_144, NULL}, - {sr_kemi_sqlang_exec_func_145, NULL}, - {sr_kemi_sqlang_exec_func_146, NULL}, - {sr_kemi_sqlang_exec_func_147, NULL}, - {sr_kemi_sqlang_exec_func_148, NULL}, - {sr_kemi_sqlang_exec_func_149, NULL}, - {sr_kemi_sqlang_exec_func_150, NULL}, - {sr_kemi_sqlang_exec_func_151, NULL}, - {sr_kemi_sqlang_exec_func_152, NULL}, - {sr_kemi_sqlang_exec_func_153, NULL}, - {sr_kemi_sqlang_exec_func_154, NULL}, - {sr_kemi_sqlang_exec_func_155, NULL}, - {sr_kemi_sqlang_exec_func_156, NULL}, - {sr_kemi_sqlang_exec_func_157, NULL}, - {sr_kemi_sqlang_exec_func_158, NULL}, - {sr_kemi_sqlang_exec_func_159, NULL}, - {sr_kemi_sqlang_exec_func_160, NULL}, - {sr_kemi_sqlang_exec_func_161, NULL}, - {sr_kemi_sqlang_exec_func_162, NULL}, - {sr_kemi_sqlang_exec_func_163, NULL}, - {sr_kemi_sqlang_exec_func_164, NULL}, - {sr_kemi_sqlang_exec_func_165, NULL}, - {sr_kemi_sqlang_exec_func_166, NULL}, - {sr_kemi_sqlang_exec_func_167, NULL}, - {sr_kemi_sqlang_exec_func_168, NULL}, - {sr_kemi_sqlang_exec_func_169, NULL}, - {sr_kemi_sqlang_exec_func_170, NULL}, - {sr_kemi_sqlang_exec_func_171, NULL}, - {sr_kemi_sqlang_exec_func_172, NULL}, - {sr_kemi_sqlang_exec_func_173, NULL}, - {sr_kemi_sqlang_exec_func_174, NULL}, - {sr_kemi_sqlang_exec_func_175, NULL}, - {sr_kemi_sqlang_exec_func_176, NULL}, - {sr_kemi_sqlang_exec_func_177, NULL}, - {sr_kemi_sqlang_exec_func_178, NULL}, - {sr_kemi_sqlang_exec_func_179, NULL}, - {sr_kemi_sqlang_exec_func_180, NULL}, - {sr_kemi_sqlang_exec_func_181, NULL}, - {sr_kemi_sqlang_exec_func_182, NULL}, - {sr_kemi_sqlang_exec_func_183, NULL}, - {sr_kemi_sqlang_exec_func_184, NULL}, - {sr_kemi_sqlang_exec_func_185, NULL}, - {sr_kemi_sqlang_exec_func_186, NULL}, - {sr_kemi_sqlang_exec_func_187, NULL}, - {sr_kemi_sqlang_exec_func_188, NULL}, - {sr_kemi_sqlang_exec_func_189, NULL}, - {sr_kemi_sqlang_exec_func_190, NULL}, - {sr_kemi_sqlang_exec_func_191, NULL}, - {sr_kemi_sqlang_exec_func_192, NULL}, - {sr_kemi_sqlang_exec_func_193, NULL}, - {sr_kemi_sqlang_exec_func_194, NULL}, - {sr_kemi_sqlang_exec_func_195, NULL}, - {sr_kemi_sqlang_exec_func_196, NULL}, - {sr_kemi_sqlang_exec_func_197, NULL}, - {sr_kemi_sqlang_exec_func_198, NULL}, - {sr_kemi_sqlang_exec_func_199, NULL}, - {sr_kemi_sqlang_exec_func_200, NULL}, - {sr_kemi_sqlang_exec_func_201, NULL}, - {sr_kemi_sqlang_exec_func_202, NULL}, - {sr_kemi_sqlang_exec_func_203, NULL}, - {sr_kemi_sqlang_exec_func_204, NULL}, - {sr_kemi_sqlang_exec_func_205, NULL}, - {sr_kemi_sqlang_exec_func_206, NULL}, - {sr_kemi_sqlang_exec_func_207, NULL}, - {sr_kemi_sqlang_exec_func_208, NULL}, - {sr_kemi_sqlang_exec_func_209, NULL}, - {sr_kemi_sqlang_exec_func_210, NULL}, - {sr_kemi_sqlang_exec_func_211, NULL}, - {sr_kemi_sqlang_exec_func_212, NULL}, - {sr_kemi_sqlang_exec_func_213, NULL}, - {sr_kemi_sqlang_exec_func_214, NULL}, - {sr_kemi_sqlang_exec_func_215, NULL}, - {sr_kemi_sqlang_exec_func_216, NULL}, - {sr_kemi_sqlang_exec_func_217, NULL}, - {sr_kemi_sqlang_exec_func_218, NULL}, - {sr_kemi_sqlang_exec_func_219, NULL}, - {sr_kemi_sqlang_exec_func_220, NULL}, - {sr_kemi_sqlang_exec_func_221, NULL}, - {sr_kemi_sqlang_exec_func_222, NULL}, - {sr_kemi_sqlang_exec_func_223, NULL}, - {sr_kemi_sqlang_exec_func_224, NULL}, - {sr_kemi_sqlang_exec_func_225, NULL}, - {sr_kemi_sqlang_exec_func_226, NULL}, - {sr_kemi_sqlang_exec_func_227, NULL}, - {sr_kemi_sqlang_exec_func_228, NULL}, - {sr_kemi_sqlang_exec_func_229, NULL}, - {sr_kemi_sqlang_exec_func_230, NULL}, - {sr_kemi_sqlang_exec_func_231, NULL}, - {sr_kemi_sqlang_exec_func_232, NULL}, - {sr_kemi_sqlang_exec_func_233, NULL}, - {sr_kemi_sqlang_exec_func_234, NULL}, - {sr_kemi_sqlang_exec_func_235, NULL}, - {sr_kemi_sqlang_exec_func_236, NULL}, - {sr_kemi_sqlang_exec_func_237, NULL}, - {sr_kemi_sqlang_exec_func_238, NULL}, - {sr_kemi_sqlang_exec_func_239, NULL}, - {sr_kemi_sqlang_exec_func_240, NULL}, - {sr_kemi_sqlang_exec_func_241, NULL}, - {sr_kemi_sqlang_exec_func_242, NULL}, - {sr_kemi_sqlang_exec_func_243, NULL}, - {sr_kemi_sqlang_exec_func_244, NULL}, - {sr_kemi_sqlang_exec_func_245, NULL}, - {sr_kemi_sqlang_exec_func_246, NULL}, - {sr_kemi_sqlang_exec_func_247, NULL}, - {sr_kemi_sqlang_exec_func_248, NULL}, - {sr_kemi_sqlang_exec_func_249, NULL}, - {sr_kemi_sqlang_exec_func_250, NULL}, - {sr_kemi_sqlang_exec_func_251, NULL}, - {sr_kemi_sqlang_exec_func_252, NULL}, - {sr_kemi_sqlang_exec_func_253, NULL}, - {sr_kemi_sqlang_exec_func_254, NULL}, - {sr_kemi_sqlang_exec_func_255, NULL}, - {sr_kemi_sqlang_exec_func_256, NULL}, - {sr_kemi_sqlang_exec_func_257, NULL}, - {sr_kemi_sqlang_exec_func_258, NULL}, - {sr_kemi_sqlang_exec_func_259, NULL}, - {sr_kemi_sqlang_exec_func_260, NULL}, - {sr_kemi_sqlang_exec_func_261, NULL}, - {sr_kemi_sqlang_exec_func_262, NULL}, - {sr_kemi_sqlang_exec_func_263, NULL}, - {sr_kemi_sqlang_exec_func_264, NULL}, - {sr_kemi_sqlang_exec_func_265, NULL}, - {sr_kemi_sqlang_exec_func_266, NULL}, - {sr_kemi_sqlang_exec_func_267, NULL}, - {sr_kemi_sqlang_exec_func_268, NULL}, - {sr_kemi_sqlang_exec_func_269, NULL}, - {sr_kemi_sqlang_exec_func_270, NULL}, - {sr_kemi_sqlang_exec_func_271, NULL}, - {sr_kemi_sqlang_exec_func_272, NULL}, - {sr_kemi_sqlang_exec_func_273, NULL}, - {sr_kemi_sqlang_exec_func_274, NULL}, - {sr_kemi_sqlang_exec_func_275, NULL}, - {sr_kemi_sqlang_exec_func_276, NULL}, - {sr_kemi_sqlang_exec_func_277, NULL}, - {sr_kemi_sqlang_exec_func_278, NULL}, - {sr_kemi_sqlang_exec_func_279, NULL}, - {sr_kemi_sqlang_exec_func_280, NULL}, - {sr_kemi_sqlang_exec_func_281, NULL}, - {sr_kemi_sqlang_exec_func_282, NULL}, - {sr_kemi_sqlang_exec_func_283, NULL}, - {sr_kemi_sqlang_exec_func_284, NULL}, - {sr_kemi_sqlang_exec_func_285, NULL}, - {sr_kemi_sqlang_exec_func_286, NULL}, - {sr_kemi_sqlang_exec_func_287, NULL}, - {sr_kemi_sqlang_exec_func_288, NULL}, - {sr_kemi_sqlang_exec_func_289, NULL}, - {sr_kemi_sqlang_exec_func_290, NULL}, - {sr_kemi_sqlang_exec_func_291, NULL}, - {sr_kemi_sqlang_exec_func_292, NULL}, - {sr_kemi_sqlang_exec_func_293, NULL}, - {sr_kemi_sqlang_exec_func_294, NULL}, - {sr_kemi_sqlang_exec_func_295, NULL}, - {sr_kemi_sqlang_exec_func_296, NULL}, - {sr_kemi_sqlang_exec_func_297, NULL}, - {sr_kemi_sqlang_exec_func_298, NULL}, - {sr_kemi_sqlang_exec_func_299, NULL}, - {sr_kemi_sqlang_exec_func_300, NULL}, - {sr_kemi_sqlang_exec_func_301, NULL}, - {sr_kemi_sqlang_exec_func_302, NULL}, - {sr_kemi_sqlang_exec_func_303, NULL}, - {sr_kemi_sqlang_exec_func_304, NULL}, - {sr_kemi_sqlang_exec_func_305, NULL}, - {sr_kemi_sqlang_exec_func_306, NULL}, - {sr_kemi_sqlang_exec_func_307, NULL}, - {sr_kemi_sqlang_exec_func_308, NULL}, - {sr_kemi_sqlang_exec_func_309, NULL}, - {sr_kemi_sqlang_exec_func_310, NULL}, - {sr_kemi_sqlang_exec_func_311, NULL}, - {sr_kemi_sqlang_exec_func_312, NULL}, - {sr_kemi_sqlang_exec_func_313, NULL}, - {sr_kemi_sqlang_exec_func_314, NULL}, - {sr_kemi_sqlang_exec_func_315, NULL}, - {sr_kemi_sqlang_exec_func_316, NULL}, - {sr_kemi_sqlang_exec_func_317, NULL}, - {sr_kemi_sqlang_exec_func_318, NULL}, - {sr_kemi_sqlang_exec_func_319, NULL}, - {sr_kemi_sqlang_exec_func_320, NULL}, - {sr_kemi_sqlang_exec_func_321, NULL}, - {sr_kemi_sqlang_exec_func_322, NULL}, - {sr_kemi_sqlang_exec_func_323, NULL}, - {sr_kemi_sqlang_exec_func_324, NULL}, - {sr_kemi_sqlang_exec_func_325, NULL}, - {sr_kemi_sqlang_exec_func_326, NULL}, - {sr_kemi_sqlang_exec_func_327, NULL}, - {sr_kemi_sqlang_exec_func_328, NULL}, - {sr_kemi_sqlang_exec_func_329, NULL}, - {sr_kemi_sqlang_exec_func_330, NULL}, - {sr_kemi_sqlang_exec_func_331, NULL}, - {sr_kemi_sqlang_exec_func_332, NULL}, - {sr_kemi_sqlang_exec_func_333, NULL}, - {sr_kemi_sqlang_exec_func_334, NULL}, - {sr_kemi_sqlang_exec_func_335, NULL}, - {sr_kemi_sqlang_exec_func_336, NULL}, - {sr_kemi_sqlang_exec_func_337, NULL}, - {sr_kemi_sqlang_exec_func_338, NULL}, - {sr_kemi_sqlang_exec_func_339, NULL}, - {sr_kemi_sqlang_exec_func_340, NULL}, - {sr_kemi_sqlang_exec_func_341, NULL}, - {sr_kemi_sqlang_exec_func_342, NULL}, - {sr_kemi_sqlang_exec_func_343, NULL}, - {sr_kemi_sqlang_exec_func_344, NULL}, - {sr_kemi_sqlang_exec_func_345, NULL}, - {sr_kemi_sqlang_exec_func_346, NULL}, - {sr_kemi_sqlang_exec_func_347, NULL}, - {sr_kemi_sqlang_exec_func_348, NULL}, - {sr_kemi_sqlang_exec_func_349, NULL}, - {sr_kemi_sqlang_exec_func_350, NULL}, - {sr_kemi_sqlang_exec_func_351, NULL}, - {sr_kemi_sqlang_exec_func_352, NULL}, - {sr_kemi_sqlang_exec_func_353, NULL}, - {sr_kemi_sqlang_exec_func_354, NULL}, - {sr_kemi_sqlang_exec_func_355, NULL}, - {sr_kemi_sqlang_exec_func_356, NULL}, - {sr_kemi_sqlang_exec_func_357, NULL}, - {sr_kemi_sqlang_exec_func_358, NULL}, - {sr_kemi_sqlang_exec_func_359, NULL}, - {sr_kemi_sqlang_exec_func_360, NULL}, - {sr_kemi_sqlang_exec_func_361, NULL}, - {sr_kemi_sqlang_exec_func_362, NULL}, - {sr_kemi_sqlang_exec_func_363, NULL}, - {sr_kemi_sqlang_exec_func_364, NULL}, - {sr_kemi_sqlang_exec_func_365, NULL}, - {sr_kemi_sqlang_exec_func_366, NULL}, - {sr_kemi_sqlang_exec_func_367, NULL}, - {sr_kemi_sqlang_exec_func_368, NULL}, - {sr_kemi_sqlang_exec_func_369, NULL}, - {sr_kemi_sqlang_exec_func_370, NULL}, - {sr_kemi_sqlang_exec_func_371, NULL}, - {sr_kemi_sqlang_exec_func_372, NULL}, - {sr_kemi_sqlang_exec_func_373, NULL}, - {sr_kemi_sqlang_exec_func_374, NULL}, - {sr_kemi_sqlang_exec_func_375, NULL}, - {sr_kemi_sqlang_exec_func_376, NULL}, - {sr_kemi_sqlang_exec_func_377, NULL}, - {sr_kemi_sqlang_exec_func_378, NULL}, - {sr_kemi_sqlang_exec_func_379, NULL}, - {sr_kemi_sqlang_exec_func_380, NULL}, - {sr_kemi_sqlang_exec_func_381, NULL}, - {sr_kemi_sqlang_exec_func_382, NULL}, - {sr_kemi_sqlang_exec_func_383, NULL}, - {sr_kemi_sqlang_exec_func_384, NULL}, - {sr_kemi_sqlang_exec_func_385, NULL}, - {sr_kemi_sqlang_exec_func_386, NULL}, - {sr_kemi_sqlang_exec_func_387, NULL}, - {sr_kemi_sqlang_exec_func_388, NULL}, - {sr_kemi_sqlang_exec_func_389, NULL}, - {sr_kemi_sqlang_exec_func_390, NULL}, - {sr_kemi_sqlang_exec_func_391, NULL}, - {sr_kemi_sqlang_exec_func_392, NULL}, - {sr_kemi_sqlang_exec_func_393, NULL}, - {sr_kemi_sqlang_exec_func_394, NULL}, - {sr_kemi_sqlang_exec_func_395, NULL}, - {sr_kemi_sqlang_exec_func_396, NULL}, - {sr_kemi_sqlang_exec_func_397, NULL}, - {sr_kemi_sqlang_exec_func_398, NULL}, - {sr_kemi_sqlang_exec_func_399, NULL}, - {sr_kemi_sqlang_exec_func_400, NULL}, - {sr_kemi_sqlang_exec_func_401, NULL}, - {sr_kemi_sqlang_exec_func_402, NULL}, - {sr_kemi_sqlang_exec_func_403, NULL}, - {sr_kemi_sqlang_exec_func_404, NULL}, - {sr_kemi_sqlang_exec_func_405, NULL}, - {sr_kemi_sqlang_exec_func_406, NULL}, - {sr_kemi_sqlang_exec_func_407, NULL}, - {sr_kemi_sqlang_exec_func_408, NULL}, - {sr_kemi_sqlang_exec_func_409, NULL}, - {sr_kemi_sqlang_exec_func_410, NULL}, - {sr_kemi_sqlang_exec_func_411, NULL}, - {sr_kemi_sqlang_exec_func_412, NULL}, - {sr_kemi_sqlang_exec_func_413, NULL}, - {sr_kemi_sqlang_exec_func_414, NULL}, - {sr_kemi_sqlang_exec_func_415, NULL}, - {sr_kemi_sqlang_exec_func_416, NULL}, - {sr_kemi_sqlang_exec_func_417, NULL}, - {sr_kemi_sqlang_exec_func_418, NULL}, - {sr_kemi_sqlang_exec_func_419, NULL}, - {sr_kemi_sqlang_exec_func_420, NULL}, - {sr_kemi_sqlang_exec_func_421, NULL}, - {sr_kemi_sqlang_exec_func_422, NULL}, - {sr_kemi_sqlang_exec_func_423, NULL}, - {sr_kemi_sqlang_exec_func_424, NULL}, - {sr_kemi_sqlang_exec_func_425, NULL}, - {sr_kemi_sqlang_exec_func_426, NULL}, - {sr_kemi_sqlang_exec_func_427, NULL}, - {sr_kemi_sqlang_exec_func_428, NULL}, - {sr_kemi_sqlang_exec_func_429, NULL}, - {sr_kemi_sqlang_exec_func_430, NULL}, - {sr_kemi_sqlang_exec_func_431, NULL}, - {sr_kemi_sqlang_exec_func_432, NULL}, - {sr_kemi_sqlang_exec_func_433, NULL}, - {sr_kemi_sqlang_exec_func_434, NULL}, - {sr_kemi_sqlang_exec_func_435, NULL}, - {sr_kemi_sqlang_exec_func_436, NULL}, - {sr_kemi_sqlang_exec_func_437, NULL}, - {sr_kemi_sqlang_exec_func_438, NULL}, - {sr_kemi_sqlang_exec_func_439, NULL}, - {sr_kemi_sqlang_exec_func_440, NULL}, - {sr_kemi_sqlang_exec_func_441, NULL}, - {sr_kemi_sqlang_exec_func_442, NULL}, - {sr_kemi_sqlang_exec_func_443, NULL}, - {sr_kemi_sqlang_exec_func_444, NULL}, - {sr_kemi_sqlang_exec_func_445, NULL}, - {sr_kemi_sqlang_exec_func_446, NULL}, - {sr_kemi_sqlang_exec_func_447, NULL}, - {sr_kemi_sqlang_exec_func_448, NULL}, - {sr_kemi_sqlang_exec_func_449, NULL}, - {sr_kemi_sqlang_exec_func_450, NULL}, - {sr_kemi_sqlang_exec_func_451, NULL}, - {sr_kemi_sqlang_exec_func_452, NULL}, - {sr_kemi_sqlang_exec_func_453, NULL}, - {sr_kemi_sqlang_exec_func_454, NULL}, - {sr_kemi_sqlang_exec_func_455, NULL}, - {sr_kemi_sqlang_exec_func_456, NULL}, - {sr_kemi_sqlang_exec_func_457, NULL}, - {sr_kemi_sqlang_exec_func_458, NULL}, - {sr_kemi_sqlang_exec_func_459, NULL}, - {sr_kemi_sqlang_exec_func_460, NULL}, - {sr_kemi_sqlang_exec_func_461, NULL}, - {sr_kemi_sqlang_exec_func_462, NULL}, - {sr_kemi_sqlang_exec_func_463, NULL}, - {sr_kemi_sqlang_exec_func_464, NULL}, - {sr_kemi_sqlang_exec_func_465, NULL}, - {sr_kemi_sqlang_exec_func_466, NULL}, - {sr_kemi_sqlang_exec_func_467, NULL}, - {sr_kemi_sqlang_exec_func_468, NULL}, - {sr_kemi_sqlang_exec_func_469, NULL}, - {sr_kemi_sqlang_exec_func_470, NULL}, - {sr_kemi_sqlang_exec_func_471, NULL}, - {sr_kemi_sqlang_exec_func_472, NULL}, - {sr_kemi_sqlang_exec_func_473, NULL}, - {sr_kemi_sqlang_exec_func_474, NULL}, - {sr_kemi_sqlang_exec_func_475, NULL}, - {sr_kemi_sqlang_exec_func_476, NULL}, - {sr_kemi_sqlang_exec_func_477, NULL}, - {sr_kemi_sqlang_exec_func_478, NULL}, - {sr_kemi_sqlang_exec_func_479, NULL}, - {sr_kemi_sqlang_exec_func_480, NULL}, - {sr_kemi_sqlang_exec_func_481, NULL}, - {sr_kemi_sqlang_exec_func_482, NULL}, - {sr_kemi_sqlang_exec_func_483, NULL}, - {sr_kemi_sqlang_exec_func_484, NULL}, - {sr_kemi_sqlang_exec_func_485, NULL}, - {sr_kemi_sqlang_exec_func_486, NULL}, - {sr_kemi_sqlang_exec_func_487, NULL}, - {sr_kemi_sqlang_exec_func_488, NULL}, - {sr_kemi_sqlang_exec_func_489, NULL}, - {sr_kemi_sqlang_exec_func_490, NULL}, - {sr_kemi_sqlang_exec_func_491, NULL}, - {sr_kemi_sqlang_exec_func_492, NULL}, - {sr_kemi_sqlang_exec_func_493, NULL}, - {sr_kemi_sqlang_exec_func_494, NULL}, - {sr_kemi_sqlang_exec_func_495, NULL}, - {sr_kemi_sqlang_exec_func_496, NULL}, - {sr_kemi_sqlang_exec_func_497, NULL}, - {sr_kemi_sqlang_exec_func_498, NULL}, - {sr_kemi_sqlang_exec_func_499, NULL}, - {sr_kemi_sqlang_exec_func_500, NULL}, - {sr_kemi_sqlang_exec_func_501, NULL}, - {sr_kemi_sqlang_exec_func_502, NULL}, - {sr_kemi_sqlang_exec_func_503, NULL}, - {sr_kemi_sqlang_exec_func_504, NULL}, - {sr_kemi_sqlang_exec_func_505, NULL}, - {sr_kemi_sqlang_exec_func_506, NULL}, - {sr_kemi_sqlang_exec_func_507, NULL}, - {sr_kemi_sqlang_exec_func_508, NULL}, - {sr_kemi_sqlang_exec_func_509, NULL}, - {sr_kemi_sqlang_exec_func_510, NULL}, - {sr_kemi_sqlang_exec_func_511, NULL}, - {sr_kemi_sqlang_exec_func_512, NULL}, - {sr_kemi_sqlang_exec_func_513, NULL}, - {sr_kemi_sqlang_exec_func_514, NULL}, - {sr_kemi_sqlang_exec_func_515, NULL}, - {sr_kemi_sqlang_exec_func_516, NULL}, - {sr_kemi_sqlang_exec_func_517, NULL}, - {sr_kemi_sqlang_exec_func_518, NULL}, - {sr_kemi_sqlang_exec_func_519, NULL}, - {sr_kemi_sqlang_exec_func_520, NULL}, - {sr_kemi_sqlang_exec_func_521, NULL}, - {sr_kemi_sqlang_exec_func_522, NULL}, - {sr_kemi_sqlang_exec_func_523, NULL}, - {sr_kemi_sqlang_exec_func_524, NULL}, - {sr_kemi_sqlang_exec_func_525, NULL}, - {sr_kemi_sqlang_exec_func_526, NULL}, - {sr_kemi_sqlang_exec_func_527, NULL}, - {sr_kemi_sqlang_exec_func_528, NULL}, - {sr_kemi_sqlang_exec_func_529, NULL}, - {sr_kemi_sqlang_exec_func_530, NULL}, - {sr_kemi_sqlang_exec_func_531, NULL}, - {sr_kemi_sqlang_exec_func_532, NULL}, - {sr_kemi_sqlang_exec_func_533, NULL}, - {sr_kemi_sqlang_exec_func_534, NULL}, - {sr_kemi_sqlang_exec_func_535, NULL}, - {sr_kemi_sqlang_exec_func_536, NULL}, - {sr_kemi_sqlang_exec_func_537, NULL}, - {sr_kemi_sqlang_exec_func_538, NULL}, - {sr_kemi_sqlang_exec_func_539, NULL}, - {sr_kemi_sqlang_exec_func_540, NULL}, - {sr_kemi_sqlang_exec_func_541, NULL}, - {sr_kemi_sqlang_exec_func_542, NULL}, - {sr_kemi_sqlang_exec_func_543, NULL}, - {sr_kemi_sqlang_exec_func_544, NULL}, - {sr_kemi_sqlang_exec_func_545, NULL}, - {sr_kemi_sqlang_exec_func_546, NULL}, - {sr_kemi_sqlang_exec_func_547, NULL}, - {sr_kemi_sqlang_exec_func_548, NULL}, - {sr_kemi_sqlang_exec_func_549, NULL}, - {sr_kemi_sqlang_exec_func_550, NULL}, - {sr_kemi_sqlang_exec_func_551, NULL}, - {sr_kemi_sqlang_exec_func_552, NULL}, - {sr_kemi_sqlang_exec_func_553, NULL}, - {sr_kemi_sqlang_exec_func_554, NULL}, - {sr_kemi_sqlang_exec_func_555, NULL}, - {sr_kemi_sqlang_exec_func_556, NULL}, - {sr_kemi_sqlang_exec_func_557, NULL}, - {sr_kemi_sqlang_exec_func_558, NULL}, - {sr_kemi_sqlang_exec_func_559, NULL}, - {sr_kemi_sqlang_exec_func_560, NULL}, - {sr_kemi_sqlang_exec_func_561, NULL}, - {sr_kemi_sqlang_exec_func_562, NULL}, - {sr_kemi_sqlang_exec_func_563, NULL}, - {sr_kemi_sqlang_exec_func_564, NULL}, - {sr_kemi_sqlang_exec_func_565, NULL}, - {sr_kemi_sqlang_exec_func_566, NULL}, - {sr_kemi_sqlang_exec_func_567, NULL}, - {sr_kemi_sqlang_exec_func_568, NULL}, - {sr_kemi_sqlang_exec_func_569, NULL}, - {sr_kemi_sqlang_exec_func_570, NULL}, - {sr_kemi_sqlang_exec_func_571, NULL}, - {sr_kemi_sqlang_exec_func_572, NULL}, - {sr_kemi_sqlang_exec_func_573, NULL}, - {sr_kemi_sqlang_exec_func_574, NULL}, - {sr_kemi_sqlang_exec_func_575, NULL}, - {sr_kemi_sqlang_exec_func_576, NULL}, - {sr_kemi_sqlang_exec_func_577, NULL}, - {sr_kemi_sqlang_exec_func_578, NULL}, - {sr_kemi_sqlang_exec_func_579, NULL}, - {sr_kemi_sqlang_exec_func_580, NULL}, - {sr_kemi_sqlang_exec_func_581, NULL}, - {sr_kemi_sqlang_exec_func_582, NULL}, - {sr_kemi_sqlang_exec_func_583, NULL}, - {sr_kemi_sqlang_exec_func_584, NULL}, - {sr_kemi_sqlang_exec_func_585, NULL}, - {sr_kemi_sqlang_exec_func_586, NULL}, - {sr_kemi_sqlang_exec_func_587, NULL}, - {sr_kemi_sqlang_exec_func_588, NULL}, - {sr_kemi_sqlang_exec_func_589, NULL}, - {sr_kemi_sqlang_exec_func_590, NULL}, - {sr_kemi_sqlang_exec_func_591, NULL}, - {sr_kemi_sqlang_exec_func_592, NULL}, - {sr_kemi_sqlang_exec_func_593, NULL}, - {sr_kemi_sqlang_exec_func_594, NULL}, - {sr_kemi_sqlang_exec_func_595, NULL}, - {sr_kemi_sqlang_exec_func_596, NULL}, - {sr_kemi_sqlang_exec_func_597, NULL}, - {sr_kemi_sqlang_exec_func_598, NULL}, - {sr_kemi_sqlang_exec_func_599, NULL}, - {sr_kemi_sqlang_exec_func_600, NULL}, - {sr_kemi_sqlang_exec_func_601, NULL}, - {sr_kemi_sqlang_exec_func_602, NULL}, - {sr_kemi_sqlang_exec_func_603, NULL}, - {sr_kemi_sqlang_exec_func_604, NULL}, - {sr_kemi_sqlang_exec_func_605, NULL}, - {sr_kemi_sqlang_exec_func_606, NULL}, - {sr_kemi_sqlang_exec_func_607, NULL}, - {sr_kemi_sqlang_exec_func_608, NULL}, - {sr_kemi_sqlang_exec_func_609, NULL}, - {sr_kemi_sqlang_exec_func_610, NULL}, - {sr_kemi_sqlang_exec_func_611, NULL}, - {sr_kemi_sqlang_exec_func_612, NULL}, - {sr_kemi_sqlang_exec_func_613, NULL}, - {sr_kemi_sqlang_exec_func_614, NULL}, - {sr_kemi_sqlang_exec_func_615, NULL}, - {sr_kemi_sqlang_exec_func_616, NULL}, - {sr_kemi_sqlang_exec_func_617, NULL}, - {sr_kemi_sqlang_exec_func_618, NULL}, - {sr_kemi_sqlang_exec_func_619, NULL}, - {sr_kemi_sqlang_exec_func_620, NULL}, - {sr_kemi_sqlang_exec_func_621, NULL}, - {sr_kemi_sqlang_exec_func_622, NULL}, - {sr_kemi_sqlang_exec_func_623, NULL}, - {sr_kemi_sqlang_exec_func_624, NULL}, - {sr_kemi_sqlang_exec_func_625, NULL}, - {sr_kemi_sqlang_exec_func_626, NULL}, - {sr_kemi_sqlang_exec_func_627, NULL}, - {sr_kemi_sqlang_exec_func_628, NULL}, - {sr_kemi_sqlang_exec_func_629, NULL}, - {sr_kemi_sqlang_exec_func_630, NULL}, - {sr_kemi_sqlang_exec_func_631, NULL}, - {sr_kemi_sqlang_exec_func_632, NULL}, - {sr_kemi_sqlang_exec_func_633, NULL}, - {sr_kemi_sqlang_exec_func_634, NULL}, - {sr_kemi_sqlang_exec_func_635, NULL}, - {sr_kemi_sqlang_exec_func_636, NULL}, - {sr_kemi_sqlang_exec_func_637, NULL}, - {sr_kemi_sqlang_exec_func_638, NULL}, - {sr_kemi_sqlang_exec_func_639, NULL}, - {sr_kemi_sqlang_exec_func_640, NULL}, - {sr_kemi_sqlang_exec_func_641, NULL}, - {sr_kemi_sqlang_exec_func_642, NULL}, - {sr_kemi_sqlang_exec_func_643, NULL}, - {sr_kemi_sqlang_exec_func_644, NULL}, - {sr_kemi_sqlang_exec_func_645, NULL}, - {sr_kemi_sqlang_exec_func_646, NULL}, - {sr_kemi_sqlang_exec_func_647, NULL}, - {sr_kemi_sqlang_exec_func_648, NULL}, - {sr_kemi_sqlang_exec_func_649, NULL}, - {sr_kemi_sqlang_exec_func_650, NULL}, - {sr_kemi_sqlang_exec_func_651, NULL}, - {sr_kemi_sqlang_exec_func_652, NULL}, - {sr_kemi_sqlang_exec_func_653, NULL}, - {sr_kemi_sqlang_exec_func_654, NULL}, - {sr_kemi_sqlang_exec_func_655, NULL}, - {sr_kemi_sqlang_exec_func_656, NULL}, - {sr_kemi_sqlang_exec_func_657, NULL}, - {sr_kemi_sqlang_exec_func_658, NULL}, - {sr_kemi_sqlang_exec_func_659, NULL}, - {sr_kemi_sqlang_exec_func_660, NULL}, - {sr_kemi_sqlang_exec_func_661, NULL}, - {sr_kemi_sqlang_exec_func_662, NULL}, - {sr_kemi_sqlang_exec_func_663, NULL}, - {sr_kemi_sqlang_exec_func_664, NULL}, - {sr_kemi_sqlang_exec_func_665, NULL}, - {sr_kemi_sqlang_exec_func_666, NULL}, - {sr_kemi_sqlang_exec_func_667, NULL}, - {sr_kemi_sqlang_exec_func_668, NULL}, - {sr_kemi_sqlang_exec_func_669, NULL}, - {sr_kemi_sqlang_exec_func_670, NULL}, - {sr_kemi_sqlang_exec_func_671, NULL}, - {sr_kemi_sqlang_exec_func_672, NULL}, - {sr_kemi_sqlang_exec_func_673, NULL}, - {sr_kemi_sqlang_exec_func_674, NULL}, - {sr_kemi_sqlang_exec_func_675, NULL}, - {sr_kemi_sqlang_exec_func_676, NULL}, - {sr_kemi_sqlang_exec_func_677, NULL}, - {sr_kemi_sqlang_exec_func_678, NULL}, - {sr_kemi_sqlang_exec_func_679, NULL}, - {sr_kemi_sqlang_exec_func_680, NULL}, - {sr_kemi_sqlang_exec_func_681, NULL}, - {sr_kemi_sqlang_exec_func_682, NULL}, - {sr_kemi_sqlang_exec_func_683, NULL}, - {sr_kemi_sqlang_exec_func_684, NULL}, - {sr_kemi_sqlang_exec_func_685, NULL}, - {sr_kemi_sqlang_exec_func_686, NULL}, - {sr_kemi_sqlang_exec_func_687, NULL}, - {sr_kemi_sqlang_exec_func_688, NULL}, - {sr_kemi_sqlang_exec_func_689, NULL}, - {sr_kemi_sqlang_exec_func_690, NULL}, - {sr_kemi_sqlang_exec_func_691, NULL}, - {sr_kemi_sqlang_exec_func_692, NULL}, - {sr_kemi_sqlang_exec_func_693, NULL}, - {sr_kemi_sqlang_exec_func_694, NULL}, - {sr_kemi_sqlang_exec_func_695, NULL}, - {sr_kemi_sqlang_exec_func_696, NULL}, - {sr_kemi_sqlang_exec_func_697, NULL}, - {sr_kemi_sqlang_exec_func_698, NULL}, - {sr_kemi_sqlang_exec_func_699, NULL}, - {sr_kemi_sqlang_exec_func_700, NULL}, - {sr_kemi_sqlang_exec_func_701, NULL}, - {sr_kemi_sqlang_exec_func_702, NULL}, - {sr_kemi_sqlang_exec_func_703, NULL}, - {sr_kemi_sqlang_exec_func_704, NULL}, - {sr_kemi_sqlang_exec_func_705, NULL}, - {sr_kemi_sqlang_exec_func_706, NULL}, - {sr_kemi_sqlang_exec_func_707, NULL}, - {sr_kemi_sqlang_exec_func_708, NULL}, - {sr_kemi_sqlang_exec_func_709, NULL}, - {sr_kemi_sqlang_exec_func_710, NULL}, - {sr_kemi_sqlang_exec_func_711, NULL}, - {sr_kemi_sqlang_exec_func_712, NULL}, - {sr_kemi_sqlang_exec_func_713, NULL}, - {sr_kemi_sqlang_exec_func_714, NULL}, - {sr_kemi_sqlang_exec_func_715, NULL}, - {sr_kemi_sqlang_exec_func_716, NULL}, - {sr_kemi_sqlang_exec_func_717, NULL}, - {sr_kemi_sqlang_exec_func_718, NULL}, - {sr_kemi_sqlang_exec_func_719, NULL}, - {sr_kemi_sqlang_exec_func_720, NULL}, - {sr_kemi_sqlang_exec_func_721, NULL}, - {sr_kemi_sqlang_exec_func_722, NULL}, - {sr_kemi_sqlang_exec_func_723, NULL}, - {sr_kemi_sqlang_exec_func_724, NULL}, - {sr_kemi_sqlang_exec_func_725, NULL}, - {sr_kemi_sqlang_exec_func_726, NULL}, - {sr_kemi_sqlang_exec_func_727, NULL}, - {sr_kemi_sqlang_exec_func_728, NULL}, - {sr_kemi_sqlang_exec_func_729, NULL}, - {sr_kemi_sqlang_exec_func_730, NULL}, - {sr_kemi_sqlang_exec_func_731, NULL}, - {sr_kemi_sqlang_exec_func_732, NULL}, - {sr_kemi_sqlang_exec_func_733, NULL}, - {sr_kemi_sqlang_exec_func_734, NULL}, - {sr_kemi_sqlang_exec_func_735, NULL}, - {sr_kemi_sqlang_exec_func_736, NULL}, - {sr_kemi_sqlang_exec_func_737, NULL}, - {sr_kemi_sqlang_exec_func_738, NULL}, - {sr_kemi_sqlang_exec_func_739, NULL}, - {sr_kemi_sqlang_exec_func_740, NULL}, - {sr_kemi_sqlang_exec_func_741, NULL}, - {sr_kemi_sqlang_exec_func_742, NULL}, - {sr_kemi_sqlang_exec_func_743, NULL}, - {sr_kemi_sqlang_exec_func_744, NULL}, - {sr_kemi_sqlang_exec_func_745, NULL}, - {sr_kemi_sqlang_exec_func_746, NULL}, - {sr_kemi_sqlang_exec_func_747, NULL}, - {sr_kemi_sqlang_exec_func_748, NULL}, - {sr_kemi_sqlang_exec_func_749, NULL}, - {sr_kemi_sqlang_exec_func_750, NULL}, - {sr_kemi_sqlang_exec_func_751, NULL}, - {sr_kemi_sqlang_exec_func_752, NULL}, - {sr_kemi_sqlang_exec_func_753, NULL}, - {sr_kemi_sqlang_exec_func_754, NULL}, - {sr_kemi_sqlang_exec_func_755, NULL}, - {sr_kemi_sqlang_exec_func_756, NULL}, - {sr_kemi_sqlang_exec_func_757, NULL}, - {sr_kemi_sqlang_exec_func_758, NULL}, - {sr_kemi_sqlang_exec_func_759, NULL}, - {sr_kemi_sqlang_exec_func_760, NULL}, - {sr_kemi_sqlang_exec_func_761, NULL}, - {sr_kemi_sqlang_exec_func_762, NULL}, - {sr_kemi_sqlang_exec_func_763, NULL}, - {sr_kemi_sqlang_exec_func_764, NULL}, - {sr_kemi_sqlang_exec_func_765, NULL}, - {sr_kemi_sqlang_exec_func_766, NULL}, - {sr_kemi_sqlang_exec_func_767, NULL}, - {sr_kemi_sqlang_exec_func_768, NULL}, - {sr_kemi_sqlang_exec_func_769, NULL}, - {sr_kemi_sqlang_exec_func_770, NULL}, - {sr_kemi_sqlang_exec_func_771, NULL}, - {sr_kemi_sqlang_exec_func_772, NULL}, - {sr_kemi_sqlang_exec_func_773, NULL}, - {sr_kemi_sqlang_exec_func_774, NULL}, - {sr_kemi_sqlang_exec_func_775, NULL}, - {sr_kemi_sqlang_exec_func_776, NULL}, - {sr_kemi_sqlang_exec_func_777, NULL}, - {sr_kemi_sqlang_exec_func_778, NULL}, - {sr_kemi_sqlang_exec_func_779, NULL}, - {sr_kemi_sqlang_exec_func_780, NULL}, - {sr_kemi_sqlang_exec_func_781, NULL}, - {sr_kemi_sqlang_exec_func_782, NULL}, - {sr_kemi_sqlang_exec_func_783, NULL}, - {sr_kemi_sqlang_exec_func_784, NULL}, - {sr_kemi_sqlang_exec_func_785, NULL}, - {sr_kemi_sqlang_exec_func_786, NULL}, - {sr_kemi_sqlang_exec_func_787, NULL}, - {sr_kemi_sqlang_exec_func_788, NULL}, - {sr_kemi_sqlang_exec_func_789, NULL}, - {sr_kemi_sqlang_exec_func_790, NULL}, - {sr_kemi_sqlang_exec_func_791, NULL}, - {sr_kemi_sqlang_exec_func_792, NULL}, - {sr_kemi_sqlang_exec_func_793, NULL}, - {sr_kemi_sqlang_exec_func_794, NULL}, - {sr_kemi_sqlang_exec_func_795, NULL}, - {sr_kemi_sqlang_exec_func_796, NULL}, - {sr_kemi_sqlang_exec_func_797, NULL}, - {sr_kemi_sqlang_exec_func_798, NULL}, - {sr_kemi_sqlang_exec_func_799, NULL}, - {sr_kemi_sqlang_exec_func_800, NULL}, - {sr_kemi_sqlang_exec_func_801, NULL}, - {sr_kemi_sqlang_exec_func_802, NULL}, - {sr_kemi_sqlang_exec_func_803, NULL}, - {sr_kemi_sqlang_exec_func_804, NULL}, - {sr_kemi_sqlang_exec_func_805, NULL}, - {sr_kemi_sqlang_exec_func_806, NULL}, - {sr_kemi_sqlang_exec_func_807, NULL}, - {sr_kemi_sqlang_exec_func_808, NULL}, - {sr_kemi_sqlang_exec_func_809, NULL}, - {sr_kemi_sqlang_exec_func_810, NULL}, - {sr_kemi_sqlang_exec_func_811, NULL}, - {sr_kemi_sqlang_exec_func_812, NULL}, - {sr_kemi_sqlang_exec_func_813, NULL}, - {sr_kemi_sqlang_exec_func_814, NULL}, - {sr_kemi_sqlang_exec_func_815, NULL}, - {sr_kemi_sqlang_exec_func_816, NULL}, - {sr_kemi_sqlang_exec_func_817, NULL}, - {sr_kemi_sqlang_exec_func_818, NULL}, - {sr_kemi_sqlang_exec_func_819, NULL}, - {sr_kemi_sqlang_exec_func_820, NULL}, - {sr_kemi_sqlang_exec_func_821, NULL}, - {sr_kemi_sqlang_exec_func_822, NULL}, - {sr_kemi_sqlang_exec_func_823, NULL}, - {sr_kemi_sqlang_exec_func_824, NULL}, - {sr_kemi_sqlang_exec_func_825, NULL}, - {sr_kemi_sqlang_exec_func_826, NULL}, - {sr_kemi_sqlang_exec_func_827, NULL}, - {sr_kemi_sqlang_exec_func_828, NULL}, - {sr_kemi_sqlang_exec_func_829, NULL}, - {sr_kemi_sqlang_exec_func_830, NULL}, - {sr_kemi_sqlang_exec_func_831, NULL}, - {sr_kemi_sqlang_exec_func_832, NULL}, - {sr_kemi_sqlang_exec_func_833, NULL}, - {sr_kemi_sqlang_exec_func_834, NULL}, - {sr_kemi_sqlang_exec_func_835, NULL}, - {sr_kemi_sqlang_exec_func_836, NULL}, - {sr_kemi_sqlang_exec_func_837, NULL}, - {sr_kemi_sqlang_exec_func_838, NULL}, - {sr_kemi_sqlang_exec_func_839, NULL}, - {sr_kemi_sqlang_exec_func_840, NULL}, - {sr_kemi_sqlang_exec_func_841, NULL}, - {sr_kemi_sqlang_exec_func_842, NULL}, - {sr_kemi_sqlang_exec_func_843, NULL}, - {sr_kemi_sqlang_exec_func_844, NULL}, - {sr_kemi_sqlang_exec_func_845, NULL}, - {sr_kemi_sqlang_exec_func_846, NULL}, - {sr_kemi_sqlang_exec_func_847, NULL}, - {sr_kemi_sqlang_exec_func_848, NULL}, - {sr_kemi_sqlang_exec_func_849, NULL}, - {sr_kemi_sqlang_exec_func_850, NULL}, - {sr_kemi_sqlang_exec_func_851, NULL}, - {sr_kemi_sqlang_exec_func_852, NULL}, - {sr_kemi_sqlang_exec_func_853, NULL}, - {sr_kemi_sqlang_exec_func_854, NULL}, - {sr_kemi_sqlang_exec_func_855, NULL}, - {sr_kemi_sqlang_exec_func_856, NULL}, - {sr_kemi_sqlang_exec_func_857, NULL}, - {sr_kemi_sqlang_exec_func_858, NULL}, - {sr_kemi_sqlang_exec_func_859, NULL}, - {sr_kemi_sqlang_exec_func_860, NULL}, - {sr_kemi_sqlang_exec_func_861, NULL}, - {sr_kemi_sqlang_exec_func_862, NULL}, - {sr_kemi_sqlang_exec_func_863, NULL}, - {sr_kemi_sqlang_exec_func_864, NULL}, - {sr_kemi_sqlang_exec_func_865, NULL}, - {sr_kemi_sqlang_exec_func_866, NULL}, - {sr_kemi_sqlang_exec_func_867, NULL}, - {sr_kemi_sqlang_exec_func_868, NULL}, - {sr_kemi_sqlang_exec_func_869, NULL}, - {sr_kemi_sqlang_exec_func_870, NULL}, - {sr_kemi_sqlang_exec_func_871, NULL}, - {sr_kemi_sqlang_exec_func_872, NULL}, - {sr_kemi_sqlang_exec_func_873, NULL}, - {sr_kemi_sqlang_exec_func_874, NULL}, - {sr_kemi_sqlang_exec_func_875, NULL}, - {sr_kemi_sqlang_exec_func_876, NULL}, - {sr_kemi_sqlang_exec_func_877, NULL}, - {sr_kemi_sqlang_exec_func_878, NULL}, - {sr_kemi_sqlang_exec_func_879, NULL}, - {sr_kemi_sqlang_exec_func_880, NULL}, - {sr_kemi_sqlang_exec_func_881, NULL}, - {sr_kemi_sqlang_exec_func_882, NULL}, - {sr_kemi_sqlang_exec_func_883, NULL}, - {sr_kemi_sqlang_exec_func_884, NULL}, - {sr_kemi_sqlang_exec_func_885, NULL}, - {sr_kemi_sqlang_exec_func_886, NULL}, - {sr_kemi_sqlang_exec_func_887, NULL}, - {sr_kemi_sqlang_exec_func_888, NULL}, - {sr_kemi_sqlang_exec_func_889, NULL}, - {sr_kemi_sqlang_exec_func_890, NULL}, - {sr_kemi_sqlang_exec_func_891, NULL}, - {sr_kemi_sqlang_exec_func_892, NULL}, - {sr_kemi_sqlang_exec_func_893, NULL}, - {sr_kemi_sqlang_exec_func_894, NULL}, - {sr_kemi_sqlang_exec_func_895, NULL}, - {sr_kemi_sqlang_exec_func_896, NULL}, - {sr_kemi_sqlang_exec_func_897, NULL}, - {sr_kemi_sqlang_exec_func_898, NULL}, - {sr_kemi_sqlang_exec_func_899, NULL}, - {sr_kemi_sqlang_exec_func_900, NULL}, - {sr_kemi_sqlang_exec_func_901, NULL}, - {sr_kemi_sqlang_exec_func_902, NULL}, - {sr_kemi_sqlang_exec_func_903, NULL}, - {sr_kemi_sqlang_exec_func_904, NULL}, - {sr_kemi_sqlang_exec_func_905, NULL}, - {sr_kemi_sqlang_exec_func_906, NULL}, - {sr_kemi_sqlang_exec_func_907, NULL}, - {sr_kemi_sqlang_exec_func_908, NULL}, - {sr_kemi_sqlang_exec_func_909, NULL}, - {sr_kemi_sqlang_exec_func_910, NULL}, - {sr_kemi_sqlang_exec_func_911, NULL}, - {sr_kemi_sqlang_exec_func_912, NULL}, - {sr_kemi_sqlang_exec_func_913, NULL}, - {sr_kemi_sqlang_exec_func_914, NULL}, - {sr_kemi_sqlang_exec_func_915, NULL}, - {sr_kemi_sqlang_exec_func_916, NULL}, - {sr_kemi_sqlang_exec_func_917, NULL}, - {sr_kemi_sqlang_exec_func_918, NULL}, - {sr_kemi_sqlang_exec_func_919, NULL}, - {sr_kemi_sqlang_exec_func_920, NULL}, - {sr_kemi_sqlang_exec_func_921, NULL}, - {sr_kemi_sqlang_exec_func_922, NULL}, - {sr_kemi_sqlang_exec_func_923, NULL}, - {sr_kemi_sqlang_exec_func_924, NULL}, - {sr_kemi_sqlang_exec_func_925, NULL}, - {sr_kemi_sqlang_exec_func_926, NULL}, - {sr_kemi_sqlang_exec_func_927, NULL}, - {sr_kemi_sqlang_exec_func_928, NULL}, - {sr_kemi_sqlang_exec_func_929, NULL}, - {sr_kemi_sqlang_exec_func_930, NULL}, - {sr_kemi_sqlang_exec_func_931, NULL}, - {sr_kemi_sqlang_exec_func_932, NULL}, - {sr_kemi_sqlang_exec_func_933, NULL}, - {sr_kemi_sqlang_exec_func_934, NULL}, - {sr_kemi_sqlang_exec_func_935, NULL}, - {sr_kemi_sqlang_exec_func_936, NULL}, - {sr_kemi_sqlang_exec_func_937, NULL}, - {sr_kemi_sqlang_exec_func_938, NULL}, - {sr_kemi_sqlang_exec_func_939, NULL}, - {sr_kemi_sqlang_exec_func_940, NULL}, - {sr_kemi_sqlang_exec_func_941, NULL}, - {sr_kemi_sqlang_exec_func_942, NULL}, - {sr_kemi_sqlang_exec_func_943, NULL}, - {sr_kemi_sqlang_exec_func_944, NULL}, - {sr_kemi_sqlang_exec_func_945, NULL}, - {sr_kemi_sqlang_exec_func_946, NULL}, - {sr_kemi_sqlang_exec_func_947, NULL}, - {sr_kemi_sqlang_exec_func_948, NULL}, - {sr_kemi_sqlang_exec_func_949, NULL}, - {sr_kemi_sqlang_exec_func_950, NULL}, - {sr_kemi_sqlang_exec_func_951, NULL}, - {sr_kemi_sqlang_exec_func_952, NULL}, - {sr_kemi_sqlang_exec_func_953, NULL}, - {sr_kemi_sqlang_exec_func_954, NULL}, - {sr_kemi_sqlang_exec_func_955, NULL}, - {sr_kemi_sqlang_exec_func_956, NULL}, - {sr_kemi_sqlang_exec_func_957, NULL}, - {sr_kemi_sqlang_exec_func_958, NULL}, - {sr_kemi_sqlang_exec_func_959, NULL}, - {sr_kemi_sqlang_exec_func_960, NULL}, - {sr_kemi_sqlang_exec_func_961, NULL}, - {sr_kemi_sqlang_exec_func_962, NULL}, - {sr_kemi_sqlang_exec_func_963, NULL}, - {sr_kemi_sqlang_exec_func_964, NULL}, - {sr_kemi_sqlang_exec_func_965, NULL}, - {sr_kemi_sqlang_exec_func_966, NULL}, - {sr_kemi_sqlang_exec_func_967, NULL}, - {sr_kemi_sqlang_exec_func_968, NULL}, - {sr_kemi_sqlang_exec_func_969, NULL}, - {sr_kemi_sqlang_exec_func_970, NULL}, - {sr_kemi_sqlang_exec_func_971, NULL}, - {sr_kemi_sqlang_exec_func_972, NULL}, - {sr_kemi_sqlang_exec_func_973, NULL}, - {sr_kemi_sqlang_exec_func_974, NULL}, - {sr_kemi_sqlang_exec_func_975, NULL}, - {sr_kemi_sqlang_exec_func_976, NULL}, - {sr_kemi_sqlang_exec_func_977, NULL}, - {sr_kemi_sqlang_exec_func_978, NULL}, - {sr_kemi_sqlang_exec_func_979, NULL}, - {sr_kemi_sqlang_exec_func_980, NULL}, - {sr_kemi_sqlang_exec_func_981, NULL}, - {sr_kemi_sqlang_exec_func_982, NULL}, - {sr_kemi_sqlang_exec_func_983, NULL}, - {sr_kemi_sqlang_exec_func_984, NULL}, - {sr_kemi_sqlang_exec_func_985, NULL}, - {sr_kemi_sqlang_exec_func_986, NULL}, - {sr_kemi_sqlang_exec_func_987, NULL}, - {sr_kemi_sqlang_exec_func_988, NULL}, - {sr_kemi_sqlang_exec_func_989, NULL}, - {sr_kemi_sqlang_exec_func_990, NULL}, - {sr_kemi_sqlang_exec_func_991, NULL}, - {sr_kemi_sqlang_exec_func_992, NULL}, - {sr_kemi_sqlang_exec_func_993, NULL}, - {sr_kemi_sqlang_exec_func_994, NULL}, - {sr_kemi_sqlang_exec_func_995, NULL}, - {sr_kemi_sqlang_exec_func_996, NULL}, - {sr_kemi_sqlang_exec_func_997, NULL}, - {sr_kemi_sqlang_exec_func_998, NULL}, - {sr_kemi_sqlang_exec_func_999, NULL}, - {sr_kemi_sqlang_exec_func_1000, NULL}, - {sr_kemi_sqlang_exec_func_1001, NULL}, - {sr_kemi_sqlang_exec_func_1002, NULL}, - {sr_kemi_sqlang_exec_func_1003, NULL}, - {sr_kemi_sqlang_exec_func_1004, NULL}, - {sr_kemi_sqlang_exec_func_1005, NULL}, - {sr_kemi_sqlang_exec_func_1006, NULL}, - {sr_kemi_sqlang_exec_func_1007, NULL}, - {sr_kemi_sqlang_exec_func_1008, NULL}, - {sr_kemi_sqlang_exec_func_1009, NULL}, - {sr_kemi_sqlang_exec_func_1010, NULL}, - {sr_kemi_sqlang_exec_func_1011, NULL}, - {sr_kemi_sqlang_exec_func_1012, NULL}, - {sr_kemi_sqlang_exec_func_1013, NULL}, - {sr_kemi_sqlang_exec_func_1014, NULL}, - {sr_kemi_sqlang_exec_func_1015, NULL}, - {sr_kemi_sqlang_exec_func_1016, NULL}, - {sr_kemi_sqlang_exec_func_1017, NULL}, - {sr_kemi_sqlang_exec_func_1018, NULL}, - {sr_kemi_sqlang_exec_func_1019, NULL}, - {sr_kemi_sqlang_exec_func_1020, NULL}, - {sr_kemi_sqlang_exec_func_1021, NULL}, - {sr_kemi_sqlang_exec_func_1022, NULL}, - {sr_kemi_sqlang_exec_func_1023, NULL}, {NULL, NULL}}; - -/** - * - */ -sr_kemi_t *sr_kemi_sqlang_export_get(int idx) -{ - if(idx < 0 || idx >= SR_KEMI_SQLANG_EXPORT_SIZE) - return NULL; - return _sr_kemi_sqlang_export_list[idx].ket; -} - -/** - * - */ -SQFUNCTION sr_kemi_sqlang_export_associate(sr_kemi_t *ket) -{ - int i; - for(i = 0; i < SR_KEMI_SQLANG_EXPORT_SIZE; i++) { - if(_sr_kemi_sqlang_export_list[i].ket == NULL) { - _sr_kemi_sqlang_export_list[i].ket = ket; - return _sr_kemi_sqlang_export_list[i].pfunc; - } - if(_sr_kemi_sqlang_export_list[i].ket == ket) { - return _sr_kemi_sqlang_export_list[i].pfunc; - } - } - LM_ERR("no more indexing slots\n"); - return NULL; -} diff --git a/src/modules/app_sqlang/app_sqlang_kemi_export.h b/src/modules/app_sqlang/app_sqlang_kemi_export.h deleted file mode 100644 index 1b549d9e1..000000000 --- a/src/modules/app_sqlang/app_sqlang_kemi_export.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (C) 2017 Daniel-Constantin Mierla (asipto.com) - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -/** - * this file is generated - do not edit - */ - -#ifndef __APP_SQLANG_KEMI_EXPORT_H__ -#define __APP_SQLANG_KEMI_EXPORT_H__ - -#include -#include "../../core/kemi.h" - -#define SR_KEMI_SQLANG_EXPORT_SIZE 1024 - -typedef struct sr_kemi_sqlang_export -{ - SQFUNCTION pfunc; - sr_kemi_t *ket; -} sr_kemi_sqlang_export_t; - -sr_kemi_t *sr_kemi_sqlang_export_get(int idx); -SQFUNCTION sr_kemi_sqlang_export_associate(sr_kemi_t *ket); - -#endif diff --git a/src/modules/app_sqlang/app_sqlang_mod.c b/src/modules/app_sqlang/app_sqlang_mod.c deleted file mode 100644 index ff095db4b..000000000 --- a/src/modules/app_sqlang/app_sqlang_mod.c +++ /dev/null @@ -1,574 +0,0 @@ -/** - * Copyright (C) 2017 Daniel-Constantin Mierla (asipto.com) - * - * This file is part of Kamailio, a free SIP server. - * - * This file 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 - * - * - * This file 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 - * - */ - -#include -#include -#include -#include - -#include "../../core/sr_module.h" -#include "../../core/dprint.h" -#include "../../core/mod_fix.h" -#include "../../core/kemi.h" - -#include "app_sqlang_api.h" - -MODULE_VERSION - -static int mod_init(void); -static int child_init(int rank); -static void mod_destroy(void); - -static int w_app_sqlang_dostring(sip_msg_t *msg, char *script, char *extra); -static int w_app_sqlang_dofile(sip_msg_t *msg, char *script, char *extra); -static int w_app_sqlang_runstring(sip_msg_t *msg, char *script, char *extra); -static int w_app_sqlang_run( - sip_msg_t *msg, char *func, char *p1, char *p2, char *p3); -static int w_app_sqlang_run0( - sip_msg_t *msg, char *func, char *p1, char *p2, char *p3); -static int w_app_sqlang_run1( - sip_msg_t *msg, char *func, char *p1, char *p2, char *p3); -static int w_app_sqlang_run2( - sip_msg_t *msg, char *func, char *p1, char *p2, char *p3); -static int w_app_sqlang_run3( - sip_msg_t *msg, char *func, char *p1, char *p2, char *p3); - -static int fixup_sqlang_run(void **param, int param_no); - -extern str _sr_sqlang_load_file; - -/* clang-format off */ -static cmd_export_t cmds[]={ - {"sqlang_dostring", (cmd_function)w_app_sqlang_dostring, 1, fixup_spve_null, - 0, ANY_ROUTE}, - {"sqlang_dofile", (cmd_function)w_app_sqlang_dofile, 1, fixup_spve_null, - 0, ANY_ROUTE}, - {"sqlang_runstring", (cmd_function)w_app_sqlang_runstring, 1, fixup_spve_null, - 0, ANY_ROUTE}, - {"sqlang_run", (cmd_function)w_app_sqlang_run0, 1, fixup_sqlang_run, - 0, ANY_ROUTE}, - {"sqlang_run", (cmd_function)w_app_sqlang_run1, 2, fixup_sqlang_run, - 0, ANY_ROUTE}, - {"sqlang_run", (cmd_function)w_app_sqlang_run2, 3, fixup_sqlang_run, - 0, ANY_ROUTE}, - {"sqlang_run", (cmd_function)w_app_sqlang_run3, 4, fixup_sqlang_run, - 0, ANY_ROUTE}, - - {0, 0, 0, 0, 0, 0} -}; - -static param_export_t params[]={ - {"load", PARAM_STR, &_sr_sqlang_load_file}, - {0, 0, 0} -}; - -struct module_exports exports = { - "app_sqlang", - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* exported functions */ - params, /* exported parameters */ - 0, /* exported rpc functions */ - 0, /* exported pseudo-variables */ - 0, /* response handlingfunction */ - mod_init, /* module init function */ - child_init, /* per child init function */ - mod_destroy /* module destroy function */ -}; -/* clang-format on */ - -/** - * init module function - */ -static int mod_init(void) -{ - if(sqlang_sr_init_mod() < 0) - return -1; - - if(app_sqlang_init_rpc() < 0) { - LM_ERR("failed to register RPC commands\n"); - return -1; - } - - return 0; -} - -/** - * init module children - */ -static int child_init(int rank) -{ - if(rank == PROC_INIT) - return 0; - return sqlang_sr_init_child(); -} - -/** - * destroy module function - */ -static void mod_destroy(void) -{ - sqlang_sr_destroy(); -} - -/** - * - */ -int sr_kemi_config_engine_sqlang( - sip_msg_t *msg, int rtype, str *rname, str *rparam) -{ - int ret; - - ret = -1; - if(rtype == REQUEST_ROUTE) { - if(rname != NULL && rname->s != NULL) { - ret = app_sqlang_run_ex(msg, rname->s, - (rparam && rparam->s) ? rparam->s : NULL, NULL, NULL, 0); - } else { - ret = app_sqlang_run_ex( - msg, "ksr_request_route", NULL, NULL, NULL, 1); - } - } else if(rtype == CORE_ONREPLY_ROUTE) { - if(kemi_reply_route_callback.len > 0) { - ret = app_sqlang_run_ex( - msg, kemi_reply_route_callback.s, NULL, NULL, NULL, 0); - } - } else if(rtype == BRANCH_ROUTE) { - if(rname != NULL && rname->s != NULL) { - ret = app_sqlang_run_ex(msg, rname->s, NULL, NULL, NULL, 0); - } - } else if(rtype == FAILURE_ROUTE) { - if(rname != NULL && rname->s != NULL) { - ret = app_sqlang_run_ex(msg, rname->s, NULL, NULL, NULL, 0); - } - } else if(rtype == BRANCH_FAILURE_ROUTE) { - if(rname != NULL && rname->s != NULL) { - ret = app_sqlang_run_ex(msg, rname->s, NULL, NULL, NULL, 0); - } - } else if(rtype == TM_ONREPLY_ROUTE) { - if(rname != NULL && rname->s != NULL) { - ret = app_sqlang_run_ex(msg, rname->s, NULL, NULL, NULL, 0); - } - } else if(rtype == ONSEND_ROUTE) { - if(kemi_onsend_route_callback.len > 0) { - ret = app_sqlang_run_ex( - msg, kemi_onsend_route_callback.s, NULL, NULL, NULL, 0); - } - return 1; - } else if(rtype == EVENT_ROUTE) { - if(rname != NULL && rname->s != NULL) { - ret = app_sqlang_run_ex(msg, rname->s, - (rparam && rparam->s) ? rparam->s : NULL, NULL, NULL, 0); - } - } else { - if(rname != NULL) { - LM_ERR("route type %d with name [%.*s] not implemented\n", rtype, - rname->len, rname->s); - } else { - LM_ERR("route type %d with no name not implemented\n", rtype); - } - } - - if(rname != NULL) { - LM_DBG("execution of route type %d with name [%.*s] returned %d\n", - rtype, rname->len, rname->s, ret); - } else { - LM_DBG("execution of route type %d with no name returned %d\n", rtype, - ret); - } - - return 1; -} - -#define SQLANG_BUF_STACK_SIZE 1024 -static char _sqlang_buf_stack[4][SQLANG_BUF_STACK_SIZE]; - -/** - * - */ -static int ki_app_sqlang_dostring(sip_msg_t *msg, str *script) -{ - if(script == NULL || script->s == NULL - || script->len >= SQLANG_BUF_STACK_SIZE - 1) { - LM_ERR("script too short or too long %d\n", (script) ? script->len : 0); - return -1; - } - if(!sqlang_sr_initialized()) { - LM_ERR("sqlang env not initialized"); - return -1; - } - memcpy(_sqlang_buf_stack[0], script->s, script->len); - _sqlang_buf_stack[0][script->len] = '\0'; - return app_sqlang_dostring(msg, _sqlang_buf_stack[0]); -} - -/** - * - */ -static int w_app_sqlang_dostring(struct sip_msg *msg, char *script, char *extra) -{ - str s; - if(fixup_get_svalue(msg, (gparam_p)script, &s) < 0) { - LM_ERR("cannot get the script\n"); - return -1; - } - return ki_app_sqlang_dostring(msg, &s); -} - -/** - * - */ -static int ki_app_sqlang_dofile(sip_msg_t *msg, str *script) -{ - if(script == NULL || script->s == NULL - || script->len >= SQLANG_BUF_STACK_SIZE - 1) { - LM_ERR("script too short or too long %d\n", (script) ? script->len : 0); - return -1; - } - if(!sqlang_sr_initialized()) { - LM_ERR("sqlang env not initialized"); - return -1; - } - memcpy(_sqlang_buf_stack[0], script->s, script->len); - _sqlang_buf_stack[0][script->len] = '\0'; - return app_sqlang_dofile(msg, _sqlang_buf_stack[0]); -} - -/** - * - */ -static int w_app_sqlang_dofile(struct sip_msg *msg, char *script, char *extra) -{ - str s; - if(fixup_get_svalue(msg, (gparam_p)script, &s) < 0) { - LM_ERR("cannot get the script\n"); - return -1; - } - return ki_app_sqlang_dofile(msg, &s); -} - -/** - * - */ -static int ki_app_sqlang_runstring(sip_msg_t *msg, str *script) -{ - if(script == NULL || script->s == NULL - || script->len >= SQLANG_BUF_STACK_SIZE - 1) { - LM_ERR("script too short or too long %d\n", (script) ? script->len : 0); - return -1; - } - if(!sqlang_sr_initialized()) { - LM_ERR("sqlang env not initialized"); - return -1; - } - memcpy(_sqlang_buf_stack[0], script->s, script->len); - _sqlang_buf_stack[0][script->len] = '\0'; - return app_sqlang_runstring(msg, _sqlang_buf_stack[0]); -} - -/** - * - */ -static int w_app_sqlang_runstring( - struct sip_msg *msg, char *script, char *extra) -{ - str s; - if(fixup_get_svalue(msg, (gparam_p)script, &s) < 0) { - LM_ERR("cannot get the script\n"); - return -1; - } - return ki_app_sqlang_runstring(msg, &s); -} - -/** - * - */ -static int w_app_sqlang_run( - struct sip_msg *msg, char *func, char *p1, char *p2, char *p3) -{ - str s; - if(!sqlang_sr_initialized()) { - LM_ERR("sqlang env not initialized"); - return -1; - } - if(fixup_get_svalue(msg, (gparam_p)func, &s) < 0) { - LM_ERR("cannot get the function\n"); - return -1; - } - if(s.len >= SQLANG_BUF_STACK_SIZE - 1) { - LM_ERR("function too long %d\n", s.len); - return -1; - } - memcpy(_sqlang_buf_stack[0], s.s, s.len); - _sqlang_buf_stack[0][s.len] = '\0'; - - if(p1 != NULL) { - if(fixup_get_svalue(msg, (gparam_p)p1, &s) < 0) { - LM_ERR("cannot get p1\n"); - return -1; - } - if(s.len >= SQLANG_BUF_STACK_SIZE - 1) { - LM_ERR("p1 too long %d\n", s.len); - return -1; - } - memcpy(_sqlang_buf_stack[1], s.s, s.len); - _sqlang_buf_stack[1][s.len] = '\0'; - - if(p2 != NULL) { - if(fixup_get_svalue(msg, (gparam_p)p2, &s) < 0) { - LM_ERR("cannot get p2\n"); - return -1; - } - if(s.len >= SQLANG_BUF_STACK_SIZE - 1) { - LM_ERR("p2 too long %d\n", s.len); - return -1; - } - memcpy(_sqlang_buf_stack[2], s.s, s.len); - _sqlang_buf_stack[2][s.len] = '\0'; - - if(p3 != NULL) { - if(fixup_get_svalue(msg, (gparam_p)p3, &s) < 0) { - LM_ERR("cannot get p3\n"); - return -1; - } - if(s.len >= SQLANG_BUF_STACK_SIZE - 1) { - LM_ERR("p3 too long %d\n", s.len); - return -1; - } - memcpy(_sqlang_buf_stack[3], s.s, s.len); - _sqlang_buf_stack[3][s.len] = '\0'; - } - } else { - p3 = NULL; - } - } else { - p2 = NULL; - p3 = NULL; - } - - return app_sqlang_run(msg, _sqlang_buf_stack[0], - (p1 != NULL) ? _sqlang_buf_stack[1] : NULL, - (p2 != NULL) ? _sqlang_buf_stack[2] : NULL, - (p3 != NULL) ? _sqlang_buf_stack[3] : NULL); -} - -static int w_app_sqlang_run0( - struct sip_msg *msg, char *func, char *p1, char *p2, char *p3) -{ - return w_app_sqlang_run(msg, func, NULL, NULL, NULL); -} - -static int w_app_sqlang_run1( - struct sip_msg *msg, char *func, char *p1, char *p2, char *p3) -{ - return w_app_sqlang_run(msg, func, p1, NULL, NULL); -} - -static int w_app_sqlang_run2( - struct sip_msg *msg, char *func, char *p1, char *p2, char *p3) -{ - return w_app_sqlang_run(msg, func, p1, p2, NULL); -} - -static int w_app_sqlang_run3( - struct sip_msg *msg, char *func, char *p1, char *p2, char *p3) -{ - return w_app_sqlang_run(msg, func, p1, p2, p3); -} - -static int fixup_sqlang_run(void **param, int param_no) -{ - return fixup_spve_null(param, 1); -} - -/** - * - */ -static int ki_app_sqlang_run(sip_msg_t *msg, str *func) -{ - if(func == NULL || func->s == NULL || func->len < 0) { - LM_ERR("invalid function name\n"); - return -1; - } - if(func->s[func->len] != '\0') { - LM_ERR("invalid terminated function name\n"); - return -1; - } - return app_sqlang_run(msg, func->s, NULL, NULL, NULL); -} - -/** - * - */ -static int ki_app_sqlang_run_p1(sip_msg_t *msg, str *func, str *p1) -{ - if(func == NULL || func->s == NULL || func->len <= 0) { - LM_ERR("invalid function name\n"); - return -1; - } - if(func->s[func->len] != '\0') { - LM_ERR("invalid terminated function name\n"); - return -1; - } - if(p1 == NULL || p1->s == NULL || p1->len < 0) { - LM_ERR("invalid p1 value\n"); - return -1; - } - if(p1->s[p1->len] != '\0') { - LM_ERR("invalid terminated p1 value\n"); - return -1; - } - return app_sqlang_run(msg, func->s, p1->s, NULL, NULL); -} - -/** - * - */ -static int ki_app_sqlang_run_p2(sip_msg_t *msg, str *func, str *p1, str *p2) -{ - if(func == NULL || func->s == NULL || func->len <= 0) { - LM_ERR("invalid function name\n"); - return -1; - } - if(func->s[func->len] != '\0') { - LM_ERR("invalid terminated function name\n"); - return -1; - } - if(p1 == NULL || p1->s == NULL || p1->len < 0) { - LM_ERR("invalid p1 value\n"); - return -1; - } - if(p1->s[p1->len] != '\0') { - LM_ERR("invalid terminated p1 value\n"); - return -1; - } - if(p2 == NULL || p2->s == NULL || p2->len < 0) { - LM_ERR("invalid p2 value\n"); - return -1; - } - if(p2->s[p2->len] != '\0') { - LM_ERR("invalid terminated p2 value\n"); - return -1; - } - return app_sqlang_run(msg, func->s, p1->s, p2->s, NULL); -} - -/** - * - */ -static int ki_app_sqlang_run_p3( - sip_msg_t *msg, str *func, str *p1, str *p2, str *p3) -{ - if(func == NULL || func->s == NULL || func->len <= 0) { - LM_ERR("invalid function name\n"); - return -1; - } - if(func->s[func->len] != '\0') { - LM_ERR("invalid terminated function name\n"); - return -1; - } - if(p1 == NULL || p1->s == NULL || p1->len < 0) { - LM_ERR("invalid p1 value\n"); - return -1; - } - if(p1->s[p1->len] != '\0') { - LM_ERR("invalid terminated p1 value\n"); - return -1; - } - if(p2 == NULL || p2->s == NULL || p2->len < 0) { - LM_ERR("invalid p2 value\n"); - return -1; - } - if(p2->s[p2->len] != '\0') { - LM_ERR("invalid terminated p2 value\n"); - return -1; - } - if(p3 == NULL || p3->s == NULL || p3->len < 0) { - LM_ERR("invalid p3 value\n"); - return -1; - } - if(p3->s[p3->len] != '\0') { - LM_ERR("invalid terminated p3 value\n"); - return -1; - } - return app_sqlang_run(msg, func->s, p1->s, p2->s, p3->s); -} - -/** - * - */ -/* clang-format off */ -static sr_kemi_t sr_kemi_app_sqlang_exports[] = { - { str_init("app_sqlang"), str_init("dostring"), - SR_KEMIP_INT, ki_app_sqlang_dostring, - { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } - }, - { str_init("app_sqlang"), str_init("dofile"), - SR_KEMIP_INT, ki_app_sqlang_dofile, - { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } - }, - { str_init("app_sqlang"), str_init("runstring"), - SR_KEMIP_INT, ki_app_sqlang_runstring, - { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } - }, - { str_init("app_sqlang"), str_init("run"), - SR_KEMIP_INT, ki_app_sqlang_run, - { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } - }, - { str_init("app_sqlang"), str_init("run_p1"), - SR_KEMIP_INT, ki_app_sqlang_run_p1, - { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } - }, - { str_init("app_sqlang"), str_init("run_p2"), - SR_KEMIP_INT, ki_app_sqlang_run_p2, - { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, - SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } - }, - { str_init("app_sqlang"), str_init("run_p3"), - SR_KEMIP_INT, ki_app_sqlang_run_p3, - { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, - SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE } - }, - - { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } } -}; -/* clang-format on */ - - -/** - * - */ -int mod_register(char *path, int *dlflags, void *p1, void *p2) -{ - str ename = str_init("sqlang"); - - *dlflags = RTLD_NOW | RTLD_GLOBAL; - - sr_kemi_eng_register(&ename, sr_kemi_config_engine_sqlang); - sr_kemi_modules_add(sr_kemi_app_sqlang_exports); - - return 0; -} diff --git a/src/modules/app_sqlang/doc/app_sqlang_admin.xml b/src/modules/app_sqlang/doc/app_sqlang_admin.xml deleted file mode 100644 index 498052e96..000000000 --- a/src/modules/app_sqlang/doc/app_sqlang_admin.xml +++ /dev/null @@ -1,288 +0,0 @@ - - - -%docentities; - -]> - - - - - - &adminguide; - -
- Overview - - This module allows executing Squirrel Language (SQLang) scripts from - config file. It exports all KEMI functions to SQLang in order to access - the current processed SIP message. These functions are within SQLang - object 'KSR' (a table object). - - - It includes the Squirrel Language engine (http://www.squirrel-lang.org). - Exported API from SIP router to SQLang is documented in the dokuwiki. - - - The module has two SQLang contexts: - - - - first is used for functions sqlang_dofile() - and sqlang_dostring(). - - - - - second is used for function sqlan_run() - and parameter 'load'. Therefore sqlang_run() cannot execute functions - from scripts loaded via sqlang_dofile() in config. This is kind of - caching mode, avoiding reading file every time, but you must be sure - you do not have something that is executed by default and requires - access to SIP message. This environment is also used by KEMI - framework for the config SIP routing functions. - - - - -
-
- Dependencies -
- &kamailio; Modules - - The following modules must be loaded before this module: - - - - none. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &kamailio; with this module loaded: - - - - none - - - - -
-
-
- Parameters -
- <varname>load</varname> (str) - - Set the path to the SQLang file to be loaded at startup. Then you - can use sqlang_run(function, params) to execute a function from the - script at runtime. If you use it for KEMI configuration, - then it has to include the required functions. - - - - Default value is null. - - - - Set <varname>load</varname> parameter - -... -modparam("app_sqlang", "load", "/usr/local/etc/kamailio/sqlang/myscript.sq") -... - - -
- -
- -
- Functions -
- - <function moreinfo="none">sqlang_dofile(path)</function> - - - Note: not implemented yet. - - - Execute the SQLang script stored in 'path'. The parameter can be - a string with pseudo-variables evaluated at runtime. - - - <function>sqlang_dofile</function> usage - -... -sqlang_dofile("/usr/local/etc/kamailio/sqlang/myscript.sq"); -... - - -
- -
- - <function moreinfo="none">sqlang_dostring(script)</function> - - - Note: not implemented yet. - - - Execute the Squirrel script stored in parameter. The parameter can be - a string with pseudo-variables. - - - <function>sqlang_dostring</function> usage - -... -if(!sqlang_dostring('KSR.dbg("test message\n")')) -{ - xdbg("SCRIPT: failed to execute squirrel script!\n"); -} -... - - -
- -
- - <function moreinfo="none">sqlang_run(function [, params])</function> - - - Execute the Squirrel function 'func' giving params as parameters. There - can be up to 3 string parameters. The function must exist in the - script loaded at startup via parameter 'load'. Parameters can be - strings with pseudo-variables that are evaluated at runtime. - - - <function>sqlang_run</function> usage - -... -if(!sqlang_run("sqlang_append_fu_to_reply")) -{ - xdbg("SCRIPT: failed to execute squirrel function!\n"); -} -... -sqlang_run("sqlang_funcx", "$rU", "2"); -... - - -
- -
- - <function moreinfo="none">sqlang_runstring(script)</function> - - - Note: not implemented yet. - - - Execute the SQLang script stored in parameter. The parameter can be - a string with pseudo-variables. The script is executed in JS context - specific to loaded JS files at startup. - - - <function>sqlang_runstring</function> usage - -... -if(!sqlang_runstring('KSR.dbg("Hello World from $fU\n")')) -{ - xdbg("failed to execute squirrel script!\n"); -} -... - - -
- -
- -
- RPC Commands -
- - <function moreinfo="none">app_sqlang.reload</function> - - - Marks the need to reload the SQLang script pointed by 'load' - parameter. The actual reload is done by every working process when - the next call to sqlang_run() function or KEMI config is executed. - - - Name: app_sqlang.reload - - Parameters: none - - Example: - - -... -&kamcmd; app_sqlang.reload -... - -
-
- - <function moreinfo="none">app_sqlang.api_list</function> - - - List the functions available via Kemi framework. - - - Name: app_sqlang.api_list - - Parameters: none - - Example: - - -... -&kamcmd; app_sqlang.api_list -... - -
-
- -
- Example of usage - - Create your SQLang script and stored on file system, - say: '/usr/local/etc/kamailio/sqlang/myscript.sq'. - - -... -function sr_append_fu_to_reply() -{ - KSR.hdr.append_to_reply("P-From: " + KSR.pv.get("$fu") + "\r\n"); -} -... - - - Load the script via parameter 'load' and execute function - via sqlang_run(...). - - -... -modparam("app_sqlang", "load", "/usr/local/etc/kamailio/sqlang/myscript.sq") -... -request_route { - ... - if(!sqlang_run("sr_append_fu_to_reply")) - { - xdbg("SCRIPT: failed to execute squirrel function!\n"); - } - ... -} -... - -
-
- diff --git a/src/modules/app_sqlang/squirrel/include/sqconfig.h b/src/modules/app_sqlang/squirrel/include/sqconfig.h deleted file mode 100644 index 2d26504a3..000000000 --- a/src/modules/app_sqlang/squirrel/include/sqconfig.h +++ /dev/null @@ -1,152 +0,0 @@ - -#ifdef _SQ64 - -#ifdef _MSC_VER -typedef __int64 SQInteger; -typedef unsigned __int64 SQUnsignedInteger; -typedef unsigned __int64 SQHash; /*should be the same size of a pointer*/ -#else -typedef long long SQInteger; -typedef unsigned long long SQUnsignedInteger; -typedef unsigned long long SQHash; /*should be the same size of a pointer*/ -#endif -typedef int SQInt32; -typedef unsigned int SQUnsignedInteger32; -#else -typedef int SQInteger; -typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/ -typedef unsigned int - SQUnsignedInteger32; /*must be 32 bits(also on 64bits processors)*/ -typedef unsigned int SQUnsignedInteger; -typedef unsigned int SQHash; /*should be the same size of a pointer*/ -#endif - - -#ifdef SQUSEDOUBLE -typedef double SQFloat; -#else -typedef float SQFloat; -#endif - -#if defined(SQUSEDOUBLE) && !defined(_SQ64) \ - || !defined(SQUSEDOUBLE) && defined(_SQ64) -#ifdef _MSC_VER -typedef __int64 SQRawObjectVal; //must be 64bits -#else -typedef long long SQRawObjectVal; //must be 64bits -#endif -#define SQ_OBJECT_RAWINIT() \ - { \ - _unVal.raw = 0; \ - } -#else -typedef SQUnsignedInteger - SQRawObjectVal; //is 32 bits on 32 bits builds and 64 bits otherwise -#define SQ_OBJECT_RAWINIT() -#endif - -#ifndef SQ_ALIGNMENT // SQ_ALIGNMENT shall be less than or equal to SQ_MALLOC alignments, and its value shall be power of 2. -#if defined(SQUSEDOUBLE) || defined(_SQ64) -#define SQ_ALIGNMENT 8 -#else -#define SQ_ALIGNMENT 4 -#endif -#endif - -typedef void *SQUserPointer; -typedef SQUnsignedInteger SQBool; -typedef SQInteger SQRESULT; - -#ifdef SQUNICODE -#include -#include - - -typedef wchar_t SQChar; - - -#define scstrcmp wcscmp -#ifdef _WIN32 -#define scsprintf _snwprintf -#else -#define scsprintf swprintf -#endif -#define scstrlen wcslen -#define scstrtod wcstod -#ifdef _SQ64 -#define scstrtol wcstoll -#else -#define scstrtol wcstol -#endif -#define scstrtoul wcstoul -#define scvsprintf vswprintf -#define scstrstr wcsstr -#define scprintf wprintf - -#ifdef _WIN32 -#define WCHAR_SIZE 2 -#define WCHAR_SHIFT_MUL 1 -#define MAX_CHAR 0xFFFF -#else -#define WCHAR_SIZE 4 -#define WCHAR_SHIFT_MUL 2 -#define MAX_CHAR 0xFFFFFFFF -#endif - -#define _SC(a) L##a - - -#define scisspace iswspace -#define scisdigit iswdigit -#define scisprint iswprint -#define scisxdigit iswxdigit -#define scisalpha iswalpha -#define sciscntrl iswcntrl -#define scisalnum iswalnum - - -#define sq_rsl(l) ((l) << WCHAR_SHIFT_MUL) - -#else -typedef char SQChar; -#define _SC(a) a -#define scstrcmp strcmp -#ifdef _MSC_VER -#define scsprintf _snprintf -#else -#define scsprintf snprintf -#endif -#define scstrlen strlen -#define scstrtod strtod -#ifdef _SQ64 -#ifdef _MSC_VER -#define scstrtol _strtoi64 -#else -#define scstrtol strtoll -#endif -#else -#define scstrtol strtol -#endif -#define scstrtoul strtoul -#define scvsprintf vsnprintf -#define scstrstr strstr -#define scisspace isspace -#define scisdigit isdigit -#define scisprint isprint -#define scisxdigit isxdigit -#define sciscntrl iscntrl -#define scisalpha isalpha -#define scisalnum isalnum -#define scprintf printf -#define MAX_CHAR 0xFF - -#define sq_rsl(l) (l) - -#endif - -#ifdef _SQ64 -#define _PRINT_INT_PREC _SC("ll") -#define _PRINT_INT_FMT _SC("%lld") -#else -#define _PRINT_INT_FMT _SC("%d") -#endif diff --git a/src/modules/app_sqlang/squirrel/include/sqstdaux.h b/src/modules/app_sqlang/squirrel/include/sqstdaux.h deleted file mode 100644 index 8cfe0b030..000000000 --- a/src/modules/app_sqlang/squirrel/include/sqstdaux.h +++ /dev/null @@ -1,20 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQSTD_AUXLIB_H_ -#define _SQSTD_AUXLIB_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - - SQUIRREL_API void sqstd_seterrorhandlers(HSQUIRRELVM v); - SQUIRREL_API void sqstd_printcallstack(HSQUIRRELVM v); - - SQUIRREL_API SQRESULT sqstd_throwerrorf( - HSQUIRRELVM v, const SQChar *err, ...); - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /* _SQSTD_AUXLIB_H_ */ diff --git a/src/modules/app_sqlang/squirrel/include/sqstdblob.h b/src/modules/app_sqlang/squirrel/include/sqstdblob.h deleted file mode 100644 index bec25f8d1..000000000 --- a/src/modules/app_sqlang/squirrel/include/sqstdblob.h +++ /dev/null @@ -1,21 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQSTDBLOB_H_ -#define _SQSTDBLOB_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - - SQUIRREL_API SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size); - SQUIRREL_API SQRESULT sqstd_getblob( - HSQUIRRELVM v, SQInteger idx, SQUserPointer *ptr); - SQUIRREL_API SQInteger sqstd_getblobsize(HSQUIRRELVM v, SQInteger idx); - - SQUIRREL_API SQRESULT sqstd_register_bloblib(HSQUIRRELVM v); - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*_SQSTDBLOB_H_*/ diff --git a/src/modules/app_sqlang/squirrel/include/sqstdio.h b/src/modules/app_sqlang/squirrel/include/sqstdio.h deleted file mode 100644 index 821ae9f4e..000000000 --- a/src/modules/app_sqlang/squirrel/include/sqstdio.h +++ /dev/null @@ -1,64 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQSTDIO_H_ -#define _SQSTDIO_H_ - -#ifdef __cplusplus - -#define SQSTD_STREAM_TYPE_TAG 0x80000000 - -struct SQStream -{ - virtual ~SQStream() - { - } - virtual SQInteger Read(void *buffer, SQInteger size) = 0; - virtual SQInteger Write(void *buffer, SQInteger size) = 0; - virtual SQInteger Flush() = 0; - virtual SQInteger Tell() = 0; - virtual SQInteger Len() = 0; - virtual SQInteger Seek(SQInteger offset, SQInteger origin) = 0; - virtual bool IsValid() = 0; - virtual bool EOS() = 0; -}; - -extern "C" -{ -#endif - -#define SQ_SEEK_CUR 0 -#define SQ_SEEK_END 1 -#define SQ_SEEK_SET 2 - - typedef void *SQFILE; - - SQUIRREL_API SQFILE sqstd_fopen(const SQChar *, const SQChar *); - SQUIRREL_API SQInteger sqstd_fread( - SQUserPointer, SQInteger, SQInteger, SQFILE); - SQUIRREL_API SQInteger sqstd_fwrite( - const SQUserPointer, SQInteger, SQInteger, SQFILE); - SQUIRREL_API SQInteger sqstd_fseek(SQFILE, SQInteger, SQInteger); - SQUIRREL_API SQInteger sqstd_ftell(SQFILE); - SQUIRREL_API SQInteger sqstd_fflush(SQFILE); - SQUIRREL_API SQInteger sqstd_fclose(SQFILE); - SQUIRREL_API SQInteger sqstd_feof(SQFILE); - - SQUIRREL_API SQRESULT sqstd_createfile( - HSQUIRRELVM v, SQFILE file, SQBool own); - SQUIRREL_API SQRESULT sqstd_getfile( - HSQUIRRELVM v, SQInteger idx, SQFILE *file); - - //compiler helpers - SQUIRREL_API SQRESULT sqstd_loadfile( - HSQUIRRELVM v, const SQChar *filename, SQBool printerror); - SQUIRREL_API SQRESULT sqstd_dofile(HSQUIRRELVM v, const SQChar *filename, - SQBool retval, SQBool printerror); - SQUIRREL_API SQRESULT sqstd_writeclosuretofile( - HSQUIRRELVM v, const SQChar *filename); - - SQUIRREL_API SQRESULT sqstd_register_iolib(HSQUIRRELVM v); - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*_SQSTDIO_H_*/ diff --git a/src/modules/app_sqlang/squirrel/include/sqstdmath.h b/src/modules/app_sqlang/squirrel/include/sqstdmath.h deleted file mode 100644 index db1b44936..000000000 --- a/src/modules/app_sqlang/squirrel/include/sqstdmath.h +++ /dev/null @@ -1,16 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQSTD_MATH_H_ -#define _SQSTD_MATH_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - - SQUIRREL_API SQRESULT sqstd_register_mathlib(HSQUIRRELVM v); - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*_SQSTD_MATH_H_*/ diff --git a/src/modules/app_sqlang/squirrel/include/sqstdstring.h b/src/modules/app_sqlang/squirrel/include/sqstdstring.h deleted file mode 100644 index d34c1e844..000000000 --- a/src/modules/app_sqlang/squirrel/include/sqstdstring.h +++ /dev/null @@ -1,43 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQSTD_STRING_H_ -#define _SQSTD_STRING_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - - typedef unsigned int SQRexBool; - typedef struct SQRex SQRex; - - typedef struct - { - const SQChar *begin; - SQInteger len; - } SQRexMatch; - - SQUIRREL_API SQRex *sqstd_rex_compile( - const SQChar *pattern, const SQChar **error); - SQUIRREL_API void sqstd_rex_free(SQRex *exp); - SQUIRREL_API SQBool sqstd_rex_match(SQRex *exp, const SQChar *text); - SQUIRREL_API SQBool sqstd_rex_search(SQRex *exp, const SQChar *text, - const SQChar **out_begin, const SQChar **out_end); - SQUIRREL_API SQBool sqstd_rex_searchrange(SQRex *exp, - const SQChar *text_begin, const SQChar *text_end, - const SQChar **out_begin, const SQChar **out_end); - SQUIRREL_API SQInteger sqstd_rex_getsubexpcount(SQRex *exp); - SQUIRREL_API SQBool sqstd_rex_getsubexp( - SQRex *exp, SQInteger n, SQRexMatch *subexp); - - SQUIRREL_API SQRESULT sqstd_format(HSQUIRRELVM v, - SQInteger nformatstringidx, SQInteger *outlen, SQChar **output); - - SQUIRREL_API void sqstd_pushstringf(HSQUIRRELVM v, const SQChar *s, ...); - - SQUIRREL_API SQRESULT sqstd_register_stringlib(HSQUIRRELVM v); - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*_SQSTD_STRING_H_*/ diff --git a/src/modules/app_sqlang/squirrel/include/sqstdsystem.h b/src/modules/app_sqlang/squirrel/include/sqstdsystem.h deleted file mode 100644 index fa859ab47..000000000 --- a/src/modules/app_sqlang/squirrel/include/sqstdsystem.h +++ /dev/null @@ -1,16 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQSTD_SYSTEMLIB_H_ -#define _SQSTD_SYSTEMLIB_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - - SQUIRREL_API SQInteger sqstd_register_systemlib(HSQUIRRELVM v); - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /* _SQSTD_SYSTEMLIB_H_ */ diff --git a/src/modules/app_sqlang/squirrel/include/squirrel.h b/src/modules/app_sqlang/squirrel/include/squirrel.h deleted file mode 100644 index 8ca175975..000000000 --- a/src/modules/app_sqlang/squirrel/include/squirrel.h +++ /dev/null @@ -1,474 +0,0 @@ -/* -Copyright (c) 2003-2022 Alberto Demichelis - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ -#ifndef _SQUIRREL_H_ -#define _SQUIRREL_H_ - -#ifdef _SQ_CONFIG_INCLUDE -#include _SQ_CONFIG_INCLUDE -#endif - -#ifdef __cplusplus -extern "C" -{ -#endif - -#ifndef SQUIRREL_API -#define SQUIRREL_API extern -#endif - -#if(defined(_WIN64) || defined(_LP64)) -#ifndef _SQ64 -#define _SQ64 -#endif -#endif - - -#define SQTrue (1) -#define SQFalse (0) - - struct SQVM; - struct SQTable; - struct SQArray; - struct SQString; - struct SQClosure; - struct SQGenerator; - struct SQNativeClosure; - struct SQUserData; - struct SQFunctionProto; - struct SQRefCounted; - struct SQClass; - struct SQInstance; - struct SQDelegable; - struct SQOuter; - -#ifdef _UNICODE -#define SQUNICODE -#endif - -#include "sqconfig.h" - -#define SQUIRREL_VERSION _SC("Squirrel 3.2 stable") -#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2022 Alberto Demichelis") -#define SQUIRREL_AUTHOR _SC("Alberto Demichelis") -#define SQUIRREL_VERSION_NUMBER 320 - -#define SQ_VMSTATE_IDLE 0 -#define SQ_VMSTATE_RUNNING 1 -#define SQ_VMSTATE_SUSPENDED 2 - -#define SQUIRREL_EOB 0 -#define SQ_BYTECODE_STREAM_TAG 0xFAFA - -#define SQOBJECT_REF_COUNTED 0x08000000 -#define SQOBJECT_NUMERIC 0x04000000 -#define SQOBJECT_DELEGABLE 0x02000000 -#define SQOBJECT_CANBEFALSE 0x01000000 - -#define SQ_MATCHTYPEMASKSTRING (-99999) - -#define _RT_MASK 0x00FFFFFF -#define _RAW_TYPE(type) (type & _RT_MASK) - -#define _RT_NULL 0x00000001 -#define _RT_INTEGER 0x00000002 -#define _RT_FLOAT 0x00000004 -#define _RT_BOOL 0x00000008 -#define _RT_STRING 0x00000010 -#define _RT_TABLE 0x00000020 -#define _RT_ARRAY 0x00000040 -#define _RT_USERDATA 0x00000080 -#define _RT_CLOSURE 0x00000100 -#define _RT_NATIVECLOSURE 0x00000200 -#define _RT_GENERATOR 0x00000400 -#define _RT_USERPOINTER 0x00000800 -#define _RT_THREAD 0x00001000 -#define _RT_FUNCPROTO 0x00002000 -#define _RT_CLASS 0x00004000 -#define _RT_INSTANCE 0x00008000 -#define _RT_WEAKREF 0x00010000 -#define _RT_OUTER 0x00020000 - - typedef enum tagSQObjectType - { - OT_NULL = (_RT_NULL | SQOBJECT_CANBEFALSE), - OT_INTEGER = (_RT_INTEGER | SQOBJECT_NUMERIC | SQOBJECT_CANBEFALSE), - OT_FLOAT = (_RT_FLOAT | SQOBJECT_NUMERIC | SQOBJECT_CANBEFALSE), - OT_BOOL = (_RT_BOOL | SQOBJECT_CANBEFALSE), - OT_STRING = (_RT_STRING | SQOBJECT_REF_COUNTED), - OT_TABLE = (_RT_TABLE | SQOBJECT_REF_COUNTED | SQOBJECT_DELEGABLE), - OT_ARRAY = (_RT_ARRAY | SQOBJECT_REF_COUNTED), - OT_USERDATA = - (_RT_USERDATA | SQOBJECT_REF_COUNTED | SQOBJECT_DELEGABLE), - OT_CLOSURE = (_RT_CLOSURE | SQOBJECT_REF_COUNTED), - OT_NATIVECLOSURE = (_RT_NATIVECLOSURE | SQOBJECT_REF_COUNTED), - OT_GENERATOR = (_RT_GENERATOR | SQOBJECT_REF_COUNTED), - OT_USERPOINTER = _RT_USERPOINTER, - OT_THREAD = (_RT_THREAD | SQOBJECT_REF_COUNTED), - OT_FUNCPROTO = - (_RT_FUNCPROTO | SQOBJECT_REF_COUNTED), //internal usage only - OT_CLASS = (_RT_CLASS | SQOBJECT_REF_COUNTED), - OT_INSTANCE = - (_RT_INSTANCE | SQOBJECT_REF_COUNTED | SQOBJECT_DELEGABLE), - OT_WEAKREF = (_RT_WEAKREF | SQOBJECT_REF_COUNTED), - OT_OUTER = (_RT_OUTER | SQOBJECT_REF_COUNTED) //internal usage only - } SQObjectType; - -#define ISREFCOUNTED(t) (t & SQOBJECT_REF_COUNTED) - - - typedef union tagSQObjectValue - { - struct SQTable *pTable; - struct SQArray *pArray; - struct SQClosure *pClosure; - struct SQOuter *pOuter; - struct SQGenerator *pGenerator; - struct SQNativeClosure *pNativeClosure; - struct SQString *pString; - struct SQUserData *pUserData; - SQInteger nInteger; - SQFloat fFloat; - SQUserPointer pUserPointer; - struct SQFunctionProto *pFunctionProto; - struct SQRefCounted *pRefCounted; - struct SQDelegable *pDelegable; - struct SQVM *pThread; - struct SQClass *pClass; - struct SQInstance *pInstance; - struct SQWeakRef *pWeakRef; - SQRawObjectVal raw; - } SQObjectValue; - - - typedef struct tagSQObject - { - SQObjectType _type; - SQObjectValue _unVal; - } SQObject; - - typedef struct tagSQMemberHandle - { - SQBool _static; - SQInteger _index; - } SQMemberHandle; - - typedef struct tagSQStackInfos - { - const SQChar *funcname; - const SQChar *source; - SQInteger line; - } SQStackInfos; - - typedef struct SQVM *HSQUIRRELVM; - typedef SQObject HSQOBJECT; - typedef SQMemberHandle HSQMEMBERHANDLE; - typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM); - typedef SQInteger (*SQRELEASEHOOK)(SQUserPointer, SQInteger size); - typedef void (*SQCOMPILERERROR)(HSQUIRRELVM, const SQChar * /*desc*/, - const SQChar * /*source*/, SQInteger /*line*/, - SQInteger /*column*/); - typedef void (*SQPRINTFUNCTION)(HSQUIRRELVM, const SQChar *, ...); - typedef void (*SQDEBUGHOOK)(HSQUIRRELVM /*v*/, SQInteger /*type*/, - const SQChar * /*sourcename*/, SQInteger /*line*/, - const SQChar * /*funcname*/); - typedef SQInteger (*SQWRITEFUNC)(SQUserPointer, SQUserPointer, SQInteger); - typedef SQInteger (*SQREADFUNC)(SQUserPointer, SQUserPointer, SQInteger); - - typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer); - - typedef struct tagSQRegFunction - { - const SQChar *name; - SQFUNCTION f; - SQInteger nparamscheck; - const SQChar *typemask; - } SQRegFunction; - - typedef struct tagSQFunctionInfo - { - SQUserPointer funcid; - const SQChar *name; - const SQChar *source; - SQInteger line; - } SQFunctionInfo; - - /*vm*/ - SQUIRREL_API HSQUIRRELVM sq_open(SQInteger initialstacksize); - SQUIRREL_API HSQUIRRELVM sq_newthread( - HSQUIRRELVM friendvm, SQInteger initialstacksize); - SQUIRREL_API void sq_seterrorhandler(HSQUIRRELVM v); - SQUIRREL_API void sq_close(HSQUIRRELVM v); - SQUIRREL_API void sq_setforeignptr(HSQUIRRELVM v, SQUserPointer p); - SQUIRREL_API SQUserPointer sq_getforeignptr(HSQUIRRELVM v); - SQUIRREL_API void sq_setsharedforeignptr(HSQUIRRELVM v, SQUserPointer p); - SQUIRREL_API SQUserPointer sq_getsharedforeignptr(HSQUIRRELVM v); - SQUIRREL_API void sq_setvmreleasehook(HSQUIRRELVM v, SQRELEASEHOOK hook); - SQUIRREL_API SQRELEASEHOOK sq_getvmreleasehook(HSQUIRRELVM v); - SQUIRREL_API void sq_setsharedreleasehook( - HSQUIRRELVM v, SQRELEASEHOOK hook); - SQUIRREL_API SQRELEASEHOOK sq_getsharedreleasehook(HSQUIRRELVM v); - SQUIRREL_API void sq_setprintfunc( - HSQUIRRELVM v, SQPRINTFUNCTION printfunc, SQPRINTFUNCTION errfunc); - SQUIRREL_API SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v); - SQUIRREL_API SQPRINTFUNCTION sq_geterrorfunc(HSQUIRRELVM v); - SQUIRREL_API SQRESULT sq_suspendvm(HSQUIRRELVM v); - SQUIRREL_API SQRESULT sq_wakeupvm(HSQUIRRELVM v, SQBool resumedret, - SQBool retval, SQBool raiseerror, SQBool throwerror); - SQUIRREL_API SQInteger sq_getvmstate(HSQUIRRELVM v); - SQUIRREL_API SQInteger sq_getversion(); - - /*compiler*/ - SQUIRREL_API SQRESULT sq_compile(HSQUIRRELVM v, SQLEXREADFUNC read, - SQUserPointer p, const SQChar *sourcename, SQBool raiseerror); - SQUIRREL_API SQRESULT sq_compilebuffer(HSQUIRRELVM v, const SQChar *s, - SQInteger size, const SQChar *sourcename, SQBool raiseerror); - SQUIRREL_API void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable); - SQUIRREL_API void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable); - SQUIRREL_API void sq_setcompilererrorhandler( - HSQUIRRELVM v, SQCOMPILERERROR f); - - /*stack operations*/ - SQUIRREL_API void sq_push(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop); - SQUIRREL_API void sq_poptop(HSQUIRRELVM v); - SQUIRREL_API void sq_remove(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQInteger sq_gettop(HSQUIRRELVM v); - SQUIRREL_API void sq_settop(HSQUIRRELVM v, SQInteger newtop); - SQUIRREL_API SQRESULT sq_reservestack(HSQUIRRELVM v, SQInteger nsize); - SQUIRREL_API SQInteger sq_cmp(HSQUIRRELVM v); - SQUIRREL_API void sq_move(HSQUIRRELVM dest, HSQUIRRELVM src, SQInteger idx); - - /*object creation handling*/ - SQUIRREL_API SQUserPointer sq_newuserdata( - HSQUIRRELVM v, SQUnsignedInteger size); - SQUIRREL_API void sq_newtable(HSQUIRRELVM v); - SQUIRREL_API void sq_newtableex(HSQUIRRELVM v, SQInteger initialcapacity); - SQUIRREL_API void sq_newarray(HSQUIRRELVM v, SQInteger size); - SQUIRREL_API void sq_newclosure( - HSQUIRRELVM v, SQFUNCTION func, SQUnsignedInteger nfreevars); - SQUIRREL_API SQRESULT sq_setparamscheck( - HSQUIRRELVM v, SQInteger nparamscheck, const SQChar *typemask); - SQUIRREL_API SQRESULT sq_bindenv(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQRESULT sq_setclosureroot(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQRESULT sq_getclosureroot(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API void sq_pushstring( - HSQUIRRELVM v, const SQChar *s, SQInteger len); - SQUIRREL_API void sq_pushfloat(HSQUIRRELVM v, SQFloat f); - SQUIRREL_API void sq_pushinteger(HSQUIRRELVM v, SQInteger n); - SQUIRREL_API void sq_pushbool(HSQUIRRELVM v, SQBool b); - SQUIRREL_API void sq_pushuserpointer(HSQUIRRELVM v, SQUserPointer p); - SQUIRREL_API void sq_pushnull(HSQUIRRELVM v); - SQUIRREL_API void sq_pushthread(HSQUIRRELVM v, HSQUIRRELVM thread); - SQUIRREL_API SQObjectType sq_gettype(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQRESULT sq_typeof(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQHash sq_gethash(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQRESULT sq_getbase(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQBool sq_instanceof(HSQUIRRELVM v); - SQUIRREL_API SQRESULT sq_tostring(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b); - SQUIRREL_API SQRESULT sq_getstringandsize( - HSQUIRRELVM v, SQInteger idx, const SQChar **c, SQInteger *size); - SQUIRREL_API SQRESULT sq_getstring( - HSQUIRRELVM v, SQInteger idx, const SQChar **c); - SQUIRREL_API SQRESULT sq_getinteger( - HSQUIRRELVM v, SQInteger idx, SQInteger *i); - SQUIRREL_API SQRESULT sq_getfloat(HSQUIRRELVM v, SQInteger idx, SQFloat *f); - SQUIRREL_API SQRESULT sq_getbool(HSQUIRRELVM v, SQInteger idx, SQBool *b); - SQUIRREL_API SQRESULT sq_getthread( - HSQUIRRELVM v, SQInteger idx, HSQUIRRELVM *thread); - SQUIRREL_API SQRESULT sq_getuserpointer( - HSQUIRRELVM v, SQInteger idx, SQUserPointer *p); - SQUIRREL_API SQRESULT sq_getuserdata(HSQUIRRELVM v, SQInteger idx, - SQUserPointer *p, SQUserPointer *typetag); - SQUIRREL_API SQRESULT sq_settypetag( - HSQUIRRELVM v, SQInteger idx, SQUserPointer typetag); - SQUIRREL_API SQRESULT sq_gettypetag( - HSQUIRRELVM v, SQInteger idx, SQUserPointer *typetag); - SQUIRREL_API void sq_setreleasehook( - HSQUIRRELVM v, SQInteger idx, SQRELEASEHOOK hook); - SQUIRREL_API SQRELEASEHOOK sq_getreleasehook(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQChar *sq_getscratchpad(HSQUIRRELVM v, SQInteger minsize); - SQUIRREL_API SQRESULT sq_getfunctioninfo( - HSQUIRRELVM v, SQInteger level, SQFunctionInfo *fi); - SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v, SQInteger idx, - SQInteger *nparams, SQInteger *nfreevars); - SQUIRREL_API SQRESULT sq_getclosurename(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQRESULT sq_setnativeclosurename( - HSQUIRRELVM v, SQInteger idx, const SQChar *name); - SQUIRREL_API SQRESULT sq_setinstanceup( - HSQUIRRELVM v, SQInteger idx, SQUserPointer p); - SQUIRREL_API SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, - SQUserPointer *p, SQUserPointer typetag, SQBool throwerror); - SQUIRREL_API SQRESULT sq_setclassudsize( - HSQUIRRELVM v, SQInteger idx, SQInteger udsize); - SQUIRREL_API SQRESULT sq_newclass(HSQUIRRELVM v, SQBool hasbase); - SQUIRREL_API SQRESULT sq_createinstance(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQRESULT sq_setattributes(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQRESULT sq_getattributes(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQRESULT sq_getclass(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API void sq_weakref(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v, SQObjectType t); - SQUIRREL_API SQRESULT sq_getmemberhandle( - HSQUIRRELVM v, SQInteger idx, HSQMEMBERHANDLE *handle); - SQUIRREL_API SQRESULT sq_getbyhandle( - HSQUIRRELVM v, SQInteger idx, const HSQMEMBERHANDLE *handle); - SQUIRREL_API SQRESULT sq_setbyhandle( - HSQUIRRELVM v, SQInteger idx, const HSQMEMBERHANDLE *handle); - - /*object manipulation*/ - SQUIRREL_API void sq_pushroottable(HSQUIRRELVM v); - SQUIRREL_API void sq_pushregistrytable(HSQUIRRELVM v); - SQUIRREL_API void sq_pushconsttable(HSQUIRRELVM v); - SQUIRREL_API SQRESULT sq_setroottable(HSQUIRRELVM v); - SQUIRREL_API SQRESULT sq_setconsttable(HSQUIRRELVM v); - SQUIRREL_API SQRESULT sq_newslot( - HSQUIRRELVM v, SQInteger idx, SQBool bstatic); - SQUIRREL_API SQRESULT sq_deleteslot( - HSQUIRRELVM v, SQInteger idx, SQBool pushval); - SQUIRREL_API SQRESULT sq_set(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQRESULT sq_get(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQRESULT sq_rawget(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQRESULT sq_rawset(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQRESULT sq_rawdeleteslot( - HSQUIRRELVM v, SQInteger idx, SQBool pushval); - SQUIRREL_API SQRESULT sq_newmember( - HSQUIRRELVM v, SQInteger idx, SQBool bstatic); - SQUIRREL_API SQRESULT sq_rawnewmember( - HSQUIRRELVM v, SQInteger idx, SQBool bstatic); - SQUIRREL_API SQRESULT sq_arrayappend(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQRESULT sq_arraypop( - HSQUIRRELVM v, SQInteger idx, SQBool pushval); - SQUIRREL_API SQRESULT sq_arrayresize( - HSQUIRRELVM v, SQInteger idx, SQInteger newsize); - SQUIRREL_API SQRESULT sq_arrayreverse(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQRESULT sq_arrayremove( - HSQUIRRELVM v, SQInteger idx, SQInteger itemidx); - SQUIRREL_API SQRESULT sq_arrayinsert( - HSQUIRRELVM v, SQInteger idx, SQInteger destpos); - SQUIRREL_API SQRESULT sq_setdelegate(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQRESULT sq_getdelegate(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQRESULT sq_clone(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQRESULT sq_setfreevariable( - HSQUIRRELVM v, SQInteger idx, SQUnsignedInteger nval); - SQUIRREL_API SQRESULT sq_next(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQRESULT sq_getweakrefval(HSQUIRRELVM v, SQInteger idx); - SQUIRREL_API SQRESULT sq_clear(HSQUIRRELVM v, SQInteger idx); - - /*calls*/ - SQUIRREL_API SQRESULT sq_call( - HSQUIRRELVM v, SQInteger params, SQBool retval, SQBool raiseerror); - SQUIRREL_API SQRESULT sq_resume( - HSQUIRRELVM v, SQBool retval, SQBool raiseerror); - SQUIRREL_API const SQChar *sq_getlocal( - HSQUIRRELVM v, SQUnsignedInteger level, SQUnsignedInteger idx); - SQUIRREL_API SQRESULT sq_getcallee(HSQUIRRELVM v); - SQUIRREL_API const SQChar *sq_getfreevariable( - HSQUIRRELVM v, SQInteger idx, SQUnsignedInteger nval); - SQUIRREL_API SQRESULT sq_throwerror(HSQUIRRELVM v, const SQChar *err); - SQUIRREL_API SQRESULT sq_throwobject(HSQUIRRELVM v); - SQUIRREL_API void sq_reseterror(HSQUIRRELVM v); - SQUIRREL_API void sq_getlasterror(HSQUIRRELVM v); - SQUIRREL_API SQRESULT sq_tailcall(HSQUIRRELVM v, SQInteger nparams); - - /*raw object handling*/ - SQUIRREL_API SQRESULT sq_getstackobj( - HSQUIRRELVM v, SQInteger idx, HSQOBJECT *po); - SQUIRREL_API void sq_pushobject(HSQUIRRELVM v, HSQOBJECT obj); - SQUIRREL_API void sq_addref(HSQUIRRELVM v, HSQOBJECT *po); - SQUIRREL_API SQBool sq_release(HSQUIRRELVM v, HSQOBJECT *po); - SQUIRREL_API SQUnsignedInteger sq_getrefcount(HSQUIRRELVM v, HSQOBJECT *po); - SQUIRREL_API void sq_resetobject(HSQOBJECT *po); - SQUIRREL_API const SQChar *sq_objtostring(const HSQOBJECT *o); - SQUIRREL_API SQBool sq_objtobool(const HSQOBJECT *o); - SQUIRREL_API SQInteger sq_objtointeger(const HSQOBJECT *o); - SQUIRREL_API SQFloat sq_objtofloat(const HSQOBJECT *o); - SQUIRREL_API SQUserPointer sq_objtouserpointer(const HSQOBJECT *o); - SQUIRREL_API SQRESULT sq_getobjtypetag( - const HSQOBJECT *o, SQUserPointer *typetag); - SQUIRREL_API SQUnsignedInteger sq_getvmrefcount( - HSQUIRRELVM v, const HSQOBJECT *po); - - - /*GC*/ - SQUIRREL_API SQInteger sq_collectgarbage(HSQUIRRELVM v); - SQUIRREL_API SQRESULT sq_resurrectunreachable(HSQUIRRELVM v); - - /*serialization*/ - SQUIRREL_API SQRESULT sq_writeclosure( - HSQUIRRELVM vm, SQWRITEFUNC writef, SQUserPointer up); - SQUIRREL_API SQRESULT sq_readclosure( - HSQUIRRELVM vm, SQREADFUNC readf, SQUserPointer up); - - /*mem allocation*/ - SQUIRREL_API void *sq_malloc(SQUnsignedInteger size); - SQUIRREL_API void *sq_realloc( - void *p, SQUnsignedInteger oldsize, SQUnsignedInteger newsize); - SQUIRREL_API void sq_free(void *p, SQUnsignedInteger size); - - /*debug*/ - SQUIRREL_API SQRESULT sq_stackinfos( - HSQUIRRELVM v, SQInteger level, SQStackInfos *si); - SQUIRREL_API void sq_setdebughook(HSQUIRRELVM v); - SQUIRREL_API void sq_setnativedebughook(HSQUIRRELVM v, SQDEBUGHOOK hook); - -/*UTILITY MACRO*/ -#define sq_isnumeric(o) ((o)._type & SQOBJECT_NUMERIC) -#define sq_istable(o) ((o)._type == OT_TABLE) -#define sq_isarray(o) ((o)._type == OT_ARRAY) -#define sq_isfunction(o) ((o)._type == OT_FUNCPROTO) -#define sq_isclosure(o) ((o)._type == OT_CLOSURE) -#define sq_isgenerator(o) ((o)._type == OT_GENERATOR) -#define sq_isnativeclosure(o) ((o)._type == OT_NATIVECLOSURE) -#define sq_isstring(o) ((o)._type == OT_STRING) -#define sq_isinteger(o) ((o)._type == OT_INTEGER) -#define sq_isfloat(o) ((o)._type == OT_FLOAT) -#define sq_isuserpointer(o) ((o)._type == OT_USERPOINTER) -#define sq_isuserdata(o) ((o)._type == OT_USERDATA) -#define sq_isthread(o) ((o)._type == OT_THREAD) -#define sq_isnull(o) ((o)._type == OT_NULL) -#define sq_isclass(o) ((o)._type == OT_CLASS) -#define sq_isinstance(o) ((o)._type == OT_INSTANCE) -#define sq_isbool(o) ((o)._type == OT_BOOL) -#define sq_isweakref(o) ((o)._type == OT_WEAKREF) -#define sq_type(o) ((o)._type) - -/* deprecated */ -#define sq_createslot(v, n) sq_newslot(v, n, SQFalse) - -#define SQ_OK (0) -#define SQ_ERROR (-1) - -#define SQ_FAILED(res) (res < 0) -#define SQ_SUCCEEDED(res) (res >= 0) - -#ifdef __GNUC__ -#define SQ_UNUSED_ARG(x) x __attribute__((__unused__)) -#else -#define SQ_UNUSED_ARG(x) x -#endif - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*_SQUIRREL_H_*/ diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/Makefile b/src/modules/app_sqlang/squirrel/sqstdlib/Makefile deleted file mode 100644 index 6746d144f..000000000 --- a/src/modules/app_sqlang/squirrel/sqstdlib/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -SQUIRREL= .. - - -OUT?= $(SQUIRREL)/lib/libsqstdlib.a -INCZ?= -I$(SQUIRREL)/include -I. -Iinclude -DEFS= $(CC_EXTRA_FLAGS) -LIB= -SQMARCH64?= -m64 - -OBJS= \ - sqstdblob.o \ - sqstdio.o \ - sqstdstream.o \ - sqstdmath.o \ - sqstdsystem.o \ - sqstdstring.o \ - sqstdaux.o \ - sqstdrex.o - -SRCS= \ - sqstdblob.cpp \ - sqstdio.cpp \ - sqstdstream.cpp \ - sqstdmath.cpp \ - sqstdsystem.cpp \ - sqstdstring.cpp \ - sqstdaux.cpp \ - sqstdrex.cpp - - -sq32: - $(CC) -O2 -fno-exceptions -fno-rtti -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS) - $(AR) rc $(OUT) *.o - rm *.o - -sqprof: - $(CC) -O2 -pg -fno-exceptions -fno-rtti -pie -gstabs -g3 -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS) - $(AR) rc $(OUT) *.o - rm *.o - -sq64: - $(CC) -O2 $(SQMARCH64) -fno-exceptions -D_SQ64 -fno-rtti -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS) - $(AR) rc $(OUT) *.o - rm *.o diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdaux.cpp b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdaux.cpp deleted file mode 100644 index 75c165339..000000000 --- a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdaux.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include -#include -#include - -void sqstd_printcallstack(HSQUIRRELVM v) -{ - SQPRINTFUNCTION pf = sq_geterrorfunc(v); - if(pf) { - SQStackInfos si; - SQInteger i; - SQFloat f; - const SQChar *s; - SQInteger level=1; //1 is to skip this function that is level 0 - const SQChar *name=0; - SQInteger seq=0; - pf(v,_SC("\nCALLSTACK\n")); - while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si))) - { - const SQChar *fn=_SC("unknown"); - const SQChar *src=_SC("unknown"); - if(si.funcname)fn=si.funcname; - if(si.source)src=si.source; - pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line); - level++; - } - level=0; - pf(v,_SC("\nLOCALS\n")); - - for(level=0;level<10;level++){ - seq=0; - while((name = sq_getlocal(v,level,seq))) - { - seq++; - switch(sq_gettype(v,-1)) - { - case OT_NULL: - pf(v,_SC("[%s] NULL\n"),name); - break; - case OT_INTEGER: - sq_getinteger(v,-1,&i); - pf(v,_SC("[%s] %d\n"),name,i); - break; - case OT_FLOAT: - sq_getfloat(v,-1,&f); - pf(v,_SC("[%s] %.14g\n"),name,f); - break; - case OT_USERPOINTER: - pf(v,_SC("[%s] USERPOINTER\n"),name); - break; - case OT_STRING: - sq_getstring(v,-1,&s); - pf(v,_SC("[%s] \"%s\"\n"),name,s); - break; - case OT_TABLE: - pf(v,_SC("[%s] TABLE\n"),name); - break; - case OT_ARRAY: - pf(v,_SC("[%s] ARRAY\n"),name); - break; - case OT_CLOSURE: - pf(v,_SC("[%s] CLOSURE\n"),name); - break; - case OT_NATIVECLOSURE: - pf(v,_SC("[%s] NATIVECLOSURE\n"),name); - break; - case OT_GENERATOR: - pf(v,_SC("[%s] GENERATOR\n"),name); - break; - case OT_USERDATA: - pf(v,_SC("[%s] USERDATA\n"),name); - break; - case OT_THREAD: - pf(v,_SC("[%s] THREAD\n"),name); - break; - case OT_CLASS: - pf(v,_SC("[%s] CLASS\n"),name); - break; - case OT_INSTANCE: - pf(v,_SC("[%s] INSTANCE\n"),name); - break; - case OT_WEAKREF: - pf(v,_SC("[%s] WEAKREF\n"),name); - break; - case OT_BOOL:{ - SQBool bval; - sq_getbool(v,-1,&bval); - pf(v,_SC("[%s] %s\n"),name,bval == SQTrue ? _SC("true"):_SC("false")); - } - break; - default: assert(0); break; - } - sq_pop(v,1); - } - } - } -} - -static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v) -{ - SQPRINTFUNCTION pf = sq_geterrorfunc(v); - if(pf) { - const SQChar *sErr = 0; - if(sq_gettop(v)>=1) { - if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) { - pf(v,_SC("\nAN ERROR HAS OCCURRED [%s]\n"),sErr); - } - else{ - pf(v,_SC("\nAN ERROR HAS OCCURRED [unknown]\n")); - } - sqstd_printcallstack(v); - } - } - return 0; -} - -void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column) -{ - SQPRINTFUNCTION pf = sq_geterrorfunc(v); - if(pf) { - pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr); - } -} - -void sqstd_seterrorhandlers(HSQUIRRELVM v) -{ - sq_setcompilererrorhandler(v,_sqstd_compiler_error); - sq_newclosure(v,_sqstd_aux_printerror,0); - sq_seterrorhandler(v); -} - -SQRESULT sqstd_throwerrorf(HSQUIRRELVM v,const SQChar *err,...) -{ - SQInteger n=256; - va_list args; -begin: - va_start(args,err); - SQChar *b=sq_getscratchpad(v,n); - SQInteger r=scvsprintf(b,n,err,args); - va_end(args); - if (r>=n) { - n=r+1;//required+null - goto begin; - } else if (r<0) { - return sq_throwerror(v,_SC("@failed to generate formatted error message")); - } else { - return sq_throwerror(v,b); - } -} diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdblob.cpp b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdblob.cpp deleted file mode 100644 index 22df0cf95..000000000 --- a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdblob.cpp +++ /dev/null @@ -1,283 +0,0 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include -#include -#include -#include "sqstdstream.h" -#include "sqstdblobimpl.h" - -#define SQSTD_BLOB_TYPE_TAG ((SQUnsignedInteger)(SQSTD_STREAM_TYPE_TAG | 0x00000002)) - -//Blob - - -#define SETUP_BLOB(v) \ - SQBlob *self = NULL; \ - { if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_BLOB_TYPE_TAG,SQFalse))) \ - return sq_throwerror(v,_SC("invalid type tag")); } \ - if(!self || !self->IsValid()) \ - return sq_throwerror(v,_SC("the blob is invalid")); - - -static SQInteger _blob_resize(HSQUIRRELVM v) -{ - SETUP_BLOB(v); - SQInteger size; - sq_getinteger(v,2,&size); - if(!self->Resize(size)) - return sq_throwerror(v,_SC("resize failed")); - return 0; -} - -static void __swap_dword(unsigned int *n) -{ - *n=(unsigned int)(((*n&0xFF000000)>>24) | - ((*n&0x00FF0000)>>8) | - ((*n&0x0000FF00)<<8) | - ((*n&0x000000FF)<<24)); -} - -static void __swap_word(unsigned short *n) -{ - *n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00); -} - -static SQInteger _blob_swap4(HSQUIRRELVM v) -{ - SETUP_BLOB(v); - SQInteger num=(self->Len()-(self->Len()%4))>>2; - unsigned int *t=(unsigned int *)self->GetBuf(); - for(SQInteger i = 0; i < num; i++) { - __swap_dword(&t[i]); - } - return 0; -} - -static SQInteger _blob_swap2(HSQUIRRELVM v) -{ - SETUP_BLOB(v); - SQInteger num=(self->Len()-(self->Len()%2))>>1; - unsigned short *t = (unsigned short *)self->GetBuf(); - for(SQInteger i = 0; i < num; i++) { - __swap_word(&t[i]); - } - return 0; -} - -static SQInteger _blob__set(HSQUIRRELVM v) -{ - SETUP_BLOB(v); - SQInteger idx,val; - sq_getinteger(v,2,&idx); - sq_getinteger(v,3,&val); - if(idx < 0 || idx >= self->Len()) - return sq_throwerror(v,_SC("index out of range")); - ((unsigned char *)self->GetBuf())[idx] = (unsigned char) val; - sq_push(v,3); - return 1; -} - -static SQInteger _blob__get(HSQUIRRELVM v) -{ - SETUP_BLOB(v); - SQInteger idx; - - if ((sq_gettype(v, 2) & SQOBJECT_NUMERIC) == 0) - { - sq_pushnull(v); - return sq_throwobject(v); - } - sq_getinteger(v,2,&idx); - if(idx < 0 || idx >= self->Len()) - return sq_throwerror(v,_SC("index out of range")); - sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]); - return 1; -} - -static SQInteger _blob__nexti(HSQUIRRELVM v) -{ - SETUP_BLOB(v); - if(sq_gettype(v,2) == OT_NULL) { - sq_pushinteger(v, 0); - return 1; - } - SQInteger idx; - if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) { - if(idx+1 < self->Len()) { - sq_pushinteger(v, idx+1); - return 1; - } - sq_pushnull(v); - return 1; - } - return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type")); -} - -static SQInteger _blob__typeof(HSQUIRRELVM v) -{ - sq_pushstring(v,_SC("blob"),-1); - return 1; -} - -static SQInteger _blob_releasehook(SQUserPointer p, SQInteger SQ_UNUSED_ARG(size)) -{ - SQBlob *self = (SQBlob*)p; - self->~SQBlob(); - sq_free(self,sizeof(SQBlob)); - return 1; -} - -static SQInteger _blob_constructor(HSQUIRRELVM v) -{ - SQInteger nparam = sq_gettop(v); - SQInteger size = 0; - if(nparam == 2) { - sq_getinteger(v, 2, &size); - } - if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size")); - //SQBlob *b = new SQBlob(size); - - SQBlob *b = new (sq_malloc(sizeof(SQBlob)))SQBlob(size); - if(SQ_FAILED(sq_setinstanceup(v,1,b))) { - b->~SQBlob(); - sq_free(b,sizeof(SQBlob)); - return sq_throwerror(v, _SC("cannot create blob")); - } - sq_setreleasehook(v,1,_blob_releasehook); - return 0; -} - -static SQInteger _blob__cloned(HSQUIRRELVM v) -{ - SQBlob *other = NULL; - { - if(SQ_FAILED(sq_getinstanceup(v,2,(SQUserPointer*)&other,(SQUserPointer)SQSTD_BLOB_TYPE_TAG,SQFalse))) - return SQ_ERROR; - } - //SQBlob *thisone = new SQBlob(other->Len()); - SQBlob *thisone = new (sq_malloc(sizeof(SQBlob)))SQBlob(other->Len()); - memcpy(thisone->GetBuf(),other->GetBuf(),thisone->Len()); - if(SQ_FAILED(sq_setinstanceup(v,1,thisone))) { - thisone->~SQBlob(); - sq_free(thisone,sizeof(SQBlob)); - return sq_throwerror(v, _SC("cannot clone blob")); - } - sq_setreleasehook(v,1,_blob_releasehook); - return 0; -} - -#define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck} -static const SQRegFunction _blob_methods[] = { - _DECL_BLOB_FUNC(constructor,-1,_SC("xn")), - _DECL_BLOB_FUNC(resize,2,_SC("xn")), - _DECL_BLOB_FUNC(swap2,1,_SC("x")), - _DECL_BLOB_FUNC(swap4,1,_SC("x")), - _DECL_BLOB_FUNC(_set,3,_SC("xnn")), - _DECL_BLOB_FUNC(_get,2,_SC("x.")), - _DECL_BLOB_FUNC(_typeof,1,_SC("x")), - _DECL_BLOB_FUNC(_nexti,2,_SC("x")), - _DECL_BLOB_FUNC(_cloned,2,_SC("xx")), - {NULL,(SQFUNCTION)0,0,NULL} -}; - - - -//GLOBAL FUNCTIONS - -static SQInteger _g_blob_casti2f(HSQUIRRELVM v) -{ - SQInteger i; - sq_getinteger(v,2,&i); - sq_pushfloat(v,*((const SQFloat *)&i)); - return 1; -} - -static SQInteger _g_blob_castf2i(HSQUIRRELVM v) -{ - SQFloat f; - sq_getfloat(v,2,&f); - sq_pushinteger(v,*((const SQInteger *)&f)); - return 1; -} - -static SQInteger _g_blob_swap2(HSQUIRRELVM v) -{ - SQInteger i; - sq_getinteger(v,2,&i); - unsigned short s = (unsigned short)i; - sq_pushinteger(v, ((s << 8) | ((s >> 8) & 0x00FFu)) & 0xFFFFu); - return 1; -} - -static SQInteger _g_blob_swap4(HSQUIRRELVM v) -{ - SQInteger i; - sq_getinteger(v,2,&i); - unsigned int t4 = (unsigned int)i; - __swap_dword(&t4); - sq_pushinteger(v,(SQInteger)t4); - return 1; -} - -static SQInteger _g_blob_swapfloat(HSQUIRRELVM v) -{ - SQFloat f; - sq_getfloat(v,2,&f); - __swap_dword((unsigned int *)&f); - sq_pushfloat(v,f); - return 1; -} - -#define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck} -static const SQRegFunction bloblib_funcs[]={ - _DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")), - _DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")), - _DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")), - _DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")), - _DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")), - {NULL,(SQFUNCTION)0,0,NULL} -}; - -SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr) -{ - SQBlob *blob; - if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG,SQTrue))) - return -1; - *ptr = blob->GetBuf(); - return SQ_OK; -} - -SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx) -{ - SQBlob *blob; - if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG,SQTrue))) - return -1; - return blob->Len(); -} - -SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size) -{ - SQInteger top = sq_gettop(v); - sq_pushregistrytable(v); - sq_pushstring(v,_SC("std_blob"),-1); - if(SQ_SUCCEEDED(sq_get(v,-2))) { - sq_remove(v,-2); //removes the registry - sq_push(v,1); // push the this - sq_pushinteger(v,size); //size - SQBlob *blob = NULL; - if(SQ_SUCCEEDED(sq_call(v,2,SQTrue,SQFalse)) - && SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG,SQTrue))) { - sq_remove(v,-2); - return blob->GetBuf(); - } - } - sq_settop(v,top); - return NULL; -} - -SQRESULT sqstd_register_bloblib(HSQUIRRELVM v) -{ - return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs); -} - diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdblobimpl.h b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdblobimpl.h deleted file mode 100644 index e035495e1..000000000 --- a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdblobimpl.h +++ /dev/null @@ -1,137 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQSTD_BLOBIMPL_H_ -#define _SQSTD_BLOBIMPL_H_ - -struct SQBlob : public SQStream -{ - SQBlob(SQInteger size) - { - _size = size; - _allocated = size; - _buf = (unsigned char *)sq_malloc(size); - memset(_buf, 0, _size); - _ptr = 0; - _owns = true; - } - virtual ~SQBlob() - { - sq_free(_buf, _allocated); - } - SQInteger Write(void *buffer, SQInteger size) - { - if(!CanAdvance(size)) { - GrowBufOf(_ptr + size - _size); - } - memcpy(&_buf[_ptr], buffer, size); - _ptr += size; - return size; - } - SQInteger Read(void *buffer, SQInteger size) - { - SQInteger n = size; - if(!CanAdvance(size)) { - if((_size - _ptr) > 0) - n = _size - _ptr; - else - return 0; - } - memcpy(buffer, &_buf[_ptr], n); - _ptr += n; - return n; - } - bool Resize(SQInteger n) - { - if(!_owns) - return false; - if(n != _allocated) { - unsigned char *newbuf = (unsigned char *)sq_malloc(n); - memset(newbuf, 0, n); - if(_size > n) - memcpy(newbuf, _buf, n); - else - memcpy(newbuf, _buf, _size); - sq_free(_buf, _allocated); - _buf = newbuf; - _allocated = n; - if(_size > _allocated) - _size = _allocated; - if(_ptr > _allocated) - _ptr = _allocated; - } - return true; - } - bool GrowBufOf(SQInteger n) - { - bool ret = true; - if(_size + n > _allocated) { - if(_size + n > _size * 2) - ret = Resize(_size + n); - else - ret = Resize(_size * 2); - } - _size = _size + n; - return ret; - } - bool CanAdvance(SQInteger n) - { - if(_ptr + n > _size) - return false; - return true; - } - SQInteger Seek(SQInteger offset, SQInteger origin) - { - switch(origin) { - case SQ_SEEK_SET: - if(offset > _size || offset < 0) - return -1; - _ptr = offset; - break; - case SQ_SEEK_CUR: - if(_ptr + offset > _size || _ptr + offset < 0) - return -1; - _ptr += offset; - break; - case SQ_SEEK_END: - if(_size + offset > _size || _size + offset < 0) - return -1; - _ptr = _size + offset; - break; - default: - return -1; - } - return 0; - } - bool IsValid() - { - return _size == 0 || _buf ? true : false; - } - bool EOS() - { - return _ptr == _size; - } - SQInteger Flush() - { - return 0; - } - SQInteger Tell() - { - return _ptr; - } - SQInteger Len() - { - return _size; - } - SQUserPointer GetBuf() - { - return _buf; - } - -private: - SQInteger _size; - SQInteger _allocated; - SQInteger _ptr; - unsigned char *_buf; - bool _owns; -}; - -#endif //_SQSTD_BLOBIMPL_H_ diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdio.cpp b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdio.cpp deleted file mode 100644 index ec6ee07ed..000000000 --- a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdio.cpp +++ /dev/null @@ -1,489 +0,0 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include -#include -#include "sqstdstream.h" - -#define SQSTD_FILE_TYPE_TAG ((SQUnsignedInteger)(SQSTD_STREAM_TYPE_TAG | 0x00000001)) -//basic API -SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode) -{ -#ifndef SQUNICODE - return (SQFILE)fopen(filename,mode); -#else - return (SQFILE)_wfopen(filename,mode); -#endif -} - -SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file) -{ - SQInteger ret = (SQInteger)fread(buffer,size,count,(FILE *)file); - return ret; -} - -SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file) -{ - return (SQInteger)fwrite(buffer,size,count,(FILE *)file); -} - -SQInteger sqstd_fseek(SQFILE file, SQInteger offset, SQInteger origin) -{ - SQInteger realorigin; - switch(origin) { - case SQ_SEEK_CUR: realorigin = SEEK_CUR; break; - case SQ_SEEK_END: realorigin = SEEK_END; break; - case SQ_SEEK_SET: realorigin = SEEK_SET; break; - default: return -1; //failed - } - return fseek((FILE *)file,(long)offset,(int)realorigin); -} - -SQInteger sqstd_ftell(SQFILE file) -{ - return ftell((FILE *)file); -} - -SQInteger sqstd_fflush(SQFILE file) -{ - return fflush((FILE *)file); -} - -SQInteger sqstd_fclose(SQFILE file) -{ - return fclose((FILE *)file); -} - -SQInteger sqstd_feof(SQFILE file) -{ - return feof((FILE *)file); -} - -//File -struct SQFile : public SQStream { - SQFile() { _handle = NULL; _owns = false;} - SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;} - virtual ~SQFile() { Close(); } - bool Open(const SQChar *filename ,const SQChar *mode) { - Close(); - if( (_handle = sqstd_fopen(filename,mode)) ) { - _owns = true; - return true; - } - return false; - } - void Close() { - if(_handle && _owns) { - sqstd_fclose(_handle); - _handle = NULL; - _owns = false; - } - } - SQInteger Read(void *buffer,SQInteger size) { - return sqstd_fread(buffer,1,size,_handle); - } - SQInteger Write(void *buffer,SQInteger size) { - return sqstd_fwrite(buffer,1,size,_handle); - } - SQInteger Flush() { - return sqstd_fflush(_handle); - } - SQInteger Tell() { - return sqstd_ftell(_handle); - } - SQInteger Len() { - SQInteger prevpos=Tell(); - Seek(0,SQ_SEEK_END); - SQInteger size=Tell(); - Seek(prevpos,SQ_SEEK_SET); - return size; - } - SQInteger Seek(SQInteger offset, SQInteger origin) { - return sqstd_fseek(_handle,offset,origin); - } - bool IsValid() { return _handle?true:false; } - bool EOS() { return Tell()==Len()?true:false;} - SQFILE GetHandle() {return _handle;} -private: - SQFILE _handle; - bool _owns; -}; - -static SQInteger _file__typeof(HSQUIRRELVM v) -{ - sq_pushstring(v,_SC("file"),-1); - return 1; -} - -static SQInteger _file_releasehook(SQUserPointer p, SQInteger SQ_UNUSED_ARG(size)) -{ - SQFile *self = (SQFile*)p; - self->~SQFile(); - sq_free(self,sizeof(SQFile)); - return 1; -} - -static SQInteger _file_constructor(HSQUIRRELVM v) -{ - const SQChar *filename,*mode; - bool owns = true; - SQFile *f; - SQFILE newf; - if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) { - sq_getstring(v, 2, &filename); - sq_getstring(v, 3, &mode); - newf = sqstd_fopen(filename, mode); - if(!newf) return sq_throwerror(v, _SC("cannot open file")); - } else if(sq_gettype(v,2) == OT_USERPOINTER) { - owns = !(sq_gettype(v,3) == OT_NULL); - sq_getuserpointer(v,2,&newf); - } else { - return sq_throwerror(v,_SC("wrong parameter")); - } - - f = new (sq_malloc(sizeof(SQFile)))SQFile(newf,owns); - if(SQ_FAILED(sq_setinstanceup(v,1,f))) { - f->~SQFile(); - sq_free(f,sizeof(SQFile)); - return sq_throwerror(v, _SC("cannot create blob with negative size")); - } - sq_setreleasehook(v,1,_file_releasehook); - return 0; -} - -static SQInteger _file_close(HSQUIRRELVM v) -{ - SQFile *self = NULL; - if(SQ_SUCCEEDED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_FILE_TYPE_TAG, SQTrue)) - && self != NULL) - { - self->Close(); - } - return 0; -} - -//bindings -#define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck} -static const SQRegFunction _file_methods[] = { - _DECL_FILE_FUNC(constructor,3,_SC("x")), - _DECL_FILE_FUNC(_typeof,1,_SC("x")), - _DECL_FILE_FUNC(close,1,_SC("x")), - {NULL,(SQFUNCTION)0,0,NULL} -}; - - - -SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own) -{ - SQInteger top = sq_gettop(v); - sq_pushregistrytable(v); - sq_pushstring(v,_SC("std_file"),-1); - if(SQ_SUCCEEDED(sq_get(v,-2))) { - sq_remove(v,-2); //removes the registry - sq_pushroottable(v); // push the this - sq_pushuserpointer(v,file); //file - if(own){ - sq_pushinteger(v,1); //true - } - else{ - sq_pushnull(v); //false - } - if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) { - sq_remove(v,-2); - return SQ_OK; - } - } - sq_settop(v,top); - return SQ_ERROR; -} - -SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file) -{ - SQFile *fileobj = NULL; - if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG,SQFalse))) { - *file = fileobj->GetHandle(); - return SQ_OK; - } - return sq_throwerror(v,_SC("not a file")); -} - - - -#define IO_BUFFER_SIZE 2048 -struct IOBuffer { - unsigned char buffer[IO_BUFFER_SIZE]; - SQInteger size; - SQInteger ptr; - SQFILE file; -}; - -SQInteger _read_byte(IOBuffer *iobuffer) -{ - if(iobuffer->ptr < iobuffer->size) { - - SQInteger ret = iobuffer->buffer[iobuffer->ptr]; - iobuffer->ptr++; - return ret; - } - else { - if( (iobuffer->size = sqstd_fread(iobuffer->buffer,1,IO_BUFFER_SIZE,iobuffer->file )) > 0 ) - { - SQInteger ret = iobuffer->buffer[0]; - iobuffer->ptr = 1; - return ret; - } - } - - return 0; -} - -SQInteger _read_two_bytes(IOBuffer *iobuffer) -{ - if(iobuffer->ptr < iobuffer->size) { - if(iobuffer->size < 2) return 0; - SQInteger ret = *((const wchar_t*)&iobuffer->buffer[iobuffer->ptr]); - iobuffer->ptr += 2; - return ret; - } - else { - if( (iobuffer->size = sqstd_fread(iobuffer->buffer,1,IO_BUFFER_SIZE,iobuffer->file )) > 0 ) - { - if(iobuffer->size < 2) return 0; - SQInteger ret = *((const wchar_t*)&iobuffer->buffer[0]); - iobuffer->ptr = 2; - return ret; - } - } - - return 0; -} - -static SQInteger _io_file_lexfeed_PLAIN(SQUserPointer iobuf) -{ - IOBuffer *iobuffer = (IOBuffer *)iobuf; - return _read_byte(iobuffer); - -} - -#ifdef SQUNICODE -static SQInteger _io_file_lexfeed_UTF8(SQUserPointer iobuf) -{ - IOBuffer *iobuffer = (IOBuffer *)iobuf; -#define READ(iobuf) \ - if((inchar = (unsigned char)_read_byte(iobuf)) == 0) \ - return 0; - - static const SQInteger utf8_lengths[16] = - { - 1,1,1,1,1,1,1,1, /* 0000 to 0111 : 1 byte (plain ASCII) */ - 0,0,0,0, /* 1000 to 1011 : not valid */ - 2,2, /* 1100, 1101 : 2 bytes */ - 3, /* 1110 : 3 bytes */ - 4 /* 1111 :4 bytes */ - }; - static const unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07}; - unsigned char inchar; - SQInteger c = 0; - READ(iobuffer); - c = inchar; - // - if(c >= 0x80) { - SQInteger tmp; - SQInteger codelen = utf8_lengths[c>>4]; - if(codelen == 0) - return 0; - //"invalid UTF-8 stream"; - tmp = c&byte_masks[codelen]; - for(SQInteger n = 0; n < codelen-1; n++) { - tmp<<=6; - READ(iobuffer); - tmp |= inchar & 0x3F; - } - c = tmp; - } - return c; -} -#endif - -static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer iobuf) -{ - SQInteger ret; - IOBuffer *iobuffer = (IOBuffer *)iobuf; - if( (ret = _read_two_bytes(iobuffer)) > 0 ) - return ret; - return 0; -} - -static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer iobuf) -{ - SQInteger c; - IOBuffer *iobuffer = (IOBuffer *)iobuf; - if( (c = _read_two_bytes(iobuffer)) > 0 ) { - c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00); - return c; - } - return 0; -} - -SQInteger file_read(SQUserPointer file,SQUserPointer buf,SQInteger size) -{ - SQInteger ret; - if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret; - return -1; -} - -SQInteger file_write(SQUserPointer file,SQUserPointer p,SQInteger size) -{ - return sqstd_fwrite(p,1,size,(SQFILE)file); -} - -SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror) -{ - SQFILE file = sqstd_fopen(filename,_SC("rb")); - - SQInteger ret; - unsigned short us; - unsigned char uc; - SQLEXREADFUNC func = _io_file_lexfeed_PLAIN; - if(file){ - ret = sqstd_fread(&us,1,2,file); - if(ret != 2) { - //probably an empty file - us = 0; - } - if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE - sqstd_fseek(file,0,SQ_SEEK_SET); - if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) { - sqstd_fclose(file); - return SQ_OK; - } - } - else { //SCRIPT - - switch(us) - { - //gotta swap the next 2 lines on BIG endian machines - case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian; - case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian; - case 0xBBEF: - if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) { - sqstd_fclose(file); - return sq_throwerror(v,_SC("io error")); - } - if(uc != 0xBF) { - sqstd_fclose(file); - return sq_throwerror(v,_SC("Unrecognized encoding")); - } -#ifdef SQUNICODE - func = _io_file_lexfeed_UTF8; -#else - func = _io_file_lexfeed_PLAIN; -#endif - break;//UTF-8 ; - default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii - } - IOBuffer buffer; - buffer.ptr = 0; - buffer.size = 0; - buffer.file = file; - if(SQ_SUCCEEDED(sq_compile(v,func,&buffer,filename,printerror))){ - sqstd_fclose(file); - return SQ_OK; - } - } - sqstd_fclose(file); - return SQ_ERROR; - } - return sq_throwerror(v,_SC("cannot open the file")); -} - -SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror) -{ - //at least one entry must exist in order for us to push it as the environment - if(sq_gettop(v) == 0) - return sq_throwerror(v,_SC("environment table expected")); - - if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) { - sq_push(v,-2); - if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) { - sq_remove(v,retval?-2:-1); //removes the closure - return 1; - } - sq_pop(v,1); //removes the closure - } - return SQ_ERROR; -} - -SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename) -{ - SQFILE file = sqstd_fopen(filename,_SC("wb+")); - if(!file) return sq_throwerror(v,_SC("cannot open the file")); - if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) { - sqstd_fclose(file); - return SQ_OK; - } - sqstd_fclose(file); - return SQ_ERROR; //forward the error -} - -SQInteger _g_io_loadfile(HSQUIRRELVM v) -{ - const SQChar *filename; - SQBool printerror = SQFalse; - sq_getstring(v,2,&filename); - if(sq_gettop(v) >= 3) { - sq_getbool(v,3,&printerror); - } - if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) - return 1; - return SQ_ERROR; //propagates the error -} - -SQInteger _g_io_writeclosuretofile(HSQUIRRELVM v) -{ - const SQChar *filename; - sq_getstring(v,2,&filename); - if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,filename))) - return 1; - return SQ_ERROR; //propagates the error -} - -SQInteger _g_io_dofile(HSQUIRRELVM v) -{ - const SQChar *filename; - SQBool printerror = SQFalse; - sq_getstring(v,2,&filename); - if(sq_gettop(v) >= 3) { - sq_getbool(v,3,&printerror); - } - sq_push(v,1); //repush the this - if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror))) - return 1; - return SQ_ERROR; //propagates the error -} - -#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck} -static const SQRegFunction iolib_funcs[]={ - _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")), - _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")), - _DECL_GLOBALIO_FUNC(writeclosuretofile,3,_SC(".sc")), - {NULL,(SQFUNCTION)0,0,NULL} -}; - -SQRESULT sqstd_register_iolib(HSQUIRRELVM v) -{ - SQInteger top = sq_gettop(v); - //create delegate - declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs); - sq_pushstring(v,_SC("stdout"),-1); - sqstd_createfile(v,stdout,SQFalse); - sq_newslot(v,-3,SQFalse); - sq_pushstring(v,_SC("stdin"),-1); - sqstd_createfile(v,stdin,SQFalse); - sq_newslot(v,-3,SQFalse); - sq_pushstring(v,_SC("stderr"),-1); - sqstd_createfile(v,stderr,SQFalse); - sq_newslot(v,-3,SQFalse); - sq_settop(v,top); - return SQ_OK; -} diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdlib.dsp b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdlib.dsp deleted file mode 100644 index 7453243fe..000000000 --- a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdlib.dsp +++ /dev/null @@ -1,131 +0,0 @@ -# Microsoft Developer Studio Project File - Name="sqstdlib" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=sqstdlib - Win32 Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "sqstdlib.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "sqstdlib.mak" CFG="sqstdlib - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "sqstdlib - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "sqstdlib - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_LocalPath ".." -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "sqstdlib - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "..\include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD BASE RSC /l 0x410 /d "NDEBUG" -# ADD RSC /l 0x410 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"..\lib\sqstdlib.lib" - -!ELSEIF "$(CFG)" == "sqstdlib - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD BASE RSC /l 0x410 /d "_DEBUG" -# ADD RSC /l 0x410 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"..\lib\sqstdlib.lib" - -!ENDIF - -# Begin Target - -# Name "sqstdlib - Win32 Release" -# Name "sqstdlib - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\sqstdblob.cpp -# End Source File -# Begin Source File - -SOURCE=.\sqstdio.cpp -# End Source File -# Begin Source File - -SOURCE=.\sqstdmath.cpp -# End Source File -# Begin Source File - -SOURCE=.\sqstdrex.cpp -# End Source File -# Begin Source File - -SOURCE=.\sqstdstream.cpp -# End Source File -# Begin Source File - -SOURCE=.\sqstdstring.cpp -# End Source File -# Begin Source File - -SOURCE=.\sqstdaux.cpp -# End Source File -# Begin Source File - -SOURCE=.\sqstdsystem.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\sqstdblobimpl.h -# End Source File -# Begin Source File - -SOURCE=.\sqstdstream.h -# End Source File -# End Group -# End Target -# End Project diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdmath.cpp b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdmath.cpp deleted file mode 100644 index c41ffd5e0..000000000 --- a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdmath.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include -#include - -#define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \ - SQFloat f; \ - sq_getfloat(v,2,&f); \ - sq_pushfloat(v,(SQFloat)_funcname(f)); \ - return 1; \ -} - -#define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \ - SQFloat p1,p2; \ - sq_getfloat(v,2,&p1); \ - sq_getfloat(v,3,&p2); \ - sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \ - return 1; \ -} - -static SQInteger math_srand(HSQUIRRELVM v) -{ - SQInteger i; - if(SQ_FAILED(sq_getinteger(v,2,&i))) - return sq_throwerror(v,_SC("invalid param")); - srand((unsigned int)i); - return 0; -} - -static SQInteger math_rand(HSQUIRRELVM v) -{ - sq_pushinteger(v,rand()); - return 1; -} - -static SQInteger math_abs(HSQUIRRELVM v) -{ - SQInteger n; - sq_getinteger(v,2,&n); - sq_pushinteger(v,(SQInteger)abs((int)n)); - return 1; -} - -SINGLE_ARG_FUNC(sqrt) -SINGLE_ARG_FUNC(fabs) -SINGLE_ARG_FUNC(sin) -SINGLE_ARG_FUNC(cos) -SINGLE_ARG_FUNC(asin) -SINGLE_ARG_FUNC(acos) -SINGLE_ARG_FUNC(log) -SINGLE_ARG_FUNC(log10) -SINGLE_ARG_FUNC(tan) -SINGLE_ARG_FUNC(atan) -TWO_ARGS_FUNC(atan2) -TWO_ARGS_FUNC(pow) -SINGLE_ARG_FUNC(floor) -SINGLE_ARG_FUNC(ceil) -SINGLE_ARG_FUNC(exp) - -#define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck} -static const SQRegFunction mathlib_funcs[] = { - _DECL_FUNC(sqrt,2,_SC(".n")), - _DECL_FUNC(sin,2,_SC(".n")), - _DECL_FUNC(cos,2,_SC(".n")), - _DECL_FUNC(asin,2,_SC(".n")), - _DECL_FUNC(acos,2,_SC(".n")), - _DECL_FUNC(log,2,_SC(".n")), - _DECL_FUNC(log10,2,_SC(".n")), - _DECL_FUNC(tan,2,_SC(".n")), - _DECL_FUNC(atan,2,_SC(".n")), - _DECL_FUNC(atan2,3,_SC(".nn")), - _DECL_FUNC(pow,3,_SC(".nn")), - _DECL_FUNC(floor,2,_SC(".n")), - _DECL_FUNC(ceil,2,_SC(".n")), - _DECL_FUNC(exp,2,_SC(".n")), - _DECL_FUNC(srand,2,_SC(".n")), - _DECL_FUNC(rand,1,NULL), - _DECL_FUNC(fabs,2,_SC(".n")), - _DECL_FUNC(abs,2,_SC(".n")), - {NULL,(SQFUNCTION)0,0,NULL} -}; -#undef _DECL_FUNC - -#ifndef M_PI -#define M_PI (3.14159265358979323846) -#endif - -SQRESULT sqstd_register_mathlib(HSQUIRRELVM v) -{ - SQInteger i=0; - while(mathlib_funcs[i].name!=0) { - sq_pushstring(v,mathlib_funcs[i].name,-1); - sq_newclosure(v,mathlib_funcs[i].f,0); - sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask); - sq_setnativeclosurename(v,-1,mathlib_funcs[i].name); - sq_newslot(v,-3,SQFalse); - i++; - } - sq_pushstring(v,_SC("RAND_MAX"),-1); - sq_pushinteger(v,RAND_MAX); - sq_newslot(v,-3,SQFalse); - sq_pushstring(v,_SC("PI"),-1); - sq_pushfloat(v,(SQFloat)M_PI); - sq_newslot(v,-3,SQFalse); - return SQ_OK; -} diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdrex.cpp b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdrex.cpp deleted file mode 100644 index bc6680934..000000000 --- a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdrex.cpp +++ /dev/null @@ -1,666 +0,0 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include -#include -#include - -#ifdef _DEBUG -#include - -static const SQChar *g_nnames[] = -{ - _SC("NONE"),_SC("OP_GREEDY"), _SC("OP_OR"), - _SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"), _SC("OP_CLASS"), - _SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"), - _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB"),_SC("OP_MB") -}; - -#endif - -#define OP_GREEDY (MAX_CHAR+1) // * + ? {n} -#define OP_OR (MAX_CHAR+2) -#define OP_EXPR (MAX_CHAR+3) //parentesis () -#define OP_NOCAPEXPR (MAX_CHAR+4) //parentesis (?:) -#define OP_DOT (MAX_CHAR+5) -#define OP_CLASS (MAX_CHAR+6) -#define OP_CCLASS (MAX_CHAR+7) -#define OP_NCLASS (MAX_CHAR+8) //negates class the [^ -#define OP_RANGE (MAX_CHAR+9) -#define OP_CHAR (MAX_CHAR+10) -#define OP_EOL (MAX_CHAR+11) -#define OP_BOL (MAX_CHAR+12) -#define OP_WB (MAX_CHAR+13) -#define OP_MB (MAX_CHAR+14) //match balanced - -#define SQREX_SYMBOL_ANY_CHAR ('.') -#define SQREX_SYMBOL_GREEDY_ONE_OR_MORE ('+') -#define SQREX_SYMBOL_GREEDY_ZERO_OR_MORE ('*') -#define SQREX_SYMBOL_GREEDY_ZERO_OR_ONE ('?') -#define SQREX_SYMBOL_BRANCH ('|') -#define SQREX_SYMBOL_END_OF_STRING ('$') -#define SQREX_SYMBOL_BEGINNING_OF_STRING ('^') -#define SQREX_SYMBOL_ESCAPE_CHAR ('\\') - - -typedef int SQRexNodeType; - -typedef struct tagSQRexNode{ - SQRexNodeType type; - SQInteger left; - SQInteger right; - SQInteger next; -}SQRexNode; - -struct SQRex{ - const SQChar *_eol; - const SQChar *_bol; - const SQChar *_p; - SQInteger _first; - SQInteger _op; - SQRexNode *_nodes; - SQInteger _nallocated; - SQInteger _nsize; - SQInteger _nsubexpr; - SQRexMatch *_matches; - SQInteger _currsubexp; - void *_jmpbuf; - const SQChar **_error; -}; - -static SQInteger sqstd_rex_list(SQRex *exp); - -static SQInteger sqstd_rex_newnode(SQRex *exp, SQRexNodeType type) -{ - SQRexNode n; - n.type = type; - n.next = n.right = n.left = -1; - if(type == OP_EXPR) - n.right = exp->_nsubexpr++; - if(exp->_nallocated < (exp->_nsize + 1)) { - SQInteger oldsize = exp->_nallocated; - exp->_nallocated *= 2; - exp->_nodes = (SQRexNode *)sq_realloc(exp->_nodes, oldsize * sizeof(SQRexNode) ,exp->_nallocated * sizeof(SQRexNode)); - } - exp->_nodes[exp->_nsize++] = n; - SQInteger newid = exp->_nsize - 1; - return (SQInteger)newid; -} - -static void sqstd_rex_error(SQRex *exp,const SQChar *error) -{ - if(exp->_error) *exp->_error = error; - longjmp(*((jmp_buf*)exp->_jmpbuf),-1); -} - -static void sqstd_rex_expect(SQRex *exp, SQInteger n){ - if((*exp->_p) != n) - sqstd_rex_error(exp, _SC("expected paren")); - exp->_p++; -} - -static SQChar sqstd_rex_escapechar(SQRex *exp) -{ - if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR){ - exp->_p++; - switch(*exp->_p) { - case 'v': exp->_p++; return '\v'; - case 'n': exp->_p++; return '\n'; - case 't': exp->_p++; return '\t'; - case 'r': exp->_p++; return '\r'; - case 'f': exp->_p++; return '\f'; - default: return (*exp->_p++); - } - } else if(!scisprint(*exp->_p)) sqstd_rex_error(exp,_SC("letter expected")); - return (*exp->_p++); -} - -static SQInteger sqstd_rex_charclass(SQRex *exp,SQInteger classid) -{ - SQInteger n = sqstd_rex_newnode(exp,OP_CCLASS); - exp->_nodes[n].left = classid; - return n; -} - -static SQInteger sqstd_rex_charnode(SQRex *exp,SQBool isclass) -{ - SQChar t; - if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR) { - exp->_p++; - switch(*exp->_p) { - case 'n': exp->_p++; return sqstd_rex_newnode(exp,'\n'); - case 't': exp->_p++; return sqstd_rex_newnode(exp,'\t'); - case 'r': exp->_p++; return sqstd_rex_newnode(exp,'\r'); - case 'f': exp->_p++; return sqstd_rex_newnode(exp,'\f'); - case 'v': exp->_p++; return sqstd_rex_newnode(exp,'\v'); - case 'a': case 'A': case 'w': case 'W': case 's': case 'S': - case 'd': case 'D': case 'x': case 'X': case 'c': case 'C': - case 'p': case 'P': case 'l': case 'u': - { - t = *exp->_p; exp->_p++; - return sqstd_rex_charclass(exp,t); - } - case 'm': - { - SQChar cb, ce; //cb = character begin match ce = character end match - cb = *++exp->_p; //skip 'm' - ce = *++exp->_p; - exp->_p++; //points to the next char to be parsed - if ((!cb) || (!ce)) sqstd_rex_error(exp,_SC("balanced chars expected")); - if ( cb == ce ) sqstd_rex_error(exp,_SC("open/close char can't be the same")); - SQInteger node = sqstd_rex_newnode(exp,OP_MB); - exp->_nodes[node].left = cb; - exp->_nodes[node].right = ce; - return node; - } - case 0: - sqstd_rex_error(exp,_SC("letter expected for argument of escape sequence")); - break; - case 'b': - case 'B': - if(!isclass) { - SQInteger node = sqstd_rex_newnode(exp,OP_WB); - exp->_nodes[node].left = *exp->_p; - exp->_p++; - return node; - } //else default - default: - t = *exp->_p; exp->_p++; - return sqstd_rex_newnode(exp,t); - } - } - else if(!scisprint(*exp->_p)) { - - sqstd_rex_error(exp,_SC("letter expected")); - } - t = *exp->_p; exp->_p++; - return sqstd_rex_newnode(exp,t); -} -static SQInteger sqstd_rex_class(SQRex *exp) -{ - SQInteger ret = -1; - SQInteger first = -1,chain; - if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING){ - ret = sqstd_rex_newnode(exp,OP_NCLASS); - exp->_p++; - }else ret = sqstd_rex_newnode(exp,OP_CLASS); - - if(*exp->_p == ']') sqstd_rex_error(exp,_SC("empty class")); - chain = ret; - while(*exp->_p != ']' && exp->_p != exp->_eol) { - if(*exp->_p == '-' && first != -1){ - SQInteger r; - if(*exp->_p++ == ']') sqstd_rex_error(exp,_SC("unfinished range")); - r = sqstd_rex_newnode(exp,OP_RANGE); - if(exp->_nodes[first].type>*exp->_p) sqstd_rex_error(exp,_SC("invalid range")); - if(exp->_nodes[first].type == OP_CCLASS) sqstd_rex_error(exp,_SC("cannot use character classes in ranges")); - exp->_nodes[r].left = exp->_nodes[first].type; - SQInteger t = sqstd_rex_escapechar(exp); - exp->_nodes[r].right = t; - exp->_nodes[chain].next = r; - chain = r; - first = -1; - } - else{ - if(first!=-1){ - SQInteger c = first; - exp->_nodes[chain].next = c; - chain = c; - first = sqstd_rex_charnode(exp,SQTrue); - } - else{ - first = sqstd_rex_charnode(exp,SQTrue); - } - } - } - if(first!=-1){ - SQInteger c = first; - exp->_nodes[chain].next = c; - } - /* hack? */ - exp->_nodes[ret].left = exp->_nodes[ret].next; - exp->_nodes[ret].next = -1; - return ret; -} - -static SQInteger sqstd_rex_parsenumber(SQRex *exp) -{ - SQInteger ret = *exp->_p-'0'; - SQInteger positions = 10; - exp->_p++; - while(isdigit(*exp->_p)) { - ret = ret*10+(*exp->_p++-'0'); - if(positions==1000000000) sqstd_rex_error(exp,_SC("overflow in numeric constant")); - positions *= 10; - }; - return ret; -} - -static SQInteger sqstd_rex_element(SQRex *exp) -{ - SQInteger ret = -1; - switch(*exp->_p) - { - case '(': { - SQInteger expr; - exp->_p++; - - - if(*exp->_p =='?') { - exp->_p++; - sqstd_rex_expect(exp,':'); - expr = sqstd_rex_newnode(exp,OP_NOCAPEXPR); - } - else - expr = sqstd_rex_newnode(exp,OP_EXPR); - SQInteger newn = sqstd_rex_list(exp); - exp->_nodes[expr].left = newn; - ret = expr; - sqstd_rex_expect(exp,')'); - } - break; - case '[': - exp->_p++; - ret = sqstd_rex_class(exp); - sqstd_rex_expect(exp,']'); - break; - case SQREX_SYMBOL_END_OF_STRING: exp->_p++; ret = sqstd_rex_newnode(exp,OP_EOL);break; - case SQREX_SYMBOL_ANY_CHAR: exp->_p++; ret = sqstd_rex_newnode(exp,OP_DOT);break; - default: - ret = sqstd_rex_charnode(exp,SQFalse); - break; - } - - - SQBool isgreedy = SQFalse; - unsigned short p0 = 0, p1 = 0; - switch(*exp->_p){ - case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break; - case SQREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break; - case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; isgreedy = SQTrue; break; - case '{': - exp->_p++; - if(!isdigit(*exp->_p)) sqstd_rex_error(exp,_SC("number expected")); - p0 = (unsigned short)sqstd_rex_parsenumber(exp); - /*******************************/ - switch(*exp->_p) { - case '}': - p1 = p0; exp->_p++; - break; - case ',': - exp->_p++; - p1 = 0xFFFF; - if(isdigit(*exp->_p)){ - p1 = (unsigned short)sqstd_rex_parsenumber(exp); - } - sqstd_rex_expect(exp,'}'); - break; - default: - sqstd_rex_error(exp,_SC(", or } expected")); - } - /*******************************/ - isgreedy = SQTrue; - break; - - } - if(isgreedy) { - SQInteger nnode = sqstd_rex_newnode(exp,OP_GREEDY); - exp->_nodes[nnode].left = ret; - exp->_nodes[nnode].right = ((p0)<<16)|p1; - ret = nnode; - } - - if((*exp->_p != SQREX_SYMBOL_BRANCH) && (*exp->_p != ')') && (*exp->_p != SQREX_SYMBOL_GREEDY_ZERO_OR_MORE) && (*exp->_p != SQREX_SYMBOL_GREEDY_ONE_OR_MORE) && (*exp->_p != '\0')) { - SQInteger nnode = sqstd_rex_element(exp); - exp->_nodes[ret].next = nnode; - } - - return ret; -} - -static SQInteger sqstd_rex_list(SQRex *exp) -{ - SQInteger ret=-1,e; - if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING) { - exp->_p++; - ret = sqstd_rex_newnode(exp,OP_BOL); - } - e = sqstd_rex_element(exp); - if(ret != -1) { - exp->_nodes[ret].next = e; - } - else ret = e; - - if(*exp->_p == SQREX_SYMBOL_BRANCH) { - SQInteger temp,tright; - exp->_p++; - temp = sqstd_rex_newnode(exp,OP_OR); - exp->_nodes[temp].left = ret; - tright = sqstd_rex_list(exp); - exp->_nodes[temp].right = tright; - ret = temp; - } - return ret; -} - -static SQBool sqstd_rex_matchcclass(SQInteger cclass,SQChar c) -{ - switch(cclass) { - case 'a': return isalpha(c)?SQTrue:SQFalse; - case 'A': return !isalpha(c)?SQTrue:SQFalse; - case 'w': return (isalnum(c) || c == '_')?SQTrue:SQFalse; - case 'W': return (!isalnum(c) && c != '_')?SQTrue:SQFalse; - case 's': return isspace(c)?SQTrue:SQFalse; - case 'S': return !isspace(c)?SQTrue:SQFalse; - case 'd': return isdigit(c)?SQTrue:SQFalse; - case 'D': return !isdigit(c)?SQTrue:SQFalse; - case 'x': return isxdigit(c)?SQTrue:SQFalse; - case 'X': return !isxdigit(c)?SQTrue:SQFalse; - case 'c': return iscntrl(c)?SQTrue:SQFalse; - case 'C': return !iscntrl(c)?SQTrue:SQFalse; - case 'p': return ispunct(c)?SQTrue:SQFalse; - case 'P': return !ispunct(c)?SQTrue:SQFalse; - case 'l': return islower(c)?SQTrue:SQFalse; - case 'u': return isupper(c)?SQTrue:SQFalse; - } - return SQFalse; /*cannot happen*/ -} - -static SQBool sqstd_rex_matchclass(SQRex* exp,SQRexNode *node,SQChar c) -{ - do { - switch(node->type) { - case OP_RANGE: - if(c >= node->left && c <= node->right) return SQTrue; - break; - case OP_CCLASS: - if(sqstd_rex_matchcclass(node->left,c)) return SQTrue; - break; - default: - if(c == node->type)return SQTrue; - } - } while((node->next != -1) && (node = &exp->_nodes[node->next])); - return SQFalse; -} - -static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar *str,SQRexNode *next) -{ - - SQRexNodeType type = node->type; - switch(type) { - case OP_GREEDY: { - //SQRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL; - SQRexNode *greedystop = NULL; - SQInteger p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0; - const SQChar *s=str, *good = str; - - if(node->next != -1) { - greedystop = &exp->_nodes[node->next]; - } - else { - greedystop = next; - } - - while((nmaches == 0xFFFF || nmaches < p1)) { - - const SQChar *stop; - if(!(s = sqstd_rex_matchnode(exp,&exp->_nodes[node->left],s,greedystop))) - break; - nmaches++; - good=s; - if(greedystop) { - //checks that 0 matches satisfy the expression(if so skips) - //if not would always stop(for instance if is a '?') - if(greedystop->type != OP_GREEDY || - (greedystop->type == OP_GREEDY && ((greedystop->right >> 16)&0x0000FFFF) != 0)) - { - SQRexNode *gnext = NULL; - if(greedystop->next != -1) { - gnext = &exp->_nodes[greedystop->next]; - }else if(next && next->next != -1){ - gnext = &exp->_nodes[next->next]; - } - stop = sqstd_rex_matchnode(exp,greedystop,s,gnext); - if(stop) { - //if satisfied stop it - if(p0 == p1 && p0 == nmaches) break; - else if(nmaches >= p0 && p1 == 0xFFFF) break; - else if(nmaches >= p0 && nmaches <= p1) break; - } - } - } - - if(s >= exp->_eol) - break; - } - if(p0 == p1 && p0 == nmaches) return good; - else if(nmaches >= p0 && p1 == 0xFFFF) return good; - else if(nmaches >= p0 && nmaches <= p1) return good; - return NULL; - } - case OP_OR: { - const SQChar *asd = str; - SQRexNode *temp=&exp->_nodes[node->left]; - while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) { - if(temp->next != -1) - temp = &exp->_nodes[temp->next]; - else - return asd; - } - asd = str; - temp = &exp->_nodes[node->right]; - while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) { - if(temp->next != -1) - temp = &exp->_nodes[temp->next]; - else - return asd; - } - return NULL; - break; - } - case OP_EXPR: - case OP_NOCAPEXPR:{ - SQRexNode *n = &exp->_nodes[node->left]; - const SQChar *cur = str; - SQInteger capture = -1; - if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) { - capture = exp->_currsubexp; - exp->_matches[capture].begin = cur; - exp->_currsubexp++; - } - SQInteger tempcap = exp->_currsubexp; - do { - SQRexNode *subnext = NULL; - if(n->next != -1) { - subnext = &exp->_nodes[n->next]; - }else { - subnext = next; - } - if(!(cur = sqstd_rex_matchnode(exp,n,cur,subnext))) { - if(capture != -1){ - exp->_matches[capture].begin = 0; - exp->_matches[capture].len = 0; - } - return NULL; - } - } while((n->next != -1) && (n = &exp->_nodes[n->next])); - - exp->_currsubexp = tempcap; - if(capture != -1) - exp->_matches[capture].len = cur - exp->_matches[capture].begin; - return cur; - } - case OP_WB: - if((str == exp->_bol && !isspace(*str)) - || (str == exp->_eol && !isspace(*(str-1))) - || (!isspace(*str) && isspace(*(str+1))) - || (isspace(*str) && !isspace(*(str+1))) ) { - return (node->left == 'b')?str:NULL; - } - return (node->left == 'b')?NULL:str; - case OP_BOL: - if(str == exp->_bol) return str; - return NULL; - case OP_EOL: - if(str == exp->_eol) return str; - return NULL; - case OP_DOT:{ - if (str == exp->_eol) return NULL; - str++; - } - return str; - case OP_NCLASS: - case OP_CLASS: - if (str == exp->_eol) return NULL; - if(sqstd_rex_matchclass(exp,&exp->_nodes[node->left],*str)?(type == OP_CLASS?SQTrue:SQFalse):(type == OP_NCLASS?SQTrue:SQFalse)) { - str++; - return str; - } - return NULL; - case OP_CCLASS: - if (str == exp->_eol) return NULL; - if(sqstd_rex_matchcclass(node->left,*str)) { - str++; - return str; - } - return NULL; - case OP_MB: - { - SQInteger cb = node->left; //char that opens a balanced expression - if(*str != cb) return NULL; // string doesn't start with open char - SQInteger ce = node->right; //char that closes a balanced expression - SQInteger cont = 1; - const SQChar *streol = exp->_eol; - while (++str < streol) { - if (*str == ce) { - if (--cont == 0) { - return ++str; - } - } - else if (*str == cb) cont++; - } - } - return NULL; // string ends out of balance - default: /* char */ - if (str == exp->_eol) return NULL; - if(*str != node->type) return NULL; - str++; - return str; - } - return NULL; -} - -/* public api */ -SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error) -{ - SQRex * volatile exp = (SQRex *)sq_malloc(sizeof(SQRex)); // "volatile" is needed for setjmp() - exp->_eol = exp->_bol = NULL; - exp->_p = pattern; - exp->_nallocated = (SQInteger)scstrlen(pattern) * sizeof(SQChar); - exp->_nodes = (SQRexNode *)sq_malloc(exp->_nallocated * sizeof(SQRexNode)); - exp->_nsize = 0; - exp->_matches = 0; - exp->_nsubexpr = 0; - exp->_first = sqstd_rex_newnode(exp,OP_EXPR); - exp->_error = error; - exp->_jmpbuf = sq_malloc(sizeof(jmp_buf)); - if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) { - SQInteger res = sqstd_rex_list(exp); - exp->_nodes[exp->_first].left = res; - if(*exp->_p!='\0') - sqstd_rex_error(exp,_SC("unexpected character")); -#ifdef _DEBUG - { - SQInteger nsize,i; - SQRexNode *t; - nsize = exp->_nsize; - t = &exp->_nodes[0]; - scprintf(_SC("\n")); - for(i = 0;i < nsize; i++) { - if(exp->_nodes[i].type>MAX_CHAR) - scprintf(_SC("[%02d] %10s "), (SQInt32)i,g_nnames[exp->_nodes[i].type-MAX_CHAR]); - else - scprintf(_SC("[%02d] %10c "), (SQInt32)i,exp->_nodes[i].type); - scprintf(_SC("left %02d right %02d next %02d\n"), (SQInt32)exp->_nodes[i].left, (SQInt32)exp->_nodes[i].right, (SQInt32)exp->_nodes[i].next); - } - scprintf(_SC("\n")); - } -#endif - exp->_matches = (SQRexMatch *) sq_malloc(exp->_nsubexpr * sizeof(SQRexMatch)); - memset(exp->_matches,0,exp->_nsubexpr * sizeof(SQRexMatch)); - } - else{ - sqstd_rex_free(exp); - return NULL; - } - return exp; -} - -void sqstd_rex_free(SQRex *exp) -{ - if(exp) { - if(exp->_nodes) sq_free(exp->_nodes,exp->_nallocated * sizeof(SQRexNode)); - if(exp->_jmpbuf) sq_free(exp->_jmpbuf,sizeof(jmp_buf)); - if(exp->_matches) sq_free(exp->_matches,exp->_nsubexpr * sizeof(SQRexMatch)); - sq_free(exp,sizeof(SQRex)); - } -} - -SQBool sqstd_rex_match(SQRex* exp,const SQChar* text) -{ - const SQChar* res = NULL; - exp->_bol = text; - exp->_eol = text + scstrlen(text); - exp->_currsubexp = 0; - res = sqstd_rex_matchnode(exp,exp->_nodes,text,NULL); - if(res == NULL || res != exp->_eol) - return SQFalse; - return SQTrue; -} - -SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end) -{ - const SQChar *cur = NULL; - SQInteger node = exp->_first; - if(text_begin >= text_end) return SQFalse; - exp->_bol = text_begin; - exp->_eol = text_end; - do { - cur = text_begin; - while(node != -1) { - exp->_currsubexp = 0; - cur = sqstd_rex_matchnode(exp,&exp->_nodes[node],cur,NULL); - if(!cur) - break; - node = exp->_nodes[node].next; - } - text_begin++; - } while(cur == NULL && text_begin != text_end); - - if(cur == NULL) - return SQFalse; - - --text_begin; - - if(out_begin) *out_begin = text_begin; - if(out_end) *out_end = cur; - return SQTrue; -} - -SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end) -{ - return sqstd_rex_searchrange(exp,text,text + scstrlen(text),out_begin,out_end); -} - -SQInteger sqstd_rex_getsubexpcount(SQRex* exp) -{ - return exp->_nsubexpr; -} - -SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp) -{ - if( n<0 || n >= exp->_nsubexpr) return SQFalse; - *subexp = exp->_matches[n]; - return SQTrue; -} - diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdstream.cpp b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdstream.cpp deleted file mode 100644 index 605a56c5e..000000000 --- a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdstream.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include -#include -#include -#include -#include -#include "sqstdstream.h" -#include "sqstdblobimpl.h" - -#define SETUP_STREAM(v) \ - SQStream *self = NULL; \ - if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)((SQUnsignedInteger)SQSTD_STREAM_TYPE_TAG),SQFalse))) \ - return sq_throwerror(v,_SC("invalid type tag")); \ - if(!self || !self->IsValid()) \ - return sq_throwerror(v,_SC("the stream is invalid")); - -SQInteger _stream_readblob(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - SQUserPointer data,blobp; - SQInteger size,res; - sq_getinteger(v,2,&size); - if(size > self->Len()) { - size = self->Len(); - } - data = sq_getscratchpad(v,size); - res = self->Read(data,size); - if(res <= 0) - return sq_throwerror(v,_SC("no data left to read")); - blobp = sqstd_createblob(v,res); - memcpy(blobp,data,res); - return 1; -} - -#define SAFE_READN(ptr,len) { \ - if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \ - } -SQInteger _stream_readn(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - SQInteger format; - sq_getinteger(v, 2, &format); - switch(format) { - case 'l': { - SQInteger i; - SAFE_READN(&i, sizeof(i)); - sq_pushinteger(v, i); - } - break; - case 'i': { - SQInt32 i; - SAFE_READN(&i, sizeof(i)); - sq_pushinteger(v, i); - } - break; - case 's': { - short s; - SAFE_READN(&s, sizeof(short)); - sq_pushinteger(v, s); - } - break; - case 'w': { - unsigned short w; - SAFE_READN(&w, sizeof(unsigned short)); - sq_pushinteger(v, w); - } - break; - case 'c': { - char c; - SAFE_READN(&c, sizeof(char)); - sq_pushinteger(v, c); - } - break; - case 'b': { - unsigned char c; - SAFE_READN(&c, sizeof(unsigned char)); - sq_pushinteger(v, c); - } - break; - case 'f': { - float f; - SAFE_READN(&f, sizeof(float)); - sq_pushfloat(v, f); - } - break; - case 'd': { - double d; - SAFE_READN(&d, sizeof(double)); - sq_pushfloat(v, (SQFloat)d); - } - break; - default: - return sq_throwerror(v, _SC("invalid format")); - } - return 1; -} - -SQInteger _stream_writeblob(HSQUIRRELVM v) -{ - SQUserPointer data; - SQInteger size; - SETUP_STREAM(v); - if(SQ_FAILED(sqstd_getblob(v,2,&data))) - return sq_throwerror(v,_SC("invalid parameter")); - size = sqstd_getblobsize(v,2); - if(self->Write(data,size) != size) - return sq_throwerror(v,_SC("io error")); - sq_pushinteger(v,size); - return 1; -} - -SQInteger _stream_writen(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - SQInteger format, ti; - SQFloat tf; - sq_getinteger(v, 3, &format); - switch(format) { - case 'l': { - SQInteger i; - sq_getinteger(v, 2, &ti); - i = ti; - self->Write(&i, sizeof(SQInteger)); - } - break; - case 'i': { - SQInt32 i; - sq_getinteger(v, 2, &ti); - i = (SQInt32)ti; - self->Write(&i, sizeof(SQInt32)); - } - break; - case 's': { - short s; - sq_getinteger(v, 2, &ti); - s = (short)ti; - self->Write(&s, sizeof(short)); - } - break; - case 'w': { - unsigned short w; - sq_getinteger(v, 2, &ti); - w = (unsigned short)ti; - self->Write(&w, sizeof(unsigned short)); - } - break; - case 'c': { - char c; - sq_getinteger(v, 2, &ti); - c = (char)ti; - self->Write(&c, sizeof(char)); - } - break; - case 'b': { - unsigned char b; - sq_getinteger(v, 2, &ti); - b = (unsigned char)ti; - self->Write(&b, sizeof(unsigned char)); - } - break; - case 'f': { - float f; - sq_getfloat(v, 2, &tf); - f = (float)tf; - self->Write(&f, sizeof(float)); - } - break; - case 'd': { - double d; - sq_getfloat(v, 2, &tf); - d = tf; - self->Write(&d, sizeof(double)); - } - break; - default: - return sq_throwerror(v, _SC("invalid format")); - } - return 0; -} - -SQInteger _stream_seek(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - SQInteger offset, origin = SQ_SEEK_SET; - sq_getinteger(v, 2, &offset); - if(sq_gettop(v) > 2) { - SQInteger t; - sq_getinteger(v, 3, &t); - switch(t) { - case 'b': origin = SQ_SEEK_SET; break; - case 'c': origin = SQ_SEEK_CUR; break; - case 'e': origin = SQ_SEEK_END; break; - default: return sq_throwerror(v,_SC("invalid origin")); - } - } - sq_pushinteger(v, self->Seek(offset, origin)); - return 1; -} - -SQInteger _stream_tell(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - sq_pushinteger(v, self->Tell()); - return 1; -} - -SQInteger _stream_len(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - sq_pushinteger(v, self->Len()); - return 1; -} - -SQInteger _stream_flush(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - if(!self->Flush()) - sq_pushinteger(v, 1); - else - sq_pushnull(v); - return 1; -} - -SQInteger _stream_eos(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - if(self->EOS()) - sq_pushinteger(v, 1); - else - sq_pushnull(v); - return 1; -} - - SQInteger _stream__cloned(HSQUIRRELVM v) - { - return sq_throwerror(v,_SC("this object cannot be cloned")); - } - -static const SQRegFunction _stream_methods[] = { - _DECL_STREAM_FUNC(readblob,2,_SC("xn")), - _DECL_STREAM_FUNC(readn,2,_SC("xn")), - _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")), - _DECL_STREAM_FUNC(writen,3,_SC("xnn")), - _DECL_STREAM_FUNC(seek,-2,_SC("xnn")), - _DECL_STREAM_FUNC(tell,1,_SC("x")), - _DECL_STREAM_FUNC(len,1,_SC("x")), - _DECL_STREAM_FUNC(eos,1,_SC("x")), - _DECL_STREAM_FUNC(flush,1,_SC("x")), - _DECL_STREAM_FUNC(_cloned,0,NULL), - {NULL,(SQFUNCTION)0,0,NULL} -}; - -void init_streamclass(HSQUIRRELVM v) -{ - sq_pushregistrytable(v); - sq_pushstring(v,_SC("std_stream"),-1); - if(SQ_FAILED(sq_get(v,-2))) { - sq_pushstring(v,_SC("std_stream"),-1); - sq_newclass(v,SQFalse); - sq_settypetag(v,-1,(SQUserPointer)((SQUnsignedInteger)SQSTD_STREAM_TYPE_TAG)); - SQInteger i = 0; - while(_stream_methods[i].name != 0) { - const SQRegFunction &f = _stream_methods[i]; - sq_pushstring(v,f.name,-1); - sq_newclosure(v,f.f,0); - sq_setparamscheck(v,f.nparamscheck,f.typemask); - sq_newslot(v,-3,SQFalse); - i++; - } - sq_newslot(v,-3,SQFalse); - sq_pushroottable(v); - sq_pushstring(v,_SC("stream"),-1); - sq_pushstring(v,_SC("std_stream"),-1); - sq_get(v,-4); - sq_newslot(v,-3,SQFalse); - sq_pop(v,1); - } - else { - sq_pop(v,1); //result - } - sq_pop(v,1); -} - -SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,const SQRegFunction *methods,const SQRegFunction *globals) -{ - if(sq_gettype(v,-1) != OT_TABLE) - return sq_throwerror(v,_SC("table expected")); - SQInteger top = sq_gettop(v); - //create delegate - init_streamclass(v); - sq_pushregistrytable(v); - sq_pushstring(v,reg_name,-1); - sq_pushstring(v,_SC("std_stream"),-1); - if(SQ_SUCCEEDED(sq_get(v,-3))) { - sq_newclass(v,SQTrue); - sq_settypetag(v,-1,typetag); - SQInteger i = 0; - while(methods[i].name != 0) { - const SQRegFunction &f = methods[i]; - sq_pushstring(v,f.name,-1); - sq_newclosure(v,f.f,0); - sq_setparamscheck(v,f.nparamscheck,f.typemask); - sq_setnativeclosurename(v,-1,f.name); - sq_newslot(v,-3,SQFalse); - i++; - } - sq_newslot(v,-3,SQFalse); - sq_pop(v,1); - - i = 0; - while(globals[i].name!=0) - { - const SQRegFunction &f = globals[i]; - sq_pushstring(v,f.name,-1); - sq_newclosure(v,f.f,0); - sq_setparamscheck(v,f.nparamscheck,f.typemask); - sq_setnativeclosurename(v,-1,f.name); - sq_newslot(v,-3,SQFalse); - i++; - } - //register the class in the target table - sq_pushstring(v,name,-1); - sq_pushregistrytable(v); - sq_pushstring(v,reg_name,-1); - sq_get(v,-2); - sq_remove(v,-2); - sq_newslot(v,-3,SQFalse); - - sq_settop(v,top); - return SQ_OK; - } - sq_settop(v,top); - return SQ_ERROR; -} diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdstream.h b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdstream.h deleted file mode 100644 index 969d74458..000000000 --- a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdstream.h +++ /dev/null @@ -1,23 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQSTD_STREAM_H_ -#define _SQSTD_STREAM_H_ - -SQInteger _stream_readblob(HSQUIRRELVM v); -SQInteger _stream_readline(HSQUIRRELVM v); -SQInteger _stream_readn(HSQUIRRELVM v); -SQInteger _stream_writeblob(HSQUIRRELVM v); -SQInteger _stream_writen(HSQUIRRELVM v); -SQInteger _stream_seek(HSQUIRRELVM v); -SQInteger _stream_tell(HSQUIRRELVM v); -SQInteger _stream_len(HSQUIRRELVM v); -SQInteger _stream_eos(HSQUIRRELVM v); -SQInteger _stream_flush(HSQUIRRELVM v); - -#define _DECL_STREAM_FUNC(name, nparams, typecheck) \ - { \ - _SC(#name), _stream_##name, nparams, typecheck \ - } -SQRESULT declare_stream(HSQUIRRELVM v, const SQChar *name, - SQUserPointer typetag, const SQChar *reg_name, - const SQRegFunction *methods, const SQRegFunction *globals); -#endif /*_SQSTD_STREAM_H_*/ diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdstring.cpp b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdstring.cpp deleted file mode 100644 index ca3df3ed8..000000000 --- a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdstring.cpp +++ /dev/null @@ -1,552 +0,0 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX_FORMAT_LEN 20 -#define MAX_WFORMAT_LEN 3 -#define ADDITIONAL_FORMAT_SPACE (100*sizeof(SQChar)) - -static SQUserPointer rex_typetag = NULL; - -static SQBool isfmtchr(SQChar ch) -{ - switch(ch) { - case '-': case '+': case ' ': case '#': case '0': return SQTrue; - } - return SQFalse; -} - -static SQInteger validate_format(HSQUIRRELVM v, SQChar *fmt, const SQChar *src, SQInteger n,SQInteger &width) -{ - SQChar *dummy; - SQChar swidth[MAX_WFORMAT_LEN]; - SQInteger wc = 0; - SQInteger start = n; - fmt[0] = '%'; - while (isfmtchr(src[n])) n++; - while (scisdigit(src[n])) { - swidth[wc] = src[n]; - n++; - wc++; - if(wc>=MAX_WFORMAT_LEN) - return sq_throwerror(v,_SC("width format too long")); - } - swidth[wc] = '\0'; - if(wc > 0) { - width = scstrtol(swidth,&dummy,10); - } - else - width = 0; - if (src[n] == '.') { - n++; - - wc = 0; - while (scisdigit(src[n])) { - swidth[wc] = src[n]; - n++; - wc++; - if(wc>=MAX_WFORMAT_LEN) - return sq_throwerror(v,_SC("precision format too long")); - } - swidth[wc] = '\0'; - if(wc > 0) { - width += scstrtol(swidth,&dummy,10); - - } - } - if (n-start > MAX_FORMAT_LEN ) - return sq_throwerror(v,_SC("format too long")); - memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(SQChar)); - fmt[(n-start)+2] = '\0'; - return n; -} - -SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output) -{ - const SQChar *format; - SQChar *dest; - SQChar fmt[MAX_FORMAT_LEN]; - const SQRESULT res = sq_getstring(v,nformatstringidx,&format); - if (SQ_FAILED(res)) { - return res; // propagate the error - } - SQInteger format_size = sq_getsize(v,nformatstringidx); - SQInteger allocated = (format_size+2)*sizeof(SQChar); - dest = sq_getscratchpad(v,allocated); - SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0; - //while(format[n] != '\0') - while(n < format_size) - { - if(format[n] != '%') { - assert(i < allocated); - dest[i++] = format[n]; - n++; - } - else if(format[n+1] == '%') { //handles %% - dest[i++] = '%'; - n += 2; - } - else { - n++; - if( nparam > sq_gettop(v) ) - return sq_throwerror(v,_SC("not enough parameters for the given format string")); - n = validate_format(v,fmt,format,n,w); - if(n < 0) return -1; - SQInteger addlen = 0; - SQInteger valtype = 0; - const SQChar *ts = NULL; - SQInteger ti = 0; - SQFloat tf = 0; - switch(format[n]) { - case 's': - if(SQ_FAILED(sq_getstring(v,nparam,&ts))) - return sq_throwerror(v,_SC("string expected for the specified format")); - addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar)); - valtype = 's'; - break; - case 'i': case 'd': case 'o': case 'u': case 'x': case 'X': -#ifdef _SQ64 - { - size_t flen = scstrlen(fmt); - SQInteger fpos = flen - 1; - SQChar f = fmt[fpos]; - const SQChar *prec = (const SQChar *)_PRINT_INT_PREC; - while(*prec != _SC('\0')) { - fmt[fpos++] = *prec++; - } - fmt[fpos++] = f; - fmt[fpos++] = _SC('\0'); - } -#endif - case 'c': - if(SQ_FAILED(sq_getinteger(v,nparam,&ti))) - return sq_throwerror(v,_SC("integer expected for the specified format")); - addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar)); - valtype = 'i'; - break; - case 'f': case 'g': case 'G': case 'e': case 'E': - if(SQ_FAILED(sq_getfloat(v,nparam,&tf))) - return sq_throwerror(v,_SC("float expected for the specified format")); - addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar)); - valtype = 'f'; - break; - default: - return sq_throwerror(v,_SC("invalid format")); - } - n++; - allocated += addlen + sizeof(SQChar); - dest = sq_getscratchpad(v,allocated); - switch(valtype) { - case 's': i += scsprintf(&dest[i],allocated,fmt,ts); break; - case 'i': i += scsprintf(&dest[i],allocated,fmt,ti); break; - case 'f': i += scsprintf(&dest[i],allocated,fmt,tf); break; - }; - nparam ++; - } - } - *outlen = i; - dest[i] = '\0'; - *output = dest; - return SQ_OK; -} - -void sqstd_pushstringf(HSQUIRRELVM v,const SQChar *s,...) -{ - SQInteger n=256; - va_list args; -begin: - va_start(args,s); - SQChar *b=sq_getscratchpad(v,n); - SQInteger r=scvsprintf(b,n,s,args); - va_end(args); - if (r>=n) { - n=r+1;//required+null - goto begin; - } else if (r<0) { - sq_pushnull(v); - } else { - sq_pushstring(v,b,r); - } -} - -static SQInteger _string_printf(HSQUIRRELVM v) -{ - SQChar *dest = NULL; - SQInteger length = 0; - if(SQ_FAILED(sqstd_format(v,2,&length,&dest))) - return -1; - - SQPRINTFUNCTION printfunc = sq_getprintfunc(v); - if(printfunc) printfunc(v,_SC("%s"),dest); - - return 0; -} - -static SQInteger _string_format(HSQUIRRELVM v) -{ - SQChar *dest = NULL; - SQInteger length = 0; - if(SQ_FAILED(sqstd_format(v,2,&length,&dest))) - return -1; - sq_pushstring(v,dest,length); - return 1; -} - -static void __strip_l(const SQChar *str,const SQChar **start) -{ - const SQChar *t = str; - while(((*t) != '\0') && scisspace(*t)){ t++; } - *start = t; -} - -static void __strip_r(const SQChar *str,SQInteger len,const SQChar **end) -{ - if(len == 0) { - *end = str; - return; - } - const SQChar *t = &str[len-1]; - while(t >= str && scisspace(*t)) { t--; } - *end = t + 1; -} - -static SQInteger _string_strip(HSQUIRRELVM v) -{ - const SQChar *str,*start,*end; - sq_getstring(v,2,&str); - SQInteger len = sq_getsize(v,2); - __strip_l(str,&start); - __strip_r(str,len,&end); - sq_pushstring(v,start,end - start); - return 1; -} - -static SQInteger _string_lstrip(HSQUIRRELVM v) -{ - const SQChar *str,*start; - sq_getstring(v,2,&str); - __strip_l(str,&start); - sq_pushstring(v,start,-1); - return 1; -} - -static SQInteger _string_rstrip(HSQUIRRELVM v) -{ - const SQChar *str,*end; - sq_getstring(v,2,&str); - SQInteger len = sq_getsize(v,2); - __strip_r(str,len,&end); - sq_pushstring(v,str,end - str); - return 1; -} - -static SQInteger _string_split(HSQUIRRELVM v) -{ - const SQChar *str,*seps; - SQInteger sepsize; - SQBool skipempty = SQFalse; - sq_getstring(v,2,&str); - sq_getstringandsize(v,3,&seps,&sepsize); - if(sepsize == 0) return sq_throwerror(v,_SC("empty separators string")); - if(sq_gettop(v)>3) { - sq_getbool(v,4,&skipempty); - } - const SQChar *start = str; - const SQChar *end = str; - sq_newarray(v,0); - while(*end != '\0') - { - SQChar cur = *end; - for(SQInteger i = 0; i < sepsize; i++) - { - if(cur == seps[i]) - { - if(!skipempty || (end != start)) { - sq_pushstring(v,start,end-start); - sq_arrayappend(v,-2); - } - start = end + 1; - break; - } - } - end++; - } - if(end != start) - { - sq_pushstring(v,start,end-start); - sq_arrayappend(v,-2); - } - return 1; -} - -static SQInteger _string_escape(HSQUIRRELVM v) -{ - const SQChar *str; - SQChar *dest,*resstr; - SQInteger size; - sq_getstring(v,2,&str); - size = sq_getsize(v,2); - if(size == 0) { - sq_push(v,2); - return 1; - } -#ifdef SQUNICODE -#if WCHAR_SIZE == 2 - const SQChar *escpat = _SC("\\x%04x"); - const SQInteger maxescsize = 6; -#else //WCHAR_SIZE == 4 - const SQChar *escpat = _SC("\\x%08x"); - const SQInteger maxescsize = 10; -#endif -#else - const SQChar *escpat = _SC("\\x%02x"); - const SQInteger maxescsize = 4; -#endif - SQInteger destcharsize = (size * maxescsize); //assumes every char could be escaped - resstr = dest = (SQChar *)sq_getscratchpad(v,destcharsize * sizeof(SQChar)); - SQChar c; - SQChar escch; - SQInteger escaped = 0; - for(int n = 0; n < size; n++){ - c = *str++; - escch = 0; - if(scisprint(c) || c == 0) { - switch(c) { - case '\a': escch = 'a'; break; - case '\b': escch = 'b'; break; - case '\t': escch = 't'; break; - case '\n': escch = 'n'; break; - case '\v': escch = 'v'; break; - case '\f': escch = 'f'; break; - case '\r': escch = 'r'; break; - case '\\': escch = '\\'; break; - case '\"': escch = '\"'; break; - case '\'': escch = '\''; break; - case 0: escch = '0'; break; - } - if(escch) { - *dest++ = '\\'; - *dest++ = escch; - escaped++; - } - else { - *dest++ = c; - } - } - else { - - dest += scsprintf(dest, destcharsize, escpat, c); - escaped++; - } - } - - if(escaped) { - sq_pushstring(v,resstr,dest - resstr); - } - else { - sq_push(v,2); //nothing escaped - } - return 1; -} - -static SQInteger _string_startswith(HSQUIRRELVM v) -{ - const SQChar *str,*cmp; - sq_getstring(v,2,&str); - sq_getstring(v,3,&cmp); - SQInteger len = sq_getsize(v,2); - SQInteger cmplen = sq_getsize(v,3); - SQBool ret = SQFalse; - if(cmplen <= len) { - ret = memcmp(str,cmp,sq_rsl(cmplen)) == 0 ? SQTrue : SQFalse; - } - sq_pushbool(v,ret); - return 1; -} - -static SQInteger _string_endswith(HSQUIRRELVM v) -{ - const SQChar *str,*cmp; - sq_getstring(v,2,&str); - sq_getstring(v,3,&cmp); - SQInteger len = sq_getsize(v,2); - SQInteger cmplen = sq_getsize(v,3); - SQBool ret = SQFalse; - if(cmplen <= len) { - ret = memcmp(&str[len - cmplen],cmp,sq_rsl(cmplen)) == 0 ? SQTrue : SQFalse; - } - sq_pushbool(v,ret); - return 1; -} - -#define SETUP_REX(v) \ - SQRex *self = NULL; \ - if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer *)&self,rex_typetag,SQFalse))) { \ - return sq_throwerror(v,_SC("invalid type tag")); \ - } - -static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger SQ_UNUSED_ARG(size)) -{ - SQRex *self = ((SQRex *)p); - sqstd_rex_free(self); - return 1; -} - -static SQInteger _regexp_match(HSQUIRRELVM v) -{ - SETUP_REX(v); - const SQChar *str; - sq_getstring(v,2,&str); - if(sqstd_rex_match(self,str) == SQTrue) - { - sq_pushbool(v,SQTrue); - return 1; - } - sq_pushbool(v,SQFalse); - return 1; -} - -static void _addrexmatch(HSQUIRRELVM v,const SQChar *str,const SQChar *begin,const SQChar *end) -{ - sq_newtable(v); - sq_pushstring(v,_SC("begin"),-1); - sq_pushinteger(v,begin - str); - sq_rawset(v,-3); - sq_pushstring(v,_SC("end"),-1); - sq_pushinteger(v,end - str); - sq_rawset(v,-3); -} - -static SQInteger _regexp_search(HSQUIRRELVM v) -{ - SETUP_REX(v); - const SQChar *str,*begin,*end; - SQInteger start = 0; - sq_getstring(v,2,&str); - if(sq_gettop(v) > 2) sq_getinteger(v,3,&start); - if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) { - _addrexmatch(v,str,begin,end); - return 1; - } - return 0; -} - -static SQInteger _regexp_capture(HSQUIRRELVM v) -{ - SETUP_REX(v); - const SQChar *str,*begin,*end; - SQInteger start = 0; - sq_getstring(v,2,&str); - if(sq_gettop(v) > 2) sq_getinteger(v,3,&start); - if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) { - SQInteger n = sqstd_rex_getsubexpcount(self); - SQRexMatch match; - sq_newarray(v,0); - for(SQInteger i = 0;i < n; i++) { - sqstd_rex_getsubexp(self,i,&match); - if(match.len > 0) - _addrexmatch(v,str,match.begin,match.begin+match.len); - else - _addrexmatch(v,str,str,str); //empty match - sq_arrayappend(v,-2); - } - return 1; - } - return 0; -} - -static SQInteger _regexp_subexpcount(HSQUIRRELVM v) -{ - SETUP_REX(v); - sq_pushinteger(v,sqstd_rex_getsubexpcount(self)); - return 1; -} - -static SQInteger _regexp_constructor(HSQUIRRELVM v) -{ - SQRex *self = NULL; - if (SQ_FAILED(sq_getinstanceup(v, 1, (SQUserPointer *)&self, rex_typetag, SQFalse))) { - return sq_throwerror(v, _SC("invalid type tag")); - } - if (self != NULL) { - return sq_throwerror(v, _SC("invalid regexp object")); - } - const SQChar *error,*pattern; - sq_getstring(v,2,&pattern); - SQRex *rex = sqstd_rex_compile(pattern,&error); - if(!rex) return sq_throwerror(v,error); - sq_setinstanceup(v,1,rex); - sq_setreleasehook(v,1,_rexobj_releasehook); - return 0; -} - -static SQInteger _regexp__typeof(HSQUIRRELVM v) -{ - sq_pushstring(v,_SC("regexp"),-1); - return 1; -} - -#define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask} -static const SQRegFunction rexobj_funcs[]={ - _DECL_REX_FUNC(constructor,2,_SC(".s")), - _DECL_REX_FUNC(search,-2,_SC("xsn")), - _DECL_REX_FUNC(match,2,_SC("xs")), - _DECL_REX_FUNC(capture,-2,_SC("xsn")), - _DECL_REX_FUNC(subexpcount,1,_SC("x")), - _DECL_REX_FUNC(_typeof,1,_SC("x")), - {NULL,(SQFUNCTION)0,0,NULL} -}; -#undef _DECL_REX_FUNC - -#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask} -static const SQRegFunction stringlib_funcs[]={ - _DECL_FUNC(format,-2,_SC(".s")), - _DECL_FUNC(printf,-2,_SC(".s")), - _DECL_FUNC(strip,2,_SC(".s")), - _DECL_FUNC(lstrip,2,_SC(".s")), - _DECL_FUNC(rstrip,2,_SC(".s")), - _DECL_FUNC(split,-3,_SC(".ssb")), - _DECL_FUNC(escape,2,_SC(".s")), - _DECL_FUNC(startswith,3,_SC(".ss")), - _DECL_FUNC(endswith,3,_SC(".ss")), - {NULL,(SQFUNCTION)0,0,NULL} -}; -#undef _DECL_FUNC - - -SQInteger sqstd_register_stringlib(HSQUIRRELVM v) -{ - sq_pushstring(v,_SC("regexp"),-1); - sq_newclass(v,SQFalse); - rex_typetag = (SQUserPointer)rexobj_funcs; - sq_settypetag(v, -1, rex_typetag); - SQInteger i = 0; - while(rexobj_funcs[i].name != 0) { - const SQRegFunction &f = rexobj_funcs[i]; - sq_pushstring(v,f.name,-1); - sq_newclosure(v,f.f,0); - sq_setparamscheck(v,f.nparamscheck,f.typemask); - sq_setnativeclosurename(v,-1,f.name); - sq_newslot(v,-3,SQFalse); - i++; - } - sq_newslot(v,-3,SQFalse); - - i = 0; - while(stringlib_funcs[i].name!=0) - { - sq_pushstring(v,stringlib_funcs[i].name,-1); - sq_newclosure(v,stringlib_funcs[i].f,0); - sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask); - sq_setnativeclosurename(v,-1,stringlib_funcs[i].name); - sq_newslot(v,-3,SQFalse); - i++; - } - return 1; -} diff --git a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdsystem.cpp b/src/modules/app_sqlang/squirrel/sqstdlib/sqstdsystem.cpp deleted file mode 100644 index d326be1af..000000000 --- a/src/modules/app_sqlang/squirrel/sqstdlib/sqstdsystem.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include -#include -#include - -#ifdef SQUNICODE -#include -#define scgetenv _wgetenv -#define scsystem _wsystem -#define scasctime _wasctime -#define scremove _wremove -#define screname _wrename -#else -#define scgetenv getenv -#define scsystem system -#define scasctime asctime -#define scremove remove -#define screname rename -#endif -#ifdef IOS - #include - extern char **environ; -#endif - -static SQInteger _system_getenv(HSQUIRRELVM v) -{ - const SQChar *s; - if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){ - sq_pushstring(v,scgetenv(s),-1); - return 1; - } - return 0; -} - -static SQInteger _system_system(HSQUIRRELVM v) -{ - const SQChar *s; - if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){ - #ifdef IOS - pid_t pid; - posix_spawn(&pid, s, NULL, NULL, NULL, environ); - sq_pushinteger(v, 0); - #else - sq_pushinteger(v,scsystem(s)); - #endif - return 1; - } - return sq_throwerror(v,_SC("wrong param")); -} - -static SQInteger _system_clock(HSQUIRRELVM v) -{ - sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC); - return 1; -} - -static SQInteger _system_time(HSQUIRRELVM v) -{ - SQInteger t = (SQInteger)time(NULL); - sq_pushinteger(v,t); - return 1; -} - -static SQInteger _system_remove(HSQUIRRELVM v) -{ - const SQChar *s; - sq_getstring(v,2,&s); - if(scremove(s)==-1) - return sq_throwerror(v,_SC("remove() failed")); - return 0; -} - -static SQInteger _system_rename(HSQUIRRELVM v) -{ - const SQChar *oldn,*newn; - sq_getstring(v,2,&oldn); - sq_getstring(v,3,&newn); - if(screname(oldn,newn)==-1) - return sq_throwerror(v,_SC("rename() failed")); - return 0; -} - -static void _set_integer_slot(HSQUIRRELVM v,const SQChar *name,SQInteger val) -{ - sq_pushstring(v,name,-1); - sq_pushinteger(v,val); - sq_rawset(v,-3); -} - -static SQInteger _system_date(HSQUIRRELVM v) -{ - time_t t; - SQInteger it; - SQInteger format = 'l'; - if(sq_gettop(v) > 1) { - sq_getinteger(v,2,&it); - t = it; - if(sq_gettop(v) > 2) { - sq_getinteger(v,3,(SQInteger*)&format); - } - } - else { - time(&t); - } - tm *date; - if(format == 'u') - date = gmtime(&t); - else - date = localtime(&t); - if(!date) - return sq_throwerror(v,_SC("crt api failure")); - sq_newtable(v); - _set_integer_slot(v, _SC("sec"), date->tm_sec); - _set_integer_slot(v, _SC("min"), date->tm_min); - _set_integer_slot(v, _SC("hour"), date->tm_hour); - _set_integer_slot(v, _SC("day"), date->tm_mday); - _set_integer_slot(v, _SC("month"), date->tm_mon); - _set_integer_slot(v, _SC("year"), date->tm_year+1900); - _set_integer_slot(v, _SC("wday"), date->tm_wday); - _set_integer_slot(v, _SC("yday"), date->tm_yday); - return 1; -} - - - -#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask} -static const SQRegFunction systemlib_funcs[]={ - _DECL_FUNC(getenv,2,_SC(".s")), - _DECL_FUNC(system,2,_SC(".s")), - _DECL_FUNC(clock,0,NULL), - _DECL_FUNC(time,1,NULL), - _DECL_FUNC(date,-1,_SC(".nn")), - _DECL_FUNC(remove,2,_SC(".s")), - _DECL_FUNC(rename,3,_SC(".ss")), - {NULL,(SQFUNCTION)0,0,NULL} -}; -#undef _DECL_FUNC - -SQInteger sqstd_register_systemlib(HSQUIRRELVM v) -{ - SQInteger i=0; - while(systemlib_funcs[i].name!=0) - { - sq_pushstring(v,systemlib_funcs[i].name,-1); - sq_newclosure(v,systemlib_funcs[i].f,0); - sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask); - sq_setnativeclosurename(v,-1,systemlib_funcs[i].name); - sq_newslot(v,-3,SQFalse); - i++; - } - return 1; -} diff --git a/src/modules/app_sqlang/squirrel/squirrel/Makefile b/src/modules/app_sqlang/squirrel/squirrel/Makefile deleted file mode 100644 index f647111c0..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -SQUIRREL= .. - - -OUT?= $(SQUIRREL)/lib/libsquirrel.a -INCZ?= -I$(SQUIRREL)/include -I. -Iinclude -DEFS= $(CC_EXTRA_FLAGS) -LIB= -SQMARCH64?= -m64 - -OBJS= \ - sqapi.o \ - sqbaselib.o \ - sqfuncstate.o \ - sqdebug.o \ - sqlexer.o \ - sqobject.o \ - sqcompiler.o \ - sqstate.o \ - sqtable.o \ - sqmem.o \ - sqvm.o \ - sqclass.o - -SRCS= \ - sqapi.cpp \ - sqbaselib.cpp \ - sqfuncstate.cpp \ - sqdebug.cpp \ - sqlexer.cpp \ - sqobject.cpp \ - sqcompiler.cpp \ - sqstate.cpp \ - sqtable.cpp \ - sqmem.cpp \ - sqvm.cpp \ - sqclass.cpp - - - -sq32: - $(CC) -O2 -fno-exceptions -fno-rtti -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS) - $(AR) rc $(OUT) *.o - rm *.o - -sqprof: - $(CC) -O2 -pg -fno-exceptions -fno-rtti -pie -gstabs -g3 -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS) - $(AR) rc $(OUT) *.o - rm *.o - -sq64: - $(CC) -O2 $(SQMARCH64) -D_SQ64 -fno-exceptions -fno-rtti -Wall -fno-strict-aliasing -c $(SRCS) $(INCZ) $(DEFS) - $(AR) rc $(OUT) *.o - rm *.o diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqapi.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqapi.cpp deleted file mode 100644 index 54eecac4d..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqapi.cpp +++ /dev/null @@ -1,1631 +0,0 @@ -/* - see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#include "sqvm.h" -#include "sqstring.h" -#include "sqtable.h" -#include "sqarray.h" -#include "sqfuncproto.h" -#include "sqclosure.h" -#include "squserdata.h" -#include "sqcompiler.h" -#include "sqfuncstate.h" -#include "sqclass.h" - -static bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPtr **o) -{ - *o = &stack_get(v,idx); - if(sq_type(**o) != type){ - SQObjectPtr oval = v->PrintObjVal(**o); - v->Raise_Error(_SC("wrong argument type, expected '%s' got '%.50s'"),IdType2Name(type),_stringval(oval)); - return false; - } - return true; -} - -#define _GETSAFE_OBJ(v,idx,type,o) { if(!sq_aux_gettypedarg(v,idx,type,&o)) return SQ_ERROR; } - -#define sq_aux_paramscheck(v,count) \ -{ \ - if(sq_gettop(v) < count){ v->Raise_Error(_SC("not enough params in the stack")); return SQ_ERROR; }\ -} - - -SQInteger sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type) -{ - SQUnsignedInteger buf_size = 100 *sizeof(SQChar); - scsprintf(_ss(v)->GetScratchPad(buf_size), buf_size, _SC("unexpected type %s"), IdType2Name(type)); - return sq_throwerror(v, _ss(v)->GetScratchPad(-1)); -} - -HSQUIRRELVM sq_open(SQInteger initialstacksize) -{ - SQSharedState *ss; - SQVM *v; - sq_new(ss, SQSharedState); - ss->Init(); - v = (SQVM *)SQ_MALLOC(sizeof(SQVM)); - new (v) SQVM(ss); - ss->_root_vm = v; - if(v->Init(NULL, initialstacksize)) { - return v; - } else { - sq_delete(v, SQVM); - return NULL; - } - return v; -} - -HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize) -{ - SQSharedState *ss; - SQVM *v; - ss=_ss(friendvm); - - v= (SQVM *)SQ_MALLOC(sizeof(SQVM)); - new (v) SQVM(ss); - - if(v->Init(friendvm, initialstacksize)) { - friendvm->Push(v); - return v; - } else { - sq_delete(v, SQVM); - return NULL; - } -} - -SQInteger sq_getvmstate(HSQUIRRELVM v) -{ - if(v->_suspended) - return SQ_VMSTATE_SUSPENDED; - else { - if(v->_callsstacksize != 0) return SQ_VMSTATE_RUNNING; - else return SQ_VMSTATE_IDLE; - } -} - -void sq_seterrorhandler(HSQUIRRELVM v) -{ - SQObject o = stack_get(v, -1); - if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) { - v->_errorhandler = o; - v->Pop(); - } -} - -void sq_setnativedebughook(HSQUIRRELVM v,SQDEBUGHOOK hook) -{ - v->_debughook_native = hook; - v->_debughook_closure.Null(); - v->_debughook = hook?true:false; -} - -void sq_setdebughook(HSQUIRRELVM v) -{ - SQObject o = stack_get(v,-1); - if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) { - v->_debughook_closure = o; - v->_debughook_native = NULL; - v->_debughook = !sq_isnull(o); - v->Pop(); - } -} - -void sq_close(HSQUIRRELVM v) -{ - SQSharedState *ss = _ss(v); - _thread(ss->_root_vm)->Finalize(); - sq_delete(ss, SQSharedState); -} - -SQInteger sq_getversion() -{ - return SQUIRREL_VERSION_NUMBER; -} - -SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror) -{ - SQObjectPtr o; -#ifndef NO_COMPILER - if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) { - v->Push(SQClosure::Create(_ss(v), _funcproto(o), _table(v->_roottable)->GetWeakRef(OT_TABLE))); - return SQ_OK; - } - return SQ_ERROR; -#else - return sq_throwerror(v,_SC("this is a no compiler build")); -#endif -} - -void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable) -{ - _ss(v)->_debuginfo = enable?true:false; -} - -void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable) -{ - _ss(v)->_notifyallexceptions = enable?true:false; -} - -void sq_addref(HSQUIRRELVM v,HSQOBJECT *po) -{ - if(!ISREFCOUNTED(sq_type(*po))) return; -#ifdef NO_GARBAGE_COLLECTOR - __AddRef(po->_type,po->_unVal); -#else - _ss(v)->_refs_table.AddRef(*po); -#endif -} - -SQUnsignedInteger sq_getrefcount(HSQUIRRELVM v,HSQOBJECT *po) -{ - if(!ISREFCOUNTED(sq_type(*po))) return 0; -#ifdef NO_GARBAGE_COLLECTOR - return po->_unVal.pRefCounted->_uiRef; -#else - return _ss(v)->_refs_table.GetRefCount(*po); -#endif -} - -SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po) -{ - if(!ISREFCOUNTED(sq_type(*po))) return SQTrue; -#ifdef NO_GARBAGE_COLLECTOR - bool ret = (po->_unVal.pRefCounted->_uiRef <= 1) ? SQTrue : SQFalse; - __Release(po->_type,po->_unVal); - return ret; //the ret val doesn't work(and cannot be fixed) -#else - return _ss(v)->_refs_table.Release(*po); -#endif -} - -SQUnsignedInteger sq_getvmrefcount(HSQUIRRELVM SQ_UNUSED_ARG(v), const HSQOBJECT *po) -{ - if (!ISREFCOUNTED(sq_type(*po))) return 0; - return po->_unVal.pRefCounted->_uiRef; -} - -const SQChar *sq_objtostring(const HSQOBJECT *o) -{ - if(sq_type(*o) == OT_STRING) { - return _stringval(*o); - } - return NULL; -} - -SQInteger sq_objtointeger(const HSQOBJECT *o) -{ - if(sq_isnumeric(*o)) { - return tointeger(*o); - } - return 0; -} - -SQFloat sq_objtofloat(const HSQOBJECT *o) -{ - if(sq_isnumeric(*o)) { - return tofloat(*o); - } - return 0; -} - -SQBool sq_objtobool(const HSQOBJECT *o) -{ - if(sq_isbool(*o)) { - return _integer(*o); - } - return SQFalse; -} - -SQUserPointer sq_objtouserpointer(const HSQOBJECT *o) -{ - if(sq_isuserpointer(*o)) { - return _userpointer(*o); - } - return 0; -} - -void sq_pushnull(HSQUIRRELVM v) -{ - v->PushNull(); -} - -void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len) -{ - if(s) - v->Push(SQObjectPtr(SQString::Create(_ss(v), s, len))); - else v->PushNull(); -} - -void sq_pushinteger(HSQUIRRELVM v,SQInteger n) -{ - v->Push(n); -} - -void sq_pushbool(HSQUIRRELVM v,SQBool b) -{ - v->Push(b?true:false); -} - -void sq_pushfloat(HSQUIRRELVM v,SQFloat n) -{ - v->Push(n); -} - -void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p) -{ - v->Push(p); -} - -void sq_pushthread(HSQUIRRELVM v, HSQUIRRELVM thread) -{ - v->Push(thread); -} - -SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size) -{ - SQUserData *ud = SQUserData::Create(_ss(v), size + SQ_ALIGNMENT); - v->Push(ud); - return (SQUserPointer)sq_aligning(ud + 1); -} - -void sq_newtable(HSQUIRRELVM v) -{ - v->Push(SQTable::Create(_ss(v), 0)); -} - -void sq_newtableex(HSQUIRRELVM v,SQInteger initialcapacity) -{ - v->Push(SQTable::Create(_ss(v), initialcapacity)); -} - -void sq_newarray(HSQUIRRELVM v,SQInteger size) -{ - v->Push(SQArray::Create(_ss(v), size)); -} - -SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase) -{ - SQClass *baseclass = NULL; - if(hasbase) { - SQObjectPtr &base = stack_get(v,-1); - if(sq_type(base) != OT_CLASS) - return sq_throwerror(v,_SC("invalid base type")); - baseclass = _class(base); - } - SQClass *newclass = SQClass::Create(_ss(v), baseclass); - if(baseclass) v->Pop(); - v->Push(newclass); - return SQ_OK; -} - -SQBool sq_instanceof(HSQUIRRELVM v) -{ - SQObjectPtr &inst = stack_get(v,-1); - SQObjectPtr &cl = stack_get(v,-2); - if(sq_type(inst) != OT_INSTANCE || sq_type(cl) != OT_CLASS) - return sq_throwerror(v,_SC("invalid param type")); - return _instance(inst)->InstanceOf(_class(cl))?SQTrue:SQFalse; -} - -SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx) -{ - sq_aux_paramscheck(v,2); - SQObjectPtr *arr; - _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); - _array(*arr)->Append(v->GetUp(-1)); - v->Pop(); - return SQ_OK; -} - -SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval) -{ - sq_aux_paramscheck(v, 1); - SQObjectPtr *arr; - _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); - if(_array(*arr)->Size() > 0) { - if(pushval != 0){ v->Push(_array(*arr)->Top()); } - _array(*arr)->Pop(); - return SQ_OK; - } - return sq_throwerror(v, _SC("empty array")); -} - -SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize) -{ - sq_aux_paramscheck(v,1); - SQObjectPtr *arr; - _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); - if(newsize >= 0) { - _array(*arr)->Resize(newsize); - return SQ_OK; - } - return sq_throwerror(v,_SC("negative size")); -} - - -SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx) -{ - sq_aux_paramscheck(v, 1); - SQObjectPtr *o; - _GETSAFE_OBJ(v, idx, OT_ARRAY,o); - SQArray *arr = _array(*o); - if(arr->Size() > 0) { - SQObjectPtr t; - SQInteger size = arr->Size(); - SQInteger n = size >> 1; size -= 1; - for(SQInteger i = 0; i < n; i++) { - t = arr->_values[i]; - arr->_values[i] = arr->_values[size-i]; - arr->_values[size-i] = t; - } - return SQ_OK; - } - return SQ_OK; -} - -SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx) -{ - sq_aux_paramscheck(v, 1); - SQObjectPtr *arr; - _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); - return _array(*arr)->Remove(itemidx) ? SQ_OK : sq_throwerror(v,_SC("index out of range")); -} - -SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos) -{ - sq_aux_paramscheck(v, 1); - SQObjectPtr *arr; - _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); - SQRESULT ret = _array(*arr)->Insert(destpos, v->GetUp(-1)) ? SQ_OK : sq_throwerror(v,_SC("index out of range")); - v->Pop(); - return ret; -} - -void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars) -{ - SQNativeClosure *nc = SQNativeClosure::Create(_ss(v), func,nfreevars); - nc->_nparamscheck = 0; - for(SQUnsignedInteger i = 0; i < nfreevars; i++) { - nc->_outervalues[i] = v->Top(); - v->Pop(); - } - v->Push(SQObjectPtr(nc)); -} - -SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQInteger *nparams,SQInteger *nfreevars) -{ - SQObject o = stack_get(v, idx); - if(sq_type(o) == OT_CLOSURE) { - SQClosure *c = _closure(o); - SQFunctionProto *proto = c->_function; - *nparams = proto->_nparameters; - *nfreevars = proto->_noutervalues; - return SQ_OK; - } - else if(sq_type(o) == OT_NATIVECLOSURE) - { - SQNativeClosure *c = _nativeclosure(o); - *nparams = c->_nparamscheck; - *nfreevars = (SQInteger)c->_noutervalues; - return SQ_OK; - } - return sq_throwerror(v,_SC("the object is not a closure")); -} - -SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name) -{ - SQObject o = stack_get(v, idx); - if(sq_isnativeclosure(o)) { - SQNativeClosure *nc = _nativeclosure(o); - nc->_name = SQString::Create(_ss(v),name); - return SQ_OK; - } - return sq_throwerror(v,_SC("the object is not a nativeclosure")); -} - -SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask) -{ - SQObject o = stack_get(v, -1); - if(!sq_isnativeclosure(o)) - return sq_throwerror(v, _SC("native closure expected")); - SQNativeClosure *nc = _nativeclosure(o); - nc->_nparamscheck = nparamscheck; - if(typemask) { - SQIntVec res; - if(!CompileTypemask(res, typemask)) - return sq_throwerror(v, _SC("invalid typemask")); - nc->_typecheck.copy(res); - } - else { - nc->_typecheck.resize(0); - } - if(nparamscheck == SQ_MATCHTYPEMASKSTRING) { - nc->_nparamscheck = nc->_typecheck.size(); - } - return SQ_OK; -} - -SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &o = stack_get(v,idx); - if(!sq_isnativeclosure(o) && - !sq_isclosure(o)) - return sq_throwerror(v,_SC("the target is not a closure")); - SQObjectPtr &env = stack_get(v,-1); - if(!sq_istable(env) && - !sq_isarray(env) && - !sq_isclass(env) && - !sq_isinstance(env)) - return sq_throwerror(v,_SC("invalid environment")); - SQWeakRef *w = _refcounted(env)->GetWeakRef(sq_type(env)); - SQObjectPtr ret; - if(sq_isclosure(o)) { - SQClosure *c = _closure(o)->Clone(); - __ObjRelease(c->_env); - c->_env = w; - __ObjAddRef(c->_env); - if(_closure(o)->_base) { - c->_base = _closure(o)->_base; - __ObjAddRef(c->_base); - } - ret = c; - } - else { //then must be a native closure - SQNativeClosure *c = _nativeclosure(o)->Clone(); - __ObjRelease(c->_env); - c->_env = w; - __ObjAddRef(c->_env); - ret = c; - } - v->Pop(); - v->Push(ret); - return SQ_OK; -} - -SQRESULT sq_getclosurename(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &o = stack_get(v,idx); - if(!sq_isnativeclosure(o) && - !sq_isclosure(o)) - return sq_throwerror(v,_SC("the target is not a closure")); - if(sq_isnativeclosure(o)) - { - v->Push(_nativeclosure(o)->_name); - } - else { //closure - v->Push(_closure(o)->_function->_name); - } - return SQ_OK; -} - -SQRESULT sq_setclosureroot(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &c = stack_get(v,idx); - SQObject o = stack_get(v, -1); - if(!sq_isclosure(c)) return sq_throwerror(v, _SC("closure expected")); - if(sq_istable(o)) { - _closure(c)->SetRoot(_table(o)->GetWeakRef(OT_TABLE)); - v->Pop(); - return SQ_OK; - } - return sq_throwerror(v, _SC("invalid type")); -} - -SQRESULT sq_getclosureroot(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &c = stack_get(v,idx); - if(!sq_isclosure(c)) return sq_throwerror(v, _SC("closure expected")); - v->Push(_closure(c)->_root->_obj); - return SQ_OK; -} - -SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx) -{ - SQObject &o=stack_get(v,idx); - switch(sq_type(o)) { - case OT_TABLE: _table(o)->Clear(); break; - case OT_ARRAY: _array(o)->Resize(0); break; - default: - return sq_throwerror(v, _SC("clear only works on table and array")); - break; - - } - return SQ_OK; -} - -void sq_pushroottable(HSQUIRRELVM v) -{ - v->Push(v->_roottable); -} - -void sq_pushregistrytable(HSQUIRRELVM v) -{ - v->Push(_ss(v)->_registry); -} - -void sq_pushconsttable(HSQUIRRELVM v) -{ - v->Push(_ss(v)->_consts); -} - -SQRESULT sq_setroottable(HSQUIRRELVM v) -{ - SQObject o = stack_get(v, -1); - if(sq_istable(o) || sq_isnull(o)) { - v->_roottable = o; - v->Pop(); - return SQ_OK; - } - return sq_throwerror(v, _SC("invalid type")); -} - -SQRESULT sq_setconsttable(HSQUIRRELVM v) -{ - SQObject o = stack_get(v, -1); - if(sq_istable(o)) { - _ss(v)->_consts = o; - v->Pop(); - return SQ_OK; - } - return sq_throwerror(v, _SC("invalid type, expected table")); -} - -void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p) -{ - v->_foreignptr = p; -} - -SQUserPointer sq_getforeignptr(HSQUIRRELVM v) -{ - return v->_foreignptr; -} - -void sq_setsharedforeignptr(HSQUIRRELVM v,SQUserPointer p) -{ - _ss(v)->_foreignptr = p; -} - -SQUserPointer sq_getsharedforeignptr(HSQUIRRELVM v) -{ - return _ss(v)->_foreignptr; -} - -void sq_setvmreleasehook(HSQUIRRELVM v,SQRELEASEHOOK hook) -{ - v->_releasehook = hook; -} - -SQRELEASEHOOK sq_getvmreleasehook(HSQUIRRELVM v) -{ - return v->_releasehook; -} - -void sq_setsharedreleasehook(HSQUIRRELVM v,SQRELEASEHOOK hook) -{ - _ss(v)->_releasehook = hook; -} - -SQRELEASEHOOK sq_getsharedreleasehook(HSQUIRRELVM v) -{ - return _ss(v)->_releasehook; -} - -void sq_push(HSQUIRRELVM v,SQInteger idx) -{ - v->Push(stack_get(v, idx)); -} - -SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx) -{ - return sq_type(stack_get(v, idx)); -} - -SQRESULT sq_typeof(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &o = stack_get(v, idx); - SQObjectPtr res; - if(!v->TypeOf(o,res)) { - return SQ_ERROR; - } - v->Push(res); - return SQ_OK; -} - -SQRESULT sq_tostring(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &o = stack_get(v, idx); - SQObjectPtr res; - if(!v->ToString(o,res)) { - return SQ_ERROR; - } - v->Push(res); - return SQ_OK; -} - -void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b) -{ - SQObjectPtr &o = stack_get(v, idx); - *b = SQVM::IsFalse(o)?SQFalse:SQTrue; -} - -SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i) -{ - SQObjectPtr &o = stack_get(v, idx); - if(sq_isnumeric(o)) { - *i = tointeger(o); - return SQ_OK; - } - if(sq_isbool(o)) { - *i = SQVM::IsFalse(o)?SQFalse:SQTrue; - return SQ_OK; - } - return SQ_ERROR; -} - -SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f) -{ - SQObjectPtr &o = stack_get(v, idx); - if(sq_isnumeric(o)) { - *f = tofloat(o); - return SQ_OK; - } - return SQ_ERROR; -} - -SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b) -{ - SQObjectPtr &o = stack_get(v, idx); - if(sq_isbool(o)) { - *b = _integer(o); - return SQ_OK; - } - return SQ_ERROR; -} - -SQRESULT sq_getstringandsize(HSQUIRRELVM v,SQInteger idx,const SQChar **c,SQInteger *size) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, idx, OT_STRING,o); - *c = _stringval(*o); - *size = _string(*o)->_len; - return SQ_OK; -} - -SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, idx, OT_STRING,o); - *c = _stringval(*o); - return SQ_OK; -} - -SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, idx, OT_THREAD,o); - *thread = _thread(*o); - return SQ_OK; -} - -SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &o = stack_get(v,idx); - v->PushNull(); - if(!v->Clone(o, stack_get(v, -1))){ - v->Pop(); - return SQ_ERROR; - } - return SQ_OK; -} - -SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx) -{ - SQObjectPtr &o = stack_get(v, idx); - SQObjectType type = sq_type(o); - switch(type) { - case OT_STRING: return _string(o)->_len; - case OT_TABLE: return _table(o)->CountUsed(); - case OT_ARRAY: return _array(o)->Size(); - case OT_USERDATA: return _userdata(o)->_size; - case OT_INSTANCE: return _instance(o)->_class->_udsize; - case OT_CLASS: return _class(o)->_udsize; - default: - return sq_aux_invalidtype(v, type); - } -} - -SQHash sq_gethash(HSQUIRRELVM v, SQInteger idx) -{ - SQObjectPtr &o = stack_get(v, idx); - return HashObj(o); -} - -SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, idx, OT_USERDATA,o); - (*p) = _userdataval(*o); - if(typetag) *typetag = _userdata(*o)->_typetag; - return SQ_OK; -} - -SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag) -{ - SQObjectPtr &o = stack_get(v,idx); - switch(sq_type(o)) { - case OT_USERDATA: _userdata(o)->_typetag = typetag; break; - case OT_CLASS: _class(o)->_typetag = typetag; break; - default: return sq_throwerror(v,_SC("invalid object type")); - } - return SQ_OK; -} - -SQRESULT sq_getobjtypetag(const HSQOBJECT *o,SQUserPointer * typetag) -{ - switch(sq_type(*o)) { - case OT_INSTANCE: *typetag = _instance(*o)->_class->_typetag; break; - case OT_USERDATA: *typetag = _userdata(*o)->_typetag; break; - case OT_CLASS: *typetag = _class(*o)->_typetag; break; - default: return SQ_ERROR; - } - return SQ_OK; -} - -SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag) -{ - SQObjectPtr &o = stack_get(v,idx); - if (SQ_FAILED(sq_getobjtypetag(&o, typetag))) - return SQ_ERROR;// this is not an error it should be a bool but would break backward compatibility - return SQ_OK; -} - -SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, idx, OT_USERPOINTER,o); - (*p) = _userpointer(*o); - return SQ_OK; -} - -SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p) -{ - SQObjectPtr &o = stack_get(v,idx); - if(sq_type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance")); - _instance(o)->_userpointer = p; - return SQ_OK; -} - -SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize) -{ - SQObjectPtr &o = stack_get(v,idx); - if(sq_type(o) != OT_CLASS) return sq_throwerror(v,_SC("the object is not a class")); - if(_class(o)->_locked) return sq_throwerror(v,_SC("the class is locked")); - _class(o)->_udsize = udsize; - return SQ_OK; -} - - -SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p, SQUserPointer typetag, SQBool throwerror) -{ - SQObjectPtr &o = stack_get(v, idx); - if (sq_type(o) != OT_INSTANCE) return throwerror ? sq_throwerror(v, _SC("the object is not a class instance")) : SQ_ERROR; - (*p) = _instance(o)->_userpointer; - if (typetag != 0) { - SQClass *cl = _instance(o)->_class; - do { - if (cl->_typetag == typetag) - return SQ_OK; - cl = cl->_base; - } while (cl != NULL); - return throwerror ? sq_throwerror(v, _SC("invalid type tag")) : SQ_ERROR; - } - return SQ_OK; -} - -SQInteger sq_gettop(HSQUIRRELVM v) -{ - return (v->_top) - v->_stackbase; -} - -void sq_settop(HSQUIRRELVM v, SQInteger newtop) -{ - SQInteger top = sq_gettop(v); - if(top > newtop) - sq_pop(v, top - newtop); - else - while(top++ < newtop) sq_pushnull(v); -} - -void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop) -{ - assert(v->_top >= nelemstopop); - v->Pop(nelemstopop); -} - -void sq_poptop(HSQUIRRELVM v) -{ - assert(v->_top >= 1); - v->Pop(); -} - - -void sq_remove(HSQUIRRELVM v, SQInteger idx) -{ - v->Remove(idx); -} - -SQInteger sq_cmp(HSQUIRRELVM v) -{ - SQInteger res; - v->ObjCmp(stack_get(v, -1), stack_get(v, -2),res); - return res; -} - -SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic) -{ - sq_aux_paramscheck(v, 3); - SQObjectPtr &self = stack_get(v, idx); - if(sq_type(self) == OT_TABLE || sq_type(self) == OT_CLASS) { - SQObjectPtr &key = v->GetUp(-2); - if(sq_type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key")); - v->NewSlot(self, key, v->GetUp(-1),bstatic?true:false); - v->Pop(2); - } - return SQ_OK; -} - -SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval) -{ - sq_aux_paramscheck(v, 2); - SQObjectPtr *self; - _GETSAFE_OBJ(v, idx, OT_TABLE,self); - SQObjectPtr &key = v->GetUp(-1); - if(sq_type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key")); - SQObjectPtr res; - if(!v->DeleteSlot(*self, key, res)){ - v->Pop(); - return SQ_ERROR; - } - if(pushval) v->GetUp(-1) = res; - else v->Pop(); - return SQ_OK; -} - -SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &self = stack_get(v, idx); - if(v->Set(self, v->GetUp(-2), v->GetUp(-1),DONT_FALL_BACK)) { - v->Pop(2); - return SQ_OK; - } - return SQ_ERROR; -} - -SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &self = stack_get(v, idx); - SQObjectPtr &key = v->GetUp(-2); - if(sq_type(key) == OT_NULL) { - v->Pop(2); - return sq_throwerror(v, _SC("null key")); - } - switch(sq_type(self)) { - case OT_TABLE: - _table(self)->NewSlot(key, v->GetUp(-1)); - v->Pop(2); - return SQ_OK; - break; - case OT_CLASS: - _class(self)->NewSlot(_ss(v), key, v->GetUp(-1),false); - v->Pop(2); - return SQ_OK; - break; - case OT_INSTANCE: - if(_instance(self)->Set(key, v->GetUp(-1))) { - v->Pop(2); - return SQ_OK; - } - break; - case OT_ARRAY: - if(v->Set(self, key, v->GetUp(-1),false)) { - v->Pop(2); - return SQ_OK; - } - break; - default: - v->Pop(2); - return sq_throwerror(v, _SC("rawset works only on array/table/class and instance")); - } - v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR; -} - -SQRESULT sq_newmember(HSQUIRRELVM v,SQInteger idx,SQBool bstatic) -{ - SQObjectPtr &self = stack_get(v, idx); - if(sq_type(self) != OT_CLASS) return sq_throwerror(v, _SC("new member only works with classes")); - SQObjectPtr &key = v->GetUp(-3); - if(sq_type(key) == OT_NULL) return sq_throwerror(v, _SC("null key")); - if(!v->NewSlotA(self,key,v->GetUp(-2),v->GetUp(-1),bstatic?true:false,false)) { - v->Pop(3); - return SQ_ERROR; - } - v->Pop(3); - return SQ_OK; -} - -SQRESULT sq_rawnewmember(HSQUIRRELVM v,SQInteger idx,SQBool bstatic) -{ - SQObjectPtr &self = stack_get(v, idx); - if(sq_type(self) != OT_CLASS) return sq_throwerror(v, _SC("new member only works with classes")); - SQObjectPtr &key = v->GetUp(-3); - if(sq_type(key) == OT_NULL) return sq_throwerror(v, _SC("null key")); - if(!v->NewSlotA(self,key,v->GetUp(-2),v->GetUp(-1),bstatic?true:false,true)) { - v->Pop(3); - return SQ_ERROR; - } - v->Pop(3); - return SQ_OK; -} - -SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &self = stack_get(v, idx); - SQObjectPtr &mt = v->GetUp(-1); - SQObjectType type = sq_type(self); - switch(type) { - case OT_TABLE: - if(sq_type(mt) == OT_TABLE) { - if(!_table(self)->SetDelegate(_table(mt))) { - return sq_throwerror(v, _SC("delegate cycle")); - } - v->Pop(); - } - else if(sq_type(mt)==OT_NULL) { - _table(self)->SetDelegate(NULL); v->Pop(); } - else return sq_aux_invalidtype(v,type); - break; - case OT_USERDATA: - if(sq_type(mt)==OT_TABLE) { - _userdata(self)->SetDelegate(_table(mt)); v->Pop(); } - else if(sq_type(mt)==OT_NULL) { - _userdata(self)->SetDelegate(NULL); v->Pop(); } - else return sq_aux_invalidtype(v, type); - break; - default: - return sq_aux_invalidtype(v, type); - break; - } - return SQ_OK; -} - -SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval) -{ - sq_aux_paramscheck(v, 2); - SQObjectPtr *self; - _GETSAFE_OBJ(v, idx, OT_TABLE,self); - SQObjectPtr &key = v->GetUp(-1); - SQObjectPtr t; - if(_table(*self)->Get(key,t)) { - _table(*self)->Remove(key); - } - if(pushval != 0) - v->GetUp(-1) = t; - else - v->Pop(); - return SQ_OK; -} - -SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &self=stack_get(v,idx); - switch(sq_type(self)){ - case OT_TABLE: - case OT_USERDATA: - if(!_delegable(self)->_delegate){ - v->PushNull(); - break; - } - v->Push(SQObjectPtr(_delegable(self)->_delegate)); - break; - default: return sq_throwerror(v,_SC("wrong type")); break; - } - return SQ_OK; - -} - -SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &self=stack_get(v,idx); - SQObjectPtr &obj = v->GetUp(-1); - if(v->Get(self,obj,obj,false,DONT_FALL_BACK)) - return SQ_OK; - v->Pop(); - return SQ_ERROR; -} - -SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &self=stack_get(v,idx); - SQObjectPtr &obj = v->GetUp(-1); - switch(sq_type(self)) { - case OT_TABLE: - if(_table(self)->Get(obj,obj)) - return SQ_OK; - break; - case OT_CLASS: - if(_class(self)->Get(obj,obj)) - return SQ_OK; - break; - case OT_INSTANCE: - if(_instance(self)->Get(obj,obj)) - return SQ_OK; - break; - case OT_ARRAY:{ - if(sq_isnumeric(obj)){ - if(_array(self)->Get(tointeger(obj),obj)) { - return SQ_OK; - } - } - else { - v->Pop(); - return sq_throwerror(v,_SC("invalid index type for an array")); - } - } - break; - default: - v->Pop(); - return sq_throwerror(v,_SC("rawget works only on array/table/instance and class")); - } - v->Pop(); - return sq_throwerror(v,_SC("the index doesn't exist")); -} - -SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po) -{ - *po=stack_get(v,idx); - return SQ_OK; -} - -const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx) -{ - SQUnsignedInteger cstksize=v->_callsstacksize; - SQUnsignedInteger lvl=(cstksize-level)-1; - SQInteger stackbase=v->_stackbase; - if(lvl_callsstack[(cstksize-i)-1]; - stackbase-=ci._prevstkbase; - } - SQVM::CallInfo &ci=v->_callsstack[lvl]; - if(sq_type(ci._closure)!=OT_CLOSURE) - return NULL; - SQClosure *c=_closure(ci._closure); - SQFunctionProto *func=c->_function; - if(func->_noutervalues > (SQInteger)idx) { - v->Push(*_outer(c->_outervalues[idx])->_valptr); - return _stringval(func->_outervalues[idx]._name); - } - idx -= func->_noutervalues; - return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions)-1); - } - return NULL; -} - -void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj) -{ - v->Push(SQObjectPtr(obj)); -} - -void sq_resetobject(HSQOBJECT *po) -{ - po->_unVal.pUserPointer=NULL;po->_type=OT_NULL; -} - -SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err) -{ - v->_lasterror=SQString::Create(_ss(v),err); - return SQ_ERROR; -} - -SQRESULT sq_throwobject(HSQUIRRELVM v) -{ - v->_lasterror = v->GetUp(-1); - v->Pop(); - return SQ_ERROR; -} - - -void sq_reseterror(HSQUIRRELVM v) -{ - v->_lasterror.Null(); -} - -void sq_getlasterror(HSQUIRRELVM v) -{ - v->Push(v->_lasterror); -} - -SQRESULT sq_reservestack(HSQUIRRELVM v,SQInteger nsize) -{ - if (((SQUnsignedInteger)v->_top + nsize) > v->_stack.size()) { - if(v->_nmetamethodscall) { - return sq_throwerror(v,_SC("cannot resize stack while in a metamethod")); - } - v->_stack.resize(v->_stack.size() + ((v->_top + nsize) - v->_stack.size())); - } - return SQ_OK; -} - -SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror) -{ - if (sq_type(v->GetUp(-1)) == OT_GENERATOR) - { - v->PushNull(); //retval - if (!v->Execute(v->GetUp(-2), 0, v->_top, v->GetUp(-1), raiseerror, SQVM::ET_RESUME_GENERATOR)) - {v->Raise_Error(v->_lasterror); return SQ_ERROR;} - if(!retval) - v->Pop(); - return SQ_OK; - } - return sq_throwerror(v,_SC("only generators can be resumed")); -} - -SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror) -{ - SQObjectPtr res; - if(!v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false)){ - v->Pop(params); //pop args - return SQ_ERROR; - } - if(!v->_suspended) - v->Pop(params); //pop args - if(retval) - v->Push(res); // push result - return SQ_OK; -} - -SQRESULT sq_tailcall(HSQUIRRELVM v, SQInteger nparams) -{ - SQObjectPtr &res = v->GetUp(-(nparams + 1)); - if (sq_type(res) != OT_CLOSURE) { - return sq_throwerror(v, _SC("only closure can be tail called")); - } - SQClosure *clo = _closure(res); - if (clo->_function->_bgenerator) - { - return sq_throwerror(v, _SC("generators cannot be tail called")); - } - - SQInteger stackbase = (v->_top - nparams) - v->_stackbase; - if (!v->TailCall(clo, stackbase, nparams)) { - return SQ_ERROR; - } - return SQ_TAILCALL_FLAG; -} - -SQRESULT sq_suspendvm(HSQUIRRELVM v) -{ - return v->Suspend(); -} - -SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseerror,SQBool throwerror) -{ - SQObjectPtr ret; - if(!v->_suspended) - return sq_throwerror(v,_SC("cannot resume a vm that is not running any code")); - SQInteger target = v->_suspended_target; - if(wakeupret) { - if(target != -1) { - v->GetAt(v->_stackbase+v->_suspended_target)=v->GetUp(-1); //retval - } - v->Pop(); - } else if(target != -1) { v->GetAt(v->_stackbase+v->_suspended_target).Null(); } - SQObjectPtr dummy; - if(!v->Execute(dummy,-1,-1,ret,raiseerror,throwerror?SQVM::ET_RESUME_THROW_VM : SQVM::ET_RESUME_VM)) { - return SQ_ERROR; - } - if(retval) - v->Push(ret); - return SQ_OK; -} - -void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook) -{ - SQObjectPtr &ud=stack_get(v,idx); - switch(sq_type(ud) ) { - case OT_USERDATA: _userdata(ud)->_hook = hook; break; - case OT_INSTANCE: _instance(ud)->_hook = hook; break; - case OT_CLASS: _class(ud)->_hook = hook; break; - default: return; - } -} - -SQRELEASEHOOK sq_getreleasehook(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &ud=stack_get(v,idx); - switch(sq_type(ud) ) { - case OT_USERDATA: return _userdata(ud)->_hook; break; - case OT_INSTANCE: return _instance(ud)->_hook; break; - case OT_CLASS: return _class(ud)->_hook; break; - default: return NULL; - } -} - -void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f) -{ - _ss(v)->_compilererrorhandler = f; -} - -SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, -1, OT_CLOSURE,o); - unsigned short tag = SQ_BYTECODE_STREAM_TAG; - if(_closure(*o)->_function->_noutervalues) - return sq_throwerror(v,_SC("a closure with free variables bound cannot be serialized")); - if(w(up,&tag,2) != 2) - return sq_throwerror(v,_SC("io error")); - if(!_closure(*o)->Save(v,up,w)) - return SQ_ERROR; - return SQ_OK; -} - -SQRESULT sq_readclosure(HSQUIRRELVM v,SQREADFUNC r,SQUserPointer up) -{ - SQObjectPtr closure; - - unsigned short tag; - if(r(up,&tag,2) != 2) - return sq_throwerror(v,_SC("io error")); - if(tag != SQ_BYTECODE_STREAM_TAG) - return sq_throwerror(v,_SC("invalid stream")); - if(!SQClosure::Load(v,up,r,closure)) - return SQ_ERROR; - v->Push(closure); - return SQ_OK; -} - -SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize) -{ - return _ss(v)->GetScratchPad(minsize); -} - -SQRESULT sq_resurrectunreachable(HSQUIRRELVM v) -{ -#ifndef NO_GARBAGE_COLLECTOR - _ss(v)->ResurrectUnreachable(v); - return SQ_OK; -#else - return sq_throwerror(v,_SC("sq_resurrectunreachable requires a garbage collector build")); -#endif -} - -SQInteger sq_collectgarbage(HSQUIRRELVM v) -{ -#ifndef NO_GARBAGE_COLLECTOR - return _ss(v)->CollectGarbage(v); -#else - return -1; -#endif -} - -SQRESULT sq_getcallee(HSQUIRRELVM v) -{ - if(v->_callsstacksize > 1) - { - v->Push(v->_callsstack[v->_callsstacksize - 2]._closure); - return SQ_OK; - } - return sq_throwerror(v,_SC("no closure in the calls stack")); -} - -const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval) -{ - SQObjectPtr &self=stack_get(v,idx); - const SQChar *name = NULL; - switch(sq_type(self)) - { - case OT_CLOSURE:{ - SQClosure *clo = _closure(self); - SQFunctionProto *fp = clo->_function; - if(((SQUnsignedInteger)fp->_noutervalues) > nval) { - v->Push(*(_outer(clo->_outervalues[nval])->_valptr)); - SQOuterVar &ov = fp->_outervalues[nval]; - name = _stringval(ov._name); - } - } - break; - case OT_NATIVECLOSURE:{ - SQNativeClosure *clo = _nativeclosure(self); - if(clo->_noutervalues > nval) { - v->Push(clo->_outervalues[nval]); - name = _SC("@NATIVE"); - } - } - break; - default: break; //shutup compiler - } - return name; -} - -SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval) -{ - SQObjectPtr &self=stack_get(v,idx); - switch(sq_type(self)) - { - case OT_CLOSURE:{ - SQFunctionProto *fp = _closure(self)->_function; - if(((SQUnsignedInteger)fp->_noutervalues) > nval){ - *(_outer(_closure(self)->_outervalues[nval])->_valptr) = stack_get(v,-1); - } - else return sq_throwerror(v,_SC("invalid free var index")); - } - break; - case OT_NATIVECLOSURE: - if(_nativeclosure(self)->_noutervalues > nval){ - _nativeclosure(self)->_outervalues[nval] = stack_get(v,-1); - } - else return sq_throwerror(v,_SC("invalid free var index")); - break; - default: - return sq_aux_invalidtype(v, sq_type(self)); - } - v->Pop(); - return SQ_OK; -} - -SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, idx, OT_CLASS,o); - SQObjectPtr &key = stack_get(v,-2); - SQObjectPtr &val = stack_get(v,-1); - SQObjectPtr attrs; - if(sq_type(key) == OT_NULL) { - attrs = _class(*o)->_attributes; - _class(*o)->_attributes = val; - v->Pop(2); - v->Push(attrs); - return SQ_OK; - }else if(_class(*o)->GetAttributes(key,attrs)) { - _class(*o)->SetAttributes(key,val); - v->Pop(2); - v->Push(attrs); - return SQ_OK; - } - return sq_throwerror(v,_SC("wrong index")); -} - -SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, idx, OT_CLASS,o); - SQObjectPtr &key = stack_get(v,-1); - SQObjectPtr attrs; - if(sq_type(key) == OT_NULL) { - attrs = _class(*o)->_attributes; - v->Pop(); - v->Push(attrs); - return SQ_OK; - } - else if(_class(*o)->GetAttributes(key,attrs)) { - v->Pop(); - v->Push(attrs); - return SQ_OK; - } - return sq_throwerror(v,_SC("wrong index")); -} - -SQRESULT sq_getmemberhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, idx, OT_CLASS,o); - SQObjectPtr &key = stack_get(v,-1); - SQTable *m = _class(*o)->_members; - SQObjectPtr val; - if(m->Get(key,val)) { - handle->_static = _isfield(val) ? SQFalse : SQTrue; - handle->_index = _member_idx(val); - v->Pop(); - return SQ_OK; - } - return sq_throwerror(v,_SC("wrong index")); -} - -SQRESULT _getmemberbyhandle(HSQUIRRELVM v,SQObjectPtr &self,const HSQMEMBERHANDLE *handle,SQObjectPtr *&val) -{ - switch(sq_type(self)) { - case OT_INSTANCE: { - SQInstance *i = _instance(self); - if(handle->_static) { - SQClass *c = i->_class; - val = &c->_methods[handle->_index].val; - } - else { - val = &i->_values[handle->_index]; - - } - } - break; - case OT_CLASS: { - SQClass *c = _class(self); - if(handle->_static) { - val = &c->_methods[handle->_index].val; - } - else { - val = &c->_defaultvalues[handle->_index].val; - } - } - break; - default: - return sq_throwerror(v,_SC("wrong type(expected class or instance)")); - } - return SQ_OK; -} - -SQRESULT sq_getbyhandle(HSQUIRRELVM v,SQInteger idx,const HSQMEMBERHANDLE *handle) -{ - SQObjectPtr &self = stack_get(v,idx); - SQObjectPtr *val = NULL; - if(SQ_FAILED(_getmemberbyhandle(v,self,handle,val))) { - return SQ_ERROR; - } - v->Push(_realval(*val)); - return SQ_OK; -} - -SQRESULT sq_setbyhandle(HSQUIRRELVM v,SQInteger idx,const HSQMEMBERHANDLE *handle) -{ - SQObjectPtr &self = stack_get(v,idx); - SQObjectPtr &newval = stack_get(v,-1); - SQObjectPtr *val = NULL; - if(SQ_FAILED(_getmemberbyhandle(v,self,handle,val))) { - return SQ_ERROR; - } - *val = newval; - v->Pop(); - return SQ_OK; -} - -SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, idx, OT_CLASS,o); - if(_class(*o)->_base) - v->Push(SQObjectPtr(_class(*o)->_base)); - else - v->PushNull(); - return SQ_OK; -} - -SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, idx, OT_INSTANCE,o); - v->Push(SQObjectPtr(_instance(*o)->_class)); - return SQ_OK; -} - -SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr *o = NULL; - _GETSAFE_OBJ(v, idx, OT_CLASS,o); - v->Push(_class(*o)->CreateInstance()); - return SQ_OK; -} - -void sq_weakref(HSQUIRRELVM v,SQInteger idx) -{ - SQObject &o=stack_get(v,idx); - if(ISREFCOUNTED(sq_type(o))) { - v->Push(_refcounted(o)->GetWeakRef(sq_type(o))); - return; - } - v->Push(o); -} - -SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr &o = stack_get(v,idx); - if(sq_type(o) != OT_WEAKREF) { - return sq_throwerror(v,_SC("the object must be a weakref")); - } - v->Push(_weakref(o)->_obj); - return SQ_OK; -} - -SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t) -{ - SQSharedState *ss = _ss(v); - switch(t) { - case OT_TABLE: v->Push(ss->_table_default_delegate); break; - case OT_ARRAY: v->Push(ss->_array_default_delegate); break; - case OT_STRING: v->Push(ss->_string_default_delegate); break; - case OT_INTEGER: case OT_FLOAT: v->Push(ss->_number_default_delegate); break; - case OT_GENERATOR: v->Push(ss->_generator_default_delegate); break; - case OT_CLOSURE: case OT_NATIVECLOSURE: v->Push(ss->_closure_default_delegate); break; - case OT_THREAD: v->Push(ss->_thread_default_delegate); break; - case OT_CLASS: v->Push(ss->_class_default_delegate); break; - case OT_INSTANCE: v->Push(ss->_instance_default_delegate); break; - case OT_WEAKREF: v->Push(ss->_weakref_default_delegate); break; - default: return sq_throwerror(v,_SC("the type doesn't have a default delegate")); - } - return SQ_OK; -} - -SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx) -{ - SQObjectPtr o=stack_get(v,idx),&refpos = stack_get(v,-1),realkey,val; - if(sq_type(o) == OT_GENERATOR) { - return sq_throwerror(v,_SC("cannot iterate a generator")); - } - int faketojump; - if(!v->FOREACH_OP(o,realkey,val,refpos,0,666,faketojump)) - return SQ_ERROR; - if(faketojump != 666) { - v->Push(realkey); - v->Push(val); - return SQ_OK; - } - return SQ_ERROR; -} - -struct BufState{ - const SQChar *buf; - SQInteger ptr; - SQInteger size; -}; - -SQInteger buf_lexfeed(SQUserPointer file) -{ - BufState *buf=(BufState*)file; - if(buf->size<(buf->ptr+1)) - return 0; - return buf->buf[buf->ptr++]; -} - -SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror) { - BufState buf; - buf.buf = s; - buf.size = size; - buf.ptr = 0; - return sq_compile(v, buf_lexfeed, &buf, sourcename, raiseerror); -} - -void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx) -{ - dest->Push(stack_get(src,idx)); -} - -void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc,SQPRINTFUNCTION errfunc) -{ - _ss(v)->_printfunc = printfunc; - _ss(v)->_errorfunc = errfunc; -} - -SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v) -{ - return _ss(v)->_printfunc; -} - -SQPRINTFUNCTION sq_geterrorfunc(HSQUIRRELVM v) -{ - return _ss(v)->_errorfunc; -} - -void *sq_malloc(SQUnsignedInteger size) -{ - return SQ_MALLOC(size); -} - -void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize) -{ - return SQ_REALLOC(p,oldsize,newsize); -} - -void sq_free(void *p,SQUnsignedInteger size) -{ - SQ_FREE(p,size); -} diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqarray.h b/src/modules/app_sqlang/squirrel/squirrel/sqarray.h deleted file mode 100644 index 01eef47a8..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqarray.h +++ /dev/null @@ -1,134 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQARRAY_H_ -#define _SQARRAY_H_ - -struct SQArray : public CHAINABLE_OBJ -{ -private: - SQArray(SQSharedState *ss, SQInteger nsize) - { - _values.resize(nsize); - INIT_CHAIN(); - ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); - } - ~SQArray() - { - REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this); - } - -public: - static SQArray *Create(SQSharedState *ss, SQInteger nInitialSize) - { - SQArray *newarray = (SQArray *)SQ_MALLOC(sizeof(SQArray)); - new(newarray) SQArray(ss, nInitialSize); - return newarray; - } -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable **chain); - SQObjectType GetType() - { - return OT_ARRAY; - } -#endif - void Finalize() - { - _values.resize(0); - } - bool Get(const SQInteger nidx, SQObjectPtr &val) - { - if(nidx >= 0 && nidx < (SQInteger)_values.size()) { - SQObjectPtr &o = _values[nidx]; - val = _realval(o); - return true; - } else - return false; - } - bool Set(const SQInteger nidx, const SQObjectPtr &val) - { - if(nidx >= 0 && nidx < (SQInteger)_values.size()) { - _values[nidx] = val; - return true; - } else - return false; - } - SQInteger Next( - const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) - { - SQUnsignedInteger idx = TranslateIndex(refpos); - while(idx < _values.size()) { - //first found - outkey = (SQInteger)idx; - SQObjectPtr &o = _values[idx]; - outval = _realval(o); - //return idx for the next iteration - return ++idx; - } - //nothing to iterate anymore - return -1; - } - SQArray *Clone() - { - SQArray *anew = Create(_opt_ss(this), 0); - anew->_values.copy(_values); - return anew; - } - SQInteger Size() const - { - return _values.size(); - } - void Resize(SQInteger size) - { - SQObjectPtr _null; - Resize(size, _null); - } - void Resize(SQInteger size, SQObjectPtr &fill) - { - _values.resize(size, fill); - ShrinkIfNeeded(); - } - void Reserve(SQInteger size) - { - _values.reserve(size); - } - void Append(const SQObject &o) - { - _values.push_back(o); - } - void Extend(const SQArray *a); - SQObjectPtr &Top() - { - return _values.top(); - } - void Pop() - { - _values.pop_back(); - ShrinkIfNeeded(); - } - bool Insert(SQInteger idx, const SQObject &val) - { - if(idx < 0 || idx > (SQInteger)_values.size()) - return false; - _values.insert(idx, val); - return true; - } - void ShrinkIfNeeded() - { - if(_values.size() <= _values.capacity() >> 2) //shrink the array - _values.shrinktofit(); - } - bool Remove(SQInteger idx) - { - if(idx < 0 || idx >= (SQInteger)_values.size()) - return false; - _values.remove(idx); - ShrinkIfNeeded(); - return true; - } - void Release() - { - sq_delete(this, SQArray); - } - - SQObjectPtrVec _values; -}; -#endif //_SQARRAY_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqbaselib.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqbaselib.cpp deleted file mode 100644 index eb56491e6..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqbaselib.cpp +++ /dev/null @@ -1,1404 +0,0 @@ -/* - see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#include "sqvm.h" -#include "sqstring.h" -#include "sqtable.h" -#include "sqarray.h" -#include "sqfuncproto.h" -#include "sqclosure.h" -#include "sqclass.h" -#include -#include -#include - -static bool str2num(const SQChar *s,SQObjectPtr &res,SQInteger base) -{ - SQChar *end; - const SQChar *e = s; - bool iseintbase = base > 13; //to fix error converting hexadecimals with e like 56f0791e - bool isfloat = false; - SQChar c; - while((c = *e) != _SC('\0')) - { - if (c == _SC('.') || (!iseintbase && (c == _SC('E') || c == _SC('e')))) { //e and E is for scientific notation - isfloat = true; - break; - } - e++; - } - if(isfloat){ - SQFloat r = SQFloat(scstrtod(s,&end)); - if(s == end) return false; - res = r; - } - else{ - SQInteger r = SQInteger(scstrtol(s,&end,(int)base)); - if(s == end) return false; - res = r; - } - return true; -} - -static SQInteger base_dummy(HSQUIRRELVM SQ_UNUSED_ARG(v)) -{ - return 0; -} - -#ifndef NO_GARBAGE_COLLECTOR -static SQInteger base_collectgarbage(HSQUIRRELVM v) -{ - sq_pushinteger(v, sq_collectgarbage(v)); - return 1; -} -static SQInteger base_resurectureachable(HSQUIRRELVM v) -{ - sq_resurrectunreachable(v); - return 1; -} -#endif - -static SQInteger base_getroottable(HSQUIRRELVM v) -{ - v->Push(v->_roottable); - return 1; -} - -static SQInteger base_getconsttable(HSQUIRRELVM v) -{ - v->Push(_ss(v)->_consts); - return 1; -} - - -static SQInteger base_setroottable(HSQUIRRELVM v) -{ - SQObjectPtr o = v->_roottable; - if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR; - v->Push(o); - return 1; -} - -static SQInteger base_setconsttable(HSQUIRRELVM v) -{ - SQObjectPtr o = _ss(v)->_consts; - if(SQ_FAILED(sq_setconsttable(v))) return SQ_ERROR; - v->Push(o); - return 1; -} - -static SQInteger base_seterrorhandler(HSQUIRRELVM v) -{ - sq_seterrorhandler(v); - return 0; -} - -static SQInteger base_setdebughook(HSQUIRRELVM v) -{ - sq_setdebughook(v); - return 0; -} - -static SQInteger base_enabledebuginfo(HSQUIRRELVM v) -{ - SQObjectPtr &o=stack_get(v,2); - - sq_enabledebuginfo(v,SQVM::IsFalse(o)?SQFalse:SQTrue); - return 0; -} - -static SQInteger __getcallstackinfos(HSQUIRRELVM v,SQInteger level) -{ - SQStackInfos si; - SQInteger seq = 0; - const SQChar *name = NULL; - - if (SQ_SUCCEEDED(sq_stackinfos(v, level, &si))) - { - const SQChar *fn = _SC("unknown"); - const SQChar *src = _SC("unknown"); - if(si.funcname)fn = si.funcname; - if(si.source)src = si.source; - sq_newtable(v); - sq_pushstring(v, _SC("func"), -1); - sq_pushstring(v, fn, -1); - sq_newslot(v, -3, SQFalse); - sq_pushstring(v, _SC("src"), -1); - sq_pushstring(v, src, -1); - sq_newslot(v, -3, SQFalse); - sq_pushstring(v, _SC("line"), -1); - sq_pushinteger(v, si.line); - sq_newslot(v, -3, SQFalse); - sq_pushstring(v, _SC("locals"), -1); - sq_newtable(v); - seq=0; - while ((name = sq_getlocal(v, level, seq))) { - sq_pushstring(v, name, -1); - sq_push(v, -2); - sq_newslot(v, -4, SQFalse); - sq_pop(v, 1); - seq++; - } - sq_newslot(v, -3, SQFalse); - return 1; - } - - return 0; -} -static SQInteger base_getstackinfos(HSQUIRRELVM v) -{ - SQInteger level; - sq_getinteger(v, -1, &level); - return __getcallstackinfos(v,level); -} - -static SQInteger base_assert(HSQUIRRELVM v) -{ - if(SQVM::IsFalse(stack_get(v,2))){ - SQInteger top = sq_gettop(v); - if (top>2 && SQ_SUCCEEDED(sq_tostring(v,3))) { - const SQChar *str = 0; - if (SQ_SUCCEEDED(sq_getstring(v,-1,&str))) { - return sq_throwerror(v, str); - } - } - return sq_throwerror(v, _SC("assertion failed")); - } - return 0; -} - -static SQInteger get_slice_params(HSQUIRRELVM v,SQInteger &sidx,SQInteger &eidx,SQObjectPtr &o) -{ - SQInteger top = sq_gettop(v); - sidx=0; - eidx=0; - o=stack_get(v,1); - if(top>1){ - SQObjectPtr &start=stack_get(v,2); - if(sq_type(start)!=OT_NULL && sq_isnumeric(start)){ - sidx=tointeger(start); - } - } - if(top>2){ - SQObjectPtr &end=stack_get(v,3); - if(sq_isnumeric(end)){ - eidx=tointeger(end); - } - } - else { - eidx = sq_getsize(v,1); - } - return 1; -} - -static SQInteger base_print(HSQUIRRELVM v) -{ - const SQChar *str; - if(SQ_SUCCEEDED(sq_tostring(v,2))) - { - if(SQ_SUCCEEDED(sq_getstring(v,-1,&str))) { - if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%s"),str); - return 0; - } - } - return SQ_ERROR; -} - -static SQInteger base_error(HSQUIRRELVM v) -{ - const SQChar *str; - if(SQ_SUCCEEDED(sq_tostring(v,2))) - { - if(SQ_SUCCEEDED(sq_getstring(v,-1,&str))) { - if(_ss(v)->_errorfunc) _ss(v)->_errorfunc(v,_SC("%s"),str); - return 0; - } - } - return SQ_ERROR; -} - -static SQInteger base_compilestring(HSQUIRRELVM v) -{ - SQInteger nargs=sq_gettop(v); - const SQChar *src=NULL,*name=_SC("unnamedbuffer"); - SQInteger size; - sq_getstring(v,2,&src); - size=sq_getsize(v,2); - if(nargs>2){ - sq_getstring(v,3,&name); - } - if(SQ_SUCCEEDED(sq_compilebuffer(v,src,size,name,SQFalse))) - return 1; - else - return SQ_ERROR; -} - -static SQInteger base_newthread(HSQUIRRELVM v) -{ - SQObjectPtr &func = stack_get(v,2); - SQInteger stksize = (_closure(func)->_function->_stacksize << 1) +2; - HSQUIRRELVM newv = sq_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize); - sq_move(newv,v,-2); - return 1; -} - -static SQInteger base_suspend(HSQUIRRELVM v) -{ - return sq_suspendvm(v); -} - -static SQInteger base_array(HSQUIRRELVM v) -{ - SQArray *a; - SQObject &size = stack_get(v,2); - if(sq_gettop(v) > 2) { - a = SQArray::Create(_ss(v),0); - a->Resize(tointeger(size),stack_get(v,3)); - } - else { - a = SQArray::Create(_ss(v),tointeger(size)); - } - v->Push(a); - return 1; -} - -static SQInteger base_type(HSQUIRRELVM v) -{ - SQObjectPtr &o = stack_get(v,2); - v->Push(SQString::Create(_ss(v),GetTypeName(o),-1)); - return 1; -} - -static SQInteger base_callee(HSQUIRRELVM v) -{ - if(v->_callsstacksize > 1) - { - v->Push(v->_callsstack[v->_callsstacksize - 2]._closure); - return 1; - } - return sq_throwerror(v,_SC("no closure in the calls stack")); -} - -static const SQRegFunction base_funcs[]={ - //generic - {_SC("seterrorhandler"),base_seterrorhandler,2, NULL}, - {_SC("setdebughook"),base_setdebughook,2, NULL}, - {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL}, - {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")}, - {_SC("getroottable"),base_getroottable,1, NULL}, - {_SC("setroottable"),base_setroottable,2, NULL}, - {_SC("getconsttable"),base_getconsttable,1, NULL}, - {_SC("setconsttable"),base_setconsttable,2, NULL}, - {_SC("assert"),base_assert,-2, NULL}, - {_SC("print"),base_print,2, NULL}, - {_SC("error"),base_error,2, NULL}, - {_SC("compilestring"),base_compilestring,-2, _SC(".ss")}, - {_SC("newthread"),base_newthread,2, _SC(".c")}, - {_SC("suspend"),base_suspend,-1, NULL}, - {_SC("array"),base_array,-2, _SC(".n")}, - {_SC("type"),base_type,2, NULL}, - {_SC("callee"),base_callee,0,NULL}, - {_SC("dummy"),base_dummy,0,NULL}, -#ifndef NO_GARBAGE_COLLECTOR - {_SC("collectgarbage"),base_collectgarbage,0, NULL}, - {_SC("resurrectunreachable"),base_resurectureachable,0, NULL}, -#endif - {NULL,(SQFUNCTION)0,0,NULL} -}; - -void sq_base_register(HSQUIRRELVM v) -{ - SQInteger i=0; - sq_pushroottable(v); - while(base_funcs[i].name!=0) { - sq_pushstring(v,base_funcs[i].name,-1); - sq_newclosure(v,base_funcs[i].f,0); - sq_setnativeclosurename(v,-1,base_funcs[i].name); - sq_setparamscheck(v,base_funcs[i].nparamscheck,base_funcs[i].typemask); - sq_newslot(v,-3, SQFalse); - i++; - } - - sq_pushstring(v,_SC("_versionnumber_"),-1); - sq_pushinteger(v,SQUIRREL_VERSION_NUMBER); - sq_newslot(v,-3, SQFalse); - sq_pushstring(v,_SC("_version_"),-1); - sq_pushstring(v,SQUIRREL_VERSION,-1); - sq_newslot(v,-3, SQFalse); - sq_pushstring(v,_SC("_charsize_"),-1); - sq_pushinteger(v,sizeof(SQChar)); - sq_newslot(v,-3, SQFalse); - sq_pushstring(v,_SC("_intsize_"),-1); - sq_pushinteger(v,sizeof(SQInteger)); - sq_newslot(v,-3, SQFalse); - sq_pushstring(v,_SC("_floatsize_"),-1); - sq_pushinteger(v,sizeof(SQFloat)); - sq_newslot(v,-3, SQFalse); - sq_pop(v,1); -} - -static SQInteger default_delegate_len(HSQUIRRELVM v) -{ - v->Push(SQInteger(sq_getsize(v,1))); - return 1; -} - -static SQInteger default_delegate_tofloat(HSQUIRRELVM v) -{ - SQObjectPtr &o=stack_get(v,1); - switch(sq_type(o)){ - case OT_STRING:{ - SQObjectPtr res; - if(str2num(_stringval(o),res,10)){ - v->Push(SQObjectPtr(tofloat(res))); - break; - }} - return sq_throwerror(v, _SC("cannot convert the string")); - break; - case OT_INTEGER:case OT_FLOAT: - v->Push(SQObjectPtr(tofloat(o))); - break; - case OT_BOOL: - v->Push(SQObjectPtr((SQFloat)(_integer(o)?1:0))); - break; - default: - v->PushNull(); - break; - } - return 1; -} - -static SQInteger default_delegate_tointeger(HSQUIRRELVM v) -{ - SQObjectPtr &o=stack_get(v,1); - SQInteger base = 10; - if(sq_gettop(v) > 1) { - sq_getinteger(v,2,&base); - } - switch(sq_type(o)){ - case OT_STRING:{ - SQObjectPtr res; - if(str2num(_stringval(o),res,base)){ - v->Push(SQObjectPtr(tointeger(res))); - break; - }} - return sq_throwerror(v, _SC("cannot convert the string")); - break; - case OT_INTEGER:case OT_FLOAT: - v->Push(SQObjectPtr(tointeger(o))); - break; - case OT_BOOL: - v->Push(SQObjectPtr(_integer(o)?(SQInteger)1:(SQInteger)0)); - break; - default: - v->PushNull(); - break; - } - return 1; -} - -static SQInteger default_delegate_tostring(HSQUIRRELVM v) -{ - if(SQ_FAILED(sq_tostring(v,1))) - return SQ_ERROR; - return 1; -} - -static SQInteger obj_delegate_weakref(HSQUIRRELVM v) -{ - sq_weakref(v,1); - return 1; -} - -static SQInteger obj_clear(HSQUIRRELVM v) -{ - return SQ_SUCCEEDED(sq_clear(v,-1)) ? 1 : SQ_ERROR; -} - - -static SQInteger number_delegate_tochar(HSQUIRRELVM v) -{ - SQObject &o=stack_get(v,1); - SQChar c = (SQChar)tointeger(o); - v->Push(SQString::Create(_ss(v),(const SQChar *)&c,1)); - return 1; -} - - - -///////////////////////////////////////////////////////////////// -//TABLE DEFAULT DELEGATE - -static SQInteger table_rawdelete(HSQUIRRELVM v) -{ - if(SQ_FAILED(sq_rawdeleteslot(v,1,SQTrue))) - return SQ_ERROR; - return 1; -} - - -static SQInteger container_rawexists(HSQUIRRELVM v) -{ - if(SQ_SUCCEEDED(sq_rawget(v,-2))) { - sq_pushbool(v,SQTrue); - return 1; - } - sq_pushbool(v,SQFalse); - return 1; -} - -static SQInteger container_rawset(HSQUIRRELVM v) -{ - return SQ_SUCCEEDED(sq_rawset(v,-3)) ? 1 : SQ_ERROR; -} - - -static SQInteger container_rawget(HSQUIRRELVM v) -{ - return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR; -} - -static SQInteger table_setdelegate(HSQUIRRELVM v) -{ - if(SQ_FAILED(sq_setdelegate(v,-2))) - return SQ_ERROR; - sq_push(v,-1); // -1 because sq_setdelegate pops 1 - return 1; -} - -static SQInteger table_getdelegate(HSQUIRRELVM v) -{ - return SQ_SUCCEEDED(sq_getdelegate(v,-1))?1:SQ_ERROR; -} - -static SQInteger table_filter(HSQUIRRELVM v) -{ - SQObject &o = stack_get(v,1); - SQTable *tbl = _table(o); - SQObjectPtr ret = SQTable::Create(_ss(v),0); - - SQObjectPtr itr, key, val; - SQInteger nitr; - while((nitr = tbl->Next(false, itr, key, val)) != -1) { - itr = (SQInteger)nitr; - - v->Push(o); - v->Push(key); - v->Push(val); - if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) { - return SQ_ERROR; - } - if(!SQVM::IsFalse(v->GetUp(-1))) { - _table(ret)->NewSlot(key, val); - } - v->Pop(); - } - - v->Push(ret); - return 1; -} - -static SQInteger table_map(HSQUIRRELVM v) -{ - SQObject &o = stack_get(v, 1); - SQTable *tbl = _table(o); - SQInteger nitr, n = 0; - SQInteger nitems = tbl->CountUsed(); - SQObjectPtr ret = SQArray::Create(_ss(v), nitems); - SQObjectPtr itr, key, val; - while ((nitr = tbl->Next(false, itr, key, val)) != -1) { - itr = (SQInteger)nitr; - - v->Push(o); - v->Push(key); - v->Push(val); - if (SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) { - return SQ_ERROR; - } - _array(ret)->Set(n, v->GetUp(-1)); - v->Pop(); - n++; - } - - v->Push(ret); - return 1; -} - -#define TABLE_TO_ARRAY_FUNC(_funcname_,_valname_) static SQInteger _funcname_(HSQUIRRELVM v) \ -{ \ - SQObject &o = stack_get(v, 1); \ - SQTable *t = _table(o); \ - SQObjectPtr itr, key, val; \ - SQObjectPtr _null; \ - SQInteger nitr, n = 0; \ - SQInteger nitems = t->CountUsed(); \ - SQArray *a = SQArray::Create(_ss(v), nitems); \ - a->Resize(nitems, _null); \ - if (nitems) { \ - while ((nitr = t->Next(false, itr, key, val)) != -1) { \ - itr = (SQInteger)nitr; \ - a->Set(n, _valname_); \ - n++; \ - } \ - } \ - v->Push(a); \ - return 1; \ -} - -TABLE_TO_ARRAY_FUNC(table_keys, key) -TABLE_TO_ARRAY_FUNC(table_values, val) - - -const SQRegFunction SQSharedState::_table_default_delegate_funcz[]={ - {_SC("len"),default_delegate_len,1, _SC("t")}, - {_SC("rawget"),container_rawget,2, _SC("t")}, - {_SC("rawset"),container_rawset,3, _SC("t")}, - {_SC("rawdelete"),table_rawdelete,2, _SC("t")}, - {_SC("rawin"),container_rawexists,2, _SC("t")}, - {_SC("weakref"),obj_delegate_weakref,1, NULL }, - {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, - {_SC("clear"),obj_clear,1, _SC(".")}, - {_SC("setdelegate"),table_setdelegate,2, _SC(".t|o")}, - {_SC("getdelegate"),table_getdelegate,1, _SC(".")}, - {_SC("filter"),table_filter,2, _SC("tc")}, - {_SC("map"),table_map,2, _SC("tc") }, - {_SC("keys"),table_keys,1, _SC("t") }, - {_SC("values"),table_values,1, _SC("t") }, - {NULL,(SQFUNCTION)0,0,NULL} -}; - -//ARRAY DEFAULT DELEGATE/////////////////////////////////////// - -static SQInteger array_append(HSQUIRRELVM v) -{ - return SQ_SUCCEEDED(sq_arrayappend(v,-2)) ? 1 : SQ_ERROR; -} - -static SQInteger array_extend(HSQUIRRELVM v) -{ - _array(stack_get(v,1))->Extend(_array(stack_get(v,2))); - sq_pop(v,1); - return 1; -} - -static SQInteger array_reverse(HSQUIRRELVM v) -{ - return SQ_SUCCEEDED(sq_arrayreverse(v,-1)) ? 1 : SQ_ERROR; -} - -static SQInteger array_pop(HSQUIRRELVM v) -{ - return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR; -} - -static SQInteger array_top(HSQUIRRELVM v) -{ - SQObject &o=stack_get(v,1); - if(_array(o)->Size()>0){ - v->Push(_array(o)->Top()); - return 1; - } - else return sq_throwerror(v,_SC("top() on an empty array")); -} - -static SQInteger array_insert(HSQUIRRELVM v) -{ - SQObject &o=stack_get(v,1); - SQObject &idx=stack_get(v,2); - SQObject &val=stack_get(v,3); - if(!_array(o)->Insert(tointeger(idx),val)) - return sq_throwerror(v,_SC("index out of range")); - sq_pop(v,2); - return 1; -} - -static SQInteger array_remove(HSQUIRRELVM v) -{ - SQObject &o = stack_get(v, 1); - SQObject &idx = stack_get(v, 2); - if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type")); - SQObjectPtr val; - if(_array(o)->Get(tointeger(idx), val)) { - _array(o)->Remove(tointeger(idx)); - v->Push(val); - return 1; - } - return sq_throwerror(v, _SC("idx out of range")); -} - -static SQInteger array_resize(HSQUIRRELVM v) -{ - SQObject &o = stack_get(v, 1); - SQObject &nsize = stack_get(v, 2); - SQObjectPtr fill; - if(sq_isnumeric(nsize)) { - SQInteger sz = tointeger(nsize); - if (sz<0) - return sq_throwerror(v, _SC("resizing to negative length")); - - if(sq_gettop(v) > 2) - fill = stack_get(v, 3); - _array(o)->Resize(sz,fill); - sq_settop(v, 1); - return 1; - } - return sq_throwerror(v, _SC("size must be a number")); -} - -static SQInteger __map_array(SQArray *dest,SQArray *src,HSQUIRRELVM v) { - SQObjectPtr temp; - SQInteger size = src->Size(); - SQObject &closure = stack_get(v, 2); - v->Push(closure); - - SQInteger nArgs = 0; - if(sq_type(closure) == OT_CLOSURE) { - nArgs = _closure(closure)->_function->_nparameters; - } - else if (sq_type(closure) == OT_NATIVECLOSURE) { - SQInteger nParamsCheck = _nativeclosure(closure)->_nparamscheck; - if (nParamsCheck > 0) - nArgs = nParamsCheck; - else // push all params when there is no check or only minimal count set - nArgs = 4; - } - - for(SQInteger n = 0; n < size; n++) { - src->Get(n,temp); - v->Push(src); - v->Push(temp); - if (nArgs >= 3) - v->Push(SQObjectPtr(n)); - if (nArgs >= 4) - v->Push(src); - if(SQ_FAILED(sq_call(v,nArgs,SQTrue,SQFalse))) { - return SQ_ERROR; - } - dest->Set(n,v->GetUp(-1)); - v->Pop(); - } - v->Pop(); - return 0; -} - -static SQInteger array_map(HSQUIRRELVM v) -{ - SQObject &o = stack_get(v,1); - SQInteger size = _array(o)->Size(); - SQObjectPtr ret = SQArray::Create(_ss(v),size); - if(SQ_FAILED(__map_array(_array(ret),_array(o),v))) - return SQ_ERROR; - v->Push(ret); - return 1; -} - -static SQInteger array_apply(HSQUIRRELVM v) -{ - SQObject &o = stack_get(v,1); - if(SQ_FAILED(__map_array(_array(o),_array(o),v))) - return SQ_ERROR; - sq_pop(v,1); - return 1; -} - -static SQInteger array_reduce(HSQUIRRELVM v) -{ - SQObject &o = stack_get(v,1); - SQArray *a = _array(o); - SQInteger size = a->Size(); - SQObjectPtr res; - SQInteger iterStart; - if (sq_gettop(v)>2) { - res = stack_get(v,3); - iterStart = 0; - } else if (size==0) { - return 0; - } else { - a->Get(0,res); - iterStart = 1; - } - if (size > iterStart) { - SQObjectPtr other; - v->Push(stack_get(v,2)); - for (SQInteger n = iterStart; n < size; n++) { - a->Get(n,other); - v->Push(o); - v->Push(res); - v->Push(other); - if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) { - return SQ_ERROR; - } - res = v->GetUp(-1); - v->Pop(); - } - v->Pop(); - } - v->Push(res); - return 1; -} - -static SQInteger array_filter(HSQUIRRELVM v) -{ - SQObject &o = stack_get(v,1); - SQArray *a = _array(o); - SQObjectPtr ret = SQArray::Create(_ss(v),0); - SQInteger size = a->Size(); - SQObjectPtr val; - for(SQInteger n = 0; n < size; n++) { - a->Get(n,val); - v->Push(o); - v->Push(n); - v->Push(val); - if(SQ_FAILED(sq_call(v,3,SQTrue,SQFalse))) { - return SQ_ERROR; - } - if(!SQVM::IsFalse(v->GetUp(-1))) { - _array(ret)->Append(val); - } - v->Pop(); - } - v->Push(ret); - return 1; -} - -static SQInteger array_find(HSQUIRRELVM v) -{ - SQObject &o = stack_get(v,1); - SQObjectPtr &val = stack_get(v,2); - SQArray *a = _array(o); - SQInteger size = a->Size(); - SQObjectPtr temp; - for(SQInteger n = 0; n < size; n++) { - bool res = false; - a->Get(n,temp); - if(SQVM::IsEqual(temp,val,res) && res) { - v->Push(n); - return 1; - } - } - return 0; -} - - -static bool _sort_compare(HSQUIRRELVM v, SQArray *arr, SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret) -{ - if(func < 0) { - if(!v->ObjCmp(a,b,ret)) return false; - } - else { - SQInteger top = sq_gettop(v); - sq_push(v, func); - sq_pushroottable(v); - v->Push(a); - v->Push(b); - SQObjectPtr *valptr = arr->_values._vals; - SQUnsignedInteger precallsize = arr->_values.size(); - if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) { - if(!sq_isstring( v->_lasterror)) - v->Raise_Error(_SC("compare func failed")); - return false; - } - if(SQ_FAILED(sq_getinteger(v, -1, &ret))) { - v->Raise_Error(_SC("numeric value expected as return value of the compare function")); - return false; - } - if (precallsize != arr->_values.size() || valptr != arr->_values._vals) { - v->Raise_Error(_SC("array resized during sort operation")); - return false; - } - sq_settop(v, top); - return true; - } - return true; -} - -static bool _hsort_sift_down(HSQUIRRELVM v,SQArray *arr, SQInteger root, SQInteger bottom, SQInteger func) -{ - SQInteger maxChild; - SQInteger done = 0; - SQInteger ret; - SQInteger root2; - while (((root2 = root * 2) <= bottom) && (!done)) - { - if (root2 == bottom) { - maxChild = root2; - } - else { - if(!_sort_compare(v,arr,arr->_values[root2],arr->_values[root2 + 1],func,ret)) - return false; - if (ret > 0) { - maxChild = root2; - } - else { - maxChild = root2 + 1; - } - } - - if(!_sort_compare(v,arr,arr->_values[root],arr->_values[maxChild],func,ret)) - return false; - if (ret < 0) { - if (root == maxChild) { - v->Raise_Error(_SC("inconsistent compare function")); - return false; // We'd be swapping ourselve. The compare function is incorrect - } - - _Swap(arr->_values[root],arr->_values[maxChild]); - root = maxChild; - } - else { - done = 1; - } - } - return true; -} - -static bool _hsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger SQ_UNUSED_ARG(l), SQInteger SQ_UNUSED_ARG(r),SQInteger func) -{ - SQArray *a = _array(arr); - SQInteger i; - SQInteger array_size = a->Size(); - for (i = (array_size / 2); i >= 0; i--) { - if(!_hsort_sift_down(v,a, i, array_size - 1,func)) return false; - } - - for (i = array_size-1; i >= 1; i--) - { - _Swap(a->_values[0],a->_values[i]); - if(!_hsort_sift_down(v,a, 0, i-1,func)) return false; - } - return true; -} - -static SQInteger array_sort(HSQUIRRELVM v) -{ - SQInteger func = -1; - SQObjectPtr &o = stack_get(v,1); - if(_array(o)->Size() > 1) { - if(sq_gettop(v) == 2) func = 2; - if(!_hsort(v, o, 0, _array(o)->Size()-1, func)) - return SQ_ERROR; - - } - sq_settop(v,1); - return 1; -} - -static SQInteger array_slice(HSQUIRRELVM v) -{ - SQInteger sidx,eidx; - SQObjectPtr o; - if(get_slice_params(v,sidx,eidx,o)==-1)return -1; - SQInteger alen = _array(o)->Size(); - if(sidx < 0)sidx = alen + sidx; - if(eidx < 0)eidx = alen + eidx; - if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes")); - if(eidx > alen || sidx < 0)return sq_throwerror(v, _SC("slice out of range")); - SQArray *arr=SQArray::Create(_ss(v),eidx-sidx); - SQObjectPtr t; - SQInteger count=0; - for(SQInteger i=sidx;iGet(i,t); - arr->Set(count++,t); - } - v->Push(arr); - return 1; - -} - -const SQRegFunction SQSharedState::_array_default_delegate_funcz[]={ - {_SC("len"),default_delegate_len,1, _SC("a")}, - {_SC("append"),array_append,2, _SC("a")}, - {_SC("extend"),array_extend,2, _SC("aa")}, - {_SC("push"),array_append,2, _SC("a")}, - {_SC("pop"),array_pop,1, _SC("a")}, - {_SC("top"),array_top,1, _SC("a")}, - {_SC("insert"),array_insert,3, _SC("an")}, - {_SC("remove"),array_remove,2, _SC("an")}, - {_SC("resize"),array_resize,-2, _SC("an")}, - {_SC("reverse"),array_reverse,1, _SC("a")}, - {_SC("sort"),array_sort,-1, _SC("ac")}, - {_SC("slice"),array_slice,-1, _SC("ann")}, - {_SC("weakref"),obj_delegate_weakref,1, NULL }, - {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, - {_SC("clear"),obj_clear,1, _SC(".")}, - {_SC("map"),array_map,2, _SC("ac")}, - {_SC("apply"),array_apply,2, _SC("ac")}, - {_SC("reduce"),array_reduce,-2, _SC("ac.")}, - {_SC("filter"),array_filter,2, _SC("ac")}, - {_SC("find"),array_find,2, _SC("a.")}, - {NULL,(SQFUNCTION)0,0,NULL} -}; - -//STRING DEFAULT DELEGATE////////////////////////// -static SQInteger string_slice(HSQUIRRELVM v) -{ - SQInteger sidx,eidx; - SQObjectPtr o; - if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1; - SQInteger slen = _string(o)->_len; - if(sidx < 0)sidx = slen + sidx; - if(eidx < 0)eidx = slen + eidx; - if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes")); - if(eidx > slen || sidx < 0) return sq_throwerror(v, _SC("slice out of range")); - v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx)); - return 1; -} - -static SQInteger string_find(HSQUIRRELVM v) -{ - SQInteger top,start_idx=0; - const SQChar *str,*substr,*ret; - if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){ - if(top>2)sq_getinteger(v,3,&start_idx); - if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){ - ret=scstrstr(&str[start_idx],substr); - if(ret){ - sq_pushinteger(v,(SQInteger)(ret-str)); - return 1; - } - } - return 0; - } - return sq_throwerror(v,_SC("invalid param")); -} - -#define STRING_TOFUNCZ(func) static SQInteger string_##func(HSQUIRRELVM v) \ -{\ - SQInteger sidx,eidx; \ - SQObjectPtr str; \ - if(SQ_FAILED(get_slice_params(v,sidx,eidx,str)))return -1; \ - SQInteger slen = _string(str)->_len; \ - if(sidx < 0)sidx = slen + sidx; \ - if(eidx < 0)eidx = slen + eidx; \ - if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes")); \ - if(eidx > slen || sidx < 0) return sq_throwerror(v,_SC("slice out of range")); \ - SQInteger len=_string(str)->_len; \ - const SQChar *sthis=_stringval(str); \ - SQChar *snew=(_ss(v)->GetScratchPad(sq_rsl(len))); \ - memcpy(snew,sthis,sq_rsl(len));\ - for(SQInteger i=sidx;iPush(SQString::Create(_ss(v),snew,len)); \ - return 1; \ -} - - -STRING_TOFUNCZ(tolower) -STRING_TOFUNCZ(toupper) - -const SQRegFunction SQSharedState::_string_default_delegate_funcz[]={ - {_SC("len"),default_delegate_len,1, _SC("s")}, - {_SC("tointeger"),default_delegate_tointeger,-1, _SC("sn")}, - {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")}, - {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, - {_SC("slice"),string_slice,-1, _SC("s n n")}, - {_SC("find"),string_find,-2, _SC("s s n")}, - {_SC("tolower"),string_tolower,-1, _SC("s n n")}, - {_SC("toupper"),string_toupper,-1, _SC("s n n")}, - {_SC("weakref"),obj_delegate_weakref,1, NULL }, - {NULL,(SQFUNCTION)0,0,NULL} -}; - -//INTEGER DEFAULT DELEGATE////////////////////////// -const SQRegFunction SQSharedState::_number_default_delegate_funcz[]={ - {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")}, - {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")}, - {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, - {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")}, - {_SC("weakref"),obj_delegate_weakref,1, NULL }, - {NULL,(SQFUNCTION)0,0,NULL} -}; - -//CLOSURE DEFAULT DELEGATE////////////////////////// -static SQInteger closure_pcall(HSQUIRRELVM v) -{ - return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQFalse))?1:SQ_ERROR; -} - -static SQInteger closure_call(HSQUIRRELVM v) -{ - SQObjectPtr &c = stack_get(v, -1); - if (sq_type(c) == OT_CLOSURE && (_closure(c)->_function->_bgenerator == false)) - { - return sq_tailcall(v, sq_gettop(v) - 1); - } - return SQ_SUCCEEDED(sq_call(v, sq_gettop(v) - 1, SQTrue, SQTrue)) ? 1 : SQ_ERROR; -} - -static SQInteger _closure_acall(HSQUIRRELVM v,SQBool raiseerror) -{ - SQArray *aparams=_array(stack_get(v,2)); - SQInteger nparams=aparams->Size(); - v->Push(stack_get(v,1)); - for(SQInteger i=0;iPush(aparams->_values[i]); - return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue,raiseerror))?1:SQ_ERROR; -} - -static SQInteger closure_acall(HSQUIRRELVM v) -{ - return _closure_acall(v,SQTrue); -} - -static SQInteger closure_pacall(HSQUIRRELVM v) -{ - return _closure_acall(v,SQFalse); -} - -static SQInteger closure_bindenv(HSQUIRRELVM v) -{ - if(SQ_FAILED(sq_bindenv(v,1))) - return SQ_ERROR; - return 1; -} - -static SQInteger closure_getroot(HSQUIRRELVM v) -{ - if(SQ_FAILED(sq_getclosureroot(v,-1))) - return SQ_ERROR; - return 1; -} - -static SQInteger closure_setroot(HSQUIRRELVM v) -{ - if(SQ_FAILED(sq_setclosureroot(v,-2))) - return SQ_ERROR; - return 1; -} - -static SQInteger closure_getinfos(HSQUIRRELVM v) { - SQObject o = stack_get(v,1); - SQTable *res = SQTable::Create(_ss(v),4); - if(sq_type(o) == OT_CLOSURE) { - SQFunctionProto *f = _closure(o)->_function; - SQInteger nparams = f->_nparameters + (f->_varparams?1:0); - SQObjectPtr params = SQArray::Create(_ss(v),nparams); - SQObjectPtr defparams = SQArray::Create(_ss(v),f->_ndefaultparams); - for(SQInteger n = 0; n_nparameters; n++) { - _array(params)->Set((SQInteger)n,f->_parameters[n]); - } - for(SQInteger j = 0; j_ndefaultparams; j++) { - _array(defparams)->Set((SQInteger)j,_closure(o)->_defaultparams[j]); - } - if(f->_varparams) { - _array(params)->Set(nparams-1,SQString::Create(_ss(v),_SC("..."),-1)); - } - res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),false); - res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),f->_name); - res->NewSlot(SQString::Create(_ss(v),_SC("src"),-1),f->_sourcename); - res->NewSlot(SQString::Create(_ss(v),_SC("parameters"),-1),params); - res->NewSlot(SQString::Create(_ss(v),_SC("varargs"),-1),f->_varparams); - res->NewSlot(SQString::Create(_ss(v),_SC("defparams"),-1),defparams); - } - else { //OT_NATIVECLOSURE - SQNativeClosure *nc = _nativeclosure(o); - res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),true); - res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),nc->_name); - res->NewSlot(SQString::Create(_ss(v),_SC("paramscheck"),-1),nc->_nparamscheck); - SQObjectPtr typecheck; - if(nc->_typecheck.size() > 0) { - typecheck = - SQArray::Create(_ss(v), nc->_typecheck.size()); - for(SQUnsignedInteger n = 0; n_typecheck.size(); n++) { - _array(typecheck)->Set((SQInteger)n,nc->_typecheck[n]); - } - } - res->NewSlot(SQString::Create(_ss(v),_SC("typecheck"),-1),typecheck); - } - v->Push(res); - return 1; -} - - - -const SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={ - {_SC("call"),closure_call,-1, _SC("c")}, - {_SC("pcall"),closure_pcall,-1, _SC("c")}, - {_SC("acall"),closure_acall,2, _SC("ca")}, - {_SC("pacall"),closure_pacall,2, _SC("ca")}, - {_SC("weakref"),obj_delegate_weakref,1, NULL }, - {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, - {_SC("bindenv"),closure_bindenv,2, _SC("c x|y|t")}, - {_SC("getinfos"),closure_getinfos,1, _SC("c")}, - {_SC("getroot"),closure_getroot,1, _SC("c")}, - {_SC("setroot"),closure_setroot,2, _SC("ct")}, - {NULL,(SQFUNCTION)0,0,NULL} -}; - -//GENERATOR DEFAULT DELEGATE -static SQInteger generator_getstatus(HSQUIRRELVM v) -{ - SQObject &o=stack_get(v,1); - switch(_generator(o)->_state){ - case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break; - case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break; - case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break; - } - return 1; -} - -const SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={ - {_SC("getstatus"),generator_getstatus,1, _SC("g")}, - {_SC("weakref"),obj_delegate_weakref,1, NULL }, - {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, - {NULL,(SQFUNCTION)0,0,NULL} -}; - -//THREAD DEFAULT DELEGATE -static SQInteger thread_call(HSQUIRRELVM v) -{ - SQObjectPtr o = stack_get(v,1); - if(sq_type(o) == OT_THREAD) { - SQInteger nparams = sq_gettop(v); - sq_reservestack(_thread(o), nparams + 3); - _thread(o)->Push(_thread(o)->_roottable); - for(SQInteger i = 2; i<(nparams+1); i++) - sq_move(_thread(o),v,i); - if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue,SQTrue))) { - sq_move(v,_thread(o),-1); - sq_pop(_thread(o),1); - return 1; - } - v->_lasterror = _thread(o)->_lasterror; - return SQ_ERROR; - } - return sq_throwerror(v,_SC("wrong parameter")); -} - -static SQInteger thread_wakeup(HSQUIRRELVM v) -{ - SQObjectPtr o = stack_get(v,1); - if(sq_type(o) == OT_THREAD) { - SQVM *thread = _thread(o); - SQInteger state = sq_getvmstate(thread); - if(state != SQ_VMSTATE_SUSPENDED) { - switch(state) { - case SQ_VMSTATE_IDLE: - return sq_throwerror(v,_SC("cannot wakeup an idle thread")); - break; - case SQ_VMSTATE_RUNNING: - return sq_throwerror(v,_SC("cannot wakeup a running thread")); - break; - } - } - - SQInteger wakeupret = sq_gettop(v)>1?SQTrue:SQFalse; - if(wakeupret) { - sq_move(thread,v,2); - } - if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,SQTrue,SQTrue,SQFalse))) { - sq_move(v,thread,-1); - sq_pop(thread,1); //pop retval - if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) { - sq_settop(thread,1); //pop roottable - } - return 1; - } - sq_settop(thread,1); - v->_lasterror = thread->_lasterror; - return SQ_ERROR; - } - return sq_throwerror(v,_SC("wrong parameter")); -} - -static SQInteger thread_wakeupthrow(HSQUIRRELVM v) -{ - SQObjectPtr o = stack_get(v,1); - if(sq_type(o) == OT_THREAD) { - SQVM *thread = _thread(o); - SQInteger state = sq_getvmstate(thread); - if(state != SQ_VMSTATE_SUSPENDED) { - switch(state) { - case SQ_VMSTATE_IDLE: - return sq_throwerror(v,_SC("cannot wakeup an idle thread")); - break; - case SQ_VMSTATE_RUNNING: - return sq_throwerror(v,_SC("cannot wakeup a running thread")); - break; - } - } - - sq_move(thread,v,2); - sq_throwobject(thread); - SQBool rethrow_error = SQTrue; - if(sq_gettop(v) > 2) { - sq_getbool(v,3,&rethrow_error); - } - if(SQ_SUCCEEDED(sq_wakeupvm(thread,SQFalse,SQTrue,SQTrue,SQTrue))) { - sq_move(v,thread,-1); - sq_pop(thread,1); //pop retval - if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) { - sq_settop(thread,1); //pop roottable - } - return 1; - } - sq_settop(thread,1); - if(rethrow_error) { - v->_lasterror = thread->_lasterror; - return SQ_ERROR; - } - return SQ_OK; - } - return sq_throwerror(v,_SC("wrong parameter")); -} - -static SQInteger thread_getstatus(HSQUIRRELVM v) -{ - SQObjectPtr &o = stack_get(v,1); - switch(sq_getvmstate(_thread(o))) { - case SQ_VMSTATE_IDLE: - sq_pushstring(v,_SC("idle"),-1); - break; - case SQ_VMSTATE_RUNNING: - sq_pushstring(v,_SC("running"),-1); - break; - case SQ_VMSTATE_SUSPENDED: - sq_pushstring(v,_SC("suspended"),-1); - break; - default: - return sq_throwerror(v,_SC("internal VM error")); - } - return 1; -} - -static SQInteger thread_getstackinfos(HSQUIRRELVM v) -{ - SQObjectPtr o = stack_get(v,1); - if(sq_type(o) == OT_THREAD) { - SQVM *thread = _thread(o); - SQInteger threadtop = sq_gettop(thread); - SQInteger level; - sq_getinteger(v,-1,&level); - SQRESULT res = __getcallstackinfos(thread,level); - if(SQ_FAILED(res)) - { - sq_settop(thread,threadtop); - if(sq_type(thread->_lasterror) == OT_STRING) { - sq_throwerror(v,_stringval(thread->_lasterror)); - } - else { - sq_throwerror(v,_SC("unknown error")); - } - } - if(res > 0) { - //some result - sq_move(v,thread,-1); - sq_settop(thread,threadtop); - return 1; - } - //no result - sq_settop(thread,threadtop); - return 0; - - } - return sq_throwerror(v,_SC("wrong parameter")); -} - -const SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = { - {_SC("call"), thread_call, -1, _SC("v")}, - {_SC("wakeup"), thread_wakeup, -1, _SC("v")}, - {_SC("wakeupthrow"), thread_wakeupthrow, -2, _SC("v.b")}, - {_SC("getstatus"), thread_getstatus, 1, _SC("v")}, - {_SC("weakref"),obj_delegate_weakref,1, NULL }, - {_SC("getstackinfos"),thread_getstackinfos,2, _SC("vn")}, - {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, - {NULL,(SQFUNCTION)0,0,NULL} -}; - -static SQInteger class_getattributes(HSQUIRRELVM v) -{ - return SQ_SUCCEEDED(sq_getattributes(v,-2))?1:SQ_ERROR; -} - -static SQInteger class_setattributes(HSQUIRRELVM v) -{ - return SQ_SUCCEEDED(sq_setattributes(v,-3))?1:SQ_ERROR; -} - -static SQInteger class_instance(HSQUIRRELVM v) -{ - return SQ_SUCCEEDED(sq_createinstance(v,-1))?1:SQ_ERROR; -} - -static SQInteger class_getbase(HSQUIRRELVM v) -{ - return SQ_SUCCEEDED(sq_getbase(v,-1))?1:SQ_ERROR; -} - -static SQInteger class_newmember(HSQUIRRELVM v) -{ - SQInteger top = sq_gettop(v); - SQBool bstatic = SQFalse; - if(top == 5) - { - sq_tobool(v,-1,&bstatic); - sq_pop(v,1); - } - - if(top < 4) { - sq_pushnull(v); - } - return SQ_SUCCEEDED(sq_newmember(v,-4,bstatic))?1:SQ_ERROR; -} - -static SQInteger class_rawnewmember(HSQUIRRELVM v) -{ - SQInteger top = sq_gettop(v); - SQBool bstatic = SQFalse; - if(top == 5) - { - sq_tobool(v,-1,&bstatic); - sq_pop(v,1); - } - - if(top < 4) { - sq_pushnull(v); - } - return SQ_SUCCEEDED(sq_rawnewmember(v,-4,bstatic))?1:SQ_ERROR; -} - -const SQRegFunction SQSharedState::_class_default_delegate_funcz[] = { - {_SC("getattributes"), class_getattributes, 2, _SC("y.")}, - {_SC("setattributes"), class_setattributes, 3, _SC("y..")}, - {_SC("rawget"),container_rawget,2, _SC("y")}, - {_SC("rawset"),container_rawset,3, _SC("y")}, - {_SC("rawin"),container_rawexists,2, _SC("y")}, - {_SC("weakref"),obj_delegate_weakref,1, NULL }, - {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, - {_SC("instance"),class_instance,1, _SC("y")}, - {_SC("getbase"),class_getbase,1, _SC("y")}, - {_SC("newmember"),class_newmember,-3, _SC("y")}, - {_SC("rawnewmember"),class_rawnewmember,-3, _SC("y")}, - {NULL,(SQFUNCTION)0,0,NULL} -}; - - -static SQInteger instance_getclass(HSQUIRRELVM v) -{ - if(SQ_SUCCEEDED(sq_getclass(v,1))) - return 1; - return SQ_ERROR; -} - -const SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = { - {_SC("getclass"), instance_getclass, 1, _SC("x")}, - {_SC("rawget"),container_rawget,2, _SC("x")}, - {_SC("rawset"),container_rawset,3, _SC("x")}, - {_SC("rawin"),container_rawexists,2, _SC("x")}, - {_SC("weakref"),obj_delegate_weakref,1, NULL }, - {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, - {NULL,(SQFUNCTION)0,0,NULL} -}; - -static SQInteger weakref_ref(HSQUIRRELVM v) -{ - if(SQ_FAILED(sq_getweakrefval(v,1))) - return SQ_ERROR; - return 1; -} - -const SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = { - {_SC("ref"),weakref_ref,1, _SC("r")}, - {_SC("weakref"),obj_delegate_weakref,1, NULL }, - {_SC("tostring"),default_delegate_tostring,1, _SC(".")}, - {NULL,(SQFUNCTION)0,0,NULL} -}; diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqclass.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqclass.cpp deleted file mode 100644 index 53a297630..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqclass.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/* - see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#include "sqvm.h" -#include "sqtable.h" -#include "sqclass.h" -#include "sqfuncproto.h" -#include "sqclosure.h" - - - -SQClass::SQClass(SQSharedState *ss,SQClass *base) -{ - _base = base; - _typetag = 0; - _hook = NULL; - _udsize = 0; - _locked = false; - _constructoridx = -1; - if(_base) { - _constructoridx = _base->_constructoridx; - _udsize = _base->_udsize; - _defaultvalues.copy(base->_defaultvalues); - _methods.copy(base->_methods); - _COPY_VECTOR(_metamethods,base->_metamethods,MT_LAST); - __ObjAddRef(_base); - } - _members = base?base->_members->Clone() : SQTable::Create(ss,0); - __ObjAddRef(_members); - - INIT_CHAIN(); - ADD_TO_CHAIN(&_sharedstate->_gc_chain, this); -} - -void SQClass::Finalize() { - _attributes.Null(); - _NULL_SQOBJECT_VECTOR(_defaultvalues,_defaultvalues.size()); - _methods.resize(0); - _NULL_SQOBJECT_VECTOR(_metamethods,MT_LAST); - __ObjRelease(_members); - if(_base) { - __ObjRelease(_base); - } -} - -SQClass::~SQClass() -{ - REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); - Finalize(); -} - -bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic) -{ - SQObjectPtr temp; - bool belongs_to_static_table = sq_type(val) == OT_CLOSURE || sq_type(val) == OT_NATIVECLOSURE || bstatic; - if(_locked && !belongs_to_static_table) - return false; //the class already has an instance so cannot be modified - if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value - { - _defaultvalues[_member_idx(temp)].val = val; - return true; - } - if (_members->CountUsed() >= MEMBER_MAX_COUNT) { - return false; - } - if(belongs_to_static_table) { - SQInteger mmidx; - if((sq_type(val) == OT_CLOSURE || sq_type(val) == OT_NATIVECLOSURE) && - (mmidx = ss->GetMetaMethodIdxByName(key)) != -1) { - _metamethods[mmidx] = val; - } - else { - SQObjectPtr theval = val; - if(_base && sq_type(val) == OT_CLOSURE) { - theval = _closure(val)->Clone(); - _closure(theval)->_base = _base; - __ObjAddRef(_base); //ref for the closure - } - if(sq_type(temp) == OT_NULL) { - bool isconstructor; - SQVM::IsEqual(ss->_constructoridx, key, isconstructor); - if(isconstructor) { - _constructoridx = (SQInteger)_methods.size(); - } - SQClassMember m; - m.val = theval; - _members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size()))); - _methods.push_back(m); - } - else { - _methods[_member_idx(temp)].val = theval; - } - } - return true; - } - SQClassMember m; - m.val = val; - _members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size()))); - _defaultvalues.push_back(m); - return true; -} - -SQInstance *SQClass::CreateInstance() -{ - if(!_locked) Lock(); - return SQInstance::Create(_opt_ss(this),this); -} - -SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) -{ - SQObjectPtr oval; - SQInteger idx = _members->Next(false,refpos,outkey,oval); - if(idx != -1) { - if(_ismethod(oval)) { - outval = _methods[_member_idx(oval)].val; - } - else { - SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val; - outval = _realval(o); - } - } - return idx; -} - -bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val) -{ - SQObjectPtr idx; - if(_members->Get(key,idx)) { - if(_isfield(idx)) - _defaultvalues[_member_idx(idx)].attrs = val; - else - _methods[_member_idx(idx)].attrs = val; - return true; - } - return false; -} - -bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval) -{ - SQObjectPtr idx; - if(_members->Get(key,idx)) { - outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs); - return true; - } - return false; -} - -/////////////////////////////////////////////////////////////////////// -void SQInstance::Init(SQSharedState *ss) -{ - _userpointer = NULL; - _hook = NULL; - __ObjAddRef(_class); - _delegate = _class->_members; - INIT_CHAIN(); - ADD_TO_CHAIN(&_sharedstate->_gc_chain, this); -} - -SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize) -{ - _memsize = memsize; - _class = c; - SQUnsignedInteger nvalues = _class->_defaultvalues.size(); - for(SQUnsignedInteger n = 0; n < nvalues; n++) { - new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val); - } - Init(ss); -} - -SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize) -{ - _memsize = memsize; - _class = i->_class; - SQUnsignedInteger nvalues = _class->_defaultvalues.size(); - for(SQUnsignedInteger n = 0; n < nvalues; n++) { - new (&_values[n]) SQObjectPtr(i->_values[n]); - } - Init(ss); -} - -void SQInstance::Finalize() -{ - SQUnsignedInteger nvalues = _class->_defaultvalues.size(); - __ObjRelease(_class); - _NULL_SQOBJECT_VECTOR(_values,nvalues); -} - -SQInstance::~SQInstance() -{ - REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); - if(_class){ Finalize(); } //if _class is null it was already finalized by the GC -} - -bool SQInstance::GetMetaMethod(SQVM* SQ_UNUSED_ARG(v),SQMetaMethod mm,SQObjectPtr &res) -{ - if(sq_type(_class->_metamethods[mm]) != OT_NULL) { - res = _class->_metamethods[mm]; - return true; - } - return false; -} - -bool SQInstance::InstanceOf(SQClass *trg) -{ - SQClass *parent = _class; - while(parent != NULL) { - if(parent == trg) - return true; - parent = parent->_base; - } - return false; -} diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqclass.h b/src/modules/app_sqlang/squirrel/squirrel/sqclass.h deleted file mode 100644 index f1e0e69c7..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqclass.h +++ /dev/null @@ -1,199 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQCLASS_H_ -#define _SQCLASS_H_ - -struct SQInstance; - -struct SQClassMember -{ - SQObjectPtr val; - SQObjectPtr attrs; - void Null() - { - val.Null(); - attrs.Null(); - } -}; - -typedef sqvector SQClassMemberVec; - -#define MEMBER_TYPE_METHOD 0x01000000 -#define MEMBER_TYPE_FIELD 0x02000000 -#define MEMBER_MAX_COUNT 0x00FFFFFF - -#define _ismethod(o) (_integer(o) & MEMBER_TYPE_METHOD) -#define _isfield(o) (_integer(o) & MEMBER_TYPE_FIELD) -#define _make_method_idx(i) ((SQInteger)(MEMBER_TYPE_METHOD | i)) -#define _make_field_idx(i) ((SQInteger)(MEMBER_TYPE_FIELD | i)) -#define _member_type(o) (_integer(o) & 0xFF000000) -#define _member_idx(o) (_integer(o) & 0x00FFFFFF) - -struct SQClass : public CHAINABLE_OBJ -{ - SQClass(SQSharedState *ss, SQClass *base); - -public: - static SQClass *Create(SQSharedState *ss, SQClass *base) - { - SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass)); - new(newclass) SQClass(ss, base); - return newclass; - } - ~SQClass(); - bool NewSlot(SQSharedState *ss, const SQObjectPtr &key, - const SQObjectPtr &val, bool bstatic); - bool Get(const SQObjectPtr &key, SQObjectPtr &val) - { - if(_members->Get(key, val)) { - if(_isfield(val)) { - SQObjectPtr &o = _defaultvalues[_member_idx(val)].val; - val = _realval(o); - } else { - val = _methods[_member_idx(val)].val; - } - return true; - } - return false; - } - bool GetConstructor(SQObjectPtr &ctor) - { - if(_constructoridx != -1) { - ctor = _methods[_constructoridx].val; - return true; - } - return false; - } - bool SetAttributes(const SQObjectPtr &key, const SQObjectPtr &val); - bool GetAttributes(const SQObjectPtr &key, SQObjectPtr &outval); - void Lock() - { - _locked = true; - if(_base) - _base->Lock(); - } - void Release() - { - if(_hook) { - _hook(_typetag, 0); - } - sq_delete(this, SQClass); - } - void Finalize(); -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable **); - SQObjectType GetType() - { - return OT_CLASS; - } -#endif - SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, - SQObjectPtr &outval); - SQInstance *CreateInstance(); - SQTable *_members; - SQClass *_base; - SQClassMemberVec _defaultvalues; - SQClassMemberVec _methods; - SQObjectPtr _metamethods[MT_LAST]; - SQObjectPtr _attributes; - SQUserPointer _typetag; - SQRELEASEHOOK _hook; - bool _locked; - SQInteger _constructoridx; - SQInteger _udsize; -}; - -#define calcinstancesize(_theclass_) \ - (_theclass_->_udsize \ - + sq_aligning(sizeof(SQInstance) \ - + (sizeof(SQObjectPtr) \ - * (_theclass_->_defaultvalues.size() > 0 \ - ? _theclass_->_defaultvalues \ - .size() \ - - 1 \ - : 0)))) - -struct SQInstance : public SQDelegable -{ - void Init(SQSharedState *ss); - SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize); - SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize); - -public: - static SQInstance *Create(SQSharedState *ss, SQClass *theclass) - { - - SQInteger size = calcinstancesize(theclass); - SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); - new(newinst) SQInstance(ss, theclass, size); - if(theclass->_udsize) { - newinst->_userpointer = - ((unsigned char *)newinst) + (size - theclass->_udsize); - } - return newinst; - } - SQInstance *Clone(SQSharedState *ss) - { - SQInteger size = calcinstancesize(_class); - SQInstance *newinst = (SQInstance *)SQ_MALLOC(size); - new(newinst) SQInstance(ss, this, size); - if(_class->_udsize) { - newinst->_userpointer = - ((unsigned char *)newinst) + (size - _class->_udsize); - } - return newinst; - } - ~SQInstance(); - bool Get(const SQObjectPtr &key, SQObjectPtr &val) - { - if(_class->_members->Get(key, val)) { - if(_isfield(val)) { - SQObjectPtr &o = _values[_member_idx(val)]; - val = _realval(o); - } else { - val = _class->_methods[_member_idx(val)].val; - } - return true; - } - return false; - } - bool Set(const SQObjectPtr &key, const SQObjectPtr &val) - { - SQObjectPtr idx; - if(_class->_members->Get(key, idx) && _isfield(idx)) { - _values[_member_idx(idx)] = val; - return true; - } - return false; - } - void Release() - { - _uiRef++; - if(_hook) { - _hook(_userpointer, 0); - } - _uiRef--; - if(_uiRef > 0) - return; - SQInteger size = _memsize; - this->~SQInstance(); - SQ_FREE(this, size); - } - void Finalize(); -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable **); - SQObjectType GetType() - { - return OT_INSTANCE; - } -#endif - bool InstanceOf(SQClass *trg); - bool GetMetaMethod(SQVM *v, SQMetaMethod mm, SQObjectPtr &res); - - SQClass *_class; - SQUserPointer _userpointer; - SQRELEASEHOOK _hook; - SQInteger _memsize; - SQObjectPtr _values[1]; -}; - -#endif //_SQCLASS_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqclosure.h b/src/modules/app_sqlang/squirrel/squirrel/sqclosure.h deleted file mode 100644 index c224af252..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqclosure.h +++ /dev/null @@ -1,280 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQCLOSURE_H_ -#define _SQCLOSURE_H_ - - -#define _CALC_CLOSURE_SIZE(func) \ - (sizeof(SQClosure) + (func->_noutervalues * sizeof(SQObjectPtr)) \ - + (func->_ndefaultparams * sizeof(SQObjectPtr))) - -struct SQFunctionProto; -struct SQClass; -struct SQClosure : public CHAINABLE_OBJ -{ -private: - SQClosure(SQSharedState *ss, SQFunctionProto *func) - { - _function = func; - __ObjAddRef(_function); - _base = NULL; - INIT_CHAIN(); - ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); - _env = NULL; - _root = NULL; - } - -public: - static SQClosure *Create( - SQSharedState *ss, SQFunctionProto *func, SQWeakRef *root) - { - SQInteger size = _CALC_CLOSURE_SIZE(func); - SQClosure *nc = (SQClosure *)SQ_MALLOC(size); - new(nc) SQClosure(ss, func); - nc->_outervalues = (SQObjectPtr *)(nc + 1); - nc->_defaultparams = &nc->_outervalues[func->_noutervalues]; - nc->_root = root; - __ObjAddRef(nc->_root); - _CONSTRUCT_VECTOR(SQObjectPtr, func->_noutervalues, nc->_outervalues); - _CONSTRUCT_VECTOR( - SQObjectPtr, func->_ndefaultparams, nc->_defaultparams); - return nc; - } - void Release() - { - SQFunctionProto *f = _function; - SQInteger size = _CALC_CLOSURE_SIZE(f); - _DESTRUCT_VECTOR(SQObjectPtr, f->_noutervalues, _outervalues); - _DESTRUCT_VECTOR(SQObjectPtr, f->_ndefaultparams, _defaultparams); - __ObjRelease(_function); - this->~SQClosure(); - sq_vm_free(this, size); - } - void SetRoot(SQWeakRef *r) - { - __ObjRelease(_root); - _root = r; - __ObjAddRef(_root); - } - SQClosure *Clone() - { - SQFunctionProto *f = _function; - SQClosure *ret = SQClosure::Create(_opt_ss(this), f, _root); - ret->_env = _env; - if(ret->_env) - __ObjAddRef(ret->_env); - _COPY_VECTOR(ret->_outervalues, _outervalues, f->_noutervalues); - _COPY_VECTOR(ret->_defaultparams, _defaultparams, f->_ndefaultparams); - return ret; - } - ~SQClosure(); - - bool Save(SQVM *v, SQUserPointer up, SQWRITEFUNC write); - static bool Load( - SQVM *v, SQUserPointer up, SQREADFUNC read, SQObjectPtr &ret); -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable **chain); - void Finalize() - { - SQFunctionProto *f = _function; - _NULL_SQOBJECT_VECTOR(_outervalues, f->_noutervalues); - _NULL_SQOBJECT_VECTOR(_defaultparams, f->_ndefaultparams); - } - SQObjectType GetType() - { - return OT_CLOSURE; - } -#endif - SQWeakRef *_env; - SQWeakRef *_root; - SQClass *_base; - SQFunctionProto *_function; - SQObjectPtr *_outervalues; - SQObjectPtr *_defaultparams; -}; - -////////////////////////////////////////////// -struct SQOuter : public CHAINABLE_OBJ -{ - -private: - SQOuter(SQSharedState *ss, SQObjectPtr *outer) - { - _valptr = outer; - _next = NULL; - INIT_CHAIN(); - ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); - } - -public: - static SQOuter *Create(SQSharedState *ss, SQObjectPtr *outer) - { - SQOuter *nc = (SQOuter *)SQ_MALLOC(sizeof(SQOuter)); - new(nc) SQOuter(ss, outer); - return nc; - } - ~SQOuter() - { - REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this); - } - - void Release() - { - this->~SQOuter(); - sq_vm_free(this, sizeof(SQOuter)); - } - -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable **chain); - void Finalize() - { - _value.Null(); - } - SQObjectType GetType() - { - return OT_OUTER; - } -#endif - - SQObjectPtr *_valptr; /* pointer to value on stack, or _value below */ - SQInteger _idx; /* idx in stack array, for relocation */ - SQObjectPtr _value; /* value of outer after stack frame is closed */ - SQOuter *_next; /* pointer to next outer when frame is open */ -}; - -////////////////////////////////////////////// -struct SQGenerator : public CHAINABLE_OBJ -{ - enum SQGeneratorState - { - eRunning, - eSuspended, - eDead - }; - -private: - SQGenerator(SQSharedState *ss, SQClosure *closure) - { - _closure = closure; - _state = eRunning; - _ci._generator = NULL; - INIT_CHAIN(); - ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); - } - -public: - static SQGenerator *Create(SQSharedState *ss, SQClosure *closure) - { - SQGenerator *nc = (SQGenerator *)SQ_MALLOC(sizeof(SQGenerator)); - new(nc) SQGenerator(ss, closure); - return nc; - } - ~SQGenerator() - { - REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this); - } - void Kill() - { - _state = eDead; - _stack.resize(0); - _closure.Null(); - } - void Release() - { - sq_delete(this, SQGenerator); - } - - bool Yield(SQVM *v, SQInteger target); - bool Resume(SQVM *v, SQObjectPtr &dest); -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable **chain); - void Finalize() - { - _stack.resize(0); - _closure.Null(); - } - SQObjectType GetType() - { - return OT_GENERATOR; - } -#endif - SQObjectPtr _closure; - SQObjectPtrVec _stack; - SQVM::CallInfo _ci; - ExceptionsTraps _etraps; - SQGeneratorState _state; -}; - -#define _CALC_NATVIVECLOSURE_SIZE(noutervalues) \ - (sizeof(SQNativeClosure) + (noutervalues * sizeof(SQObjectPtr))) - -struct SQNativeClosure : public CHAINABLE_OBJ -{ -private: - SQNativeClosure(SQSharedState *ss, SQFUNCTION func) - { - _function = func; - INIT_CHAIN(); - ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); - _env = NULL; - } - -public: - static SQNativeClosure *Create( - SQSharedState *ss, SQFUNCTION func, SQInteger nouters) - { - SQInteger size = _CALC_NATVIVECLOSURE_SIZE(nouters); - SQNativeClosure *nc = (SQNativeClosure *)SQ_MALLOC(size); - new(nc) SQNativeClosure(ss, func); - nc->_outervalues = (SQObjectPtr *)(nc + 1); - nc->_noutervalues = nouters; - _CONSTRUCT_VECTOR(SQObjectPtr, nc->_noutervalues, nc->_outervalues); - return nc; - } - SQNativeClosure *Clone() - { - SQNativeClosure *ret = SQNativeClosure::Create( - _opt_ss(this), _function, _noutervalues); - ret->_env = _env; - if(ret->_env) - __ObjAddRef(ret->_env); - ret->_name = _name; - _COPY_VECTOR(ret->_outervalues, _outervalues, _noutervalues); - ret->_typecheck.copy(_typecheck); - ret->_nparamscheck = _nparamscheck; - return ret; - } - ~SQNativeClosure() - { - __ObjRelease(_env); - REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this); - } - void Release() - { - SQInteger size = _CALC_NATVIVECLOSURE_SIZE(_noutervalues); - _DESTRUCT_VECTOR(SQObjectPtr, _noutervalues, _outervalues); - this->~SQNativeClosure(); - sq_free(this, size); - } - -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable **chain); - void Finalize() - { - _NULL_SQOBJECT_VECTOR(_outervalues, _noutervalues); - } - SQObjectType GetType() - { - return OT_NATIVECLOSURE; - } -#endif - SQInteger _nparamscheck; - SQIntVec _typecheck; - SQObjectPtr *_outervalues; - SQUnsignedInteger _noutervalues; - SQWeakRef *_env; - SQFUNCTION _function; - SQObjectPtr _name; -}; - - -#endif //_SQCLOSURE_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqcompiler.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqcompiler.cpp deleted file mode 100644 index 3e2144bfb..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqcompiler.cpp +++ /dev/null @@ -1,1641 +0,0 @@ -/* - see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#ifndef NO_COMPILER -#include -#include -#include "sqopcodes.h" -#include "sqstring.h" -#include "sqfuncproto.h" -#include "sqcompiler.h" -#include "sqfuncstate.h" -#include "sqlexer.h" -#include "sqvm.h" -#include "sqtable.h" - -#define EXPR 1 -#define OBJECT 2 -#define BASE 3 -#define LOCAL 4 -#define OUTER 5 - -struct SQExpState { - SQInteger etype; /* expr. type; one of EXPR, OBJECT, BASE, OUTER or LOCAL */ - SQInteger epos; /* expr. location on stack; -1 for OBJECT and BASE */ - bool donot_get; /* signal not to deref the next value */ -}; - -#define MAX_COMPILER_ERROR_LEN 256 - -struct SQScope { - SQInteger outers; - SQInteger stacksize; -}; - -#define BEGIN_SCOPE() SQScope __oldscope__ = _scope; \ - _scope.outers = _fs->_outers; \ - _scope.stacksize = _fs->GetStackSize(); - -#define RESOLVE_OUTERS() if(_fs->GetStackSize() != _scope.stacksize) { \ - if(_fs->CountOuters(_scope.stacksize)) { \ - _fs->AddInstruction(_OP_CLOSE,0,_scope.stacksize); \ - } \ - } - -#define END_SCOPE_NO_CLOSE() { if(_fs->GetStackSize() != _scope.stacksize) { \ - _fs->SetStackSize(_scope.stacksize); \ - } \ - _scope = __oldscope__; \ - } - -#define END_SCOPE() { SQInteger oldouters = _fs->_outers;\ - if(_fs->GetStackSize() != _scope.stacksize) { \ - _fs->SetStackSize(_scope.stacksize); \ - if(oldouters != _fs->_outers) { \ - _fs->AddInstruction(_OP_CLOSE,0,_scope.stacksize); \ - } \ - } \ - _scope = __oldscope__; \ - } - -#define BEGIN_BREAKBLE_BLOCK() SQInteger __nbreaks__=_fs->_unresolvedbreaks.size(); \ - SQInteger __ncontinues__=_fs->_unresolvedcontinues.size(); \ - _fs->_breaktargets.push_back(0);_fs->_continuetargets.push_back(0); - -#define END_BREAKBLE_BLOCK(continue_target) {__nbreaks__=_fs->_unresolvedbreaks.size()-__nbreaks__; \ - __ncontinues__=_fs->_unresolvedcontinues.size()-__ncontinues__; \ - if(__ncontinues__>0)ResolveContinues(_fs,__ncontinues__,continue_target); \ - if(__nbreaks__>0)ResolveBreaks(_fs,__nbreaks__); \ - _fs->_breaktargets.pop_back();_fs->_continuetargets.pop_back();} - -class SQCompiler -{ -public: - SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo) - { - _vm=v; - _lex.Init(_ss(v), rg, up,ThrowError,this); - _sourcename = SQString::Create(_ss(v), sourcename); - _lineinfo = lineinfo;_raiseerror = raiseerror; - _scope.outers = 0; - _scope.stacksize = 0; - _compilererror[0] = _SC('\0'); - } - static void ThrowError(void *ud, const SQChar *s) { - SQCompiler *c = (SQCompiler *)ud; - c->Error(s); - } - void Error(const SQChar *s, ...) - { - va_list vl; - va_start(vl, s); - scvsprintf(_compilererror, MAX_COMPILER_ERROR_LEN, s, vl); - va_end(vl); - longjmp(_errorjmp,1); - } - void Lex(){ _token = _lex.Lex();} - SQObject Expect(SQInteger tok) - { - - if(_token != tok) { - if(_token == TK_CONSTRUCTOR && tok == TK_IDENTIFIER) { - //do nothing - } - else { - const SQChar *etypename; - if(tok > 255) { - switch(tok) - { - case TK_IDENTIFIER: - etypename = _SC("IDENTIFIER"); - break; - case TK_STRING_LITERAL: - etypename = _SC("STRING_LITERAL"); - break; - case TK_INTEGER: - etypename = _SC("INTEGER"); - break; - case TK_FLOAT: - etypename = _SC("FLOAT"); - break; - default: - etypename = _lex.Tok2Str(tok); - } - Error(_SC("expected '%s'"), etypename); - } - Error(_SC("expected '%c'"), tok); - } - } - SQObjectPtr ret; - switch(tok) - { - case TK_IDENTIFIER: - ret = _fs->CreateString(_lex._svalue); - break; - case TK_STRING_LITERAL: - ret = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1); - break; - case TK_INTEGER: - ret = SQObjectPtr(_lex._nvalue); - break; - case TK_FLOAT: - ret = SQObjectPtr(_lex._fvalue); - break; - } - Lex(); - return ret; - } - bool IsEndOfStatement() { return ((_lex._prevtoken == _SC('\n')) || (_token == SQUIRREL_EOB) || (_token == _SC('}')) || (_token == _SC(';'))); } - void OptionalSemicolon() - { - if(_token == _SC(';')) { Lex(); return; } - if(!IsEndOfStatement()) { - Error(_SC("end of statement expected (; or lf)")); - } - } - void MoveIfCurrentTargetIsLocal() { - SQInteger trg = _fs->TopTarget(); - if(_fs->IsLocal(trg)) { - trg = _fs->PopTarget(); //pops the target and moves it - _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), trg); - } - } - bool Compile(SQObjectPtr &o) - { - _debugline = 1; - _debugop = 0; - - SQFuncState funcstate(_ss(_vm), NULL,ThrowError,this); - funcstate._name = SQString::Create(_ss(_vm), _SC("main")); - _fs = &funcstate; - _fs->AddParameter(_fs->CreateString(_SC("this"))); - _fs->AddParameter(_fs->CreateString(_SC("vargv"))); - _fs->_varparams = true; - _fs->_sourcename = _sourcename; - SQInteger stacksize = _fs->GetStackSize(); - if(setjmp(_errorjmp) == 0) { - Lex(); - while(_token > 0){ - Statement(); - if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon(); - } - _fs->SetStackSize(stacksize); - _fs->AddLineInfos(_lex._currentline, _lineinfo, true); - _fs->AddInstruction(_OP_RETURN, 0xFF); - _fs->SetStackSize(0); - o =_fs->BuildProto(); -#ifdef _DEBUG_DUMP - _fs->Dump(_funcproto(o)); -#endif - } - else { - if(_raiseerror && _ss(_vm)->_compilererrorhandler) { - _ss(_vm)->_compilererrorhandler(_vm, _compilererror, sq_type(_sourcename) == OT_STRING?_stringval(_sourcename):_SC("unknown"), - _lex._currentline, _lex._currentcolumn); - } - _vm->_lasterror = SQString::Create(_ss(_vm), _compilererror, -1); - return false; - } - return true; - } - void Statements() - { - while(_token != _SC('}') && _token != TK_DEFAULT && _token != TK_CASE) { - Statement(); - if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon(); - } - } - void Statement(bool closeframe = true) - { - _fs->AddLineInfos(_lex._currentline, _lineinfo); - switch(_token){ - case _SC(';'): Lex(); break; - case TK_IF: IfStatement(); break; - case TK_WHILE: WhileStatement(); break; - case TK_DO: DoWhileStatement(); break; - case TK_FOR: ForStatement(); break; - case TK_FOREACH: ForEachStatement(); break; - case TK_SWITCH: SwitchStatement(); break; - case TK_LOCAL: LocalDeclStatement(); break; - case TK_RETURN: - case TK_YIELD: { - SQOpcode op; - if(_token == TK_RETURN) { - op = _OP_RETURN; - } - else { - op = _OP_YIELD; - _fs->_bgenerator = true; - } - Lex(); - if(!IsEndOfStatement()) { - SQInteger retexp = _fs->GetCurrentPos()+1; - CommaExpr(); - if(op == _OP_RETURN && _fs->_traps > 0) - _fs->AddInstruction(_OP_POPTRAP, _fs->_traps, 0); - _fs->_returnexp = retexp; - _fs->AddInstruction(op, 1, _fs->PopTarget(),_fs->GetStackSize()); - } - else{ - if(op == _OP_RETURN && _fs->_traps > 0) - _fs->AddInstruction(_OP_POPTRAP, _fs->_traps ,0); - _fs->_returnexp = -1; - _fs->AddInstruction(op, 0xFF,0,_fs->GetStackSize()); - } - break;} - case TK_BREAK: - if(_fs->_breaktargets.size() <= 0)Error(_SC("'break' has to be in a loop block")); - if(_fs->_breaktargets.top() > 0){ - _fs->AddInstruction(_OP_POPTRAP, _fs->_breaktargets.top(), 0); - } - RESOLVE_OUTERS(); - _fs->AddInstruction(_OP_JMP, 0, -1234); - _fs->_unresolvedbreaks.push_back(_fs->GetCurrentPos()); - Lex(); - break; - case TK_CONTINUE: - if(_fs->_continuetargets.size() <= 0)Error(_SC("'continue' has to be in a loop block")); - if(_fs->_continuetargets.top() > 0) { - _fs->AddInstruction(_OP_POPTRAP, _fs->_continuetargets.top(), 0); - } - RESOLVE_OUTERS(); - _fs->AddInstruction(_OP_JMP, 0, -1234); - _fs->_unresolvedcontinues.push_back(_fs->GetCurrentPos()); - Lex(); - break; - case TK_FUNCTION: - FunctionStatement(); - break; - case TK_CLASS: - ClassStatement(); - break; - case TK_ENUM: - EnumStatement(); - break; - case _SC('{'):{ - BEGIN_SCOPE(); - Lex(); - Statements(); - Expect(_SC('}')); - if(closeframe) { - END_SCOPE(); - } - else { - END_SCOPE_NO_CLOSE(); - } - } - break; - case TK_TRY: - TryCatchStatement(); - break; - case TK_THROW: - Lex(); - CommaExpr(); - _fs->AddInstruction(_OP_THROW, _fs->PopTarget()); - break; - case TK_CONST: - { - Lex(); - SQObject id = Expect(TK_IDENTIFIER); - Expect('='); - SQObject val = ExpectScalar(); - OptionalSemicolon(); - SQTable *enums = _table(_ss(_vm)->_consts); - SQObjectPtr strongid = id; - enums->NewSlot(strongid,SQObjectPtr(val)); - strongid.Null(); - } - break; - default: - CommaExpr(); - _fs->DiscardTarget(); - //_fs->PopTarget(); - break; - } - _fs->SnoozeOpt(); - } - void EmitDerefOp(SQOpcode op) - { - SQInteger val = _fs->PopTarget(); - SQInteger key = _fs->PopTarget(); - SQInteger src = _fs->PopTarget(); - _fs->AddInstruction(op,_fs->PushTarget(),src,key,val); - } - void Emit2ArgsOP(SQOpcode op, SQInteger p3 = 0) - { - SQInteger p2 = _fs->PopTarget(); //src in OP_GET - SQInteger p1 = _fs->PopTarget(); //key in OP_GET - _fs->AddInstruction(op,_fs->PushTarget(), p1, p2, p3); - } - void EmitCompoundArith(SQInteger tok, SQInteger etype, SQInteger pos) - { - /* Generate code depending on the expression type */ - switch(etype) { - case LOCAL:{ - SQInteger p2 = _fs->PopTarget(); //src in OP_GET - SQInteger p1 = _fs->PopTarget(); //key in OP_GET - _fs->PushTarget(p1); - //EmitCompArithLocal(tok, p1, p1, p2); - _fs->AddInstruction(ChooseArithOpByToken(tok),p1, p2, p1, 0); - _fs->SnoozeOpt(); - } - break; - case OBJECT: - case BASE: - { - SQInteger val = _fs->PopTarget(); - SQInteger key = _fs->PopTarget(); - SQInteger src = _fs->PopTarget(); - /* _OP_COMPARITH mixes dest obj and source val in the arg1 */ - _fs->AddInstruction(_OP_COMPARITH, _fs->PushTarget(), (src<<16)|val, key, ChooseCompArithCharByToken(tok)); - } - break; - case OUTER: - { - SQInteger val = _fs->TopTarget(); - SQInteger tmp = _fs->PushTarget(); - _fs->AddInstruction(_OP_GETOUTER, tmp, pos); - _fs->AddInstruction(ChooseArithOpByToken(tok), tmp, val, tmp, 0); - _fs->PopTarget(); - _fs->PopTarget(); - _fs->AddInstruction(_OP_SETOUTER, _fs->PushTarget(), pos, tmp); - } - break; - } - } - void CommaExpr() - { - for(Expression();_token == ',';_fs->PopTarget(), Lex(), CommaExpr()); - } - void Expression() - { - SQExpState es = _es; - _es.etype = EXPR; - _es.epos = -1; - _es.donot_get = false; - LogicalOrExp(); - switch(_token) { - case _SC('='): - case TK_NEWSLOT: - case TK_MINUSEQ: - case TK_PLUSEQ: - case TK_MULEQ: - case TK_DIVEQ: - case TK_MODEQ:{ - SQInteger op = _token; - SQInteger ds = _es.etype; - SQInteger pos = _es.epos; - if(ds == EXPR) Error(_SC("can't assign expression")); - else if(ds == BASE) Error(_SC("'base' cannot be modified")); - Lex(); Expression(); - - switch(op){ - case TK_NEWSLOT: - if(ds == OBJECT || ds == BASE) - EmitDerefOp(_OP_NEWSLOT); - else //if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local - Error(_SC("can't 'create' a local slot")); - break; - case _SC('='): //ASSIGN - switch(ds) { - case LOCAL: - { - SQInteger src = _fs->PopTarget(); - SQInteger dst = _fs->TopTarget(); - _fs->AddInstruction(_OP_MOVE, dst, src); - } - break; - case OBJECT: - case BASE: - EmitDerefOp(_OP_SET); - break; - case OUTER: - { - SQInteger src = _fs->PopTarget(); - SQInteger dst = _fs->PushTarget(); - _fs->AddInstruction(_OP_SETOUTER, dst, pos, src); - } - } - break; - case TK_MINUSEQ: - case TK_PLUSEQ: - case TK_MULEQ: - case TK_DIVEQ: - case TK_MODEQ: - EmitCompoundArith(op, ds, pos); - break; - } - } - break; - case _SC('?'): { - Lex(); - _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); - SQInteger jzpos = _fs->GetCurrentPos(); - SQInteger trg = _fs->PushTarget(); - Expression(); - SQInteger first_exp = _fs->PopTarget(); - if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp); - SQInteger endfirstexp = _fs->GetCurrentPos(); - _fs->AddInstruction(_OP_JMP, 0, 0); - Expect(_SC(':')); - SQInteger jmppos = _fs->GetCurrentPos(); - Expression(); - SQInteger second_exp = _fs->PopTarget(); - if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); - _fs->SetInstructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos); - _fs->SetInstructionParam(jzpos, 1, endfirstexp - jzpos + 1); - _fs->SnoozeOpt(); - } - break; - } - _es = es; - } - template void INVOKE_EXP(T f) - { - SQExpState es = _es; - _es.etype = EXPR; - _es.epos = -1; - _es.donot_get = false; - (this->*f)(); - _es = es; - } - template void BIN_EXP(SQOpcode op, T f,SQInteger op3 = 0) - { - Lex(); - INVOKE_EXP(f); - SQInteger op1 = _fs->PopTarget();SQInteger op2 = _fs->PopTarget(); - _fs->AddInstruction(op, _fs->PushTarget(), op1, op2, op3); - _es.etype = EXPR; - } - void LogicalOrExp() - { - LogicalAndExp(); - for(;;) if(_token == TK_OR) { - SQInteger first_exp = _fs->PopTarget(); - SQInteger trg = _fs->PushTarget(); - _fs->AddInstruction(_OP_OR, trg, 0, first_exp, 0); - SQInteger jpos = _fs->GetCurrentPos(); - if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp); - Lex(); INVOKE_EXP(&SQCompiler::LogicalOrExp); - _fs->SnoozeOpt(); - SQInteger second_exp = _fs->PopTarget(); - if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); - _fs->SnoozeOpt(); - _fs->SetInstructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos)); - _es.etype = EXPR; - break; - }else return; - } - void LogicalAndExp() - { - BitwiseOrExp(); - for(;;) switch(_token) { - case TK_AND: { - SQInteger first_exp = _fs->PopTarget(); - SQInteger trg = _fs->PushTarget(); - _fs->AddInstruction(_OP_AND, trg, 0, first_exp, 0); - SQInteger jpos = _fs->GetCurrentPos(); - if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp); - Lex(); INVOKE_EXP(&SQCompiler::LogicalAndExp); - _fs->SnoozeOpt(); - SQInteger second_exp = _fs->PopTarget(); - if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp); - _fs->SnoozeOpt(); - _fs->SetInstructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos)); - _es.etype = EXPR; - break; - } - - default: - return; - } - } - void BitwiseOrExp() - { - BitwiseXorExp(); - for(;;) if(_token == _SC('|')) - {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseXorExp,BW_OR); - }else return; - } - void BitwiseXorExp() - { - BitwiseAndExp(); - for(;;) if(_token == _SC('^')) - {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseAndExp,BW_XOR); - }else return; - } - void BitwiseAndExp() - { - EqExp(); - for(;;) if(_token == _SC('&')) - {BIN_EXP(_OP_BITW, &SQCompiler::EqExp,BW_AND); - }else return; - } - void EqExp() - { - CompExp(); - for(;;) switch(_token) { - case TK_EQ: BIN_EXP(_OP_EQ, &SQCompiler::CompExp); break; - case TK_NE: BIN_EXP(_OP_NE, &SQCompiler::CompExp); break; - case TK_3WAYSCMP: BIN_EXP(_OP_CMP, &SQCompiler::CompExp,CMP_3W); break; - default: return; - } - } - void CompExp() - { - ShiftExp(); - for(;;) switch(_token) { - case _SC('>'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_G); break; - case _SC('<'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_L); break; - case TK_GE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_GE); break; - case TK_LE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_LE); break; - case TK_IN: BIN_EXP(_OP_EXISTS, &SQCompiler::ShiftExp); break; - case TK_INSTANCEOF: BIN_EXP(_OP_INSTANCEOF, &SQCompiler::ShiftExp); break; - default: return; - } - } - void ShiftExp() - { - PlusExp(); - for(;;) switch(_token) { - case TK_USHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_USHIFTR); break; - case TK_SHIFTL: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTL); break; - case TK_SHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTR); break; - default: return; - } - } - SQOpcode ChooseArithOpByToken(SQInteger tok) - { - switch(tok) { - case TK_PLUSEQ: case '+': return _OP_ADD; - case TK_MINUSEQ: case '-': return _OP_SUB; - case TK_MULEQ: case '*': return _OP_MUL; - case TK_DIVEQ: case '/': return _OP_DIV; - case TK_MODEQ: case '%': return _OP_MOD; - default: assert(0); - } - return _OP_ADD; - } - SQInteger ChooseCompArithCharByToken(SQInteger tok) - { - SQInteger oper; - switch(tok){ - case TK_MINUSEQ: oper = '-'; break; - case TK_PLUSEQ: oper = '+'; break; - case TK_MULEQ: oper = '*'; break; - case TK_DIVEQ: oper = '/'; break; - case TK_MODEQ: oper = '%'; break; - default: oper = 0; //shut up compiler - assert(0); break; - }; - return oper; - } - void PlusExp() - { - MultExp(); - for(;;) switch(_token) { - case _SC('+'): case _SC('-'): - BIN_EXP(ChooseArithOpByToken(_token), &SQCompiler::MultExp); break; - default: return; - } - } - - void MultExp() - { - PrefixedExpr(); - for(;;) switch(_token) { - case _SC('*'): case _SC('/'): case _SC('%'): - BIN_EXP(ChooseArithOpByToken(_token), &SQCompiler::PrefixedExpr); break; - default: return; - } - } - //if 'pos' != -1 the previous variable is a local variable - void PrefixedExpr() - { - SQInteger pos = Factor(); - for(;;) { - switch(_token) { - case _SC('.'): - pos = -1; - Lex(); - - _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER))); - if(_es.etype==BASE) { - Emit2ArgsOP(_OP_GET); - pos = _fs->TopTarget(); - _es.etype = EXPR; - _es.epos = pos; - } - else { - if(NeedGet()) { - Emit2ArgsOP(_OP_GET); - } - _es.etype = OBJECT; - } - break; - case _SC('['): - if(_lex._prevtoken == _SC('\n')) Error(_SC("cannot break deref/or comma needed after [exp]=exp slot declaration")); - Lex(); Expression(); Expect(_SC(']')); - pos = -1; - if(_es.etype==BASE) { - Emit2ArgsOP(_OP_GET); - pos = _fs->TopTarget(); - _es.etype = EXPR; - _es.epos = pos; - } - else { - if(NeedGet()) { - Emit2ArgsOP(_OP_GET); - } - _es.etype = OBJECT; - } - break; - case TK_MINUSMINUS: - case TK_PLUSPLUS: - { - if(IsEndOfStatement()) return; - SQInteger diff = (_token==TK_MINUSMINUS) ? -1 : 1; - Lex(); - switch(_es.etype) - { - case EXPR: Error(_SC("can't '++' or '--' an expression")); break; - case OBJECT: - case BASE: - if(_es.donot_get == true) { Error(_SC("can't '++' or '--' an expression")); break; } //mmh does this make sense? - Emit2ArgsOP(_OP_PINC, diff); - break; - case LOCAL: { - SQInteger src = _fs->PopTarget(); - _fs->AddInstruction(_OP_PINCL, _fs->PushTarget(), src, 0, diff); - } - break; - case OUTER: { - SQInteger tmp1 = _fs->PushTarget(); - SQInteger tmp2 = _fs->PushTarget(); - _fs->AddInstruction(_OP_GETOUTER, tmp2, _es.epos); - _fs->AddInstruction(_OP_PINCL, tmp1, tmp2, 0, diff); - _fs->AddInstruction(_OP_SETOUTER, tmp2, _es.epos, tmp2); - _fs->PopTarget(); - } - } - } - return; - break; - case _SC('('): - switch(_es.etype) { - case OBJECT: { - SQInteger key = _fs->PopTarget(); /* location of the key */ - SQInteger table = _fs->PopTarget(); /* location of the object */ - SQInteger closure = _fs->PushTarget(); /* location for the closure */ - SQInteger ttarget = _fs->PushTarget(); /* location for 'this' pointer */ - _fs->AddInstruction(_OP_PREPCALL, closure, key, table, ttarget); - } - break; - case BASE: - //Emit2ArgsOP(_OP_GET); - _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0); - break; - case OUTER: - _fs->AddInstruction(_OP_GETOUTER, _fs->PushTarget(), _es.epos); - _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0); - break; - default: - _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0); - } - _es.etype = EXPR; - Lex(); - FunctionCallArgs(); - break; - default: return; - } - } - } - SQInteger Factor() - { - //_es.etype = EXPR; - switch(_token) - { - case TK_STRING_LITERAL: - _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_fs->CreateString(_lex._svalue,_lex._longstr.size()-1))); - Lex(); - break; - case TK_BASE: - Lex(); - _fs->AddInstruction(_OP_GETBASE, _fs->PushTarget()); - _es.etype = BASE; - _es.epos = _fs->TopTarget(); - return (_es.epos); - break; - case TK_IDENTIFIER: - case TK_CONSTRUCTOR: - case TK_THIS:{ - SQObject id; - SQObject constant; - - switch(_token) { - case TK_IDENTIFIER: id = _fs->CreateString(_lex._svalue); break; - case TK_THIS: id = _fs->CreateString(_SC("this"),4); break; - case TK_CONSTRUCTOR: id = _fs->CreateString(_SC("constructor"),11); break; - } - - SQInteger pos = -1; - Lex(); - if((pos = _fs->GetLocalVariable(id)) != -1) { - /* Handle a local variable (includes 'this') */ - _fs->PushTarget(pos); - _es.etype = LOCAL; - _es.epos = pos; - } - - else if((pos = _fs->GetOuterVariable(id)) != -1) { - /* Handle a free var */ - if(NeedGet()) { - _es.epos = _fs->PushTarget(); - _fs->AddInstruction(_OP_GETOUTER, _es.epos, pos); - /* _es.etype = EXPR; already default value */ - } - else { - _es.etype = OUTER; - _es.epos = pos; - } - } - - else if(_fs->IsConstant(id, constant)) { - /* Handle named constant */ - SQObjectPtr constval; - SQObject constid; - if(sq_type(constant) == OT_TABLE) { - Expect('.'); - constid = Expect(TK_IDENTIFIER); - if(!_table(constant)->Get(constid, constval)) { - constval.Null(); - Error(_SC("invalid constant [%s.%s]"), _stringval(id), _stringval(constid)); - } - } - else { - constval = constant; - } - _es.epos = _fs->PushTarget(); - - /* generate direct or literal function depending on size */ - SQObjectType ctype = sq_type(constval); - switch(ctype) { - case OT_INTEGER: EmitLoadConstInt(_integer(constval),_es.epos); break; - case OT_FLOAT: EmitLoadConstFloat(_float(constval),_es.epos); break; - case OT_BOOL: _fs->AddInstruction(_OP_LOADBOOL, _es.epos, _integer(constval)); break; - default: _fs->AddInstruction(_OP_LOAD,_es.epos,_fs->GetConstant(constval)); break; - } - _es.etype = EXPR; - } - else { - /* Handle a non-local variable, aka a field. Push the 'this' pointer on - * the virtual stack (always found in offset 0, so no instruction needs to - * be generated), and push the key next. Generate an _OP_LOAD instruction - * for the latter. If we are not using the variable as a dref expr, generate - * the _OP_GET instruction. - */ - _fs->PushTarget(0); - _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); - if(NeedGet()) { - Emit2ArgsOP(_OP_GET); - } - _es.etype = OBJECT; - } - return _es.epos; - } - break; - case TK_DOUBLE_COLON: // "::" - _fs->AddInstruction(_OP_LOADROOT, _fs->PushTarget()); - _es.etype = OBJECT; - _token = _SC('.'); /* hack: drop into PrefixExpr, case '.'*/ - _es.epos = -1; - return _es.epos; - break; - case TK_NULL: - _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1); - Lex(); - break; - case TK_INTEGER: EmitLoadConstInt(_lex._nvalue,-1); Lex(); break; - case TK_FLOAT: EmitLoadConstFloat(_lex._fvalue,-1); Lex(); break; - case TK_TRUE: case TK_FALSE: - _fs->AddInstruction(_OP_LOADBOOL, _fs->PushTarget(),_token == TK_TRUE?1:0); - Lex(); - break; - case _SC('['): { - _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,0,NOT_ARRAY); - SQInteger apos = _fs->GetCurrentPos(),key = 0; - Lex(); - while(_token != _SC(']')) { - Expression(); - if(_token == _SC(',')) Lex(); - SQInteger val = _fs->PopTarget(); - SQInteger array = _fs->TopTarget(); - _fs->AddInstruction(_OP_APPENDARRAY, array, val, AAT_STACK); - key++; - } - _fs->SetInstructionParam(apos, 1, key); - Lex(); - } - break; - case _SC('{'): - _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE); - Lex();ParseTableOrClass(_SC(','),_SC('}')); - break; - case TK_FUNCTION: FunctionExp();break; - case _SC('@'): FunctionExp(true);break; - case TK_CLASS: Lex(); ClassExp();break; - case _SC('-'): - Lex(); - switch(_token) { - case TK_INTEGER: EmitLoadConstInt(-_lex._nvalue,-1); Lex(); break; - case TK_FLOAT: EmitLoadConstFloat(-_lex._fvalue,-1); Lex(); break; - default: UnaryOP(_OP_NEG); - } - break; - case _SC('!'): Lex(); UnaryOP(_OP_NOT); break; - case _SC('~'): - Lex(); - if(_token == TK_INTEGER) { EmitLoadConstInt(~_lex._nvalue,-1); Lex(); break; } - UnaryOP(_OP_BWNOT); - break; - case TK_TYPEOF : Lex() ;UnaryOP(_OP_TYPEOF); break; - case TK_RESUME : Lex(); UnaryOP(_OP_RESUME); break; - case TK_CLONE : Lex(); UnaryOP(_OP_CLONE); break; - case TK_RAWCALL: Lex(); Expect('('); FunctionCallArgs(true); break; - case TK_MINUSMINUS : - case TK_PLUSPLUS :PrefixIncDec(_token); break; - case TK_DELETE : DeleteExpr(); break; - case _SC('('): Lex(); CommaExpr(); Expect(_SC(')')); - break; - case TK___LINE__: EmitLoadConstInt(_lex._currentline,-1); Lex(); break; - case TK___FILE__: _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_sourcename)); Lex(); break; - default: Error(_SC("expression expected")); - } - _es.etype = EXPR; - return -1; - } - void EmitLoadConstInt(SQInteger value,SQInteger target) - { - if(target < 0) { - target = _fs->PushTarget(); - } - if(value <= INT_MAX && value > INT_MIN) { //does it fit in 32 bits? - _fs->AddInstruction(_OP_LOADINT, target,value); - } - else { - _fs->AddInstruction(_OP_LOAD, target, _fs->GetNumericConstant(value)); - } - } - void EmitLoadConstFloat(SQFloat value,SQInteger target) - { - if(target < 0) { - target = _fs->PushTarget(); - } - if(sizeof(SQFloat) == sizeof(SQInt32)) { - _fs->AddInstruction(_OP_LOADFLOAT, target,*((SQInt32 *)&value)); - } - else { - _fs->AddInstruction(_OP_LOAD, target, _fs->GetNumericConstant(value)); - } - } - void UnaryOP(SQOpcode op) - { - PrefixedExpr(); - SQInteger src = _fs->PopTarget(); - _fs->AddInstruction(op, _fs->PushTarget(), src); - } - bool NeedGet() - { - switch(_token) { - case _SC('='): case _SC('('): case TK_NEWSLOT: case TK_MODEQ: case TK_MULEQ: - case TK_DIVEQ: case TK_MINUSEQ: case TK_PLUSEQ: - return false; - case TK_PLUSPLUS: case TK_MINUSMINUS: - if (!IsEndOfStatement()) { - return false; - } - break; - } - return (!_es.donot_get || ( _es.donot_get && (_token == _SC('.') || _token == _SC('[')))); - } - void FunctionCallArgs(bool rawcall = false) - { - SQInteger nargs = 1;//this - while(_token != _SC(')')) { - Expression(); - MoveIfCurrentTargetIsLocal(); - nargs++; - if(_token == _SC(',')){ - Lex(); - if(_token == ')') Error(_SC("expression expected, found ')'")); - } - } - Lex(); - if (rawcall) { - if (nargs < 3) Error(_SC("rawcall requires at least 2 parameters (callee and this)")); - nargs -= 2; //removes callee and this from count - } - for(SQInteger i = 0; i < (nargs - 1); i++) _fs->PopTarget(); - SQInteger stackbase = _fs->PopTarget(); - SQInteger closure = _fs->PopTarget(); - _fs->AddInstruction(_OP_CALL, _fs->PushTarget(), closure, stackbase, nargs); - if (_token == '{') - { - SQInteger retval = _fs->TopTarget(); - SQInteger nkeys = 0; - Lex(); - while (_token != '}') { - switch (_token) { - case _SC('['): - Lex(); CommaExpr(); Expect(_SC(']')); - Expect(_SC('=')); Expression(); - break; - default: - _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER))); - Expect(_SC('=')); Expression(); - break; - } - if (_token == ',') Lex(); - nkeys++; - SQInteger val = _fs->PopTarget(); - SQInteger key = _fs->PopTarget(); - _fs->AddInstruction(_OP_SET, 0xFF, retval, key, val); - } - Lex(); - } - } - void ParseTableOrClass(SQInteger separator,SQInteger terminator) - { - SQInteger tpos = _fs->GetCurrentPos(),nkeys = 0; - while(_token != terminator) { - bool hasattrs = false; - bool isstatic = false; - //check if is an attribute - if(separator == ';') { - if(_token == TK_ATTR_OPEN) { - _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE); Lex(); - ParseTableOrClass(',',TK_ATTR_CLOSE); - hasattrs = true; - } - if(_token == TK_STATIC) { - isstatic = true; - Lex(); - } - } - switch(_token) { - case TK_FUNCTION: - case TK_CONSTRUCTOR:{ - SQInteger tk = _token; - Lex(); - SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : _fs->CreateString(_SC("constructor")); - _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); - SQInteger boundtarget = 0xFF; - if (_token == _SC('[')) { - boundtarget = ParseBindEnv(); - } - Expect(_SC('(')); - - CreateFunction(id, boundtarget); - _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, boundtarget); - } - break; - case _SC('['): - Lex(); CommaExpr(); Expect(_SC(']')); - Expect(_SC('=')); Expression(); - break; - case TK_STRING_LITERAL: //JSON - if(separator == ',') { //only works for tables - _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_STRING_LITERAL))); - Expect(_SC(':')); Expression(); - break; - } - default : - _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER))); - Expect(_SC('=')); Expression(); - } - if(_token == separator) Lex();//optional comma/semicolon - nkeys++; - SQInteger val = _fs->PopTarget(); - SQInteger key = _fs->PopTarget(); - SQInteger attrs = hasattrs ? _fs->PopTarget():-1; - ((void)attrs); - assert((hasattrs && (attrs == key-1)) || !hasattrs); - unsigned char flags = (hasattrs?NEW_SLOT_ATTRIBUTES_FLAG:0)|(isstatic?NEW_SLOT_STATIC_FLAG:0); - SQInteger table = _fs->TopTarget(); //<AddInstruction(_OP_NEWSLOT, 0xFF, table, key, val); - } - else { - _fs->AddInstruction(_OP_NEWSLOTA, flags, table, key, val); //this for classes only as it invokes _newmember - } - } - if(separator == _SC(',')) //hack recognizes a table from the separator - _fs->SetInstructionParam(tpos, 1, nkeys); - Lex(); - } - void LocalDeclStatement() - { - SQObject varname; - Lex(); - if( _token == TK_FUNCTION) { - SQInteger boundtarget = 0xFF; - Lex(); - varname = Expect(TK_IDENTIFIER); - if (_token == _SC('[')) { - boundtarget = ParseBindEnv(); - } - Expect(_SC('(')); - CreateFunction(varname,0xFF,false); - _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, boundtarget); - _fs->PopTarget(); - _fs->PushLocalVariable(varname); - return; - } - - do { - varname = Expect(TK_IDENTIFIER); - if(_token == _SC('=')) { - Lex(); Expression(); - SQInteger src = _fs->PopTarget(); - SQInteger dest = _fs->PushTarget(); - if(dest != src) _fs->AddInstruction(_OP_MOVE, dest, src); - } - else{ - _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1); - } - _fs->PopTarget(); - _fs->PushLocalVariable(varname); - if(_token == _SC(',')) Lex(); else break; - } while(1); - } - void IfBlock() - { - if (_token == _SC('{')) - { - BEGIN_SCOPE(); - Lex(); - Statements(); - Expect(_SC('}')); - if (true) { - END_SCOPE(); - } - else { - END_SCOPE_NO_CLOSE(); - } - } - else { - //BEGIN_SCOPE(); - Statement(); - if (_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon(); - //END_SCOPE(); - } - } - void IfStatement() - { - SQInteger jmppos; - bool haselse = false; - Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); - _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); - SQInteger jnepos = _fs->GetCurrentPos(); - - - - IfBlock(); - // - /*static int n = 0; - if (_token != _SC('}') && _token != TK_ELSE) { - printf("IF %d-----------------------!!!!!!!!!\n", n); - if (n == 5) - { - printf("asd"); - } - n++; - //OptionalSemicolon(); - }*/ - - - SQInteger endifblock = _fs->GetCurrentPos(); - if(_token == TK_ELSE){ - haselse = true; - //BEGIN_SCOPE(); - _fs->AddInstruction(_OP_JMP); - jmppos = _fs->GetCurrentPos(); - Lex(); - //Statement(); if(_lex._prevtoken != _SC('}')) OptionalSemicolon(); - IfBlock(); - //END_SCOPE(); - _fs->SetInstructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos); - } - _fs->SetInstructionParam(jnepos, 1, endifblock - jnepos + (haselse?1:0)); - } - void WhileStatement() - { - SQInteger jzpos, jmppos; - jmppos = _fs->GetCurrentPos(); - Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); - - BEGIN_BREAKBLE_BLOCK(); - _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); - jzpos = _fs->GetCurrentPos(); - BEGIN_SCOPE(); - - Statement(); - - END_SCOPE(); - _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1); - _fs->SetInstructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos); - - END_BREAKBLE_BLOCK(jmppos); - } - void DoWhileStatement() - { - Lex(); - SQInteger jmptrg = _fs->GetCurrentPos(); - BEGIN_BREAKBLE_BLOCK() - BEGIN_SCOPE(); - Statement(); - END_SCOPE(); - Expect(TK_WHILE); - SQInteger continuetrg = _fs->GetCurrentPos(); - Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); - _fs->AddInstruction(_OP_JZ, _fs->PopTarget(), 1); - _fs->AddInstruction(_OP_JMP, 0, jmptrg - _fs->GetCurrentPos() - 1); - END_BREAKBLE_BLOCK(continuetrg); - } - void ForStatement() - { - Lex(); - BEGIN_SCOPE(); - Expect(_SC('(')); - if(_token == TK_LOCAL) LocalDeclStatement(); - else if(_token != _SC(';')){ - CommaExpr(); - _fs->PopTarget(); - } - Expect(_SC(';')); - _fs->SnoozeOpt(); - SQInteger jmppos = _fs->GetCurrentPos(); - SQInteger jzpos = -1; - if(_token != _SC(';')) { CommaExpr(); _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); jzpos = _fs->GetCurrentPos(); } - Expect(_SC(';')); - _fs->SnoozeOpt(); - SQInteger expstart = _fs->GetCurrentPos() + 1; - if(_token != _SC(')')) { - CommaExpr(); - _fs->PopTarget(); - } - Expect(_SC(')')); - _fs->SnoozeOpt(); - SQInteger expend = _fs->GetCurrentPos(); - SQInteger expsize = (expend - expstart) + 1; - SQInstructionVec exp; - if(expsize > 0) { - for(SQInteger i = 0; i < expsize; i++) - exp.push_back(_fs->GetInstruction(expstart + i)); - _fs->PopInstructions(expsize); - } - BEGIN_BREAKBLE_BLOCK() - Statement(); - SQInteger continuetrg = _fs->GetCurrentPos(); - if(expsize > 0) { - for(SQInteger i = 0; i < expsize; i++) - _fs->AddInstruction(exp[i]); - } - _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1, 0); - if(jzpos> 0) _fs->SetInstructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos); - - END_BREAKBLE_BLOCK(continuetrg); - - END_SCOPE(); - } - void ForEachStatement() - { - SQObject idxname, valname; - Lex(); Expect(_SC('(')); valname = Expect(TK_IDENTIFIER); - if(_token == _SC(',')) { - idxname = valname; - Lex(); valname = Expect(TK_IDENTIFIER); - } - else{ - idxname = _fs->CreateString(_SC("@INDEX@")); - } - Expect(TK_IN); - - //save the stack size - BEGIN_SCOPE(); - //put the table in the stack(evaluate the table expression) - Expression(); Expect(_SC(')')); - SQInteger container = _fs->TopTarget(); - //push the index local var - SQInteger indexpos = _fs->PushLocalVariable(idxname); - _fs->AddInstruction(_OP_LOADNULLS, indexpos,1); - //push the value local var - SQInteger valuepos = _fs->PushLocalVariable(valname); - _fs->AddInstruction(_OP_LOADNULLS, valuepos,1); - //push reference index - SQInteger itrpos = _fs->PushLocalVariable(_fs->CreateString(_SC("@ITERATOR@"))); //use invalid id to make it inaccessible - _fs->AddInstruction(_OP_LOADNULLS, itrpos,1); - SQInteger jmppos = _fs->GetCurrentPos(); - _fs->AddInstruction(_OP_FOREACH, container, 0, indexpos); - SQInteger foreachpos = _fs->GetCurrentPos(); - _fs->AddInstruction(_OP_POSTFOREACH, container, 0, indexpos); - //generate the statement code - BEGIN_BREAKBLE_BLOCK() - Statement(); - _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1); - _fs->SetInstructionParam(foreachpos, 1, _fs->GetCurrentPos() - foreachpos); - _fs->SetInstructionParam(foreachpos + 1, 1, _fs->GetCurrentPos() - foreachpos); - END_BREAKBLE_BLOCK(foreachpos - 1); - //restore the local variable stack(remove index,val and ref idx) - _fs->PopTarget(); - END_SCOPE(); - } - void SwitchStatement() - { - Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')')); - Expect(_SC('{')); - SQInteger expr = _fs->TopTarget(); - bool bfirst = true; - SQInteger tonextcondjmp = -1; - SQInteger skipcondjmp = -1; - SQInteger __nbreaks__ = _fs->_unresolvedbreaks.size(); - _fs->_breaktargets.push_back(0); - while(_token == TK_CASE) { - if(!bfirst) { - _fs->AddInstruction(_OP_JMP, 0, 0); - skipcondjmp = _fs->GetCurrentPos(); - _fs->SetInstructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp); - } - //condition - Lex(); Expression(); Expect(_SC(':')); - SQInteger trg = _fs->PopTarget(); - SQInteger eqtarget = trg; - bool local = _fs->IsLocal(trg); - if(local) { - eqtarget = _fs->PushTarget(); //we need to allocate an extra reg - } - _fs->AddInstruction(_OP_EQ, eqtarget, trg, expr); - _fs->AddInstruction(_OP_JZ, eqtarget, 0); - if(local) { - _fs->PopTarget(); - } - - //end condition - if(skipcondjmp != -1) { - _fs->SetInstructionParam(skipcondjmp, 1, (_fs->GetCurrentPos() - skipcondjmp)); - } - tonextcondjmp = _fs->GetCurrentPos(); - BEGIN_SCOPE(); - Statements(); - END_SCOPE(); - bfirst = false; - } - if(tonextcondjmp != -1) - _fs->SetInstructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp); - if(_token == TK_DEFAULT) { - Lex(); Expect(_SC(':')); - BEGIN_SCOPE(); - Statements(); - END_SCOPE(); - } - Expect(_SC('}')); - _fs->PopTarget(); - __nbreaks__ = _fs->_unresolvedbreaks.size() - __nbreaks__; - if(__nbreaks__ > 0)ResolveBreaks(_fs, __nbreaks__); - _fs->_breaktargets.pop_back(); - } - void FunctionStatement() - { - SQObject id; - Lex(); id = Expect(TK_IDENTIFIER); - _fs->PushTarget(0); - _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); - if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET); - - while(_token == TK_DOUBLE_COLON) { - Lex(); - id = Expect(TK_IDENTIFIER); - _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id)); - if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET); - } - SQInteger boundtarget = 0xFF; - if (_token == _SC('[')) { - boundtarget = ParseBindEnv(); - } - Expect(_SC('(')); - CreateFunction(id, boundtarget); - _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, boundtarget); - EmitDerefOp(_OP_NEWSLOT); - _fs->PopTarget(); - } - void ClassStatement() - { - SQExpState es; - Lex(); - es = _es; - _es.donot_get = true; - PrefixedExpr(); - if(_es.etype == EXPR) { - Error(_SC("invalid class name")); - } - else if(_es.etype == OBJECT || _es.etype == BASE) { - ClassExp(); - EmitDerefOp(_OP_NEWSLOT); - _fs->PopTarget(); - } - else { - Error(_SC("cannot create a class in a local with the syntax(class )")); - } - _es = es; - } - SQObject ExpectScalar() - { - SQObject val; - val._type = OT_NULL; val._unVal.nInteger = 0; //shut up GCC 4.x - switch(_token) { - case TK_INTEGER: - val._type = OT_INTEGER; - val._unVal.nInteger = _lex._nvalue; - break; - case TK_FLOAT: - val._type = OT_FLOAT; - val._unVal.fFloat = _lex._fvalue; - break; - case TK_STRING_LITERAL: - val = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1); - break; - case TK_TRUE: - case TK_FALSE: - val._type = OT_BOOL; - val._unVal.nInteger = _token == TK_TRUE ? 1 : 0; - break; - case '-': - Lex(); - switch(_token) - { - case TK_INTEGER: - val._type = OT_INTEGER; - val._unVal.nInteger = -_lex._nvalue; - break; - case TK_FLOAT: - val._type = OT_FLOAT; - val._unVal.fFloat = -_lex._fvalue; - break; - default: - Error(_SC("scalar expected : integer, float")); - } - break; - default: - Error(_SC("scalar expected : integer, float, or string")); - } - Lex(); - return val; - } - void EnumStatement() - { - Lex(); - SQObject id = Expect(TK_IDENTIFIER); - Expect(_SC('{')); - - SQObject table = _fs->CreateTable(); - SQInteger nval = 0; - while(_token != _SC('}')) { - SQObject key = Expect(TK_IDENTIFIER); - SQObject val; - if(_token == _SC('=')) { - Lex(); - val = ExpectScalar(); - } - else { - val._type = OT_INTEGER; - val._unVal.nInteger = nval++; - } - _table(table)->NewSlot(SQObjectPtr(key),SQObjectPtr(val)); - if(_token == ',') Lex(); - } - SQTable *enums = _table(_ss(_vm)->_consts); - SQObjectPtr strongid = id; - enums->NewSlot(SQObjectPtr(strongid),SQObjectPtr(table)); - strongid.Null(); - Lex(); - } - void TryCatchStatement() - { - SQObject exid; - Lex(); - _fs->AddInstruction(_OP_PUSHTRAP,0,0); - _fs->_traps++; - if(_fs->_breaktargets.size()) _fs->_breaktargets.top()++; - if(_fs->_continuetargets.size()) _fs->_continuetargets.top()++; - SQInteger trappos = _fs->GetCurrentPos(); - { - BEGIN_SCOPE(); - Statement(); - END_SCOPE(); - } - _fs->_traps--; - _fs->AddInstruction(_OP_POPTRAP, 1, 0); - if(_fs->_breaktargets.size()) _fs->_breaktargets.top()--; - if(_fs->_continuetargets.size()) _fs->_continuetargets.top()--; - _fs->AddInstruction(_OP_JMP, 0, 0); - SQInteger jmppos = _fs->GetCurrentPos(); - _fs->SetInstructionParam(trappos, 1, (_fs->GetCurrentPos() - trappos)); - Expect(TK_CATCH); Expect(_SC('(')); exid = Expect(TK_IDENTIFIER); Expect(_SC(')')); - { - BEGIN_SCOPE(); - SQInteger ex_target = _fs->PushLocalVariable(exid); - _fs->SetInstructionParam(trappos, 0, ex_target); - Statement(); - _fs->SetInstructionParams(jmppos, 0, (_fs->GetCurrentPos() - jmppos), 0); - END_SCOPE(); - } - } - SQInteger ParseBindEnv() - { - SQInteger boundtarget; - Lex(); - Expression(); - boundtarget = _fs->TopTarget(); - Expect(_SC(']')); - return boundtarget; - } - void FunctionExp(bool lambda = false) - { - Lex(); - SQInteger boundtarget = 0xFF; - if (_token == _SC('[')) { - boundtarget = ParseBindEnv(); - } - Expect(_SC('(')); - SQObjectPtr dummy; - CreateFunction(dummy, boundtarget, lambda); - _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, boundtarget); - } - void ClassExp() - { - SQInteger base = -1; - SQInteger attrs = -1; - if(_token == TK_EXTENDS) { - Lex(); Expression(); - base = _fs->TopTarget(); - } - if(_token == TK_ATTR_OPEN) { - Lex(); - _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(),0,NOT_TABLE); - ParseTableOrClass(_SC(','),TK_ATTR_CLOSE); - attrs = _fs->TopTarget(); - } - Expect(_SC('{')); - if(attrs != -1) _fs->PopTarget(); - if(base != -1) _fs->PopTarget(); - _fs->AddInstruction(_OP_NEWOBJ, _fs->PushTarget(), base, attrs,NOT_CLASS); - ParseTableOrClass(_SC(';'),_SC('}')); - } - void DeleteExpr() - { - SQExpState es; - Lex(); - es = _es; - _es.donot_get = true; - PrefixedExpr(); - if(_es.etype==EXPR) Error(_SC("can't delete an expression")); - if(_es.etype==OBJECT || _es.etype==BASE) { - Emit2ArgsOP(_OP_DELETE); - } - else { - Error(_SC("cannot delete an (outer) local")); - } - _es = es; - } - void PrefixIncDec(SQInteger token) - { - SQExpState es; - SQInteger diff = (token==TK_MINUSMINUS) ? -1 : 1; - Lex(); - es = _es; - _es.donot_get = true; - PrefixedExpr(); - if(_es.etype==EXPR) { - Error(_SC("can't '++' or '--' an expression")); - } - else if(_es.etype==OBJECT || _es.etype==BASE) { - Emit2ArgsOP(_OP_INC, diff); - } - else if(_es.etype==LOCAL) { - SQInteger src = _fs->TopTarget(); - _fs->AddInstruction(_OP_INCL, src, src, 0, diff); - - } - else if(_es.etype==OUTER) { - SQInteger tmp = _fs->PushTarget(); - _fs->AddInstruction(_OP_GETOUTER, tmp, _es.epos); - _fs->AddInstruction(_OP_INCL, tmp, tmp, 0, diff); - _fs->AddInstruction(_OP_SETOUTER, tmp, _es.epos, tmp); - } - _es = es; - } - void CreateFunction(SQObject &name,SQInteger boundtarget,bool lambda = false) - { - SQFuncState *funcstate = _fs->PushChildState(_ss(_vm)); - funcstate->_name = name; - SQObject paramname; - funcstate->AddParameter(_fs->CreateString(_SC("this"))); - funcstate->_sourcename = _sourcename; - SQInteger defparams = 0; - while(_token!=_SC(')')) { - if(_token == TK_VARPARAMS) { - if(defparams > 0) Error(_SC("function with default parameters cannot have variable number of parameters")); - funcstate->AddParameter(_fs->CreateString(_SC("vargv"))); - funcstate->_varparams = true; - Lex(); - if(_token != _SC(')')) Error(_SC("expected ')'")); - break; - } - else { - paramname = Expect(TK_IDENTIFIER); - funcstate->AddParameter(paramname); - if(_token == _SC('=')) { - Lex(); - Expression(); - funcstate->AddDefaultParam(_fs->TopTarget()); - defparams++; - } - else { - if(defparams > 0) Error(_SC("expected '='")); - } - if(_token == _SC(',')) Lex(); - else if(_token != _SC(')')) Error(_SC("expected ')' or ','")); - } - } - Expect(_SC(')')); - if (boundtarget != 0xFF) { - _fs->PopTarget(); - } - for(SQInteger n = 0; n < defparams; n++) { - _fs->PopTarget(); - } - - SQFuncState *currchunk = _fs; - _fs = funcstate; - if(lambda) { - Expression(); - _fs->AddInstruction(_OP_RETURN, 1, _fs->PopTarget());} - else { - Statement(false); - } - funcstate->AddLineInfos(_lex._prevtoken == _SC('\n')?_lex._lasttokenline:_lex._currentline, _lineinfo, true); - funcstate->AddInstruction(_OP_RETURN, -1); - funcstate->SetStackSize(0); - - SQFunctionProto *func = funcstate->BuildProto(); -#ifdef _DEBUG_DUMP - funcstate->Dump(func); -#endif - _fs = currchunk; - _fs->_functions.push_back(func); - _fs->PopChildState(); - } - void ResolveBreaks(SQFuncState *funcstate, SQInteger ntoresolve) - { - while(ntoresolve > 0) { - SQInteger pos = funcstate->_unresolvedbreaks.back(); - funcstate->_unresolvedbreaks.pop_back(); - //set the jmp instruction - funcstate->SetInstructionParams(pos, 0, funcstate->GetCurrentPos() - pos, 0); - ntoresolve--; - } - } - void ResolveContinues(SQFuncState *funcstate, SQInteger ntoresolve, SQInteger targetpos) - { - while(ntoresolve > 0) { - SQInteger pos = funcstate->_unresolvedcontinues.back(); - funcstate->_unresolvedcontinues.pop_back(); - //set the jmp instruction - funcstate->SetInstructionParams(pos, 0, targetpos - pos, 0); - ntoresolve--; - } - } -private: - SQInteger _token; - SQFuncState *_fs; - SQObjectPtr _sourcename; - SQLexer _lex; - bool _lineinfo; - bool _raiseerror; - SQInteger _debugline; - SQInteger _debugop; - SQExpState _es; - SQScope _scope; - SQChar _compilererror[MAX_COMPILER_ERROR_LEN]; - jmp_buf _errorjmp; - SQVM *_vm; -}; - -bool Compile(SQVM *vm,SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo) -{ - SQCompiler p(vm, rg, up, sourcename, raiseerror, lineinfo); - return p.Compile(out); -} - -#endif diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqcompiler.h b/src/modules/app_sqlang/squirrel/squirrel/sqcompiler.h deleted file mode 100644 index 6a6eb6f8d..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqcompiler.h +++ /dev/null @@ -1,80 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQCOMPILER_H_ -#define _SQCOMPILER_H_ - -struct SQVM; - -#define TK_IDENTIFIER 258 -#define TK_STRING_LITERAL 259 -#define TK_INTEGER 260 -#define TK_FLOAT 261 -#define TK_BASE 262 -#define TK_DELETE 263 -#define TK_EQ 264 -#define TK_NE 265 -#define TK_LE 266 -#define TK_GE 267 -#define TK_SWITCH 268 -#define TK_ARROW 269 -#define TK_AND 270 -#define TK_OR 271 -#define TK_IF 272 -#define TK_ELSE 273 -#define TK_WHILE 274 -#define TK_BREAK 275 -#define TK_FOR 276 -#define TK_DO 277 -#define TK_NULL 278 -#define TK_FOREACH 279 -#define TK_IN 280 -#define TK_NEWSLOT 281 -#define TK_MODULO 282 -#define TK_LOCAL 283 -#define TK_CLONE 284 -#define TK_FUNCTION 285 -#define TK_RETURN 286 -#define TK_TYPEOF 287 -#define TK_UMINUS 288 -#define TK_PLUSEQ 289 -#define TK_MINUSEQ 290 -#define TK_CONTINUE 291 -#define TK_YIELD 292 -#define TK_TRY 293 -#define TK_CATCH 294 -#define TK_THROW 295 -#define TK_SHIFTL 296 -#define TK_SHIFTR 297 -#define TK_RESUME 298 -#define TK_DOUBLE_COLON 299 -#define TK_CASE 300 -#define TK_DEFAULT 301 -#define TK_THIS 302 -#define TK_PLUSPLUS 303 -#define TK_MINUSMINUS 304 -#define TK_3WAYSCMP 305 -#define TK_USHIFTR 306 -#define TK_CLASS 307 -#define TK_EXTENDS 308 -#define TK_CONSTRUCTOR 310 -#define TK_INSTANCEOF 311 -#define TK_VARPARAMS 312 -#define TK___LINE__ 313 -#define TK___FILE__ 314 -#define TK_TRUE 315 -#define TK_FALSE 316 -#define TK_MULEQ 317 -#define TK_DIVEQ 318 -#define TK_MODEQ 319 -#define TK_ATTR_OPEN 320 -#define TK_ATTR_CLOSE 321 -#define TK_STATIC 322 -#define TK_ENUM 323 -#define TK_CONST 324 -#define TK_RAWCALL 325 - - -typedef void (*CompilerErrorFunc)(void *ud, const SQChar *s); -bool Compile(SQVM *vm, SQLEXREADFUNC rg, SQUserPointer up, - const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, - bool lineinfo); -#endif //_SQCOMPILER_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqdebug.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqdebug.cpp deleted file mode 100644 index d55b1b2e4..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqdebug.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* - see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#include -#include "sqvm.h" -#include "sqfuncproto.h" -#include "sqclosure.h" -#include "sqstring.h" - -SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger level,SQFunctionInfo *fi) -{ - SQInteger cssize = v->_callsstacksize; - if (cssize > level) { - SQVM::CallInfo &ci = v->_callsstack[cssize-level-1]; - if(sq_isclosure(ci._closure)) { - SQClosure *c = _closure(ci._closure); - SQFunctionProto *proto = c->_function; - fi->funcid = proto; - fi->name = sq_type(proto->_name) == OT_STRING?_stringval(proto->_name):_SC("unknown"); - fi->source = sq_type(proto->_sourcename) == OT_STRING?_stringval(proto->_sourcename):_SC("unknown"); - fi->line = proto->_lineinfos[0]._line; - return SQ_OK; - } - } - return sq_throwerror(v,_SC("the object is not a closure")); -} - -SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si) -{ - SQInteger cssize = v->_callsstacksize; - if (cssize > level) { - memset(si, 0, sizeof(SQStackInfos)); - SQVM::CallInfo &ci = v->_callsstack[cssize-level-1]; - switch (sq_type(ci._closure)) { - case OT_CLOSURE:{ - SQFunctionProto *func = _closure(ci._closure)->_function; - if (sq_type(func->_name) == OT_STRING) - si->funcname = _stringval(func->_name); - if (sq_type(func->_sourcename) == OT_STRING) - si->source = _stringval(func->_sourcename); - si->line = func->GetLine(ci._ip); - } - break; - case OT_NATIVECLOSURE: - si->source = _SC("NATIVE"); - si->funcname = _SC("unknown"); - if(sq_type(_nativeclosure(ci._closure)->_name) == OT_STRING) - si->funcname = _stringval(_nativeclosure(ci._closure)->_name); - si->line = -1; - break; - default: break; //shutup compiler - } - return SQ_OK; - } - return SQ_ERROR; -} - -void SQVM::Raise_Error(const SQChar *s, ...) -{ - va_list vl; - va_start(vl, s); - SQInteger buffersize = (SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2); - scvsprintf(_sp(sq_rsl(buffersize)),buffersize, s, vl); - va_end(vl); - _lasterror = SQString::Create(_ss(this),_spval,-1); -} - -void SQVM::Raise_Error(const SQObjectPtr &desc) -{ - _lasterror = desc; -} - -SQString *SQVM::PrintObjVal(const SQObjectPtr &o) -{ - switch(sq_type(o)) { - case OT_STRING: return _string(o); - case OT_INTEGER: - scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)),sq_rsl(NUMBER_MAX_CHAR), _PRINT_INT_FMT, _integer(o)); - return SQString::Create(_ss(this), _spval); - break; - case OT_FLOAT: - scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)), sq_rsl(NUMBER_MAX_CHAR), _SC("%.14g"), _float(o)); - return SQString::Create(_ss(this), _spval); - break; - default: - return SQString::Create(_ss(this), GetTypeName(o)); - } -} - -void SQVM::Raise_IdxError(const SQObjectPtr &o) -{ - SQObjectPtr oval = PrintObjVal(o); - Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval)); -} - -void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2) -{ - SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2); - Raise_Error(_SC("comparison between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2)); -} - - -void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type) -{ - SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1); - SQInteger found = 0; - for(SQInteger i=0; i<16; i++) - { - SQInteger mask = ((SQInteger)1) << i; - if(typemask & (mask)) { - if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes); - found ++; - StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes); - } - } - Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes)); -} diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqfuncproto.h b/src/modules/app_sqlang/squirrel/squirrel/sqfuncproto.h deleted file mode 100644 index acab7bcca..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqfuncproto.h +++ /dev/null @@ -1,180 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQFUNCTION_H_ -#define _SQFUNCTION_H_ - -#include "sqopcodes.h" - -enum SQOuterType -{ - otLOCAL = 0, - otOUTER = 1 -}; - -struct SQOuterVar -{ - - SQOuterVar() - { - } - SQOuterVar(const SQObjectPtr &name, const SQObjectPtr &src, SQOuterType t) - { - _name = name; - _src = src; - _type = t; - } - SQOuterVar(const SQOuterVar &ov) - { - _type = ov._type; - _src = ov._src; - _name = ov._name; - } - SQOuterType _type; - SQObjectPtr _name; - SQObjectPtr _src; -}; - -struct SQLocalVarInfo -{ - SQLocalVarInfo() : _start_op(0), _end_op(0), _pos(0) - { - } - SQLocalVarInfo(const SQLocalVarInfo &lvi) - { - _name = lvi._name; - _start_op = lvi._start_op; - _end_op = lvi._end_op; - _pos = lvi._pos; - } - SQObjectPtr _name; - SQUnsignedInteger _start_op; - SQUnsignedInteger _end_op; - SQUnsignedInteger _pos; -}; - -struct SQLineInfo -{ - SQInteger _line; - SQInteger _op; -}; - -typedef sqvector SQOuterVarVec; -typedef sqvector SQLocalVarInfoVec; -typedef sqvector SQLineInfoVec; - -#define _FUNC_SIZE( \ - ni, nl, nparams, nfuncs, nouters, nlineinf, localinf, defparams) \ - (sizeof(SQFunctionProto) + ((ni - 1) * sizeof(SQInstruction)) \ - + (nl * sizeof(SQObjectPtr)) + (nparams * sizeof(SQObjectPtr)) \ - + (nfuncs * sizeof(SQObjectPtr)) + (nouters * sizeof(SQOuterVar)) \ - + (nlineinf * sizeof(SQLineInfo)) \ - + (localinf * sizeof(SQLocalVarInfo)) \ - + (defparams * sizeof(SQInteger))) - - -struct SQFunctionProto : public CHAINABLE_OBJ -{ -private: - SQFunctionProto(SQSharedState *ss); - ~SQFunctionProto(); - -public: - static SQFunctionProto *Create(SQSharedState *ss, SQInteger ninstructions, - SQInteger nliterals, SQInteger nparameters, SQInteger nfunctions, - SQInteger noutervalues, SQInteger nlineinfos, - SQInteger nlocalvarinfos, SQInteger ndefaultparams) - { - SQFunctionProto *f; - //I compact the whole class and members in a single memory allocation - f = (SQFunctionProto *)sq_vm_malloc(_FUNC_SIZE(ninstructions, nliterals, - nparameters, nfunctions, noutervalues, nlineinfos, - nlocalvarinfos, ndefaultparams)); - new(f) SQFunctionProto(ss); - f->_ninstructions = ninstructions; - f->_literals = (SQObjectPtr *)&f->_instructions[ninstructions]; - f->_nliterals = nliterals; - f->_parameters = (SQObjectPtr *)&f->_literals[nliterals]; - f->_nparameters = nparameters; - f->_functions = (SQObjectPtr *)&f->_parameters[nparameters]; - f->_nfunctions = nfunctions; - f->_outervalues = (SQOuterVar *)&f->_functions[nfunctions]; - f->_noutervalues = noutervalues; - f->_lineinfos = (SQLineInfo *)&f->_outervalues[noutervalues]; - f->_nlineinfos = nlineinfos; - f->_localvarinfos = (SQLocalVarInfo *)&f->_lineinfos[nlineinfos]; - f->_nlocalvarinfos = nlocalvarinfos; - f->_defaultparams = (SQInteger *)&f->_localvarinfos[nlocalvarinfos]; - f->_ndefaultparams = ndefaultparams; - - _CONSTRUCT_VECTOR(SQObjectPtr, f->_nliterals, f->_literals); - _CONSTRUCT_VECTOR(SQObjectPtr, f->_nparameters, f->_parameters); - _CONSTRUCT_VECTOR(SQObjectPtr, f->_nfunctions, f->_functions); - _CONSTRUCT_VECTOR(SQOuterVar, f->_noutervalues, f->_outervalues); - //_CONSTRUCT_VECTOR(SQLineInfo,f->_nlineinfos,f->_lineinfos); //not required are 2 integers - _CONSTRUCT_VECTOR( - SQLocalVarInfo, f->_nlocalvarinfos, f->_localvarinfos); - return f; - } - void Release() - { - _DESTRUCT_VECTOR(SQObjectPtr, _nliterals, _literals); - _DESTRUCT_VECTOR(SQObjectPtr, _nparameters, _parameters); - _DESTRUCT_VECTOR(SQObjectPtr, _nfunctions, _functions); - _DESTRUCT_VECTOR(SQOuterVar, _noutervalues, _outervalues); - //_DESTRUCT_VECTOR(SQLineInfo,_nlineinfos,_lineinfos); //not required are 2 integers - _DESTRUCT_VECTOR(SQLocalVarInfo, _nlocalvarinfos, _localvarinfos); - SQInteger size = _FUNC_SIZE(_ninstructions, _nliterals, _nparameters, - _nfunctions, _noutervalues, _nlineinfos, _nlocalvarinfos, - _ndefaultparams); - this->~SQFunctionProto(); - sq_vm_free(this, size); - } - - const SQChar *GetLocal(SQVM *v, SQUnsignedInteger stackbase, - SQUnsignedInteger nseq, SQUnsignedInteger nop); - SQInteger GetLine(SQInstruction *curr); - bool Save(SQVM *v, SQUserPointer up, SQWRITEFUNC write); - static bool Load( - SQVM *v, SQUserPointer up, SQREADFUNC read, SQObjectPtr &ret); -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable **chain); - void Finalize() - { - _NULL_SQOBJECT_VECTOR(_literals, _nliterals); - } - SQObjectType GetType() - { - return OT_FUNCPROTO; - } -#endif - SQObjectPtr _sourcename; - SQObjectPtr _name; - SQInteger _stacksize; - bool _bgenerator; - SQInteger _varparams; - - SQInteger _nlocalvarinfos; - SQLocalVarInfo *_localvarinfos; - - SQInteger _nlineinfos; - SQLineInfo *_lineinfos; - - SQInteger _nliterals; - SQObjectPtr *_literals; - - SQInteger _nparameters; - SQObjectPtr *_parameters; - - SQInteger _nfunctions; - SQObjectPtr *_functions; - - SQInteger _noutervalues; - SQOuterVar *_outervalues; - - SQInteger _ndefaultparams; - SQInteger *_defaultparams; - - SQInteger _ninstructions; - SQInstruction _instructions[1]; -}; - -#endif //_SQFUNCTION_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqfuncstate.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqfuncstate.cpp deleted file mode 100644 index 779b40df4..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqfuncstate.cpp +++ /dev/null @@ -1,649 +0,0 @@ -/* - see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#ifndef NO_COMPILER -#include "sqcompiler.h" -#include "sqstring.h" -#include "sqfuncproto.h" -#include "sqtable.h" -#include "sqopcodes.h" -#include "sqfuncstate.h" - -#ifdef _DEBUG_DUMP -SQInstructionDesc g_InstrDesc[]={ - {_SC("_OP_LINE")}, - {_SC("_OP_LOAD")}, - {_SC("_OP_LOADINT")}, - {_SC("_OP_LOADFLOAT")}, - {_SC("_OP_DLOAD")}, - {_SC("_OP_TAILCALL")}, - {_SC("_OP_CALL")}, - {_SC("_OP_PREPCALL")}, - {_SC("_OP_PREPCALLK")}, - {_SC("_OP_GETK")}, - {_SC("_OP_MOVE")}, - {_SC("_OP_NEWSLOT")}, - {_SC("_OP_DELETE")}, - {_SC("_OP_SET")}, - {_SC("_OP_GET")}, - {_SC("_OP_EQ")}, - {_SC("_OP_NE")}, - {_SC("_OP_ADD")}, - {_SC("_OP_SUB")}, - {_SC("_OP_MUL")}, - {_SC("_OP_DIV")}, - {_SC("_OP_MOD")}, - {_SC("_OP_BITW")}, - {_SC("_OP_RETURN")}, - {_SC("_OP_LOADNULLS")}, - {_SC("_OP_LOADROOT")}, - {_SC("_OP_LOADBOOL")}, - {_SC("_OP_DMOVE")}, - {_SC("_OP_JMP")}, - {_SC("_OP_JCMP")}, - {_SC("_OP_JZ")}, - {_SC("_OP_SETOUTER")}, - {_SC("_OP_GETOUTER")}, - {_SC("_OP_NEWOBJ")}, - {_SC("_OP_APPENDARRAY")}, - {_SC("_OP_COMPARITH")}, - {_SC("_OP_INC")}, - {_SC("_OP_INCL")}, - {_SC("_OP_PINC")}, - {_SC("_OP_PINCL")}, - {_SC("_OP_CMP")}, - {_SC("_OP_EXISTS")}, - {_SC("_OP_INSTANCEOF")}, - {_SC("_OP_AND")}, - {_SC("_OP_OR")}, - {_SC("_OP_NEG")}, - {_SC("_OP_NOT")}, - {_SC("_OP_BWNOT")}, - {_SC("_OP_CLOSURE")}, - {_SC("_OP_YIELD")}, - {_SC("_OP_RESUME")}, - {_SC("_OP_FOREACH")}, - {_SC("_OP_POSTFOREACH")}, - {_SC("_OP_CLONE")}, - {_SC("_OP_TYPEOF")}, - {_SC("_OP_PUSHTRAP")}, - {_SC("_OP_POPTRAP")}, - {_SC("_OP_THROW")}, - {_SC("_OP_NEWSLOTA")}, - {_SC("_OP_GETBASE")}, - {_SC("_OP_CLOSE")}, -}; -#endif -void DumpLiteral(SQObjectPtr &o) -{ - switch(sq_type(o)){ - case OT_STRING: scprintf(_SC("\"%s\""),_stringval(o));break; - case OT_FLOAT: scprintf(_SC("{%f}"),_float(o));break; - case OT_INTEGER: scprintf(_SC("{") _PRINT_INT_FMT _SC("}"),_integer(o));break; - case OT_BOOL: scprintf(_SC("%s"),_integer(o)?_SC("true"):_SC("false"));break; - default: scprintf(_SC("(%s %p)"),GetTypeName(o),(void*)_rawval(o));break; break; //shut up compiler - } -} - -SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed) -{ - _nliterals = 0; - _literals = SQTable::Create(ss,0); - _strings = SQTable::Create(ss,0); - _sharedstate = ss; - _lastline = 0; - _optimization = true; - _parent = parent; - _stacksize = 0; - _traps = 0; - _returnexp = 0; - _varparams = false; - _errfunc = efunc; - _errtarget = ed; - _bgenerator = false; - _outers = 0; - _ss = ss; - -} - -void SQFuncState::Error(const SQChar *err) -{ - _errfunc(_errtarget,err); -} - -#ifdef _DEBUG_DUMP -void SQFuncState::Dump(SQFunctionProto *func) -{ - SQUnsignedInteger n=0,i; - SQInteger si; - scprintf(_SC("SQInstruction sizeof %d\n"),(SQInt32)sizeof(SQInstruction)); - scprintf(_SC("SQObject sizeof %d\n"), (SQInt32)sizeof(SQObject)); - scprintf(_SC("--------------------------------------------------------------------\n")); - scprintf(_SC("*****FUNCTION [%s]\n"),sq_type(func->_name)==OT_STRING?_stringval(func->_name):_SC("unknown")); - scprintf(_SC("-----LITERALS\n")); - SQObjectPtr refidx,key,val; - SQInteger idx; - SQObjectPtrVec templiterals; - templiterals.resize(_nliterals); - while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) { - refidx=idx; - templiterals[_integer(val)]=key; - } - for(i=0;i>\n")); - n=0; - for(i=0;i<_parameters.size();i++){ - scprintf(_SC("[%d] "), (SQInt32)n); - DumpLiteral(_parameters[i]); - scprintf(_SC("\n")); - n++; - } - scprintf(_SC("-----LOCALS\n")); - for(si=0;si_nlocalvarinfos;si++){ - SQLocalVarInfo lvi=func->_localvarinfos[si]; - scprintf(_SC("[%d] %s \t%d %d\n"), (SQInt32)lvi._pos,_stringval(lvi._name), (SQInt32)lvi._start_op, (SQInt32)lvi._end_op); - n++; - } - scprintf(_SC("-----LINE INFO\n")); - for(i=0;i<_lineinfos.size();i++){ - SQLineInfo li=_lineinfos[i]; - scprintf(_SC("op [%d] line [%d] \n"), (SQInt32)li._op, (SQInt32)li._line); - n++; - } - scprintf(_SC("-----dump\n")); - n=0; - for(i=0;i<_instructions.size();i++){ - SQInstruction &inst=_instructions[i]; - if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){ - - SQInteger lidx = inst._arg1; - scprintf(_SC("[%03d] %15s %d "), (SQInt32)n,g_InstrDesc[inst.op].name,inst._arg0); - if(lidx >= 0xFFFFFFFF) - scprintf(_SC("null")); - else { - SQInteger refidx; - SQObjectPtr val,key,refo; - while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { - refo = refidx; - } - DumpLiteral(key); - } - if(inst.op != _OP_DLOAD) { - scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3); - } - else { - scprintf(_SC(" %d "),inst._arg2); - lidx = inst._arg3; - if(lidx >= 0xFFFFFFFF) - scprintf(_SC("null")); - else { - SQInteger refidx; - SQObjectPtr val,key,refo; - while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) { - refo = refidx; - } - DumpLiteral(key); - scprintf(_SC("\n")); - } - } - } - else if(inst.op==_OP_LOADFLOAT) { - scprintf(_SC("[%03d] %15s %d %f %d %d\n"), (SQInt32)n,g_InstrDesc[inst.op].name,inst._arg0,*((SQFloat*)&inst._arg1),inst._arg2,inst._arg3); - } - /* else if(inst.op==_OP_ARITH){ - scprintf(_SC("[%03d] %15s %d %d %d %c\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3); - }*/ - else { - scprintf(_SC("[%03d] %15s %d %d %d %d\n"), (SQInt32)n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3); - } - n++; - } - scprintf(_SC("-----\n")); - scprintf(_SC("stack size[%d]\n"), (SQInt32)func->_stacksize); - scprintf(_SC("--------------------------------------------------------------------\n\n")); -} -#endif - -SQInteger SQFuncState::GetNumericConstant(const SQInteger cons) -{ - return GetConstant(SQObjectPtr(cons)); -} - -SQInteger SQFuncState::GetNumericConstant(const SQFloat cons) -{ - return GetConstant(SQObjectPtr(cons)); -} - -SQInteger SQFuncState::GetConstant(const SQObject &cons) -{ - SQObjectPtr val; - if(!_table(_literals)->Get(cons,val)) - { - val = _nliterals; - _table(_literals)->NewSlot(cons,val); - _nliterals++; - if(_nliterals > MAX_LITERALS) { - val.Null(); - Error(_SC("internal compiler error: too many literals")); - } - } - return _integer(val); -} - -void SQFuncState::SetInstructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3) -{ - _instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&arg0); - _instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&arg1); - _instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&arg2); - _instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&arg3); -} - -void SQFuncState::SetInstructionParam(SQInteger pos,SQInteger arg,SQInteger val) -{ - switch(arg){ - case 0:_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&val);break; - case 1:case 4:_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&val);break; - case 2:_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&val);break; - case 3:_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&val);break; - }; -} - -SQInteger SQFuncState::AllocStackPos() -{ - SQInteger npos=_vlocals.size(); - _vlocals.push_back(SQLocalVarInfo()); - if(_vlocals.size()>((SQUnsignedInteger)_stacksize)) { - if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC("internal compiler error: too many locals")); - _stacksize=_vlocals.size(); - } - return npos; -} - -SQInteger SQFuncState::PushTarget(SQInteger n) -{ - if(n!=-1){ - _targetstack.push_back(n); - return n; - } - n=AllocStackPos(); - _targetstack.push_back(n); - return n; -} - -SQInteger SQFuncState::GetUpTarget(SQInteger n){ - return _targetstack[((_targetstack.size()-1)-n)]; -} - -SQInteger SQFuncState::TopTarget(){ - return _targetstack.back(); -} -SQInteger SQFuncState::PopTarget() -{ - SQUnsignedInteger npos=_targetstack.back(); - assert(npos < _vlocals.size()); - SQLocalVarInfo &t = _vlocals[npos]; - if(sq_type(t._name)==OT_NULL){ - _vlocals.pop_back(); - } - _targetstack.pop_back(); - return npos; -} - -SQInteger SQFuncState::GetStackSize() -{ - return _vlocals.size(); -} - -SQInteger SQFuncState::CountOuters(SQInteger stacksize) -{ - SQInteger outers = 0; - SQInteger k = _vlocals.size() - 1; - while(k >= stacksize) { - SQLocalVarInfo &lvi = _vlocals[k]; - k--; - if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer - outers++; - } - } - return outers; -} - -void SQFuncState::SetStackSize(SQInteger n) -{ - SQInteger size=_vlocals.size(); - while(size>n){ - size--; - SQLocalVarInfo lvi = _vlocals.back(); - if(sq_type(lvi._name)!=OT_NULL){ - if(lvi._end_op == UINT_MINUS_ONE) { //this means is an outer - _outers--; - } - lvi._end_op = GetCurrentPos(); - _localvarinfos.push_back(lvi); - } - _vlocals.pop_back(); - } -} - -bool SQFuncState::IsConstant(const SQObject &name,SQObject &e) -{ - SQObjectPtr val; - if(_table(_sharedstate->_consts)->Get(name,val)) { - e = val; - return true; - } - return false; -} - -bool SQFuncState::IsLocal(SQUnsignedInteger stkpos) -{ - if(stkpos>=_vlocals.size())return false; - else if(sq_type(_vlocals[stkpos]._name)!=OT_NULL)return true; - return false; -} - -SQInteger SQFuncState::PushLocalVariable(const SQObject &name) -{ - SQInteger pos=_vlocals.size(); - SQLocalVarInfo lvi; - lvi._name=name; - lvi._start_op=GetCurrentPos()+1; - lvi._pos=_vlocals.size(); - _vlocals.push_back(lvi); - if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size(); - return pos; -} - - - -SQInteger SQFuncState::GetLocalVariable(const SQObject &name) -{ - SQInteger locals=_vlocals.size(); - while(locals>=1){ - SQLocalVarInfo &lvi = _vlocals[locals-1]; - if(sq_type(lvi._name)==OT_STRING && _string(lvi._name)==_string(name)){ - return locals-1; - } - locals--; - } - return -1; -} - -void SQFuncState::MarkLocalAsOuter(SQInteger pos) -{ - SQLocalVarInfo &lvi = _vlocals[pos]; - lvi._end_op = UINT_MINUS_ONE; - _outers++; -} - -SQInteger SQFuncState::GetOuterVariable(const SQObject &name) -{ - SQInteger outers = _outervalues.size(); - for(SQInteger i = 0; iGetLocalVariable(name); - if(pos == -1) { - pos = _parent->GetOuterVariable(name); - if(pos != -1) { - _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otOUTER)); //local - return _outervalues.size() - 1; - } - } - else { - _parent->MarkLocalAsOuter(pos); - _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otLOCAL)); //local - return _outervalues.size() - 1; - - - } - } - return -1; -} - -void SQFuncState::AddParameter(const SQObject &name) -{ - PushLocalVariable(name); - _parameters.push_back(name); -} - -void SQFuncState::AddLineInfos(SQInteger line,bool lineop,bool force) -{ - if(_lastline!=line || force){ - SQLineInfo li; - li._line=line;li._op=(GetCurrentPos()+1); - if(lineop)AddInstruction(_OP_LINE,0,line); - if(_lastline!=line) { - _lineinfos.push_back(li); - } - _lastline=line; - } -} - -void SQFuncState::DiscardTarget() -{ - SQInteger discardedtarget = PopTarget(); - SQInteger size = _instructions.size(); - if(size > 0 && _optimization){ - SQInstruction &pi = _instructions[size-1];//previous instruction - switch(pi.op) { - case _OP_SET:case _OP_NEWSLOT:case _OP_SETOUTER:case _OP_CALL: - if(pi._arg0 == discardedtarget) { - pi._arg0 = 0xFF; - } - } - } -} - -void SQFuncState::AddInstruction(SQInstruction &i) -{ - SQInteger size = _instructions.size(); - if(size > 0 && _optimization){ //simple optimizer - SQInstruction &pi = _instructions[size-1];//previous instruction - switch(i.op) { - case _OP_JZ: - if( pi.op == _OP_CMP && pi._arg1 < 0xFF) { - pi.op = _OP_JCMP; - pi._arg0 = (unsigned char)pi._arg1; - pi._arg1 = i._arg1; - return; - } - break; - case _OP_SET: - case _OP_NEWSLOT: - if(i._arg0 == i._arg3) { - i._arg0 = 0xFF; - } - break; - case _OP_SETOUTER: - if(i._arg0 == i._arg2) { - i._arg0 = 0xFF; - } - break; - case _OP_RETURN: - if( _parent && i._arg0 != MAX_FUNC_STACKSIZE && pi.op == _OP_CALL && _returnexp < size-1) { - pi.op = _OP_TAILCALL; - } else if(pi.op == _OP_CLOSE){ - pi = i; - return; - } - break; - case _OP_GET: - if( pi.op == _OP_LOAD && pi._arg0 == i._arg2 && (!IsLocal(pi._arg0))){ - pi._arg2 = (unsigned char)i._arg1; - pi.op = _OP_GETK; - pi._arg0 = i._arg0; - - return; - } - break; - case _OP_PREPCALL: - if( pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){ - pi.op = _OP_PREPCALLK; - pi._arg0 = i._arg0; - pi._arg2 = i._arg2; - pi._arg3 = i._arg3; - return; - } - break; - case _OP_APPENDARRAY: { - SQInteger aat = -1; - switch(pi.op) { - case _OP_LOAD: aat = AAT_LITERAL; break; - case _OP_LOADINT: aat = AAT_INT; break; - case _OP_LOADBOOL: aat = AAT_BOOL; break; - case _OP_LOADFLOAT: aat = AAT_FLOAT; break; - default: break; - } - if(aat != -1 && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){ - pi.op = _OP_APPENDARRAY; - pi._arg0 = i._arg0; - pi._arg2 = (unsigned char)aat; - pi._arg3 = MAX_FUNC_STACKSIZE; - return; - } - } - break; - case _OP_MOVE: - switch(pi.op) { - case _OP_GET: case _OP_ADD: case _OP_SUB: case _OP_MUL: case _OP_DIV: case _OP_MOD: case _OP_BITW: - case _OP_LOADINT: case _OP_LOADFLOAT: case _OP_LOADBOOL: case _OP_LOAD: - - if(pi._arg0 == i._arg1) - { - pi._arg0 = i._arg0; - _optimization = false; - //_result_elimination = false; - return; - } - } - - if(pi.op == _OP_MOVE) - { - pi.op = _OP_DMOVE; - pi._arg2 = i._arg0; - pi._arg3 = (unsigned char)i._arg1; - return; - } - break; - case _OP_LOAD: - if(pi.op == _OP_LOAD && i._arg1 < 256) { - pi.op = _OP_DLOAD; - pi._arg2 = i._arg0; - pi._arg3 = (unsigned char)i._arg1; - return; - } - break; - case _OP_EQ:case _OP_NE: - if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0) )) - { - pi.op = i.op; - pi._arg0 = i._arg0; - pi._arg2 = i._arg2; - pi._arg3 = MAX_FUNC_STACKSIZE; - return; - } - break; - case _OP_LOADNULLS: - if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) { - - pi._arg1 = pi._arg1 + 1; - pi.op = _OP_LOADNULLS; - return; - } - break; - case _OP_LINE: - if(pi.op == _OP_LINE) { - _instructions.pop_back(); - _lineinfos.pop_back(); - } - break; - } - } - _optimization = true; - _instructions.push_back(i); -} - -SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len) -{ - SQObjectPtr ns(SQString::Create(_sharedstate,s,len)); - _table(_strings)->NewSlot(ns,(SQInteger)1); - return ns; -} - -SQObject SQFuncState::CreateTable() -{ - SQObjectPtr nt(SQTable::Create(_sharedstate,0)); - _table(_strings)->NewSlot(nt,(SQInteger)1); - return nt; -} - -SQFunctionProto *SQFuncState::BuildProto() -{ - - SQFunctionProto *f=SQFunctionProto::Create(_ss,_instructions.size(), - _nliterals,_parameters.size(),_functions.size(),_outervalues.size(), - _lineinfos.size(),_localvarinfos.size(),_defaultparams.size()); - - SQObjectPtr refidx,key,val; - SQInteger idx; - - f->_stacksize = _stacksize; - f->_sourcename = _sourcename; - f->_bgenerator = _bgenerator; - f->_name = _name; - - while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) { - f->_literals[_integer(val)]=key; - refidx=idx; - } - - for(SQUnsignedInteger nf = 0; nf < _functions.size(); nf++) f->_functions[nf] = _functions[nf]; - for(SQUnsignedInteger np = 0; np < _parameters.size(); np++) f->_parameters[np] = _parameters[np]; - for(SQUnsignedInteger no = 0; no < _outervalues.size(); no++) f->_outervalues[no] = _outervalues[no]; - for(SQUnsignedInteger nl = 0; nl < _localvarinfos.size(); nl++) f->_localvarinfos[nl] = _localvarinfos[nl]; - for(SQUnsignedInteger ni = 0; ni < _lineinfos.size(); ni++) f->_lineinfos[ni] = _lineinfos[ni]; - for(SQUnsignedInteger nd = 0; nd < _defaultparams.size(); nd++) f->_defaultparams[nd] = _defaultparams[nd]; - - memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(SQInstruction)); - - f->_varparams = _varparams; - - return f; -} - -SQFuncState *SQFuncState::PushChildState(SQSharedState *ss) -{ - SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState)); - new (child) SQFuncState(ss,this,_errfunc,_errtarget); - _childstates.push_back(child); - return child; -} - -void SQFuncState::PopChildState() -{ - SQFuncState *child = _childstates.back(); - sq_delete(child,SQFuncState); - _childstates.pop_back(); -} - -SQFuncState::~SQFuncState() -{ - while(_childstates.size() > 0) - { - PopChildState(); - } -} - -#endif diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqfuncstate.h b/src/modules/app_sqlang/squirrel/squirrel/sqfuncstate.h deleted file mode 100644 index 1564db7eb..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqfuncstate.h +++ /dev/null @@ -1,117 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQFUNCSTATE_H_ -#define _SQFUNCSTATE_H_ -/////////////////////////////////// -#include "squtils.h" - -struct SQFuncState -{ - SQFuncState(SQSharedState *ss, SQFuncState *parent, CompilerErrorFunc efunc, - void *ed); - ~SQFuncState(); -#ifdef _DEBUG_DUMP - void Dump(SQFunctionProto *func); -#endif - void Error(const SQChar *err); - SQFuncState *PushChildState(SQSharedState *ss); - void PopChildState(); - void AddInstruction(SQOpcode _op, SQInteger arg0 = 0, SQInteger arg1 = 0, - SQInteger arg2 = 0, SQInteger arg3 = 0) - { - SQInstruction i(_op, arg0, arg1, arg2, arg3); - AddInstruction(i); - } - void AddInstruction(SQInstruction &i); - void SetInstructionParams(SQInteger pos, SQInteger arg0, SQInteger arg1, - SQInteger arg2 = 0, SQInteger arg3 = 0); - void SetInstructionParam(SQInteger pos, SQInteger arg, SQInteger val); - SQInstruction &GetInstruction(SQInteger pos) - { - return _instructions[pos]; - } - void PopInstructions(SQInteger size) - { - for(SQInteger i = 0; i < size; i++) - _instructions.pop_back(); - } - void SetStackSize(SQInteger n); - SQInteger CountOuters(SQInteger stacksize); - void SnoozeOpt() - { - _optimization = false; - } - void AddDefaultParam(SQInteger trg) - { - _defaultparams.push_back(trg); - } - SQInteger GetDefaultParamCount() - { - return _defaultparams.size(); - } - SQInteger GetCurrentPos() - { - return _instructions.size() - 1; - } - SQInteger GetNumericConstant(const SQInteger cons); - SQInteger GetNumericConstant(const SQFloat cons); - SQInteger PushLocalVariable(const SQObject &name); - void AddParameter(const SQObject &name); - //void AddOuterValue(const SQObject &name); - SQInteger GetLocalVariable(const SQObject &name); - void MarkLocalAsOuter(SQInteger pos); - SQInteger GetOuterVariable(const SQObject &name); - SQInteger GenerateCode(); - SQInteger GetStackSize(); - SQInteger CalcStackFrameSize(); - void AddLineInfos(SQInteger line, bool lineop, bool force = false); - SQFunctionProto *BuildProto(); - SQInteger AllocStackPos(); - SQInteger PushTarget(SQInteger n = -1); - SQInteger PopTarget(); - SQInteger TopTarget(); - SQInteger GetUpTarget(SQInteger n); - void DiscardTarget(); - bool IsLocal(SQUnsignedInteger stkpos); - SQObject CreateString(const SQChar *s, SQInteger len = -1); - SQObject CreateTable(); - bool IsConstant(const SQObject &name, SQObject &e); - SQInteger _returnexp; - SQLocalVarInfoVec _vlocals; - SQIntVec _targetstack; - SQInteger _stacksize; - bool _varparams; - bool _bgenerator; - SQIntVec _unresolvedbreaks; - SQIntVec _unresolvedcontinues; - SQObjectPtrVec _functions; - SQObjectPtrVec _parameters; - SQOuterVarVec _outervalues; - SQInstructionVec _instructions; - SQLocalVarInfoVec _localvarinfos; - SQObjectPtr _literals; - SQObjectPtr _strings; - SQObjectPtr _name; - SQObjectPtr _sourcename; - SQInteger _nliterals; - SQLineInfoVec _lineinfos; - SQFuncState *_parent; - SQIntVec _scope_blocks; - SQIntVec _breaktargets; - SQIntVec _continuetargets; - SQIntVec _defaultparams; - SQInteger _lastline; - SQInteger _traps; //contains number of nested exception traps - SQInteger _outers; - bool _optimization; - SQSharedState *_sharedstate; - sqvector _childstates; - SQInteger GetConstant(const SQObject &cons); - -private: - CompilerErrorFunc _errfunc; - void *_errtarget; - SQSharedState *_ss; -}; - - -#endif //_SQFUNCSTATE_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqlexer.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqlexer.cpp deleted file mode 100644 index 6a8e7c4f3..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqlexer.cpp +++ /dev/null @@ -1,563 +0,0 @@ -/* - see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#include -#include -#include "sqtable.h" -#include "sqstring.h" -#include "sqcompiler.h" -#include "sqlexer.h" - -#define CUR_CHAR (_currdata) -#define RETURN_TOKEN(t) { _prevtoken = _curtoken; _curtoken = t; return t;} -#define IS_EOB() (CUR_CHAR <= SQUIRREL_EOB) -#define NEXT() {Next();_currentcolumn++;} -#define INIT_TEMP_STRING() { _longstr.resize(0);} -#define APPEND_CHAR(c) { _longstr.push_back(c);} -#define TERMINATE_BUFFER() {_longstr.push_back(_SC('\0'));} -#define ADD_KEYWORD(key,id) _keywords->NewSlot( SQString::Create(ss, _SC(#key)) ,SQInteger(id)) - -SQLexer::SQLexer(){} -SQLexer::~SQLexer() -{ - _keywords->Release(); -} - -void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed) -{ - _errfunc = efunc; - _errtarget = ed; - _sharedstate = ss; - _keywords = SQTable::Create(ss, 37); - ADD_KEYWORD(while, TK_WHILE); - ADD_KEYWORD(do, TK_DO); - ADD_KEYWORD(if, TK_IF); - ADD_KEYWORD(else, TK_ELSE); - ADD_KEYWORD(break, TK_BREAK); - ADD_KEYWORD(continue, TK_CONTINUE); - ADD_KEYWORD(return, TK_RETURN); - ADD_KEYWORD(null, TK_NULL); - ADD_KEYWORD(function, TK_FUNCTION); - ADD_KEYWORD(local, TK_LOCAL); - ADD_KEYWORD(for, TK_FOR); - ADD_KEYWORD(foreach, TK_FOREACH); - ADD_KEYWORD(in, TK_IN); - ADD_KEYWORD(typeof, TK_TYPEOF); - ADD_KEYWORD(base, TK_BASE); - ADD_KEYWORD(delete, TK_DELETE); - ADD_KEYWORD(try, TK_TRY); - ADD_KEYWORD(catch, TK_CATCH); - ADD_KEYWORD(throw, TK_THROW); - ADD_KEYWORD(clone, TK_CLONE); - ADD_KEYWORD(yield, TK_YIELD); - ADD_KEYWORD(resume, TK_RESUME); - ADD_KEYWORD(switch, TK_SWITCH); - ADD_KEYWORD(case, TK_CASE); - ADD_KEYWORD(default, TK_DEFAULT); - ADD_KEYWORD(this, TK_THIS); - ADD_KEYWORD(class,TK_CLASS); - ADD_KEYWORD(extends,TK_EXTENDS); - ADD_KEYWORD(constructor,TK_CONSTRUCTOR); - ADD_KEYWORD(instanceof,TK_INSTANCEOF); - ADD_KEYWORD(true,TK_TRUE); - ADD_KEYWORD(false,TK_FALSE); - ADD_KEYWORD(static,TK_STATIC); - ADD_KEYWORD(enum,TK_ENUM); - ADD_KEYWORD(const,TK_CONST); - ADD_KEYWORD(__LINE__,TK___LINE__); - ADD_KEYWORD(__FILE__,TK___FILE__); - ADD_KEYWORD(rawcall, TK_RAWCALL); - - - _readf = rg; - _up = up; - _lasttokenline = _currentline = 1; - _currentcolumn = 0; - _prevtoken = -1; - _reached_eof = SQFalse; - Next(); -} - -void SQLexer::Error(const SQChar *err) -{ - _errfunc(_errtarget,err); -} - -void SQLexer::Next() -{ - SQInteger t = _readf(_up); - if(t > MAX_CHAR) Error(_SC("Invalid character")); - if(t != 0) { - _currdata = (LexChar)t; - return; - } - _currdata = SQUIRREL_EOB; - _reached_eof = SQTrue; -} - -const SQChar *SQLexer::Tok2Str(SQInteger tok) -{ - SQObjectPtr itr, key, val; - SQInteger nitr; - while((nitr = _keywords->Next(false,itr, key, val)) != -1) { - itr = (SQInteger)nitr; - if(((SQInteger)_integer(val)) == tok) - return _stringval(key); - } - return NULL; -} - -void SQLexer::LexBlockComment() -{ - bool done = false; - while(!done) { - switch(CUR_CHAR) { - case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue; - case _SC('\n'): _currentline++; NEXT(); continue; - case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment")); - default: NEXT(); - } - } -} -void SQLexer::LexLineComment() -{ - do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB())); -} - -SQInteger SQLexer::Lex() -{ - _lasttokenline = _currentline; - while(CUR_CHAR != SQUIRREL_EOB) { - switch(CUR_CHAR){ - case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue; - case _SC('\n'): - _currentline++; - _prevtoken=_curtoken; - _curtoken=_SC('\n'); - NEXT(); - _currentcolumn=1; - continue; - case _SC('#'): LexLineComment(); continue; - case _SC('/'): - NEXT(); - switch(CUR_CHAR){ - case _SC('*'): - NEXT(); - LexBlockComment(); - continue; - case _SC('/'): - LexLineComment(); - continue; - case _SC('='): - NEXT(); - RETURN_TOKEN(TK_DIVEQ); - continue; - case _SC('>'): - NEXT(); - RETURN_TOKEN(TK_ATTR_CLOSE); - continue; - default: - RETURN_TOKEN('/'); - } - case _SC('='): - NEXT(); - if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') } - else { NEXT(); RETURN_TOKEN(TK_EQ); } - case _SC('<'): - NEXT(); - switch(CUR_CHAR) { - case _SC('='): - NEXT(); - if(CUR_CHAR == _SC('>')) { - NEXT(); - RETURN_TOKEN(TK_3WAYSCMP); - } - RETURN_TOKEN(TK_LE) - break; - case _SC('-'): NEXT(); RETURN_TOKEN(TK_NEWSLOT); break; - case _SC('<'): NEXT(); RETURN_TOKEN(TK_SHIFTL); break; - case _SC('/'): NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); break; - } - RETURN_TOKEN('<'); - case _SC('>'): - NEXT(); - if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);} - else if(CUR_CHAR == _SC('>')){ - NEXT(); - if(CUR_CHAR == _SC('>')){ - NEXT(); - RETURN_TOKEN(TK_USHIFTR); - } - RETURN_TOKEN(TK_SHIFTR); - } - else { RETURN_TOKEN('>') } - case _SC('!'): - NEXT(); - if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')} - else { NEXT(); RETURN_TOKEN(TK_NE); } - case _SC('@'): { - SQInteger stype; - NEXT(); - if(CUR_CHAR != _SC('"')) { - RETURN_TOKEN('@'); - } - if((stype=ReadString('"',true))!=-1) { - RETURN_TOKEN(stype); - } - Error(_SC("error parsing the string")); - } - case _SC('"'): - case _SC('\''): { - SQInteger stype; - if((stype=ReadString(CUR_CHAR,false))!=-1){ - RETURN_TOKEN(stype); - } - Error(_SC("error parsing the string")); - } - case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'): - case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'): - {SQInteger ret = CUR_CHAR; - NEXT(); RETURN_TOKEN(ret); } - case _SC('.'): - NEXT(); - if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') } - NEXT(); - if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); } - NEXT(); - RETURN_TOKEN(TK_VARPARAMS); - case _SC('&'): - NEXT(); - if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') } - else { NEXT(); RETURN_TOKEN(TK_AND); } - case _SC('|'): - NEXT(); - if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') } - else { NEXT(); RETURN_TOKEN(TK_OR); } - case _SC(':'): - NEXT(); - if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') } - else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); } - case _SC('*'): - NEXT(); - if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);} - else RETURN_TOKEN('*'); - case _SC('%'): - NEXT(); - if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);} - else RETURN_TOKEN('%'); - case _SC('-'): - NEXT(); - if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);} - else if (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);} - else RETURN_TOKEN('-'); - case _SC('+'): - NEXT(); - if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);} - else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);} - else RETURN_TOKEN('+'); - case SQUIRREL_EOB: - return 0; - default:{ - if (scisdigit(CUR_CHAR)) { - SQInteger ret = ReadNumber(); - RETURN_TOKEN(ret); - } - else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) { - SQInteger t = ReadID(); - RETURN_TOKEN(t); - } - else { - SQInteger c = CUR_CHAR; - if (sciscntrl((int)c)) Error(_SC("unexpected character(control)")); - NEXT(); - RETURN_TOKEN(c); - } - RETURN_TOKEN(0); - } - } - } - return 0; -} - -SQInteger SQLexer::GetIDType(const SQChar *s,SQInteger len) -{ - SQObjectPtr t; - if(_keywords->GetStr(s,len, t)) { - return SQInteger(_integer(t)); - } - return TK_IDENTIFIER; -} - -#ifdef SQUNICODE -#if WCHAR_SIZE == 2 -SQInteger SQLexer::AddUTF16(SQUnsignedInteger ch) -{ - if (ch >= 0x10000) - { - SQUnsignedInteger code = (ch - 0x10000); - APPEND_CHAR((SQChar)(0xD800 | (code >> 10))); - APPEND_CHAR((SQChar)(0xDC00 | (code & 0x3FF))); - return 2; - } - else { - APPEND_CHAR((SQChar)ch); - return 1; - } -} -#endif -#else -SQInteger SQLexer::AddUTF8(SQUnsignedInteger ch) -{ - if (ch < 0x80) { - APPEND_CHAR((char)ch); - return 1; - } - if (ch < 0x800) { - APPEND_CHAR((SQChar)((ch >> 6) | 0xC0)); - APPEND_CHAR((SQChar)((ch & 0x3F) | 0x80)); - return 2; - } - if (ch < 0x10000) { - APPEND_CHAR((SQChar)((ch >> 12) | 0xE0)); - APPEND_CHAR((SQChar)(((ch >> 6) & 0x3F) | 0x80)); - APPEND_CHAR((SQChar)((ch & 0x3F) | 0x80)); - return 3; - } - if (ch < 0x110000) { - APPEND_CHAR((SQChar)((ch >> 18) | 0xF0)); - APPEND_CHAR((SQChar)(((ch >> 12) & 0x3F) | 0x80)); - APPEND_CHAR((SQChar)(((ch >> 6) & 0x3F) | 0x80)); - APPEND_CHAR((SQChar)((ch & 0x3F) | 0x80)); - return 4; - } - return 0; -} -#endif - -SQInteger SQLexer::ProcessStringHexEscape(SQChar *dest, SQInteger maxdigits) -{ - NEXT(); - if (!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected")); - SQInteger n = 0; - while (isxdigit(CUR_CHAR) && n < maxdigits) { - dest[n] = CUR_CHAR; - n++; - NEXT(); - } - dest[n] = 0; - return n; -} - -SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim) -{ - INIT_TEMP_STRING(); - NEXT(); - if(IS_EOB()) return -1; - for(;;) { - while(CUR_CHAR != ndelim) { - SQInteger x = CUR_CHAR; - switch (x) { - case SQUIRREL_EOB: - Error(_SC("unfinished string")); - return -1; - case _SC('\n'): - if(!verbatim) Error(_SC("newline in a constant")); - APPEND_CHAR(CUR_CHAR); NEXT(); - _currentline++; - break; - case _SC('\\'): - if(verbatim) { - APPEND_CHAR('\\'); NEXT(); - } - else { - NEXT(); - switch(CUR_CHAR) { - case _SC('x'): { - const SQInteger maxdigits = sizeof(SQChar) * 2; - SQChar temp[maxdigits + 1]; - ProcessStringHexEscape(temp, maxdigits); - SQChar *stemp; - APPEND_CHAR((SQChar)scstrtoul(temp, &stemp, 16)); - } - break; - case _SC('U'): - case _SC('u'): { - const SQInteger maxdigits = CUR_CHAR == 'u' ? 4 : 8; - SQChar temp[8 + 1]; - ProcessStringHexEscape(temp, maxdigits); - SQChar *stemp; -#ifdef SQUNICODE -#if WCHAR_SIZE == 2 - AddUTF16(scstrtoul(temp, &stemp, 16)); -#else - APPEND_CHAR((SQChar)scstrtoul(temp, &stemp, 16)); -#endif -#else - AddUTF8(scstrtoul(temp, &stemp, 16)); -#endif - } - break; - case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break; - case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break; - case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break; - case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break; - case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break; - case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break; - case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break; - case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break; - case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break; - case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break; - case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break; - default: - Error(_SC("unrecognised escaper char")); - break; - } - } - break; - default: - APPEND_CHAR(CUR_CHAR); - NEXT(); - } - } - NEXT(); - if(verbatim && CUR_CHAR == '"') { //double quotation - APPEND_CHAR(CUR_CHAR); - NEXT(); - } - else { - break; - } - } - TERMINATE_BUFFER(); - SQInteger len = _longstr.size()-1; - if(ndelim == _SC('\'')) { - if(len == 0) Error(_SC("empty constant")); - if(len > 1) Error(_SC("constant too long")); - _nvalue = _longstr[0]; - return TK_INTEGER; - } - _svalue = &_longstr[0]; - return TK_STRING_LITERAL; -} - -void LexHexadecimal(const SQChar *s,SQUnsignedInteger *res) -{ - *res = 0; - while(*s != 0) - { - if(scisdigit(*s)) *res = (*res)*16+((*s++)-'0'); - else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-'A'+10); - else { assert(0); } - } -} - -void LexInteger(const SQChar *s,SQUnsignedInteger *res) -{ - *res = 0; - while(*s != 0) - { - *res = (*res)*10+((*s++)-'0'); - } -} - -SQInteger scisodigit(SQInteger c) { return c >= _SC('0') && c <= _SC('7'); } - -void LexOctal(const SQChar *s,SQUnsignedInteger *res) -{ - *res = 0; - while(*s != 0) - { - if(scisodigit(*s)) *res = (*res)*8+((*s++)-'0'); - else { assert(0); } - } -} - -SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; } - - -#define MAX_HEX_DIGITS (sizeof(SQInteger)*2) -SQInteger SQLexer::ReadNumber() -{ -#define TINT 1 -#define TFLOAT 2 -#define THEX 3 -#define TSCIENTIFIC 4 -#define TOCTAL 5 - SQInteger type = TINT, firstchar = CUR_CHAR; - SQChar *sTemp; - INIT_TEMP_STRING(); - NEXT(); - if(firstchar == _SC('0') && (toupper(CUR_CHAR) == _SC('X') || scisodigit(CUR_CHAR)) ) { - if(scisodigit(CUR_CHAR)) { - type = TOCTAL; - while(scisodigit(CUR_CHAR)) { - APPEND_CHAR(CUR_CHAR); - NEXT(); - } - if(scisdigit(CUR_CHAR)) Error(_SC("invalid octal number")); - } - else { - NEXT(); - type = THEX; - while(isxdigit(CUR_CHAR)) { - APPEND_CHAR(CUR_CHAR); - NEXT(); - } - if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number")); - } - } - else { - APPEND_CHAR((int)firstchar); - while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) { - if(CUR_CHAR == _SC('.') || isexponent(CUR_CHAR)) type = TFLOAT; - if(isexponent(CUR_CHAR)) { - if(type != TFLOAT) Error(_SC("invalid numeric format")); - type = TSCIENTIFIC; - APPEND_CHAR(CUR_CHAR); - NEXT(); - if(CUR_CHAR == '+' || CUR_CHAR == '-'){ - APPEND_CHAR(CUR_CHAR); - NEXT(); - } - if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected")); - } - - APPEND_CHAR(CUR_CHAR); - NEXT(); - } - } - TERMINATE_BUFFER(); - switch(type) { - case TSCIENTIFIC: - case TFLOAT: - _fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp); - return TK_FLOAT; - case TINT: - LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue); - return TK_INTEGER; - case THEX: - LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue); - return TK_INTEGER; - case TOCTAL: - LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue); - return TK_INTEGER; - } - return 0; -} - -SQInteger SQLexer::ReadID() -{ - SQInteger res; - INIT_TEMP_STRING(); - do { - APPEND_CHAR(CUR_CHAR); - NEXT(); - } while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_')); - TERMINATE_BUFFER(); - res = GetIDType(&_longstr[0],_longstr.size() - 1); - if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) { - _svalue = &_longstr[0]; - } - return res; -} diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqlexer.h b/src/modules/app_sqlang/squirrel/squirrel/sqlexer.h deleted file mode 100644 index b41272963..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqlexer.h +++ /dev/null @@ -1,58 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQLEXER_H_ -#define _SQLEXER_H_ - -#ifdef SQUNICODE -typedef SQChar LexChar; -#else -typedef unsigned char LexChar; -#endif - -struct SQLexer -{ - SQLexer(); - ~SQLexer(); - void Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up, - CompilerErrorFunc efunc, void *ed); - void Error(const SQChar *err); - SQInteger Lex(); - const SQChar *Tok2Str(SQInteger tok); - -private: - SQInteger GetIDType(const SQChar *s, SQInteger len); - SQInteger ReadString(SQInteger ndelim, bool verbatim); - SQInteger ReadNumber(); - void LexBlockComment(); - void LexLineComment(); - SQInteger ReadID(); - void Next(); -#ifdef SQUNICODE -#if WCHAR_SIZE == 2 - SQInteger AddUTF16(SQUnsignedInteger ch); -#endif -#else - SQInteger AddUTF8(SQUnsignedInteger ch); -#endif - SQInteger ProcessStringHexEscape(SQChar *dest, SQInteger maxdigits); - SQInteger _curtoken; - SQTable *_keywords; - SQBool _reached_eof; - -public: - SQInteger _prevtoken; - SQInteger _currentline; - SQInteger _lasttokenline; - SQInteger _currentcolumn; - const SQChar *_svalue; - SQInteger _nvalue; - SQFloat _fvalue; - SQLEXREADFUNC _readf; - SQUserPointer _up; - LexChar _currdata; - SQSharedState *_sharedstate; - sqvector _longstr; - CompilerErrorFunc _errfunc; - void *_errtarget; -}; - -#endif diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqmem.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqmem.cpp deleted file mode 100644 index 378e254b4..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqmem.cpp +++ /dev/null @@ -1,11 +0,0 @@ -/* - see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#ifndef SQ_EXCLUDE_DEFAULT_MEMFUNCTIONS -void *sq_vm_malloc(SQUnsignedInteger size){ return malloc(size); } - -void *sq_vm_realloc(void *p, SQUnsignedInteger SQ_UNUSED_ARG(oldsize), SQUnsignedInteger size){ return realloc(p, size); } - -void sq_vm_free(void *p, SQUnsignedInteger SQ_UNUSED_ARG(size)){ free(p); } -#endif diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqobject.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqobject.cpp deleted file mode 100644 index 7d7f297fc..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqobject.cpp +++ /dev/null @@ -1,677 +0,0 @@ -/* - see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#include "sqvm.h" -#include "sqstring.h" -#include "sqarray.h" -#include "sqtable.h" -#include "squserdata.h" -#include "sqfuncproto.h" -#include "sqclass.h" -#include "sqclosure.h" - - -const SQChar *IdType2Name(SQObjectType type) -{ - switch(_RAW_TYPE(type)) - { - case _RT_NULL:return _SC("null"); - case _RT_INTEGER:return _SC("integer"); - case _RT_FLOAT:return _SC("float"); - case _RT_BOOL:return _SC("bool"); - case _RT_STRING:return _SC("string"); - case _RT_TABLE:return _SC("table"); - case _RT_ARRAY:return _SC("array"); - case _RT_GENERATOR:return _SC("generator"); - case _RT_CLOSURE: - case _RT_NATIVECLOSURE: - return _SC("function"); - case _RT_USERDATA: - case _RT_USERPOINTER: - return _SC("userdata"); - case _RT_THREAD: return _SC("thread"); - case _RT_FUNCPROTO: return _SC("function"); - case _RT_CLASS: return _SC("class"); - case _RT_INSTANCE: return _SC("instance"); - case _RT_WEAKREF: return _SC("weakref"); - case _RT_OUTER: return _SC("outer"); - default: - return NULL; - } -} - -const SQChar *GetTypeName(const SQObjectPtr &obj1) -{ - return IdType2Name(sq_type(obj1)); -} - -SQString *SQString::Create(SQSharedState *ss,const SQChar *s,SQInteger len) -{ - SQString *str=ADD_STRING(ss,s,len); - return str; -} - -void SQString::Release() -{ - REMOVE_STRING(_sharedstate,this); -} - -SQInteger SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) -{ - SQInteger idx = (SQInteger)TranslateIndex(refpos); - while(idx < _len){ - outkey = (SQInteger)idx; - outval = (SQInteger)((SQUnsignedInteger)_val[idx]); - //return idx for the next iteration - return ++idx; - } - //nothing to iterate anymore - return -1; -} - -SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx) -{ - switch(sq_type(idx)){ - case OT_NULL: - return 0; - case OT_INTEGER: - return (SQUnsignedInteger)_integer(idx); - default: assert(0); break; - } - return 0; -} - -SQWeakRef *SQRefCounted::GetWeakRef(SQObjectType type) -{ - if(!_weakref) { - sq_new(_weakref,SQWeakRef); -#if defined(SQUSEDOUBLE) && !defined(_SQ64) - _weakref->_obj._unVal.raw = 0; //clean the whole union on 32 bits with double -#endif - _weakref->_obj._type = type; - _weakref->_obj._unVal.pRefCounted = this; - } - return _weakref; -} - -SQRefCounted::~SQRefCounted() -{ - if(_weakref) { - _weakref->_obj._type = OT_NULL; - _weakref->_obj._unVal.pRefCounted = NULL; - } -} - -void SQWeakRef::Release() { - if(ISREFCOUNTED(_obj._type)) { - _obj._unVal.pRefCounted->_weakref = NULL; - } - sq_delete(this,SQWeakRef); -} - -bool SQDelegable::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) { - if(_delegate) { - return _delegate->Get((*_ss(v)->_metamethods)[mm],res); - } - return false; -} - -bool SQDelegable::SetDelegate(SQTable *mt) -{ - SQTable *temp = mt; - if(temp == this) return false; - while (temp) { - if (temp->_delegate == this) return false; //cycle detected - temp = temp->_delegate; - } - if (mt) __ObjAddRef(mt); - __ObjRelease(_delegate); - _delegate = mt; - return true; -} - -bool SQGenerator::Yield(SQVM *v,SQInteger target) -{ - if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator")); return false;} - if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; } - SQInteger size = v->_top-v->_stackbase; - - _stack.resize(size); - SQObject _this = v->_stack[v->_stackbase]; - _stack._vals[0] = ISREFCOUNTED(sq_type(_this)) ? SQObjectPtr(_refcounted(_this)->GetWeakRef(sq_type(_this))) : _this; - for(SQInteger n =1; n_stack[v->_stackbase+n]; - } - for(SQInteger j =0; j < size; j++) - { - v->_stack[v->_stackbase+j].Null(); - } - - _ci = *v->ci; - _ci._generator=NULL; - for(SQInteger i=0;i<_ci._etraps;i++) { - _etraps.push_back(v->_etraps.top()); - v->_etraps.pop_back(); - // store relative stack base and size in case of resume to other _top - SQExceptionTrap &et = _etraps.back(); - et._stackbase -= v->_stackbase; - et._stacksize -= v->_stackbase; - } - _state=eSuspended; - return true; -} - -bool SQGenerator::Resume(SQVM *v,SQObjectPtr &dest) -{ - if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; } - if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; } - SQInteger size = _stack.size(); - SQInteger target = &dest - &(v->_stack._vals[v->_stackbase]); - assert(target>=0 && target<=255); - SQInteger newbase = v->_top; - if(!v->EnterFrame(v->_top, v->_top + size, false)) - return false; - v->ci->_generator = this; - v->ci->_target = (SQInt32)target; - v->ci->_closure = _ci._closure; - v->ci->_ip = _ci._ip; - v->ci->_literals = _ci._literals; - v->ci->_ncalls = _ci._ncalls; - v->ci->_etraps = _ci._etraps; - v->ci->_root = _ci._root; - - - for(SQInteger i=0;i<_ci._etraps;i++) { - v->_etraps.push_back(_etraps.top()); - _etraps.pop_back(); - SQExceptionTrap &et = v->_etraps.back(); - // restore absolute stack base and size - et._stackbase += newbase; - et._stacksize += newbase; - } - SQObject _this = _stack._vals[0]; - v->_stack[v->_stackbase] = sq_type(_this) == OT_WEAKREF ? _weakref(_this)->_obj : _this; - - for(SQInteger n = 1; n_stack[v->_stackbase+n] = _stack._vals[n]; - _stack._vals[n].Null(); - } - - _state=eRunning; - if (v->_debughook) - v->CallDebugHook(_SC('c')); - - return true; -} - -void SQArray::Extend(const SQArray *a){ - SQInteger xlen; - if((xlen=a->Size())) - for(SQInteger i=0;i_values[i]); -} - -const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop) -{ - SQUnsignedInteger nvars=_nlocalvarinfos; - const SQChar *res=NULL; - if(nvars>=nseq){ - for(SQUnsignedInteger i=0;i=nop) - { - if(nseq==0){ - vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]); - res=_stringval(_localvarinfos[i]._name); - break; - } - nseq--; - } - } - } - return res; -} - - -SQInteger SQFunctionProto::GetLine(SQInstruction *curr) -{ - SQInteger op = (SQInteger)(curr-_instructions); - SQInteger line=_lineinfos[0]._line; - SQInteger low = 0; - SQInteger high = _nlineinfos - 1; - SQInteger mid = 0; - while(low <= high) - { - mid = low + ((high - low) >> 1); - SQInteger curop = _lineinfos[mid]._op; - if(curop > op) - { - high = mid - 1; - } - else if(curop < op) { - if(mid < (_nlineinfos - 1) - && _lineinfos[mid + 1]._op >= op) { - break; - } - low = mid + 1; - } - else { //equal - break; - } - } - - while(mid > 0 && _lineinfos[mid]._op >= op) mid--; - - line = _lineinfos[mid]._line; - - return line; -} - -SQClosure::~SQClosure() -{ - __ObjRelease(_root); - __ObjRelease(_env); - __ObjRelease(_base); - REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); -} - -#define _CHECK_IO(exp) { if(!exp)return false; } -bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size) -{ - if(write(up,dest,size) != size) { - v->Raise_Error(_SC("io error (write function failure)")); - return false; - } - return true; -} - -bool SafeRead(HSQUIRRELVM v,SQREADFUNC read,SQUserPointer up,SQUserPointer dest,SQInteger size) -{ - if(size && read(up,dest,size) != size) { - v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated")); - return false; - } - return true; -} - -bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUnsignedInteger32 tag) -{ - return SafeWrite(v,write,up,&tag,sizeof(tag)); -} - -bool CheckTag(HSQUIRRELVM v,SQREADFUNC read,SQUserPointer up,SQUnsignedInteger32 tag) -{ - SQUnsignedInteger32 t; - _CHECK_IO(SafeRead(v,read,up,&t,sizeof(t))); - if(t != tag){ - v->Raise_Error(_SC("invalid or corrupted closure stream")); - return false; - } - return true; -} - -bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o) -{ - SQUnsignedInteger32 _type = (SQUnsignedInteger32)sq_type(o); - _CHECK_IO(SafeWrite(v,write,up,&_type,sizeof(_type))); - switch(sq_type(o)){ - case OT_STRING: - _CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger))); - _CHECK_IO(SafeWrite(v,write,up,_stringval(o),sq_rsl(_string(o)->_len))); - break; - case OT_BOOL: - case OT_INTEGER: - _CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break; - case OT_FLOAT: - _CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(SQFloat)));break; - case OT_NULL: - break; - default: - v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o)); - return false; - } - return true; -} - -bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o) -{ - SQUnsignedInteger32 _type; - _CHECK_IO(SafeRead(v,read,up,&_type,sizeof(_type))); - SQObjectType t = (SQObjectType)_type; - switch(t){ - case OT_STRING:{ - SQInteger len; - _CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger))); - _CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(sq_rsl(len)),sq_rsl(len))); - o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len); - } - break; - case OT_INTEGER:{ - SQInteger i; - _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break; - } - case OT_BOOL:{ - SQInteger i; - _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o._type = OT_BOOL; o._unVal.nInteger = i; break; - } - case OT_FLOAT:{ - SQFloat f; - _CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break; - } - case OT_NULL: - o.Null(); - break; - default: - v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t)); - return false; - } - return true; -} - -bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) -{ - _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD)); - _CHECK_IO(WriteTag(v,write,up,sizeof(SQChar))); - _CHECK_IO(WriteTag(v,write,up,sizeof(SQInteger))); - _CHECK_IO(WriteTag(v,write,up,sizeof(SQFloat))); - _CHECK_IO(_function->Save(v,up,write)); - _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL)); - return true; -} - -bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret) -{ - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD)); - _CHECK_IO(CheckTag(v,read,up,sizeof(SQChar))); - _CHECK_IO(CheckTag(v,read,up,sizeof(SQInteger))); - _CHECK_IO(CheckTag(v,read,up,sizeof(SQFloat))); - SQObjectPtr func; - _CHECK_IO(SQFunctionProto::Load(v,up,read,func)); - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL)); - ret = SQClosure::Create(_ss(v),_funcproto(func),_table(v->_roottable)->GetWeakRef(OT_TABLE)); - //FIXME: load an root for this closure - return true; -} - -SQFunctionProto::SQFunctionProto(SQSharedState *ss) -{ - _stacksize=0; - _bgenerator=false; - INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); -} - -SQFunctionProto::~SQFunctionProto() -{ - REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); -} - -bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write) -{ - SQInteger i,nliterals = _nliterals,nparameters = _nparameters; - SQInteger noutervalues = _noutervalues,nlocalvarinfos = _nlocalvarinfos; - SQInteger nlineinfos=_nlineinfos,ninstructions = _ninstructions,nfunctions=_nfunctions; - SQInteger ndefaultparams = _ndefaultparams; - _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); - _CHECK_IO(WriteObject(v,up,write,_sourcename)); - _CHECK_IO(WriteObject(v,up,write,_name)); - _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); - _CHECK_IO(SafeWrite(v,write,up,&nliterals,sizeof(nliterals))); - _CHECK_IO(SafeWrite(v,write,up,&nparameters,sizeof(nparameters))); - _CHECK_IO(SafeWrite(v,write,up,&noutervalues,sizeof(noutervalues))); - _CHECK_IO(SafeWrite(v,write,up,&nlocalvarinfos,sizeof(nlocalvarinfos))); - _CHECK_IO(SafeWrite(v,write,up,&nlineinfos,sizeof(nlineinfos))); - _CHECK_IO(SafeWrite(v,write,up,&ndefaultparams,sizeof(ndefaultparams))); - _CHECK_IO(SafeWrite(v,write,up,&ninstructions,sizeof(ninstructions))); - _CHECK_IO(SafeWrite(v,write,up,&nfunctions,sizeof(nfunctions))); - _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART)); - for(i=0;iSave(v,up,write)); - } - _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize))); - _CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator))); - _CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams))); - return true; -} - -bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret) -{ - SQInteger i, nliterals,nparameters; - SQInteger noutervalues ,nlocalvarinfos ; - SQInteger nlineinfos,ninstructions ,nfunctions,ndefaultparams ; - SQObjectPtr sourcename, name; - SQObjectPtr o; - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - _CHECK_IO(ReadObject(v, up, read, sourcename)); - _CHECK_IO(ReadObject(v, up, read, name)); - - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - _CHECK_IO(SafeRead(v,read,up, &nliterals, sizeof(nliterals))); - _CHECK_IO(SafeRead(v,read,up, &nparameters, sizeof(nparameters))); - _CHECK_IO(SafeRead(v,read,up, &noutervalues, sizeof(noutervalues))); - _CHECK_IO(SafeRead(v,read,up, &nlocalvarinfos, sizeof(nlocalvarinfos))); - _CHECK_IO(SafeRead(v,read,up, &nlineinfos, sizeof(nlineinfos))); - _CHECK_IO(SafeRead(v,read,up, &ndefaultparams, sizeof(ndefaultparams))); - _CHECK_IO(SafeRead(v,read,up, &ninstructions, sizeof(ninstructions))); - _CHECK_IO(SafeRead(v,read,up, &nfunctions, sizeof(nfunctions))); - - - SQFunctionProto *f = SQFunctionProto::Create(_opt_ss(v),ninstructions,nliterals,nparameters, - nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams); - SQObjectPtr proto = f; //gets a ref in case of failure - f->_sourcename = sourcename; - f->_name = name; - - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - - for(i = 0;i < nliterals; i++){ - _CHECK_IO(ReadObject(v, up, read, o)); - f->_literals[i] = o; - } - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - - for(i = 0; i < nparameters; i++){ - _CHECK_IO(ReadObject(v, up, read, o)); - f->_parameters[i] = o; - } - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - - for(i = 0; i < noutervalues; i++){ - SQUnsignedInteger type; - SQObjectPtr name; - _CHECK_IO(SafeRead(v,read,up, &type, sizeof(SQUnsignedInteger))); - _CHECK_IO(ReadObject(v, up, read, o)); - _CHECK_IO(ReadObject(v, up, read, name)); - f->_outervalues[i] = SQOuterVar(name,o, (SQOuterType)type); - } - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - - for(i = 0; i < nlocalvarinfos; i++){ - SQLocalVarInfo lvi; - _CHECK_IO(ReadObject(v, up, read, lvi._name)); - _CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(SQUnsignedInteger))); - _CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(SQUnsignedInteger))); - _CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(SQUnsignedInteger))); - f->_localvarinfos[i] = lvi; - } - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - _CHECK_IO(SafeRead(v,read,up, f->_lineinfos, sizeof(SQLineInfo)*nlineinfos)); - - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - _CHECK_IO(SafeRead(v,read,up, f->_defaultparams, sizeof(SQInteger)*ndefaultparams)); - - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - _CHECK_IO(SafeRead(v,read,up, f->_instructions, sizeof(SQInstruction)*ninstructions)); - - _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); - for(i = 0; i < nfunctions; i++){ - _CHECK_IO(_funcproto(o)->Load(v, up, read, o)); - f->_functions[i] = o; - } - _CHECK_IO(SafeRead(v,read,up, &f->_stacksize, sizeof(f->_stacksize))); - _CHECK_IO(SafeRead(v,read,up, &f->_bgenerator, sizeof(f->_bgenerator))); - _CHECK_IO(SafeRead(v,read,up, &f->_varparams, sizeof(f->_varparams))); - - ret = f; - return true; -} - -#ifndef NO_GARBAGE_COLLECTOR - -#define START_MARK() if(!(_uiRef&MARK_FLAG)){ \ - _uiRef|=MARK_FLAG; - -#define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \ - AddToChain(chain, this); } - -void SQVM::Mark(SQCollectable **chain) -{ - START_MARK() - SQSharedState::MarkObject(_lasterror,chain); - SQSharedState::MarkObject(_errorhandler,chain); - SQSharedState::MarkObject(_debughook_closure,chain); - SQSharedState::MarkObject(_roottable, chain); - SQSharedState::MarkObject(temp_reg, chain); - for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain); - for(SQInteger k = 0; k < _callsstacksize; k++) SQSharedState::MarkObject(_callsstack[k]._closure, chain); - END_MARK() -} - -void SQArray::Mark(SQCollectable **chain) -{ - START_MARK() - SQInteger len = _values.size(); - for(SQInteger i = 0;i < len; i++) SQSharedState::MarkObject(_values[i], chain); - END_MARK() -} -void SQTable::Mark(SQCollectable **chain) -{ - START_MARK() - if(_delegate) _delegate->Mark(chain); - SQInteger len = _numofnodes; - for(SQInteger i = 0; i < len; i++){ - SQSharedState::MarkObject(_nodes[i].key, chain); - SQSharedState::MarkObject(_nodes[i].val, chain); - } - END_MARK() -} - -void SQClass::Mark(SQCollectable **chain) -{ - START_MARK() - _members->Mark(chain); - if(_base) _base->Mark(chain); - SQSharedState::MarkObject(_attributes, chain); - for(SQUnsignedInteger i =0; i< _defaultvalues.size(); i++) { - SQSharedState::MarkObject(_defaultvalues[i].val, chain); - SQSharedState::MarkObject(_defaultvalues[i].attrs, chain); - } - for(SQUnsignedInteger j =0; j< _methods.size(); j++) { - SQSharedState::MarkObject(_methods[j].val, chain); - SQSharedState::MarkObject(_methods[j].attrs, chain); - } - for(SQUnsignedInteger k =0; k< MT_LAST; k++) { - SQSharedState::MarkObject(_metamethods[k], chain); - } - END_MARK() -} - -void SQInstance::Mark(SQCollectable **chain) -{ - START_MARK() - _class->Mark(chain); - SQUnsignedInteger nvalues = _class->_defaultvalues.size(); - for(SQUnsignedInteger i =0; i< nvalues; i++) { - SQSharedState::MarkObject(_values[i], chain); - } - END_MARK() -} - -void SQGenerator::Mark(SQCollectable **chain) -{ - START_MARK() - for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain); - SQSharedState::MarkObject(_closure, chain); - END_MARK() -} - -void SQFunctionProto::Mark(SQCollectable **chain) -{ - START_MARK() - for(SQInteger i = 0; i < _nliterals; i++) SQSharedState::MarkObject(_literals[i], chain); - for(SQInteger k = 0; k < _nfunctions; k++) SQSharedState::MarkObject(_functions[k], chain); - END_MARK() -} - -void SQClosure::Mark(SQCollectable **chain) -{ - START_MARK() - if(_base) _base->Mark(chain); - SQFunctionProto *fp = _function; - fp->Mark(chain); - for(SQInteger i = 0; i < fp->_noutervalues; i++) SQSharedState::MarkObject(_outervalues[i], chain); - for(SQInteger k = 0; k < fp->_ndefaultparams; k++) SQSharedState::MarkObject(_defaultparams[k], chain); - END_MARK() -} - -void SQNativeClosure::Mark(SQCollectable **chain) -{ - START_MARK() - for(SQUnsignedInteger i = 0; i < _noutervalues; i++) SQSharedState::MarkObject(_outervalues[i], chain); - END_MARK() -} - -void SQOuter::Mark(SQCollectable **chain) -{ - START_MARK() - /* If the valptr points to a closed value, that value is alive */ - if(_valptr == &_value) { - SQSharedState::MarkObject(_value, chain); - } - END_MARK() -} - -void SQUserData::Mark(SQCollectable **chain){ - START_MARK() - if(_delegate) _delegate->Mark(chain); - END_MARK() -} - -void SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; } - -#endif - diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqobject.h b/src/modules/app_sqlang/squirrel/squirrel/sqobject.h deleted file mode 100644 index 1c54e1c88..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqobject.h +++ /dev/null @@ -1,381 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQOBJECT_H_ -#define _SQOBJECT_H_ - -#include "squtils.h" - -#ifdef _SQ64 -#define UINT_MINUS_ONE (0xFFFFFFFFFFFFFFFF) -#else -#define UINT_MINUS_ONE (0xFFFFFFFF) -#endif - -#define SQ_CLOSURESTREAM_HEAD (('S' << 24) | ('Q' << 16) | ('I' << 8) | ('R')) -#define SQ_CLOSURESTREAM_PART (('P' << 24) | ('A' << 16) | ('R' << 8) | ('T')) -#define SQ_CLOSURESTREAM_TAIL (('T' << 24) | ('A' << 16) | ('I' << 8) | ('L')) - -struct SQSharedState; - -enum SQMetaMethod -{ - MT_ADD = 0, - MT_SUB = 1, - MT_MUL = 2, - MT_DIV = 3, - MT_UNM = 4, - MT_MODULO = 5, - MT_SET = 6, - MT_GET = 7, - MT_TYPEOF = 8, - MT_NEXTI = 9, - MT_CMP = 10, - MT_CALL = 11, - MT_CLONED = 12, - MT_NEWSLOT = 13, - MT_DELSLOT = 14, - MT_TOSTRING = 15, - MT_NEWMEMBER = 16, - MT_INHERITED = 17, - MT_LAST = 18 -}; - -#define MM_ADD _SC("_add") -#define MM_SUB _SC("_sub") -#define MM_MUL _SC("_mul") -#define MM_DIV _SC("_div") -#define MM_UNM _SC("_unm") -#define MM_MODULO _SC("_modulo") -#define MM_SET _SC("_set") -#define MM_GET _SC("_get") -#define MM_TYPEOF _SC("_typeof") -#define MM_NEXTI _SC("_nexti") -#define MM_CMP _SC("_cmp") -#define MM_CALL _SC("_call") -#define MM_CLONED _SC("_cloned") -#define MM_NEWSLOT _SC("_newslot") -#define MM_DELSLOT _SC("_delslot") -#define MM_TOSTRING _SC("_tostring") -#define MM_NEWMEMBER _SC("_newmember") -#define MM_INHERITED _SC("_inherited") - - -#define _CONSTRUCT_VECTOR(type, size, ptr) \ - { \ - for(SQInteger n = 0; n < ((SQInteger)size); n++) { \ - new(&ptr[n]) type(); \ - } \ - } - -#define _DESTRUCT_VECTOR(type, size, ptr) \ - { \ - for(SQInteger nl = 0; nl < ((SQInteger)size); nl++) { \ - ptr[nl].~type(); \ - } \ - } - -#define _COPY_VECTOR(dest, src, size) \ - { \ - for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \ - dest[_n_] = src[_n_]; \ - } \ - } - -#define _NULL_SQOBJECT_VECTOR(vec, size) \ - { \ - for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \ - vec[_n_].Null(); \ - } \ - } - -#define MINPOWER2 4 - -struct SQRefCounted -{ - SQUnsignedInteger _uiRef; - struct SQWeakRef *_weakref; - SQRefCounted() - { - _uiRef = 0; - _weakref = NULL; - } - virtual ~SQRefCounted(); - SQWeakRef *GetWeakRef(SQObjectType type); - virtual void Release() = 0; -}; - -struct SQWeakRef : SQRefCounted -{ - void Release(); - SQObject _obj; -}; - -#define _realval(o) \ - (sq_type((o)) != OT_WEAKREF ? (SQObject)o : _weakref(o)->_obj) - -struct SQObjectPtr; - -#define __AddRef(type, unval) \ - if(ISREFCOUNTED(type)) { \ - unval.pRefCounted->_uiRef++; \ - } - -#define __Release(type, unval) \ - if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef) == 0)) { \ - unval.pRefCounted->Release(); \ - } - -#define __ObjRelease(obj) \ - { \ - if((obj)) { \ - (obj)->_uiRef--; \ - if((obj)->_uiRef == 0) \ - (obj)->Release(); \ - (obj) = NULL; \ - } \ - } - -#define __ObjAddRef(obj) \ - { \ - (obj)->_uiRef++; \ - } - -#define is_delegable(t) (sq_type(t) & SQOBJECT_DELEGABLE) -#define raw_type(obj) _RAW_TYPE((obj)._type) - -#define _integer(obj) ((obj)._unVal.nInteger) -#define _float(obj) ((obj)._unVal.fFloat) -#define _string(obj) ((obj)._unVal.pString) -#define _table(obj) ((obj)._unVal.pTable) -#define _array(obj) ((obj)._unVal.pArray) -#define _closure(obj) ((obj)._unVal.pClosure) -#define _generator(obj) ((obj)._unVal.pGenerator) -#define _nativeclosure(obj) ((obj)._unVal.pNativeClosure) -#define _userdata(obj) ((obj)._unVal.pUserData) -#define _userpointer(obj) ((obj)._unVal.pUserPointer) -#define _thread(obj) ((obj)._unVal.pThread) -#define _funcproto(obj) ((obj)._unVal.pFunctionProto) -#define _class(obj) ((obj)._unVal.pClass) -#define _instance(obj) ((obj)._unVal.pInstance) -#define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable) -#define _weakref(obj) ((obj)._unVal.pWeakRef) -#define _outer(obj) ((obj)._unVal.pOuter) -#define _refcounted(obj) ((obj)._unVal.pRefCounted) -#define _rawval(obj) ((obj)._unVal.raw) - -#define _stringval(obj) (obj)._unVal.pString->_val -#define _userdataval(obj) \ - ((SQUserPointer)sq_aligning((obj)._unVal.pUserData + 1)) - -#define tofloat(num) \ - ((sq_type(num) == OT_INTEGER) ? (SQFloat)_integer(num) : _float(num)) -#define tointeger(num) \ - ((sq_type(num) == OT_FLOAT) ? (SQInteger)_float(num) : _integer(num)) -///////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////// -#if defined(SQUSEDOUBLE) && !defined(_SQ64) \ - || !defined(SQUSEDOUBLE) && defined(_SQ64) -#define SQ_REFOBJECT_INIT() SQ_OBJECT_RAWINIT() -#else -#define SQ_REFOBJECT_INIT() -#endif - -#define _REF_TYPE_DECL(type, _class, sym) \ - SQObjectPtr(_class *x) \ - { \ - SQ_OBJECT_RAWINIT() \ - _type = type; \ - _unVal.sym = x; \ - assert(_unVal.pTable); \ - _unVal.pRefCounted->_uiRef++; \ - } \ - inline SQObjectPtr &operator=(_class *x) \ - { \ - SQObjectType tOldType; \ - SQObjectValue unOldVal; \ - tOldType = _type; \ - unOldVal = _unVal; \ - _type = type; \ - SQ_REFOBJECT_INIT() \ - _unVal.sym = x; \ - _unVal.pRefCounted->_uiRef++; \ - __Release(tOldType, unOldVal); \ - return *this; \ - } - -#define _SCALAR_TYPE_DECL(type, _class, sym) \ - SQObjectPtr(_class x) \ - { \ - SQ_OBJECT_RAWINIT() \ - _type = type; \ - _unVal.sym = x; \ - } \ - inline SQObjectPtr &operator=(_class x) \ - { \ - __Release(_type, _unVal); \ - _type = type; \ - SQ_OBJECT_RAWINIT() \ - _unVal.sym = x; \ - return *this; \ - } -struct SQObjectPtr : public SQObject -{ - SQObjectPtr() - { - SQ_OBJECT_RAWINIT() - _type = OT_NULL; - _unVal.pUserPointer = NULL; - } - SQObjectPtr(const SQObjectPtr &o) - { - _type = o._type; - _unVal = o._unVal; - __AddRef(_type, _unVal); - } - SQObjectPtr(const SQObject &o) - { - _type = o._type; - _unVal = o._unVal; - __AddRef(_type, _unVal); - } - _REF_TYPE_DECL(OT_TABLE, SQTable, pTable) - _REF_TYPE_DECL(OT_CLASS, SQClass, pClass) - _REF_TYPE_DECL(OT_INSTANCE, SQInstance, pInstance) - _REF_TYPE_DECL(OT_ARRAY, SQArray, pArray) - _REF_TYPE_DECL(OT_CLOSURE, SQClosure, pClosure) - _REF_TYPE_DECL(OT_NATIVECLOSURE, SQNativeClosure, pNativeClosure) - _REF_TYPE_DECL(OT_OUTER, SQOuter, pOuter) - _REF_TYPE_DECL(OT_GENERATOR, SQGenerator, pGenerator) - _REF_TYPE_DECL(OT_STRING, SQString, pString) - _REF_TYPE_DECL(OT_USERDATA, SQUserData, pUserData) - _REF_TYPE_DECL(OT_WEAKREF, SQWeakRef, pWeakRef) - _REF_TYPE_DECL(OT_THREAD, SQVM, pThread) - _REF_TYPE_DECL(OT_FUNCPROTO, SQFunctionProto, pFunctionProto) - - _SCALAR_TYPE_DECL(OT_INTEGER, SQInteger, nInteger) - _SCALAR_TYPE_DECL(OT_FLOAT, SQFloat, fFloat) - _SCALAR_TYPE_DECL(OT_USERPOINTER, SQUserPointer, pUserPointer) - - SQObjectPtr(bool bBool) - { - SQ_OBJECT_RAWINIT() - _type = OT_BOOL; - _unVal.nInteger = bBool ? 1 : 0; - } - inline SQObjectPtr &operator=(bool b) - { - __Release(_type, _unVal); - SQ_OBJECT_RAWINIT() - _type = OT_BOOL; - _unVal.nInteger = b ? 1 : 0; - return *this; - } - - ~SQObjectPtr() - { - __Release(_type, _unVal); - } - - inline SQObjectPtr &operator=(const SQObjectPtr &obj) - { - SQObjectType tOldType; - SQObjectValue unOldVal; - tOldType = _type; - unOldVal = _unVal; - _unVal = obj._unVal; - _type = obj._type; - __AddRef(_type, _unVal); - __Release(tOldType, unOldVal); - return *this; - } - inline SQObjectPtr &operator=(const SQObject &obj) - { - SQObjectType tOldType; - SQObjectValue unOldVal; - tOldType = _type; - unOldVal = _unVal; - _unVal = obj._unVal; - _type = obj._type; - __AddRef(_type, _unVal); - __Release(tOldType, unOldVal); - return *this; - } - inline void Null() - { - SQObjectType tOldType = _type; - SQObjectValue unOldVal = _unVal; - _type = OT_NULL; - _unVal.raw = (SQRawObjectVal)NULL; - __Release(tOldType, unOldVal); - } - -private: - SQObjectPtr(const SQChar *) - { - } //safety -}; - - -inline void _Swap(SQObject &a, SQObject &b) -{ - SQObjectType tOldType = a._type; - SQObjectValue unOldVal = a._unVal; - a._type = b._type; - a._unVal = b._unVal; - b._type = tOldType; - b._unVal = unOldVal; -} - -///////////////////////////////////////////////////////////////////////////////////// -#ifndef NO_GARBAGE_COLLECTOR -#define MARK_FLAG 0x80000000 -struct SQCollectable : public SQRefCounted -{ - SQCollectable *_next; - SQCollectable *_prev; - SQSharedState *_sharedstate; - virtual SQObjectType GetType() = 0; - virtual void Release() = 0; - virtual void Mark(SQCollectable **chain) = 0; - void UnMark(); - virtual void Finalize() = 0; - static void AddToChain(SQCollectable **chain, SQCollectable *c); - static void RemoveFromChain(SQCollectable **chain, SQCollectable *c); -}; - - -#define ADD_TO_CHAIN(chain, obj) AddToChain(chain, obj) -#define REMOVE_FROM_CHAIN(chain, obj) \ - { \ - if(!(_uiRef & MARK_FLAG)) \ - RemoveFromChain(chain, obj); \ - } -#define CHAINABLE_OBJ SQCollectable -#define INIT_CHAIN() \ - { \ - _next = NULL; \ - _prev = NULL; \ - _sharedstate = ss; \ - } -#else - -#define ADD_TO_CHAIN(chain, obj) ((void)0) -#define REMOVE_FROM_CHAIN(chain, obj) ((void)0) -#define CHAINABLE_OBJ SQRefCounted -#define INIT_CHAIN() ((void)0) -#endif - -struct SQDelegable : public CHAINABLE_OBJ -{ - bool SetDelegate(SQTable *m); - virtual bool GetMetaMethod(SQVM *v, SQMetaMethod mm, SQObjectPtr &res); - SQTable *_delegate; -}; - -SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx); -typedef sqvector SQObjectPtrVec; -typedef sqvector SQIntVec; -const SQChar *GetTypeName(const SQObjectPtr &obj1); -const SQChar *IdType2Name(SQObjectType type); - - -#endif //_SQOBJECT_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqopcodes.h b/src/modules/app_sqlang/squirrel/squirrel/sqopcodes.h deleted file mode 100644 index aae005fda..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqopcodes.h +++ /dev/null @@ -1,141 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQOPCODES_H_ -#define _SQOPCODES_H_ - -#define MAX_FUNC_STACKSIZE 0xFF -#define MAX_LITERALS ((SQInteger)0x7FFFFFFF) - -enum BitWiseOP -{ - BW_AND = 0, - BW_OR = 2, - BW_XOR = 3, - BW_SHIFTL = 4, - BW_SHIFTR = 5, - BW_USHIFTR = 6 -}; - -enum CmpOP -{ - CMP_G = 0, - CMP_GE = 2, - CMP_L = 3, - CMP_LE = 4, - CMP_3W = 5 -}; - -enum NewObjectType -{ - NOT_TABLE = 0, - NOT_ARRAY = 1, - NOT_CLASS = 2 -}; - -enum AppendArrayType -{ - AAT_STACK = 0, - AAT_LITERAL = 1, - AAT_INT = 2, - AAT_FLOAT = 3, - AAT_BOOL = 4 -}; - -enum SQOpcode -{ - _OP_LINE = 0x00, - _OP_LOAD = 0x01, - _OP_LOADINT = 0x02, - _OP_LOADFLOAT = 0x03, - _OP_DLOAD = 0x04, - _OP_TAILCALL = 0x05, - _OP_CALL = 0x06, - _OP_PREPCALL = 0x07, - _OP_PREPCALLK = 0x08, - _OP_GETK = 0x09, - _OP_MOVE = 0x0A, - _OP_NEWSLOT = 0x0B, - _OP_DELETE = 0x0C, - _OP_SET = 0x0D, - _OP_GET = 0x0E, - _OP_EQ = 0x0F, - _OP_NE = 0x10, - _OP_ADD = 0x11, - _OP_SUB = 0x12, - _OP_MUL = 0x13, - _OP_DIV = 0x14, - _OP_MOD = 0x15, - _OP_BITW = 0x16, - _OP_RETURN = 0x17, - _OP_LOADNULLS = 0x18, - _OP_LOADROOT = 0x19, - _OP_LOADBOOL = 0x1A, - _OP_DMOVE = 0x1B, - _OP_JMP = 0x1C, - //_OP_JNZ= 0x1D, - _OP_JCMP = 0x1D, - _OP_JZ = 0x1E, - _OP_SETOUTER = 0x1F, - _OP_GETOUTER = 0x20, - _OP_NEWOBJ = 0x21, - _OP_APPENDARRAY = 0x22, - _OP_COMPARITH = 0x23, - _OP_INC = 0x24, - _OP_INCL = 0x25, - _OP_PINC = 0x26, - _OP_PINCL = 0x27, - _OP_CMP = 0x28, - _OP_EXISTS = 0x29, - _OP_INSTANCEOF = 0x2A, - _OP_AND = 0x2B, - _OP_OR = 0x2C, - _OP_NEG = 0x2D, - _OP_NOT = 0x2E, - _OP_BWNOT = 0x2F, - _OP_CLOSURE = 0x30, - _OP_YIELD = 0x31, - _OP_RESUME = 0x32, - _OP_FOREACH = 0x33, - _OP_POSTFOREACH = 0x34, - _OP_CLONE = 0x35, - _OP_TYPEOF = 0x36, - _OP_PUSHTRAP = 0x37, - _OP_POPTRAP = 0x38, - _OP_THROW = 0x39, - _OP_NEWSLOTA = 0x3A, - _OP_GETBASE = 0x3B, - _OP_CLOSE = 0x3C -}; - -struct SQInstructionDesc -{ - const SQChar *name; -}; - -struct SQInstruction -{ - SQInstruction(){}; - SQInstruction(SQOpcode _op, SQInteger a0 = 0, SQInteger a1 = 0, - SQInteger a2 = 0, SQInteger a3 = 0) - { - op = (unsigned char)_op; - _arg0 = (unsigned char)a0; - _arg1 = (SQInt32)a1; - _arg2 = (unsigned char)a2; - _arg3 = (unsigned char)a3; - } - - - SQInt32 _arg1; - unsigned char op; - unsigned char _arg0; - unsigned char _arg2; - unsigned char _arg3; -}; - -#include "squtils.h" -typedef sqvector SQInstructionVec; - -#define NEW_SLOT_ATTRIBUTES_FLAG 0x01 -#define NEW_SLOT_STATIC_FLAG 0x02 - -#endif // _SQOPCODES_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqpcheader.h b/src/modules/app_sqlang/squirrel/squirrel/sqpcheader.h deleted file mode 100644 index 8df5ef4c5..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqpcheader.h +++ /dev/null @@ -1,20 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQPCHEADER_H_ -#define _SQPCHEADER_H_ - -#if defined(_MSC_VER) && defined(_DEBUG) -#include -#endif - -#include -#include -#include -#include -#include -#include -//squirrel stuff -#include -#include "sqobject.h" -#include "sqstate.h" - -#endif //_SQPCHEADER_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqstate.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqstate.cpp deleted file mode 100644 index c89bdc4a2..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqstate.cpp +++ /dev/null @@ -1,647 +0,0 @@ -/* - see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#include "sqopcodes.h" -#include "sqvm.h" -#include "sqfuncproto.h" -#include "sqclosure.h" -#include "sqstring.h" -#include "sqtable.h" -#include "sqarray.h" -#include "squserdata.h" -#include "sqclass.h" - -SQSharedState::SQSharedState() -{ - _compilererrorhandler = NULL; - _printfunc = NULL; - _errorfunc = NULL; - _debuginfo = false; - _notifyallexceptions = false; - _foreignptr = NULL; - _releasehook = NULL; -} - -#define newsysstring(s) { \ - _systemstrings->push_back(SQString::Create(this,s)); \ - } - -#define newmetamethod(s) { \ - _metamethods->push_back(SQString::Create(this,s)); \ - _table(_metamethodsmap)->NewSlot(_metamethods->back(),(SQInteger)(_metamethods->size()-1)); \ - } - -bool CompileTypemask(SQIntVec &res,const SQChar *typemask) -{ - SQInteger i = 0; - SQInteger mask = 0; - while(typemask[i] != 0) { - switch(typemask[i]) { - case 'o': mask |= _RT_NULL; break; - case 'i': mask |= _RT_INTEGER; break; - case 'f': mask |= _RT_FLOAT; break; - case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break; - case 's': mask |= _RT_STRING; break; - case 't': mask |= _RT_TABLE; break; - case 'a': mask |= _RT_ARRAY; break; - case 'u': mask |= _RT_USERDATA; break; - case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break; - case 'b': mask |= _RT_BOOL; break; - case 'g': mask |= _RT_GENERATOR; break; - case 'p': mask |= _RT_USERPOINTER; break; - case 'v': mask |= _RT_THREAD; break; - case 'x': mask |= _RT_INSTANCE; break; - case 'y': mask |= _RT_CLASS; break; - case 'r': mask |= _RT_WEAKREF; break; - case '.': mask = -1; res.push_back(mask); i++; mask = 0; continue; - case ' ': i++; continue; //ignores spaces - default: - return false; - } - i++; - if(typemask[i] == '|') { - i++; - if(typemask[i] == 0) - return false; - continue; - } - res.push_back(mask); - mask = 0; - - } - return true; -} - -SQTable *CreateDefaultDelegate(SQSharedState *ss,const SQRegFunction *funcz) -{ - SQInteger i=0; - SQTable *t=SQTable::Create(ss,0); - while(funcz[i].name!=0){ - SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f,0); - nc->_nparamscheck = funcz[i].nparamscheck; - nc->_name = SQString::Create(ss,funcz[i].name); - if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask)) - return NULL; - t->NewSlot(SQString::Create(ss,funcz[i].name),nc); - i++; - } - return t; -} - -void SQSharedState::Init() -{ - _scratchpad=NULL; - _scratchpadsize=0; -#ifndef NO_GARBAGE_COLLECTOR - _gc_chain=NULL; -#endif - _stringtable = (SQStringTable*)SQ_MALLOC(sizeof(SQStringTable)); - new (_stringtable) SQStringTable(this); - sq_new(_metamethods,SQObjectPtrVec); - sq_new(_systemstrings,SQObjectPtrVec); - sq_new(_types,SQObjectPtrVec); - _metamethodsmap = SQTable::Create(this,MT_LAST-1); - //adding type strings to avoid memory trashing - //types names - newsysstring(_SC("null")); - newsysstring(_SC("table")); - newsysstring(_SC("array")); - newsysstring(_SC("closure")); - newsysstring(_SC("string")); - newsysstring(_SC("userdata")); - newsysstring(_SC("integer")); - newsysstring(_SC("float")); - newsysstring(_SC("userpointer")); - newsysstring(_SC("function")); - newsysstring(_SC("generator")); - newsysstring(_SC("thread")); - newsysstring(_SC("class")); - newsysstring(_SC("instance")); - newsysstring(_SC("bool")); - //meta methods - newmetamethod(MM_ADD); - newmetamethod(MM_SUB); - newmetamethod(MM_MUL); - newmetamethod(MM_DIV); - newmetamethod(MM_UNM); - newmetamethod(MM_MODULO); - newmetamethod(MM_SET); - newmetamethod(MM_GET); - newmetamethod(MM_TYPEOF); - newmetamethod(MM_NEXTI); - newmetamethod(MM_CMP); - newmetamethod(MM_CALL); - newmetamethod(MM_CLONED); - newmetamethod(MM_NEWSLOT); - newmetamethod(MM_DELSLOT); - newmetamethod(MM_TOSTRING); - newmetamethod(MM_NEWMEMBER); - newmetamethod(MM_INHERITED); - - _constructoridx = SQString::Create(this,_SC("constructor")); - _registry = SQTable::Create(this,0); - _consts = SQTable::Create(this,0); - _table_default_delegate = CreateDefaultDelegate(this,_table_default_delegate_funcz); - _array_default_delegate = CreateDefaultDelegate(this,_array_default_delegate_funcz); - _string_default_delegate = CreateDefaultDelegate(this,_string_default_delegate_funcz); - _number_default_delegate = CreateDefaultDelegate(this,_number_default_delegate_funcz); - _closure_default_delegate = CreateDefaultDelegate(this,_closure_default_delegate_funcz); - _generator_default_delegate = CreateDefaultDelegate(this,_generator_default_delegate_funcz); - _thread_default_delegate = CreateDefaultDelegate(this,_thread_default_delegate_funcz); - _class_default_delegate = CreateDefaultDelegate(this,_class_default_delegate_funcz); - _instance_default_delegate = CreateDefaultDelegate(this,_instance_default_delegate_funcz); - _weakref_default_delegate = CreateDefaultDelegate(this,_weakref_default_delegate_funcz); -} - -SQSharedState::~SQSharedState() -{ - if(_releasehook) { _releasehook(_foreignptr,0); _releasehook = NULL; } - _constructoridx.Null(); - _table(_registry)->Finalize(); - _table(_consts)->Finalize(); - _table(_metamethodsmap)->Finalize(); - _registry.Null(); - _consts.Null(); - _metamethodsmap.Null(); - while(!_systemstrings->empty()) { - _systemstrings->back().Null(); - _systemstrings->pop_back(); - } - _thread(_root_vm)->Finalize(); - _root_vm.Null(); - _table_default_delegate.Null(); - _array_default_delegate.Null(); - _string_default_delegate.Null(); - _number_default_delegate.Null(); - _closure_default_delegate.Null(); - _generator_default_delegate.Null(); - _thread_default_delegate.Null(); - _class_default_delegate.Null(); - _instance_default_delegate.Null(); - _weakref_default_delegate.Null(); - _refs_table.Finalize(); -#ifndef NO_GARBAGE_COLLECTOR - SQCollectable *t = _gc_chain; - SQCollectable *nx = NULL; - if(t) { - t->_uiRef++; - while(t) { - t->Finalize(); - nx = t->_next; - if(nx) nx->_uiRef++; - if(--t->_uiRef == 0) - t->Release(); - t = nx; - } - } - assert(_gc_chain==NULL); //just to proove a theory - while(_gc_chain){ - _gc_chain->_uiRef++; - _gc_chain->Release(); - } -#endif - - sq_delete(_types,SQObjectPtrVec); - sq_delete(_systemstrings,SQObjectPtrVec); - sq_delete(_metamethods,SQObjectPtrVec); - sq_delete(_stringtable,SQStringTable); - if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize); -} - - -SQInteger SQSharedState::GetMetaMethodIdxByName(const SQObjectPtr &name) -{ - if(sq_type(name) != OT_STRING) - return -1; - SQObjectPtr ret; - if(_table(_metamethodsmap)->Get(name,ret)) { - return _integer(ret); - } - return -1; -} - -#ifndef NO_GARBAGE_COLLECTOR - -void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain) -{ - switch(sq_type(o)){ - case OT_TABLE:_table(o)->Mark(chain);break; - case OT_ARRAY:_array(o)->Mark(chain);break; - case OT_USERDATA:_userdata(o)->Mark(chain);break; - case OT_CLOSURE:_closure(o)->Mark(chain);break; - case OT_NATIVECLOSURE:_nativeclosure(o)->Mark(chain);break; - case OT_GENERATOR:_generator(o)->Mark(chain);break; - case OT_THREAD:_thread(o)->Mark(chain);break; - case OT_CLASS:_class(o)->Mark(chain);break; - case OT_INSTANCE:_instance(o)->Mark(chain);break; - case OT_OUTER:_outer(o)->Mark(chain);break; - case OT_FUNCPROTO:_funcproto(o)->Mark(chain);break; - default: break; //shutup compiler - } -} - -void SQSharedState::RunMark(SQVM* SQ_UNUSED_ARG(vm),SQCollectable **tchain) -{ - SQVM *vms = _thread(_root_vm); - - vms->Mark(tchain); - - _refs_table.Mark(tchain); - MarkObject(_registry,tchain); - MarkObject(_consts,tchain); - MarkObject(_metamethodsmap,tchain); - MarkObject(_table_default_delegate,tchain); - MarkObject(_array_default_delegate,tchain); - MarkObject(_string_default_delegate,tchain); - MarkObject(_number_default_delegate,tchain); - MarkObject(_generator_default_delegate,tchain); - MarkObject(_thread_default_delegate,tchain); - MarkObject(_closure_default_delegate,tchain); - MarkObject(_class_default_delegate,tchain); - MarkObject(_instance_default_delegate,tchain); - MarkObject(_weakref_default_delegate,tchain); - -} - -SQInteger SQSharedState::ResurrectUnreachable(SQVM *vm) -{ - SQInteger n=0; - SQCollectable *tchain=NULL; - - RunMark(vm,&tchain); - - SQCollectable *resurrected = _gc_chain; - SQCollectable *t = resurrected; - - _gc_chain = tchain; - - SQArray *ret = NULL; - if(resurrected) { - ret = SQArray::Create(this,0); - SQCollectable *rlast = NULL; - while(t) { - rlast = t; - SQObjectType type = t->GetType(); - if(type != OT_FUNCPROTO && type != OT_OUTER) { - SQObject sqo; - sqo._type = type; - sqo._unVal.pRefCounted = t; - ret->Append(sqo); - } - t = t->_next; - n++; - } - - assert(rlast->_next == NULL); - rlast->_next = _gc_chain; - if(_gc_chain) - { - _gc_chain->_prev = rlast; - } - _gc_chain = resurrected; - } - - t = _gc_chain; - while(t) { - t->UnMark(); - t = t->_next; - } - - if(ret) { - SQObjectPtr temp = ret; - vm->Push(temp); - } - else { - vm->PushNull(); - } - return n; -} - -SQInteger SQSharedState::CollectGarbage(SQVM *vm) -{ - SQInteger n = 0; - SQCollectable *tchain = NULL; - - RunMark(vm,&tchain); - - SQCollectable *t = _gc_chain; - SQCollectable *nx = NULL; - if(t) { - t->_uiRef++; - while(t) { - t->Finalize(); - nx = t->_next; - if(nx) nx->_uiRef++; - if(--t->_uiRef == 0) - t->Release(); - t = nx; - n++; - } - } - - t = tchain; - while(t) { - t->UnMark(); - t = t->_next; - } - _gc_chain = tchain; - - return n; -} -#endif - -#ifndef NO_GARBAGE_COLLECTOR -void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c) -{ - c->_prev = NULL; - c->_next = *chain; - if(*chain) (*chain)->_prev = c; - *chain = c; -} - -void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c) -{ - if(c->_prev) c->_prev->_next = c->_next; - else *chain = c->_next; - if(c->_next) - c->_next->_prev = c->_prev; - c->_next = NULL; - c->_prev = NULL; -} -#endif - -SQChar* SQSharedState::GetScratchPad(SQInteger size) -{ - SQInteger newsize; - if(size>0) { - if(_scratchpadsize < size) { - newsize = size + (size>>1); - _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); - _scratchpadsize = newsize; - - }else if(_scratchpadsize >= (size<<5)) { - newsize = _scratchpadsize >> 1; - _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize); - _scratchpadsize = newsize; - } - } - return _scratchpad; -} - -RefTable::RefTable() -{ - AllocNodes(4); -} - -void RefTable::Finalize() -{ - RefNode *nodes = _nodes; - for(SQUnsignedInteger n = 0; n < _numofslots; n++) { - nodes->obj.Null(); - nodes++; - } -} - -RefTable::~RefTable() -{ - SQ_FREE(_buckets,(_numofslots * sizeof(RefNode *)) + (_numofslots * sizeof(RefNode))); -} - -#ifndef NO_GARBAGE_COLLECTOR -void RefTable::Mark(SQCollectable **chain) -{ - RefNode *nodes = (RefNode *)_nodes; - for(SQUnsignedInteger n = 0; n < _numofslots; n++) { - if(sq_type(nodes->obj) != OT_NULL) { - SQSharedState::MarkObject(nodes->obj,chain); - } - nodes++; - } -} -#endif - -void RefTable::AddRef(SQObject &obj) -{ - SQHash mainpos; - RefNode *prev; - RefNode *ref = Get(obj,mainpos,&prev,true); - ref->refs++; -} - -SQUnsignedInteger RefTable::GetRefCount(SQObject &obj) -{ - SQHash mainpos; - RefNode *prev; - RefNode *ref = Get(obj,mainpos,&prev,true); - return ref->refs; -} - - -SQBool RefTable::Release(SQObject &obj) -{ - SQHash mainpos; - RefNode *prev; - RefNode *ref = Get(obj,mainpos,&prev,false); - if(ref) { - if(--ref->refs == 0) { - SQObjectPtr o = ref->obj; - if(prev) { - prev->next = ref->next; - } - else { - _buckets[mainpos] = ref->next; - } - ref->next = _freelist; - _freelist = ref; - _slotused--; - ref->obj.Null(); - //<>test for shrink? - return SQTrue; - } - } - else { - assert(0); - } - return SQFalse; -} - -void RefTable::Resize(SQUnsignedInteger size) -{ - RefNode **oldbucks = _buckets; - RefNode *t = _nodes; - SQUnsignedInteger oldnumofslots = _numofslots; - AllocNodes(size); - //rehash - SQUnsignedInteger nfound = 0; - for(SQUnsignedInteger n = 0; n < oldnumofslots; n++) { - if(sq_type(t->obj) != OT_NULL) { - //add back; - assert(t->refs != 0); - RefNode *nn = Add(::HashObj(t->obj)&(_numofslots-1),t->obj); - nn->refs = t->refs; - t->obj.Null(); - nfound++; - } - t++; - } - assert(nfound == oldnumofslots); - SQ_FREE(oldbucks,(oldnumofslots * sizeof(RefNode *)) + (oldnumofslots * sizeof(RefNode))); -} - -RefTable::RefNode *RefTable::Add(SQHash mainpos,SQObject &obj) -{ - RefNode *t = _buckets[mainpos]; - RefNode *newnode = _freelist; - newnode->obj = obj; - _buckets[mainpos] = newnode; - _freelist = _freelist->next; - newnode->next = t; - assert(newnode->refs == 0); - _slotused++; - return newnode; -} - -RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add) -{ - RefNode *ref; - mainpos = ::HashObj(obj)&(_numofslots-1); - *prev = NULL; - for (ref = _buckets[mainpos]; ref; ) { - if(_rawval(ref->obj) == _rawval(obj) && sq_type(ref->obj) == sq_type(obj)) - break; - *prev = ref; - ref = ref->next; - } - if(ref == NULL && add) { - if(_numofslots == _slotused) { - assert(_freelist == 0); - Resize(_numofslots*2); - mainpos = ::HashObj(obj)&(_numofslots-1); - } - ref = Add(mainpos,obj); - } - return ref; -} - -void RefTable::AllocNodes(SQUnsignedInteger size) -{ - RefNode **bucks; - RefNode *nodes; - bucks = (RefNode **)SQ_MALLOC((size * sizeof(RefNode *)) + (size * sizeof(RefNode))); - nodes = (RefNode *)&bucks[size]; - RefNode *temp = nodes; - SQUnsignedInteger n; - for(n = 0; n < size - 1; n++) { - bucks[n] = NULL; - temp->refs = 0; - new (&temp->obj) SQObjectPtr; - temp->next = temp+1; - temp++; - } - bucks[n] = NULL; - temp->refs = 0; - new (&temp->obj) SQObjectPtr; - temp->next = NULL; - _freelist = nodes; - _nodes = nodes; - _buckets = bucks; - _slotused = 0; - _numofslots = size; -} -////////////////////////////////////////////////////////////////////////// -//SQStringTable -/* -* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.) -* http://www.lua.org/copyright.html#4 -* http://www.lua.org/source/4.0.1/src_lstring.c.html -*/ - -SQStringTable::SQStringTable(SQSharedState *ss) -{ - _sharedstate = ss; - AllocNodes(4); - _slotused = 0; -} - -SQStringTable::~SQStringTable() -{ - SQ_FREE(_strings,sizeof(SQString*)*_numofslots); - _strings = NULL; -} - -void SQStringTable::AllocNodes(SQInteger size) -{ - _numofslots = size; - _strings = (SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots); - memset(_strings,0,sizeof(SQString*)*_numofslots); -} - -SQString *SQStringTable::Add(const SQChar *news,SQInteger len) -{ - if(len<0) - len = (SQInteger)scstrlen(news); - SQHash newhash = ::_hashstr(news,len); - SQHash h = newhash&(_numofslots-1); - SQString *s; - for (s = _strings[h]; s; s = s->_next){ - if(s->_len == len && (!memcmp(news,s->_val,sq_rsl(len)))) - return s; //found - } - - SQString *t = (SQString *)SQ_MALLOC(sq_rsl(len)+sizeof(SQString)); - new (t) SQString; - t->_sharedstate = _sharedstate; - memcpy(t->_val,news,sq_rsl(len)); - t->_val[len] = _SC('\0'); - t->_len = len; - t->_hash = newhash; - t->_next = _strings[h]; - _strings[h] = t; - _slotused++; - if (_slotused > _numofslots) /* too crowded? */ - Resize(_numofslots*2); - return t; -} - -void SQStringTable::Resize(SQInteger size) -{ - SQInteger oldsize=_numofslots; - SQString **oldtable=_strings; - AllocNodes(size); - for (SQInteger i=0; i_next; - SQHash h = p->_hash&(_numofslots-1); - p->_next = _strings[h]; - _strings[h] = p; - p = next; - } - } - SQ_FREE(oldtable,oldsize*sizeof(SQString*)); -} - -void SQStringTable::Remove(SQString *bs) -{ - SQString *s; - SQString *prev=NULL; - SQHash h = bs->_hash&(_numofslots - 1); - - for (s = _strings[h]; s; ){ - if(s == bs){ - if(prev) - prev->_next = s->_next; - else - _strings[h] = s->_next; - _slotused--; - SQInteger slen = s->_len; - s->~SQString(); - SQ_FREE(s,sizeof(SQString) + sq_rsl(slen)); - return; - } - prev = s; - s = s->_next; - } - assert(0);//if this fail something is wrong -} diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqstate.h b/src/modules/app_sqlang/squirrel/squirrel/sqstate.h deleted file mode 100644 index 3507dc897..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqstate.h +++ /dev/null @@ -1,142 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQSTATE_H_ -#define _SQSTATE_H_ - -#include "squtils.h" -#include "sqobject.h" -struct SQString; -struct SQTable; -//max number of character for a printed number -#define NUMBER_MAX_CHAR 50 - -struct SQStringTable -{ - SQStringTable(SQSharedState *ss); - ~SQStringTable(); - SQString *Add(const SQChar *, SQInteger len); - void Remove(SQString *); - -private: - void Resize(SQInteger size); - void AllocNodes(SQInteger size); - SQString **_strings; - SQUnsignedInteger _numofslots; - SQUnsignedInteger _slotused; - SQSharedState *_sharedstate; -}; - -struct RefTable -{ - struct RefNode - { - SQObjectPtr obj; - SQUnsignedInteger refs; - struct RefNode *next; - }; - RefTable(); - ~RefTable(); - void AddRef(SQObject &obj); - SQBool Release(SQObject &obj); - SQUnsignedInteger GetRefCount(SQObject &obj); -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable **chain); -#endif - void Finalize(); - -private: - RefNode *Get(SQObject &obj, SQHash &mainpos, RefNode **prev, bool add); - RefNode *Add(SQHash mainpos, SQObject &obj); - void Resize(SQUnsignedInteger size); - void AllocNodes(SQUnsignedInteger size); - SQUnsignedInteger _numofslots; - SQUnsignedInteger _slotused; - RefNode *_nodes; - RefNode *_freelist; - RefNode **_buckets; -}; - -#define ADD_STRING(ss, str, len) ss->_stringtable->Add(str, len) -#define REMOVE_STRING(ss, bstr) ss->_stringtable->Remove(bstr) - -struct SQObjectPtr; - -struct SQSharedState -{ - SQSharedState(); - ~SQSharedState(); - void Init(); - -public: - SQChar *GetScratchPad(SQInteger size); - SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name); -#ifndef NO_GARBAGE_COLLECTOR - SQInteger CollectGarbage(SQVM *vm); - void RunMark(SQVM *vm, SQCollectable **tchain); - SQInteger ResurrectUnreachable(SQVM *vm); - static void MarkObject(SQObjectPtr &o, SQCollectable **chain); -#endif - SQObjectPtrVec *_metamethods; - SQObjectPtr _metamethodsmap; - SQObjectPtrVec *_systemstrings; - SQObjectPtrVec *_types; - SQStringTable *_stringtable; - RefTable _refs_table; - SQObjectPtr _registry; - SQObjectPtr _consts; - SQObjectPtr _constructoridx; -#ifndef NO_GARBAGE_COLLECTOR - SQCollectable *_gc_chain; -#endif - SQObjectPtr _root_vm; - SQObjectPtr _table_default_delegate; - static const SQRegFunction _table_default_delegate_funcz[]; - SQObjectPtr _array_default_delegate; - static const SQRegFunction _array_default_delegate_funcz[]; - SQObjectPtr _string_default_delegate; - static const SQRegFunction _string_default_delegate_funcz[]; - SQObjectPtr _number_default_delegate; - static const SQRegFunction _number_default_delegate_funcz[]; - SQObjectPtr _generator_default_delegate; - static const SQRegFunction _generator_default_delegate_funcz[]; - SQObjectPtr _closure_default_delegate; - static const SQRegFunction _closure_default_delegate_funcz[]; - SQObjectPtr _thread_default_delegate; - static const SQRegFunction _thread_default_delegate_funcz[]; - SQObjectPtr _class_default_delegate; - static const SQRegFunction _class_default_delegate_funcz[]; - SQObjectPtr _instance_default_delegate; - static const SQRegFunction _instance_default_delegate_funcz[]; - SQObjectPtr _weakref_default_delegate; - static const SQRegFunction _weakref_default_delegate_funcz[]; - - SQCOMPILERERROR _compilererrorhandler; - SQPRINTFUNCTION _printfunc; - SQPRINTFUNCTION _errorfunc; - bool _debuginfo; - bool _notifyallexceptions; - SQUserPointer _foreignptr; - SQRELEASEHOOK _releasehook; - -private: - SQChar *_scratchpad; - SQInteger _scratchpadsize; -}; - -#define _sp(s) (_sharedstate->GetScratchPad(s)) -#define _spval (_sharedstate->GetScratchPad(-1)) - -#define _table_ddel _table(_sharedstate->_table_default_delegate) -#define _array_ddel _table(_sharedstate->_array_default_delegate) -#define _string_ddel _table(_sharedstate->_string_default_delegate) -#define _number_ddel _table(_sharedstate->_number_default_delegate) -#define _generator_ddel _table(_sharedstate->_generator_default_delegate) -#define _closure_ddel _table(_sharedstate->_closure_default_delegate) -#define _thread_ddel _table(_sharedstate->_thread_default_delegate) -#define _class_ddel _table(_sharedstate->_class_default_delegate) -#define _instance_ddel _table(_sharedstate->_instance_default_delegate) -#define _weakref_ddel _table(_sharedstate->_weakref_default_delegate) - -bool CompileTypemask(SQIntVec &res, const SQChar *typemask); - - -#endif //_SQSTATE_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqstring.h b/src/modules/app_sqlang/squirrel/squirrel/sqstring.h deleted file mode 100644 index 7b3087770..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqstring.h +++ /dev/null @@ -1,39 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQSTRING_H_ -#define _SQSTRING_H_ - -inline SQHash _hashstr(const SQChar *s, size_t l) -{ - SQHash h = (SQHash)l; /* seed */ - size_t step = - (l >> 5) + 1; /* if string is too long, don't hash all its chars */ - size_t l1; - for(l1 = l; l1 >= step; l1 -= step) - h = h ^ ((h << 5) + (h >> 2) + ((unsigned short)s[l1 - 1])); - return h; -} - -struct SQString : public SQRefCounted -{ - SQString() - { - } - ~SQString() - { - } - -public: - static SQString *Create( - SQSharedState *ss, const SQChar *, SQInteger len = -1); - SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, - SQObjectPtr &outval); - void Release(); - SQSharedState *_sharedstate; - SQString *_next; //chain for the string table - SQInteger _len; - SQHash _hash; - SQChar _val[1]; -}; - - -#endif //_SQSTRING_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqtable.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqtable.cpp deleted file mode 100644 index 3a89c459d..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqtable.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/* -see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#include "sqvm.h" -#include "sqtable.h" -#include "sqfuncproto.h" -#include "sqclosure.h" - -SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize) -{ - SQInteger pow2size=MINPOWER2; - while(nInitialSize>pow2size)pow2size=pow2size<<1; - AllocNodes(pow2size); - _usednodes = 0; - _delegate = NULL; - INIT_CHAIN(); - ADD_TO_CHAIN(&_sharedstate->_gc_chain,this); -} - -void SQTable::Remove(const SQObjectPtr &key) -{ - - _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1)); - if (n) { - n->val.Null(); - n->key.Null(); - _usednodes--; - Rehash(false); - } -} - -void SQTable::AllocNodes(SQInteger nSize) -{ - _HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize); - for(SQInteger i=0;i= oldsize-oldsize/4) /* using more than 3/4? */ - AllocNodes(oldsize*2); - else if (nelems <= oldsize/4 && /* less than 1/4? */ - oldsize > MINPOWER2) - AllocNodes(oldsize/2); - else if(force) - AllocNodes(oldsize); - else - return; - _usednodes = 0; - for (SQInteger i=0; ikey) != OT_NULL) - NewSlot(old->key,old->val); - } - for(SQInteger k=0;k_nodes; - _HashNode *src = _nodes; - _HashNode *dst = nt->_nodes; - SQInteger n = 0; - for(n = 0; n < _numofnodes; n++) { - dst->key = src->key; - dst->val = src->val; - if(src->next) { - assert(src->next > basesrc); - dst->next = basedst + (src->next - basesrc); - assert(dst != dst->next); - } - dst++; - src++; - } - assert(_firstfree > basesrc); - assert(_firstfree != NULL); - nt->_firstfree = basedst + (_firstfree - basesrc); - nt->_usednodes = _usednodes; -#else - SQInteger ridx=0; - SQObjectPtr key,val; - while((ridx=Next(true,ridx,key,val))!=-1){ - nt->NewSlot(key,val); - } -#endif - nt->SetDelegate(_delegate); - return nt; -} - -bool SQTable::Get(const SQObjectPtr &key,SQObjectPtr &val) -{ - if(sq_type(key) == OT_NULL) - return false; - _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1)); - if (n) { - val = _realval(n->val); - return true; - } - return false; -} -bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val) -{ - assert(sq_type(key) != OT_NULL); - SQHash h = HashObj(key) & (_numofnodes - 1); - _HashNode *n = _Get(key, h); - if (n) { - n->val = val; - return false; - } - _HashNode *mp = &_nodes[h]; - n = mp; - - - //key not found I'll insert it - //main pos is not free - - if(sq_type(mp->key) != OT_NULL) { - n = _firstfree; /* get a free place */ - SQHash mph = HashObj(mp->key) & (_numofnodes - 1); - _HashNode *othern; /* main position of colliding node */ - - if (mp > n && (othern = &_nodes[mph]) != mp){ - /* yes; move colliding node into free position */ - while (othern->next != mp){ - assert(othern->next != NULL); - othern = othern->next; /* find previous */ - } - othern->next = n; /* redo the chain with `n' in place of `mp' */ - n->key = mp->key; - n->val = mp->val;/* copy colliding node into free pos. (mp->next also goes) */ - n->next = mp->next; - mp->key.Null(); - mp->val.Null(); - mp->next = NULL; /* now `mp' is free */ - } - else{ - /* new node will go into free position */ - n->next = mp->next; /* chain new position */ - mp->next = n; - mp = n; - } - } - mp->key = key; - - for (;;) { /* correct `firstfree' */ - if (sq_type(_firstfree->key) == OT_NULL && _firstfree->next == NULL) { - mp->val = val; - _usednodes++; - return true; /* OK; table still has a free place */ - } - else if (_firstfree == _nodes) break; /* cannot decrement from here */ - else (_firstfree)--; - } - Rehash(true); - return NewSlot(key, val); -} - -SQInteger SQTable::Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval) -{ - SQInteger idx = (SQInteger)TranslateIndex(refpos); - while (idx < _numofnodes) { - if(sq_type(_nodes[idx].key) != OT_NULL) { - //first found - _HashNode &n = _nodes[idx]; - outkey = n.key; - outval = getweakrefs?(SQObject)n.val:_realval(n.val); - //return idx for the next iteration - return ++idx; - } - ++idx; - } - //nothing to iterate anymore - return -1; -} - - -bool SQTable::Set(const SQObjectPtr &key, const SQObjectPtr &val) -{ - _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1)); - if (n) { - n->val = val; - return true; - } - return false; -} - -void SQTable::_ClearNodes() -{ - for(SQInteger i = 0;i < _numofnodes; i++) { _HashNode &n = _nodes[i]; n.key.Null(); n.val.Null(); } -} - -void SQTable::Finalize() -{ - _ClearNodes(); - SetDelegate(NULL); -} - -void SQTable::Clear() -{ - _ClearNodes(); - _usednodes = 0; - Rehash(true); -} diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqtable.h b/src/modules/app_sqlang/squirrel/squirrel/sqtable.h deleted file mode 100644 index ce0ff0de2..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqtable.h +++ /dev/null @@ -1,128 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQTABLE_H_ -#define _SQTABLE_H_ -/* -* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.) -* http://www.lua.org/copyright.html#4 -* http://www.lua.org/source/4.0.1/src_ltable.c.html -*/ - -#include "sqstring.h" - - -#define hashptr(p) ((SQHash)(((SQInteger)p) >> 3)) - -inline SQHash HashObj(const SQObject &key) -{ - switch(sq_type(key)) { - case OT_STRING: - return _string(key)->_hash; - case OT_FLOAT: - return (SQHash)((SQInteger)_float(key)); - case OT_BOOL: - case OT_INTEGER: - return (SQHash)((SQInteger)_integer(key)); - default: - return hashptr(key._unVal.pRefCounted); - } -} - -struct SQTable : public SQDelegable -{ -private: - struct _HashNode - { - _HashNode() - { - next = NULL; - } - SQObjectPtr val; - SQObjectPtr key; - _HashNode *next; - }; - _HashNode *_firstfree; - _HashNode *_nodes; - SQInteger _numofnodes; - SQInteger _usednodes; - - /////////////////////////// - void AllocNodes(SQInteger nSize); - void Rehash(bool force); - SQTable(SQSharedState *ss, SQInteger nInitialSize); - void _ClearNodes(); - -public: - static SQTable *Create(SQSharedState *ss, SQInteger nInitialSize) - { - SQTable *newtable = (SQTable *)SQ_MALLOC(sizeof(SQTable)); - new(newtable) SQTable(ss, nInitialSize); - newtable->_delegate = NULL; - return newtable; - } - void Finalize(); - SQTable *Clone(); - ~SQTable() - { - SetDelegate(NULL); - REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this); - for(SQInteger i = 0; i < _numofnodes; i++) - _nodes[i].~_HashNode(); - SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode)); - } -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable **chain); - SQObjectType GetType() - { - return OT_TABLE; - } -#endif - inline _HashNode *_Get(const SQObjectPtr &key, SQHash hash) - { - _HashNode *n = &_nodes[hash]; - do { - if(_rawval(n->key) == _rawval(key) - && sq_type(n->key) == sq_type(key)) { - return n; - } - } while((n = n->next)); - return NULL; - } - //for compiler use - inline bool GetStr(const SQChar *key, SQInteger keylen, SQObjectPtr &val) - { - SQHash hash = _hashstr(key, keylen); - _HashNode *n = &_nodes[hash & (_numofnodes - 1)]; - _HashNode *res = NULL; - do { - if(sq_type(n->key) == OT_STRING - && (scstrcmp(_stringval(n->key), key) == 0)) { - res = n; - break; - } - } while((n = n->next)); - if(res) { - val = _realval(res->val); - return true; - } - return false; - } - bool Get(const SQObjectPtr &key, SQObjectPtr &val); - void Remove(const SQObjectPtr &key); - bool Set(const SQObjectPtr &key, const SQObjectPtr &val); - //returns true if a new slot has been created false if it was already present - bool NewSlot(const SQObjectPtr &key, const SQObjectPtr &val); - SQInteger Next(bool getweakrefs, const SQObjectPtr &refpos, - SQObjectPtr &outkey, SQObjectPtr &outval); - - SQInteger CountUsed() - { - return _usednodes; - } - void Clear(); - void Release() - { - sq_delete(this, SQTable); - } -}; - -#endif //_SQTABLE_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/squirrel.dsp b/src/modules/app_sqlang/squirrel/squirrel/squirrel.dsp deleted file mode 100644 index 4778b6963..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/squirrel.dsp +++ /dev/null @@ -1,302 +0,0 @@ -# Microsoft Developer Studio Project File - Name="squirrel" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=squirrel - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "squirrel.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "squirrel.mak" CFG="squirrel - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "squirrel - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "squirrel - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_LocalPath ".." -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "squirrel - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "..\include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "GARBAGE_COLLECTOR" /YX /FD /c -# ADD BASE RSC /l 0x410 /d "NDEBUG" -# ADD RSC /l 0x410 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"..\lib\squirrel.lib" - -!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD BASE RSC /l 0x410 /d "_DEBUG" -# ADD RSC /l 0x410 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"..\lib\squirrel.lib" - -!ENDIF - -# Begin Target - -# Name "squirrel - Win32 Release" -# Name "squirrel - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\sqapi.cpp - -!IF "$(CFG)" == "squirrel - Win32 Release" - -!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" - -# ADD CPP /YX"stdafx.h" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\sqbaselib.cpp - -!IF "$(CFG)" == "squirrel - Win32 Release" - -!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" - -# ADD CPP /YX"stdafx.h" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\sqcompiler.cpp - -!IF "$(CFG)" == "squirrel - Win32 Release" - -!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" - -# ADD CPP /YX"stdafx.h" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\sqdebug.cpp - -!IF "$(CFG)" == "squirrel - Win32 Release" - -!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" - -# ADD CPP /YX"stdafx.h" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\sqfuncstate.cpp - -!IF "$(CFG)" == "squirrel - Win32 Release" - -!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" - -# ADD CPP /YX"stdafx.h" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\sqlexer.cpp - -!IF "$(CFG)" == "squirrel - Win32 Release" - -!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" - -# ADD CPP /YX"stdafx.h" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\sqmem.cpp -# End Source File -# Begin Source File - -SOURCE=.\sqobject.cpp - -!IF "$(CFG)" == "squirrel - Win32 Release" - -!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" - -# ADD CPP /YX"stdafx.h" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\sqstate.cpp - -!IF "$(CFG)" == "squirrel - Win32 Release" - -!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" - -# ADD CPP /YX"stdafx.h" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\sqtable.cpp - -!IF "$(CFG)" == "squirrel - Win32 Release" - -!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" - -# ADD CPP /YX"stdafx.h" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\sqclass.cpp - -!IF "$(CFG)" == "squirrel - Win32 Release" - -!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" - -# ADD CPP /YX"stdafx.h" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\sqvm.cpp - -!IF "$(CFG)" == "squirrel - Win32 Release" - -!ELSEIF "$(CFG)" == "squirrel - Win32 Debug" - -# ADD CPP /YX"stdafx.h" - -!ENDIF - -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\sqarray.h -# End Source File -# Begin Source File - -SOURCE=.\sqclosure.h -# End Source File -# Begin Source File - -SOURCE=.\sqcompiler.h -# End Source File -# Begin Source File - -SOURCE=.\sqfuncproto.h -# End Source File -# Begin Source File - -SOURCE=.\sqfuncstate.h -# End Source File -# Begin Source File - -SOURCE=.\sqlexer.h -# End Source File -# Begin Source File - -SOURCE=.\sqobject.h -# End Source File -# Begin Source File - -SOURCE=.\sqopcodes.h -# End Source File -# Begin Source File - -SOURCE=.\sqpcheader.h -# End Source File -# Begin Source File - -SOURCE=.\sqstate.h -# End Source File -# Begin Source File - -SOURCE=.\sqstring.h -# End Source File -# Begin Source File - -SOURCE=.\sqtable.h -# End Source File -# Begin Source File - -SOURCE=.\squserdata.h -# End Source File -# Begin Source File - -SOURCE=.\squtils.h -# End Source File -# Begin Source File - -SOURCE=.\sqclass.h -# End Source File -# Begin Source File - -SOURCE=.\sqvm.h -# End Source File -# End Group -# End Target -# End Project diff --git a/src/modules/app_sqlang/squirrel/squirrel/squserdata.h b/src/modules/app_sqlang/squirrel/squirrel/squserdata.h deleted file mode 100644 index a488e8ccf..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/squserdata.h +++ /dev/null @@ -1,55 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQUSERDATA_H_ -#define _SQUSERDATA_H_ - -struct SQUserData : SQDelegable -{ - SQUserData(SQSharedState *ss) - { - _delegate = 0; - _hook = NULL; - INIT_CHAIN(); - ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); - } - ~SQUserData() - { - REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this); - SetDelegate(NULL); - } - static SQUserData *Create(SQSharedState *ss, SQInteger size) - { - SQUserData *ud = - (SQUserData *)SQ_MALLOC(sq_aligning(sizeof(SQUserData)) + size); - new(ud) SQUserData(ss); - ud->_size = size; - ud->_typetag = 0; - return ud; - } -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable **chain); - void Finalize() - { - SetDelegate(NULL); - } - SQObjectType GetType() - { - return OT_USERDATA; - } -#endif - void Release() - { - if(_hook) - _hook((SQUserPointer)sq_aligning(this + 1), _size); - SQInteger tsize = _size; - this->~SQUserData(); - SQ_FREE(this, sq_aligning(sizeof(SQUserData)) + tsize); - } - - - SQInteger _size; - SQRELEASEHOOK _hook; - SQUserPointer _typetag; - //SQChar _val[1]; -}; - -#endif //_SQUSERDATA_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/squtils.h b/src/modules/app_sqlang/squirrel/squirrel/squtils.h deleted file mode 100644 index dee981a34..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/squtils.h +++ /dev/null @@ -1,155 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQUTILS_H_ -#define _SQUTILS_H_ - -void *sq_vm_malloc(SQUnsignedInteger size); -void *sq_vm_realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger size); -void sq_vm_free(void *p, SQUnsignedInteger size); - -#define sq_new(__ptr, __type) \ - { \ - __ptr = (__type *)sq_vm_malloc(sizeof(__type)); \ - new(__ptr) __type; \ - } -#define sq_delete(__ptr, __type) \ - { \ - __ptr->~__type(); \ - sq_vm_free(__ptr, sizeof(__type)); \ - } -#define SQ_MALLOC(__size) sq_vm_malloc((__size)); -#define SQ_FREE(__ptr, __size) sq_vm_free((__ptr), (__size)); -#define SQ_REALLOC(__ptr, __oldsize, __size) \ - sq_vm_realloc((__ptr), (__oldsize), (__size)); - -#define sq_aligning(v) \ - (((size_t)(v) + (SQ_ALIGNMENT - 1)) & (~(SQ_ALIGNMENT - 1))) - -//sqvector mini vector class, supports objects by value -template class sqvector -{ -public: - sqvector() - { - _vals = NULL; - _size = 0; - _allocated = 0; - } - sqvector(const sqvector &v) - { - copy(v); - } - void copy(const sqvector &v) - { - if(_size) { - resize(0); //destroys all previous stuff - } - //resize(v._size); - if(v._size > _allocated) { - _realloc(v._size); - } - for(SQUnsignedInteger i = 0; i < v._size; i++) { - new((void *)&_vals[i]) T(v._vals[i]); - } - _size = v._size; - } - ~sqvector() - { - if(_allocated) { - for(SQUnsignedInteger i = 0; i < _size; i++) - _vals[i].~T(); - SQ_FREE(_vals, (_allocated * sizeof(T))); - } - } - void reserve(SQUnsignedInteger newsize) - { - _realloc(newsize); - } - void resize(SQUnsignedInteger newsize, const T &fill = T()) - { - if(newsize > _allocated) - _realloc(newsize); - if(newsize > _size) { - while(_size < newsize) { - new((void *)&_vals[_size]) T(fill); - _size++; - } - } else { - for(SQUnsignedInteger i = newsize; i < _size; i++) { - _vals[i].~T(); - } - _size = newsize; - } - } - void shrinktofit() - { - if(_size > 4) { - _realloc(_size); - } - } - T &top() const - { - return _vals[_size - 1]; - } - inline SQUnsignedInteger size() const - { - return _size; - } - bool empty() const - { - return (_size <= 0); - } - inline T &push_back(const T &val = T()) - { - if(_allocated <= _size) - _realloc(_size * 2); - return *(new((void *)&_vals[_size++]) T(val)); - } - inline void pop_back() - { - _size--; - _vals[_size].~T(); - } - void insert(SQUnsignedInteger idx, const T &val) - { - resize(_size + 1); - for(SQUnsignedInteger i = _size - 1; i > idx; i--) { - _vals[i] = _vals[i - 1]; - } - _vals[idx] = val; - } - void remove(SQUnsignedInteger idx) - { - _vals[idx].~T(); - if(idx < (_size - 1)) { - memmove(&_vals[idx], &_vals[idx + 1], - sizeof(T) * (_size - idx - 1)); - } - _size--; - } - SQUnsignedInteger capacity() - { - return _allocated; - } - inline T &back() const - { - return _vals[_size - 1]; - } - inline T &operator[](SQUnsignedInteger pos) const - { - return _vals[pos]; - } - T *_vals; - -private: - void _realloc(SQUnsignedInteger newsize) - { - newsize = (newsize > 0) ? newsize : 4; - _vals = (T *)SQ_REALLOC( - _vals, _allocated * sizeof(T), newsize * sizeof(T)); - _allocated = newsize; - } - SQUnsignedInteger _size; - SQUnsignedInteger _allocated; -}; - -#endif //_SQUTILS_H_ diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqvm.cpp b/src/modules/app_sqlang/squirrel/squirrel/sqvm.cpp deleted file mode 100644 index 3f2cdb200..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqvm.cpp +++ /dev/null @@ -1,1804 +0,0 @@ -/* - see copyright notice in squirrel.h -*/ -#include "sqpcheader.h" -#include -#include -#include "sqopcodes.h" -#include "sqvm.h" -#include "sqfuncproto.h" -#include "sqclosure.h" -#include "sqstring.h" -#include "sqtable.h" -#include "squserdata.h" -#include "sqarray.h" -#include "sqclass.h" - -#define TOP() (_stack._vals[_top-1]) -#define TARGET _stack._vals[_stackbase+arg0] -#define STK(a) _stack._vals[_stackbase+(a)] - -bool SQVM::BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2) -{ - SQInteger res; - if((sq_type(o1)| sq_type(o2)) == OT_INTEGER) - { - SQInteger i1 = _integer(o1), i2 = _integer(o2); - switch(op) { - case BW_AND: res = i1 & i2; break; - case BW_OR: res = i1 | i2; break; - case BW_XOR: res = i1 ^ i2; break; - case BW_SHIFTL: res = i1 << i2; break; - case BW_SHIFTR: res = i1 >> i2; break; - case BW_USHIFTR:res = (SQInteger)(*((SQUnsignedInteger*)&i1) >> i2); break; - default: { Raise_Error(_SC("internal vm error bitwise op failed")); return false; } - } - } - else { Raise_Error(_SC("bitwise op between '%s' and '%s'"),GetTypeName(o1),GetTypeName(o2)); return false;} - trg = res; - return true; -} - -#define _ARITH_(op,trg,o1,o2) \ -{ \ - SQInteger tmask = sq_type(o1)|sq_type(o2); \ - switch(tmask) { \ - case OT_INTEGER: trg = _integer(o1) op _integer(o2);break; \ - case (OT_FLOAT|OT_INTEGER): \ - case (OT_FLOAT): trg = tofloat(o1) op tofloat(o2); break;\ - default: _GUARD(ARITH_OP((#op)[0],trg,o1,o2)); break;\ - } \ -} - -#define _ARITH_NOZERO(op,trg,o1,o2,err) \ -{ \ - SQInteger tmask = sq_type(o1)|sq_type(o2); \ - switch(tmask) { \ - case OT_INTEGER: { SQInteger i2 = _integer(o2); if(i2 == 0) { Raise_Error(err); SQ_THROW(); } trg = _integer(o1) op i2; } break;\ - case (OT_FLOAT|OT_INTEGER): \ - case (OT_FLOAT): trg = tofloat(o1) op tofloat(o2); break;\ - default: _GUARD(ARITH_OP((#op)[0],trg,o1,o2)); break;\ - } \ -} - -bool SQVM::ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2) -{ - SQInteger tmask = sq_type(o1)| sq_type(o2); - switch(tmask) { - case OT_INTEGER:{ - SQInteger res, i1 = _integer(o1), i2 = _integer(o2); - switch(op) { - case '+': res = i1 + i2; break; - case '-': res = i1 - i2; break; - case '/': if (i2 == 0) { Raise_Error(_SC("division by zero")); return false; } - else if (i2 == -1 && i1 == INT_MIN) { Raise_Error(_SC("integer overflow")); return false; } - res = i1 / i2; - break; - case '*': res = i1 * i2; break; - case '%': if (i2 == 0) { Raise_Error(_SC("modulo by zero")); return false; } - else if (i2 == -1 && i1 == INT_MIN) { res = 0; break; } - res = i1 % i2; - break; - default: res = 0xDEADBEEF; - } - trg = res; } - break; - case (OT_FLOAT|OT_INTEGER): - case (OT_FLOAT):{ - SQFloat res, f1 = tofloat(o1), f2 = tofloat(o2); - switch(op) { - case '+': res = f1 + f2; break; - case '-': res = f1 - f2; break; - case '/': res = f1 / f2; break; - case '*': res = f1 * f2; break; - case '%': res = SQFloat(fmod((double)f1,(double)f2)); break; - default: res = 0x0f; - } - trg = res; } - break; - default: - if(op == '+' && (tmask & _RT_STRING)){ - if(!StringCat(o1, o2, trg)) return false; - } - else if(!ArithMetaMethod(op,o1,o2,trg)) { - return false; - } - } - return true; -} - -SQVM::SQVM(SQSharedState *ss) -{ - _sharedstate=ss; - _suspended = SQFalse; - _suspended_target = -1; - _suspended_root = SQFalse; - _suspended_traps = -1; - _foreignptr = NULL; - _nnativecalls = 0; - _nmetamethodscall = 0; - _lasterror.Null(); - _errorhandler.Null(); - _debughook = false; - _debughook_native = NULL; - _debughook_closure.Null(); - _openouters = NULL; - ci = NULL; - _releasehook = NULL; - INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); -} - -void SQVM::Finalize() -{ - if(_releasehook) { _releasehook(_foreignptr,0); _releasehook = NULL; } - if(_openouters) CloseOuters(&_stack._vals[0]); - _roottable.Null(); - _lasterror.Null(); - _errorhandler.Null(); - _debughook = false; - _debughook_native = NULL; - _debughook_closure.Null(); - temp_reg.Null(); - _callstackdata.resize(0); - SQInteger size=_stack.size(); - for(SQInteger i=0;i_gc_chain,this); -} - -bool SQVM::ArithMetaMethod(SQInteger op,const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &dest) -{ - SQMetaMethod mm; - switch(op){ - case _SC('+'): mm=MT_ADD; break; - case _SC('-'): mm=MT_SUB; break; - case _SC('/'): mm=MT_DIV; break; - case _SC('*'): mm=MT_MUL; break; - case _SC('%'): mm=MT_MODULO; break; - default: mm = MT_ADD; assert(0); break; //shutup compiler - } - if(is_delegable(o1) && _delegable(o1)->_delegate) { - - SQObjectPtr closure; - if(_delegable(o1)->GetMetaMethod(this, mm, closure)) { - Push(o1);Push(o2); - return CallMetaMethod(closure,mm,2,dest); - } - } - Raise_Error(_SC("arith op %c on between '%s' and '%s'"),op,GetTypeName(o1),GetTypeName(o2)); - return false; -} - -bool SQVM::NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o) -{ - - switch(sq_type(o)) { - case OT_INTEGER: - trg = -_integer(o); - return true; - case OT_FLOAT: - trg = -_float(o); - return true; - case OT_TABLE: - case OT_USERDATA: - case OT_INSTANCE: - if(_delegable(o)->_delegate) { - SQObjectPtr closure; - if(_delegable(o)->GetMetaMethod(this, MT_UNM, closure)) { - Push(o); - if(!CallMetaMethod(closure, MT_UNM, 1, temp_reg)) return false; - _Swap(trg,temp_reg); - return true; - - } - } - default:break; //shutup compiler - } - Raise_Error(_SC("attempt to negate a %s"), GetTypeName(o)); - return false; -} - -#define _RET_SUCCEED(exp) { result = (exp); return true; } -bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,SQInteger &result) -{ - SQObjectType t1 = sq_type(o1), t2 = sq_type(o2); - if(t1 == t2) { - if(_rawval(o1) == _rawval(o2))_RET_SUCCEED(0); - SQObjectPtr res; - switch(t1){ - case OT_STRING: - _RET_SUCCEED(scstrcmp(_stringval(o1),_stringval(o2))); - case OT_INTEGER: - _RET_SUCCEED((_integer(o1)<_integer(o2))?-1:1); - case OT_FLOAT: - _RET_SUCCEED((_float(o1)<_float(o2))?-1:1); - case OT_TABLE: - case OT_USERDATA: - case OT_INSTANCE: - if(_delegable(o1)->_delegate) { - SQObjectPtr closure; - if(_delegable(o1)->GetMetaMethod(this, MT_CMP, closure)) { - Push(o1);Push(o2); - if(CallMetaMethod(closure,MT_CMP,2,res)) { - if(sq_type(res) != OT_INTEGER) { - Raise_Error(_SC("_cmp must return an integer")); - return false; - } - _RET_SUCCEED(_integer(res)) - } - return false; - } - } - //continues through (no break needed) - default: - _RET_SUCCEED( _userpointer(o1) < _userpointer(o2)?-1:1 ); - } - assert(0); - //if(type(res)!=OT_INTEGER) { Raise_CompareError(o1,o2); return false; } - // _RET_SUCCEED(_integer(res)); - - } - else{ - if(sq_isnumeric(o1) && sq_isnumeric(o2)){ - if((t1==OT_INTEGER) && (t2==OT_FLOAT)) { - if( _integer(o1)==_float(o2) ) { _RET_SUCCEED(0); } - else if( _integer(o1)<_float(o2) ) { _RET_SUCCEED(-1); } - _RET_SUCCEED(1); - } - else{ - if( _float(o1)==_integer(o2) ) { _RET_SUCCEED(0); } - else if( _float(o1)<_integer(o2) ) { _RET_SUCCEED(-1); } - _RET_SUCCEED(1); - } - } - else if(t1==OT_NULL) {_RET_SUCCEED(-1);} - else if(t2==OT_NULL) {_RET_SUCCEED(1);} - else { Raise_CompareError(o1,o2); return false; } - - } - assert(0); - _RET_SUCCEED(0); //cannot happen -} - -bool SQVM::CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res) -{ - SQInteger r; - if(ObjCmp(o1,o2,r)) { - switch(op) { - case CMP_G: res = (r > 0); return true; - case CMP_GE: res = (r >= 0); return true; - case CMP_L: res = (r < 0); return true; - case CMP_LE: res = (r <= 0); return true; - case CMP_3W: res = r; return true; - } - assert(0); - } - return false; -} - -bool SQVM::ToString(const SQObjectPtr &o,SQObjectPtr &res) -{ - switch(sq_type(o)) { - case OT_STRING: - res = o; - return true; - case OT_FLOAT: - scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)),sq_rsl(NUMBER_MAX_CHAR),_SC("%g"),_float(o)); - break; - case OT_INTEGER: - scsprintf(_sp(sq_rsl(NUMBER_MAX_CHAR+1)),sq_rsl(NUMBER_MAX_CHAR),_PRINT_INT_FMT,_integer(o)); - break; - case OT_BOOL: - scsprintf(_sp(sq_rsl(6)),sq_rsl(6),_integer(o)?_SC("true"):_SC("false")); - break; - case OT_NULL: - scsprintf(_sp(sq_rsl(5)),sq_rsl(5),_SC("null")); - break; - case OT_TABLE: - case OT_USERDATA: - case OT_INSTANCE: - if(_delegable(o)->_delegate) { - SQObjectPtr closure; - if(_delegable(o)->GetMetaMethod(this, MT_TOSTRING, closure)) { - Push(o); - if(CallMetaMethod(closure,MT_TOSTRING,1,res)) { - if(sq_type(res) == OT_STRING) - return true; - } - else { - return false; - } - } - } - default: - scsprintf(_sp(sq_rsl((sizeof(void*)*2)+NUMBER_MAX_CHAR)),sq_rsl((sizeof(void*)*2)+NUMBER_MAX_CHAR),_SC("(%s : 0x%p)"),GetTypeName(o),(void*)_rawval(o)); - } - res = SQString::Create(_ss(this),_spval); - return true; -} - - -bool SQVM::StringCat(const SQObjectPtr &str,const SQObjectPtr &obj,SQObjectPtr &dest) -{ - SQObjectPtr a, b; - if(!ToString(str, a)) return false; - if(!ToString(obj, b)) return false; - SQInteger l = _string(a)->_len , ol = _string(b)->_len; - SQChar *s = _sp(sq_rsl(l + ol + 1)); - memcpy(s, _stringval(a), sq_rsl(l)); - memcpy(s + l, _stringval(b), sq_rsl(ol)); - dest = SQString::Create(_ss(this), _spval, l + ol); - return true; -} - -bool SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest) -{ - if(is_delegable(obj1) && _delegable(obj1)->_delegate) { - SQObjectPtr closure; - if(_delegable(obj1)->GetMetaMethod(this, MT_TYPEOF, closure)) { - Push(obj1); - return CallMetaMethod(closure,MT_TYPEOF,1,dest); - } - } - dest = SQString::Create(_ss(this),GetTypeName(obj1)); - return true; -} - -bool SQVM::Init(SQVM *friendvm, SQInteger stacksize) -{ - _stack.resize(stacksize); - _alloccallsstacksize = 4; - _callstackdata.resize(_alloccallsstacksize); - _callsstacksize = 0; - _callsstack = &_callstackdata[0]; - _stackbase = 0; - _top = 0; - if(!friendvm) { - _roottable = SQTable::Create(_ss(this), 0); - sq_base_register(this); - } - else { - _roottable = friendvm->_roottable; - _errorhandler = friendvm->_errorhandler; - _debughook = friendvm->_debughook; - _debughook_native = friendvm->_debughook_native; - _debughook_closure = friendvm->_debughook_closure; - } - - - return true; -} - - -bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger args,SQInteger stackbase,bool tailcall) -{ - SQFunctionProto *func = closure->_function; - - SQInteger paramssize = func->_nparameters; - const SQInteger newtop = stackbase + func->_stacksize; - SQInteger nargs = args; - if(func->_varparams) - { - paramssize--; - if (nargs < paramssize) { - Raise_Error(_SC("wrong number of parameters (%d passed, at least %d required)"), - (int)nargs, (int)paramssize); - return false; - } - - //dumpstack(stackbase); - SQInteger nvargs = nargs - paramssize; - SQArray *arr = SQArray::Create(_ss(this),nvargs); - SQInteger pbase = stackbase+paramssize; - for(SQInteger n = 0; n < nvargs; n++) { - arr->_values[n] = _stack._vals[pbase]; - _stack._vals[pbase].Null(); - pbase++; - - } - _stack._vals[stackbase+paramssize] = arr; - //dumpstack(stackbase); - } - else if (paramssize != nargs) { - SQInteger ndef = func->_ndefaultparams; - SQInteger diff; - if(ndef && nargs < paramssize && (diff = paramssize - nargs) <= ndef) { - for(SQInteger n = ndef - diff; n < ndef; n++) { - _stack._vals[stackbase + (nargs++)] = closure->_defaultparams[n]; - } - } - else { - Raise_Error(_SC("wrong number of parameters (%d passed, %d required)"), - (int)nargs, (int)paramssize); - return false; - } - } - - if(closure->_env) { - _stack._vals[stackbase] = closure->_env->_obj; - } - - if(!EnterFrame(stackbase, newtop, tailcall)) return false; - - ci->_closure = closure; - ci->_literals = func->_literals; - ci->_ip = func->_instructions; - ci->_target = (SQInt32)target; - - if (_debughook) { - CallDebugHook(_SC('c')); - } - - if (closure->_function->_bgenerator) { - SQFunctionProto *f = closure->_function; - SQGenerator *gen = SQGenerator::Create(_ss(this), closure); - if(!gen->Yield(this,f->_stacksize)) - return false; - SQObjectPtr temp; - Return(1, target, temp); - STK(target) = gen; - } - - - return true; -} - -bool SQVM::Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval) -{ - SQBool _isroot = ci->_root; - SQInteger callerbase = _stackbase - ci->_prevstkbase; - - if (_debughook) { - for(SQInteger i=0; i_ncalls; i++) { - CallDebugHook(_SC('r')); - } - } - - SQObjectPtr *dest; - if (_isroot) { - dest = &(retval); - } else if (ci->_target == -1) { - dest = NULL; - } else { - dest = &_stack._vals[callerbase + ci->_target]; - } - if (dest) { - if(_arg0 != 0xFF) { - *dest = _stack._vals[_stackbase+_arg1]; - } - else { - dest->Null(); - } - //*dest = (_arg0 != 0xFF) ? _stack._vals[_stackbase+_arg1] : _null_; - } - LeaveFrame(); - return _isroot ? true : false; -} - -#define _RET_ON_FAIL(exp) { if(!exp) return false; } - -bool SQVM::PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr) -{ - SQObjectPtr trg; - _RET_ON_FAIL(ARITH_OP( op , trg, a, incr)); - target = a; - a = trg; - return true; -} - -bool SQVM::DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix,SQInteger selfidx) -{ - SQObjectPtr tmp, tself = self, tkey = key; - if (!Get(tself, tkey, tmp, 0, selfidx)) { return false; } - _RET_ON_FAIL(ARITH_OP( op , target, tmp, incr)) - if (!Set(tself, tkey, target,selfidx)) { return false; } - if (postfix) target = tmp; - return true; -} - -#define arg0 (_i_._arg0) -#define sarg0 ((SQInteger)*((const signed char *)&_i_._arg0)) -#define arg1 (_i_._arg1) -#define sarg1 (*((const SQInt32 *)&_i_._arg1)) -#define arg2 (_i_._arg2) -#define arg3 (_i_._arg3) -#define sarg3 ((SQInteger)*((const signed char *)&_i_._arg3)) - -SQRESULT SQVM::Suspend() -{ - if (_suspended) - return sq_throwerror(this, _SC("cannot suspend an already suspended vm")); - if (_nnativecalls!=2) - return sq_throwerror(this, _SC("cannot suspend through native calls/metamethods")); - return SQ_SUSPEND_FLAG; -} - - -#define _FINISH(howmuchtojump) {jump = howmuchtojump; return true; } -bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr -&o3,SQObjectPtr &o4,SQInteger SQ_UNUSED_ARG(arg_2),int exitpos,int &jump) -{ - SQInteger nrefidx; - switch(sq_type(o1)) { - case OT_TABLE: - if((nrefidx = _table(o1)->Next(false,o4, o2, o3)) == -1) _FINISH(exitpos); - o4 = (SQInteger)nrefidx; _FINISH(1); - case OT_ARRAY: - if((nrefidx = _array(o1)->Next(o4, o2, o3)) == -1) _FINISH(exitpos); - o4 = (SQInteger) nrefidx; _FINISH(1); - case OT_STRING: - if((nrefidx = _string(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos); - o4 = (SQInteger)nrefidx; _FINISH(1); - case OT_CLASS: - if((nrefidx = _class(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos); - o4 = (SQInteger)nrefidx; _FINISH(1); - case OT_USERDATA: - case OT_INSTANCE: - if(_delegable(o1)->_delegate) { - SQObjectPtr itr; - SQObjectPtr closure; - if(_delegable(o1)->GetMetaMethod(this, MT_NEXTI, closure)) { - Push(o1); - Push(o4); - if(CallMetaMethod(closure, MT_NEXTI, 2, itr)) { - o4 = o2 = itr; - if(sq_type(itr) == OT_NULL) _FINISH(exitpos); - if(!Get(o1, itr, o3, 0, DONT_FALL_BACK)) { - Raise_Error(_SC("_nexti returned an invalid idx")); // cloud be changed - return false; - } - _FINISH(1); - } - else { - return false; - } - } - Raise_Error(_SC("_nexti failed")); - return false; - } - break; - case OT_GENERATOR: - if(_generator(o1)->_state == SQGenerator::eDead) _FINISH(exitpos); - if(_generator(o1)->_state == SQGenerator::eSuspended) { - SQInteger idx = 0; - if(sq_type(o4) == OT_INTEGER) { - idx = _integer(o4) + 1; - } - o2 = idx; - o4 = idx; - _generator(o1)->Resume(this, o3); - _FINISH(0); - } - default: - Raise_Error(_SC("cannot iterate %s"), GetTypeName(o1)); - } - return false; //cannot be hit(just to avoid warnings) -} - -#define COND_LITERAL (arg3!=0?ci->_literals[arg1]:STK(arg1)) - -#define SQ_THROW() { goto exception_trap; } - -#define _GUARD(exp) { if(!exp) { SQ_THROW();} } - -bool SQVM::CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func,SQInteger boundtarget) -{ - SQInteger nouters; - SQClosure *closure = SQClosure::Create(_ss(this), func,_table(_roottable)->GetWeakRef(OT_TABLE)); - if((nouters = func->_noutervalues)) { - for(SQInteger i = 0; i_outervalues[i]; - switch(v._type){ - case otLOCAL: - FindOuter(closure->_outervalues[i], &STK(_integer(v._src))); - break; - case otOUTER: - closure->_outervalues[i] = _closure(ci->_closure)->_outervalues[_integer(v._src)]; - break; - } - } - } - SQInteger ndefparams; - if((ndefparams = func->_ndefaultparams)) { - for(SQInteger i = 0; i < ndefparams; i++) { - SQInteger spos = func->_defaultparams[i]; - closure->_defaultparams[i] = _stack._vals[_stackbase + spos]; - } - } - if (boundtarget != 0xFF) { - SQObjectPtr &val = _stack._vals[_stackbase + boundtarget]; - SQObjectType t = sq_type(val); - if (t == OT_TABLE || t == OT_CLASS || t == OT_INSTANCE || t == OT_ARRAY) { - closure->_env = _refcounted(val)->GetWeakRef(t); - __ObjAddRef(closure->_env); - } - else { - Raise_Error(_SC("cannot bind a %s as environment object"), IdType2Name(t)); - closure->Release(); - return false; - } - } - target = closure; - return true; - -} - - -bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes) -{ - SQClass *base = NULL; - SQObjectPtr attrs; - if(baseclass != -1) { - if(sq_type(_stack._vals[_stackbase+baseclass]) != OT_CLASS) { Raise_Error(_SC("trying to inherit from a %s"),GetTypeName(_stack._vals[_stackbase+baseclass])); return false; } - base = _class(_stack._vals[_stackbase + baseclass]); - } - if(attributes != MAX_FUNC_STACKSIZE) { - attrs = _stack._vals[_stackbase+attributes]; - } - target = SQClass::Create(_ss(this),base); - if(sq_type(_class(target)->_metamethods[MT_INHERITED]) != OT_NULL) { - int nparams = 2; - SQObjectPtr ret; - Push(target); Push(attrs); - if(!Call(_class(target)->_metamethods[MT_INHERITED],nparams,_top - nparams, ret, false)) { - Pop(nparams); - return false; - } - Pop(nparams); - } - _class(target)->_attributes = attrs; - return true; -} - -bool SQVM::IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2,bool &res) -{ - SQObjectType t1 = sq_type(o1), t2 = sq_type(o2); - if(t1 == t2) { - if (t1 == OT_FLOAT) { - res = (_float(o1) == _float(o2)); - } - else { - res = (_rawval(o1) == _rawval(o2)); - } - } - else { - if(sq_isnumeric(o1) && sq_isnumeric(o2)) { - res = (tofloat(o1) == tofloat(o2)); - } - else { - res = false; - } - } - return true; -} - -bool SQVM::IsFalse(SQObjectPtr &o) -{ - if(((sq_type(o) & SQOBJECT_CANBEFALSE) - && ( ((sq_type(o) == OT_FLOAT) && (_float(o) == SQFloat(0.0))) )) -#if !defined(SQUSEDOUBLE) || (defined(SQUSEDOUBLE) && defined(_SQ64)) - || (_integer(o) == 0) ) //OT_NULL|OT_INTEGER|OT_BOOL -#else - || (((sq_type(o) != OT_FLOAT) && (_integer(o) == 0))) ) //OT_NULL|OT_INTEGER|OT_BOOL -#endif - { - return true; - } - return false; -} -extern SQInstructionDesc g_InstrDesc[]; -bool SQVM::Execute(SQObjectPtr &closure, SQInteger nargs, SQInteger stackbase,SQObjectPtr &outres, SQBool raiseerror,ExecutionType et) -{ - if ((_nnativecalls + 1) > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; } - _nnativecalls++; - AutoDec ad(&_nnativecalls); - SQInteger traps = 0; - CallInfo *prevci = ci; - - switch(et) { - case ET_CALL: { - temp_reg = closure; - if(!StartCall(_closure(temp_reg), _top - nargs, nargs, stackbase, false)) { - //call the handler if there are no calls in the stack, if not relies on the previous node - if(ci == NULL) CallErrorHandler(_lasterror); - return false; - } - if(ci == prevci) { - outres = STK(_top-nargs); - return true; - } - ci->_root = SQTrue; - } - break; - case ET_RESUME_GENERATOR: _generator(closure)->Resume(this, outres); ci->_root = SQTrue; traps += ci->_etraps; break; - case ET_RESUME_VM: - case ET_RESUME_THROW_VM: - traps = _suspended_traps; - ci->_root = _suspended_root; - _suspended = SQFalse; - if(et == ET_RESUME_THROW_VM) { SQ_THROW(); } - break; - } - -exception_restore: - // - { - for(;;) - { - const SQInstruction &_i_ = *ci->_ip++; - //dumpstack(_stackbase); - //scprintf("\n[%d] %s %d %d %d %d\n",ci->_ip-_closure(ci->_closure)->_function->_instructions,g_InstrDesc[_i_.op].name,arg0,arg1,arg2,arg3); - switch(_i_.op) - { - case _OP_LINE: if (_debughook) CallDebugHook(_SC('l'),arg1); continue; - case _OP_LOAD: TARGET = ci->_literals[arg1]; continue; - case _OP_LOADINT: -#ifndef _SQ64 - TARGET = (SQInteger)arg1; continue; -#else - TARGET = (SQInteger)((SQInt32)arg1); continue; -#endif - case _OP_LOADFLOAT: TARGET = *((const SQFloat *)&arg1); continue; - case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue; - case _OP_TAILCALL:{ - SQObjectPtr &t = STK(arg1); - if (sq_type(t) == OT_CLOSURE - && (!_closure(t)->_function->_bgenerator)){ - SQObjectPtr clo = t; - SQInteger last_top = _top; - if(_openouters) CloseOuters(&(_stack._vals[_stackbase])); - for (SQInteger i = 0; i < arg3; i++) STK(i) = STK(arg2 + i); - _GUARD(StartCall(_closure(clo), ci->_target, arg3, _stackbase, true)); - if (last_top >= _top) { - _top = last_top; - } - continue; - } - } - case _OP_CALL: { - SQObjectPtr clo = STK(arg1); - switch (sq_type(clo)) { - case OT_CLOSURE: - _GUARD(StartCall(_closure(clo), sarg0, arg3, _stackbase+arg2, false)); - continue; - case OT_NATIVECLOSURE: { - bool suspend; - bool tailcall; - _GUARD(CallNative(_nativeclosure(clo), arg3, _stackbase+arg2, clo, (SQInt32)sarg0, suspend, tailcall)); - if(suspend){ - _suspended = SQTrue; - _suspended_target = sarg0; - _suspended_root = ci->_root; - _suspended_traps = traps; - outres = clo; - return true; - } - if(sarg0 != -1 && !tailcall) { - STK(arg0) = clo; - } - } - continue; - case OT_CLASS:{ - SQObjectPtr inst; - _GUARD(CreateClassInstance(_class(clo),inst,clo)); - if(sarg0 != -1) { - STK(arg0) = inst; - } - SQInteger stkbase; - switch(sq_type(clo)) { - case OT_CLOSURE: - stkbase = _stackbase+arg2; - _stack._vals[stkbase] = inst; - _GUARD(StartCall(_closure(clo), -1, arg3, stkbase, false)); - break; - case OT_NATIVECLOSURE: - bool dummy; - stkbase = _stackbase+arg2; - _stack._vals[stkbase] = inst; - _GUARD(CallNative(_nativeclosure(clo), arg3, stkbase, clo, -1, dummy, dummy)); - break; - default: break; //shutup GCC 4.x - } - } - break; - case OT_TABLE: - case OT_USERDATA: - case OT_INSTANCE:{ - SQObjectPtr closure; - if(_delegable(clo)->_delegate && _delegable(clo)->GetMetaMethod(this,MT_CALL,closure)) { - Push(clo); - for (SQInteger i = 0; i < arg3; i++) Push(STK(arg2 + i)); - if(!CallMetaMethod(closure, MT_CALL, arg3+1, clo)) SQ_THROW(); - if(sarg0 != -1) { - STK(arg0) = clo; - } - break; - } - - //Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo)); - //SQ_THROW(); - } - default: - Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo)); - SQ_THROW(); - } - } - continue; - case _OP_PREPCALL: - case _OP_PREPCALLK: { - SQObjectPtr &key = _i_.op == _OP_PREPCALLK?(ci->_literals)[arg1]:STK(arg1); - SQObjectPtr &o = STK(arg2); - if (!Get(o, key, temp_reg,0,arg2)) { - SQ_THROW(); - } - STK(arg3) = o; - _Swap(TARGET,temp_reg);//TARGET = temp_reg; - } - continue; - case _OP_GETK: - if (!Get(STK(arg2), ci->_literals[arg1], temp_reg, 0,arg2)) { SQ_THROW();} - _Swap(TARGET,temp_reg);//TARGET = temp_reg; - continue; - case _OP_MOVE: TARGET = STK(arg1); continue; - case _OP_NEWSLOT: - _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),false)); - if(arg0 != 0xFF) TARGET = STK(arg3); - continue; - case _OP_DELETE: _GUARD(DeleteSlot(STK(arg1), STK(arg2), TARGET)); continue; - case _OP_SET: - if (!Set(STK(arg1), STK(arg2), STK(arg3),arg1)) { SQ_THROW(); } - if (arg0 != 0xFF) TARGET = STK(arg3); - continue; - case _OP_GET: - if (!Get(STK(arg1), STK(arg2), temp_reg, 0,arg1)) { SQ_THROW(); } - _Swap(TARGET,temp_reg);//TARGET = temp_reg; - continue; - case _OP_EQ:{ - bool res; - if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); } - TARGET = res?true:false; - }continue; - case _OP_NE:{ - bool res; - if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); } - TARGET = (!res)?true:false; - } continue; - case _OP_ADD: _ARITH_(+,TARGET,STK(arg2),STK(arg1)); continue; - case _OP_SUB: _ARITH_(-,TARGET,STK(arg2),STK(arg1)); continue; - case _OP_MUL: _ARITH_(*,TARGET,STK(arg2),STK(arg1)); continue; - case _OP_DIV: _ARITH_NOZERO(/,TARGET,STK(arg2),STK(arg1),_SC("division by zero")); continue; - case _OP_MOD: ARITH_OP('%',TARGET,STK(arg2),STK(arg1)); continue; - case _OP_BITW: _GUARD(BW_OP( arg3,TARGET,STK(arg2),STK(arg1))); continue; - case _OP_RETURN: - if((ci)->_generator) { - (ci)->_generator->Kill(); - } - if(Return(arg0, arg1, temp_reg)){ - assert(traps==0); - //outres = temp_reg; - _Swap(outres,temp_reg); - return true; - } - continue; - case _OP_LOADNULLS:{ for(SQInt32 n=0; n < arg1; n++) STK(arg0+n).Null(); }continue; - case _OP_LOADROOT: { - SQWeakRef *w = _closure(ci->_closure)->_root; - if(sq_type(w->_obj) != OT_NULL) { - TARGET = w->_obj; - } else { - TARGET = _roottable; //shoud this be like this? or null - } - } - continue; - case _OP_LOADBOOL: TARGET = arg1?true:false; continue; - case _OP_DMOVE: STK(arg0) = STK(arg1); STK(arg2) = STK(arg3); continue; - case _OP_JMP: ci->_ip += (sarg1); continue; - //case _OP_JNZ: if(!IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue; - case _OP_JCMP: - _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg0),temp_reg)); - if(IsFalse(temp_reg)) ci->_ip+=(sarg1); - continue; - case _OP_JZ: if(IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue; - case _OP_GETOUTER: { - SQClosure *cur_cls = _closure(ci->_closure); - SQOuter *otr = _outer(cur_cls->_outervalues[arg1]); - TARGET = *(otr->_valptr); - } - continue; - case _OP_SETOUTER: { - SQClosure *cur_cls = _closure(ci->_closure); - SQOuter *otr = _outer(cur_cls->_outervalues[arg1]); - *(otr->_valptr) = STK(arg2); - if(arg0 != 0xFF) { - TARGET = STK(arg2); - } - } - continue; - case _OP_NEWOBJ: - switch(arg3) { - case NOT_TABLE: TARGET = SQTable::Create(_ss(this), arg1); continue; - case NOT_ARRAY: TARGET = SQArray::Create(_ss(this), 0); _array(TARGET)->Reserve(arg1); continue; - case NOT_CLASS: _GUARD(CLASS_OP(TARGET,arg1,arg2)); continue; - default: assert(0); continue; - } - case _OP_APPENDARRAY: - { - SQObject val; - val._unVal.raw = 0; - switch(arg2) { - case AAT_STACK: - val = STK(arg1); break; - case AAT_LITERAL: - val = ci->_literals[arg1]; break; - case AAT_INT: - val._type = OT_INTEGER; -#ifndef _SQ64 - val._unVal.nInteger = (SQInteger)arg1; -#else - val._unVal.nInteger = (SQInteger)((SQInt32)arg1); -#endif - break; - case AAT_FLOAT: - val._type = OT_FLOAT; - val._unVal.fFloat = *((const SQFloat *)&arg1); - break; - case AAT_BOOL: - val._type = OT_BOOL; - val._unVal.nInteger = arg1; - break; - default: val._type = OT_INTEGER; assert(0); break; - - } - _array(STK(arg0))->Append(val); continue; - } - case _OP_COMPARITH: { - SQInteger selfidx = (((SQUnsignedInteger)arg1&0xFFFF0000)>>16); - _GUARD(DerefInc(arg3, TARGET, STK(selfidx), STK(arg2), STK(arg1&0x0000FFFF), false, selfidx)); - } - continue; - case _OP_INC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, false, arg1));} continue; - case _OP_INCL: { - SQObjectPtr &a = STK(arg1); - if(sq_type(a) == OT_INTEGER) { - a._unVal.nInteger = _integer(a) + sarg3; - } - else { - SQObjectPtr o(sarg3); //_GUARD(LOCAL_INC('+',TARGET, STK(arg1), o)); - _ARITH_(+,a,a,o); - } - } continue; - case _OP_PINC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, true, arg1));} continue; - case _OP_PINCL: { - SQObjectPtr &a = STK(arg1); - if(sq_type(a) == OT_INTEGER) { - TARGET = a; - a._unVal.nInteger = _integer(a) + sarg3; - } - else { - SQObjectPtr o(sarg3); _GUARD(PLOCAL_INC('+',TARGET, STK(arg1), o)); - } - - } continue; - case _OP_CMP: _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg1),TARGET)) continue; - case _OP_EXISTS: TARGET = Get(STK(arg1), STK(arg2), temp_reg, GET_FLAG_DO_NOT_RAISE_ERROR | GET_FLAG_RAW, DONT_FALL_BACK) ? true : false; continue; - case _OP_INSTANCEOF: - if(sq_type(STK(arg1)) != OT_CLASS) - {Raise_Error(_SC("cannot apply instanceof between a %s and a %s"),GetTypeName(STK(arg1)),GetTypeName(STK(arg2))); SQ_THROW();} - TARGET = (sq_type(STK(arg2)) == OT_INSTANCE) ? (_instance(STK(arg2))->InstanceOf(_class(STK(arg1)))?true:false) : false; - continue; - case _OP_AND: - if(IsFalse(STK(arg2))) { - TARGET = STK(arg2); - ci->_ip += (sarg1); - } - continue; - case _OP_OR: - if(!IsFalse(STK(arg2))) { - TARGET = STK(arg2); - ci->_ip += (sarg1); - } - continue; - case _OP_NEG: _GUARD(NEG_OP(TARGET,STK(arg1))); continue; - case _OP_NOT: TARGET = IsFalse(STK(arg1)); continue; - case _OP_BWNOT: - if(sq_type(STK(arg1)) == OT_INTEGER) { - SQInteger t = _integer(STK(arg1)); - TARGET = SQInteger(~t); - continue; - } - Raise_Error(_SC("attempt to perform a bitwise op on a %s"), GetTypeName(STK(arg1))); - SQ_THROW(); - case _OP_CLOSURE: { - SQClosure *c = ci->_closure._unVal.pClosure; - SQFunctionProto *fp = c->_function; - if(!CLOSURE_OP(TARGET,fp->_functions[arg1]._unVal.pFunctionProto,arg2)) { SQ_THROW(); } - continue; - } - case _OP_YIELD:{ - if(ci->_generator) { - if(sarg1 != MAX_FUNC_STACKSIZE) temp_reg = STK(arg1); - if (_openouters) CloseOuters(&_stack._vals[_stackbase]); - _GUARD(ci->_generator->Yield(this,arg2)); - traps -= ci->_etraps; - if(sarg1 != MAX_FUNC_STACKSIZE) _Swap(STK(arg1),temp_reg);//STK(arg1) = temp_reg; - } - else { Raise_Error(_SC("trying to yield a '%s', only generator can be yielded"), GetTypeName(ci->_generator)); SQ_THROW();} - if(Return(arg0, arg1, temp_reg)){ - assert(traps == 0); - outres = temp_reg; - return true; - } - - } - continue; - case _OP_RESUME: - if(sq_type(STK(arg1)) != OT_GENERATOR){ Raise_Error(_SC("trying to resume a '%s', only generator can be resumed"), GetTypeName(STK(arg1))); SQ_THROW();} - _GUARD(_generator(STK(arg1))->Resume(this, TARGET)); - traps += ci->_etraps; - continue; - case _OP_FOREACH:{ int tojump; - _GUARD(FOREACH_OP(STK(arg0),STK(arg2),STK(arg2+1),STK(arg2+2),arg2,sarg1,tojump)); - ci->_ip += tojump; } - continue; - case _OP_POSTFOREACH: - assert(sq_type(STK(arg0)) == OT_GENERATOR); - if(_generator(STK(arg0))->_state == SQGenerator::eDead) - ci->_ip += (sarg1 - 1); - continue; - case _OP_CLONE: _GUARD(Clone(STK(arg1), TARGET)); continue; - case _OP_TYPEOF: _GUARD(TypeOf(STK(arg1), TARGET)) continue; - case _OP_PUSHTRAP:{ - SQInstruction *_iv = _closure(ci->_closure)->_function->_instructions; - _etraps.push_back(SQExceptionTrap(_top,_stackbase, &_iv[(ci->_ip-_iv)+arg1], arg0)); traps++; - ci->_etraps++; - } - continue; - case _OP_POPTRAP: { - for(SQInteger i = 0; i < arg0; i++) { - _etraps.pop_back(); traps--; - ci->_etraps--; - } - } - continue; - case _OP_THROW: Raise_Error(TARGET); SQ_THROW(); continue; - case _OP_NEWSLOTA: - _GUARD(NewSlotA(STK(arg1),STK(arg2),STK(arg3),(arg0&NEW_SLOT_ATTRIBUTES_FLAG) ? STK(arg2-1) : SQObjectPtr(),(arg0&NEW_SLOT_STATIC_FLAG)?true:false,false)); - continue; - case _OP_GETBASE:{ - SQClosure *clo = _closure(ci->_closure); - if(clo->_base) { - TARGET = clo->_base; - } - else { - TARGET.Null(); - } - continue; - } - case _OP_CLOSE: - if(_openouters) CloseOuters(&(STK(arg1))); - continue; - } - - } - } -exception_trap: - { - SQObjectPtr currerror = _lasterror; -// dumpstack(_stackbase); -// SQInteger n = 0; - SQInteger last_top = _top; - - if(_ss(this)->_notifyallexceptions || (!traps && raiseerror)) CallErrorHandler(currerror); - - while( ci ) { - if(ci->_etraps > 0) { - SQExceptionTrap &et = _etraps.top(); - ci->_ip = et._ip; - _top = et._stacksize; - _stackbase = et._stackbase; - _stack._vals[_stackbase + et._extarget] = currerror; - _etraps.pop_back(); traps--; ci->_etraps--; - while(last_top >= _top) _stack._vals[last_top--].Null(); - goto exception_restore; - } - else if (_debughook) { - //notify debugger of a "return" - //even if it really an exception unwinding the stack - for(SQInteger i = 0; i < ci->_ncalls; i++) { - CallDebugHook(_SC('r')); - } - } - if(ci->_generator) ci->_generator->Kill(); - bool mustbreak = ci && ci->_root; - LeaveFrame(); - if(mustbreak) break; - } - - _lasterror = currerror; - return false; - } - assert(0); -} - -bool SQVM::CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor) -{ - inst = theclass->CreateInstance(); - if(!theclass->GetConstructor(constructor)) { - constructor.Null(); - } - return true; -} - -void SQVM::CallErrorHandler(SQObjectPtr &error) -{ - if(sq_type(_errorhandler) != OT_NULL) { - SQObjectPtr out; - Push(_roottable); Push(error); - Call(_errorhandler, 2, _top-2, out,SQFalse); - Pop(2); - } -} - - -void SQVM::CallDebugHook(SQInteger type,SQInteger forcedline) -{ - _debughook = false; - SQFunctionProto *func=_closure(ci->_closure)->_function; - if(_debughook_native) { - const SQChar *src = sq_type(func->_sourcename) == OT_STRING?_stringval(func->_sourcename):NULL; - const SQChar *fname = sq_type(func->_name) == OT_STRING?_stringval(func->_name):NULL; - SQInteger line = forcedline?forcedline:func->GetLine(ci->_ip); - _debughook_native(this,type,src,line,fname); - } - else { - SQObjectPtr temp_reg; - SQInteger nparams=5; - Push(_roottable); Push(type); Push(func->_sourcename); Push(forcedline?forcedline:func->GetLine(ci->_ip)); Push(func->_name); - Call(_debughook_closure,nparams,_top-nparams,temp_reg,SQFalse); - Pop(nparams); - } - _debughook = true; -} - -bool SQVM::CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger newbase, SQObjectPtr &retval, SQInt32 target,bool &suspend, bool &tailcall) -{ - SQInteger nparamscheck = nclosure->_nparamscheck; - SQInteger newtop = newbase + nargs + nclosure->_noutervalues; - - if (_nnativecalls + 1 > MAX_NATIVE_CALLS) { - Raise_Error(_SC("Native stack overflow")); - return false; - } - - if(nparamscheck && (((nparamscheck > 0) && (nparamscheck != nargs)) || - ((nparamscheck < 0) && (nargs < (-nparamscheck))))) - { - Raise_Error(_SC("wrong number of parameters")); - return false; - } - - SQInteger tcs; - SQIntVec &tc = nclosure->_typecheck; - if((tcs = tc.size())) { - for(SQInteger i = 0; i < nargs && i < tcs; i++) { - if((tc._vals[i] != -1) && !(sq_type(_stack._vals[newbase+i]) & tc._vals[i])) { - Raise_ParamTypeError(i,tc._vals[i], sq_type(_stack._vals[newbase+i])); - return false; - } - } - } - - if(!EnterFrame(newbase, newtop, false)) return false; - ci->_closure = nclosure; - ci->_target = target; - - SQInteger outers = nclosure->_noutervalues; - for (SQInteger i = 0; i < outers; i++) { - _stack._vals[newbase+nargs+i] = nclosure->_outervalues[i]; - } - if(nclosure->_env) { - _stack._vals[newbase] = nclosure->_env->_obj; - } - - _nnativecalls++; - SQInteger ret = (nclosure->_function)(this); - _nnativecalls--; - - suspend = false; - tailcall = false; - if (ret == SQ_TAILCALL_FLAG) { - tailcall = true; - return true; - } - else if (ret == SQ_SUSPEND_FLAG) { - suspend = true; - } - else if (ret < 0) { - LeaveFrame(); - Raise_Error(_lasterror); - return false; - } - if(ret) { - retval = _stack._vals[_top-1]; - } - else { - retval.Null(); - } - //retval = ret ? _stack._vals[_top-1] : _null_; - LeaveFrame(); - return true; -} - -bool SQVM::TailCall(SQClosure *closure, SQInteger parambase,SQInteger nparams) -{ - SQInteger last_top = _top; - SQObjectPtr clo = closure; - if (ci->_root) - { - Raise_Error("root calls cannot invoke tailcalls"); - return false; - } - for (SQInteger i = 0; i < nparams; i++) STK(i) = STK(parambase + i); - bool ret = StartCall(closure, ci->_target, nparams, _stackbase, true); - if (last_top >= _top) { - _top = last_top; - } - return ret; -} - -#define FALLBACK_OK 0 -#define FALLBACK_NO_MATCH 1 -#define FALLBACK_ERROR 2 - -bool SQVM::Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, SQUnsignedInteger getflags, SQInteger selfidx) -{ - switch(sq_type(self)){ - case OT_TABLE: - if(_table(self)->Get(key,dest))return true; - break; - case OT_ARRAY: - if (sq_isnumeric(key)) { if (_array(self)->Get(tointeger(key), dest)) { return true; } if ((getflags & GET_FLAG_DO_NOT_RAISE_ERROR) == 0) Raise_IdxError(key); return false; } - break; - case OT_INSTANCE: - if(_instance(self)->Get(key,dest)) return true; - break; - case OT_CLASS: - if(_class(self)->Get(key,dest)) return true; - break; - case OT_STRING: - if(sq_isnumeric(key)){ - SQInteger n = tointeger(key); - SQInteger len = _string(self)->_len; - if (n < 0) { n += len; } - if (n >= 0 && n < len) { - dest = SQInteger(_stringval(self)[n]); - return true; - } - if ((getflags & GET_FLAG_DO_NOT_RAISE_ERROR) == 0) Raise_IdxError(key); - return false; - } - break; - default:break; //shut up compiler - } - if ((getflags & GET_FLAG_RAW) == 0) { - switch(FallBackGet(self,key,dest)) { - case FALLBACK_OK: return true; //okie - case FALLBACK_NO_MATCH: break; //keep falling back - case FALLBACK_ERROR: return false; // the metamethod failed - } - if(InvokeDefaultDelegate(self,key,dest)) { - return true; - } - } -//#ifdef ROOT_FALLBACK - if(selfidx == 0) { - SQWeakRef *w = _closure(ci->_closure)->_root; - if(sq_type(w->_obj) != OT_NULL) - { - if(Get(*((const SQObjectPtr *)&w->_obj),key,dest,0,DONT_FALL_BACK)) return true; - } - - } -//#endif - if ((getflags & GET_FLAG_DO_NOT_RAISE_ERROR) == 0) Raise_IdxError(key); - return false; -} - -bool SQVM::InvokeDefaultDelegate(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest) -{ - SQTable *ddel = NULL; - switch(sq_type(self)) { - case OT_CLASS: ddel = _class_ddel; break; - case OT_TABLE: ddel = _table_ddel; break; - case OT_ARRAY: ddel = _array_ddel; break; - case OT_STRING: ddel = _string_ddel; break; - case OT_INSTANCE: ddel = _instance_ddel; break; - case OT_INTEGER:case OT_FLOAT:case OT_BOOL: ddel = _number_ddel; break; - case OT_GENERATOR: ddel = _generator_ddel; break; - case OT_CLOSURE: case OT_NATIVECLOSURE: ddel = _closure_ddel; break; - case OT_THREAD: ddel = _thread_ddel; break; - case OT_WEAKREF: ddel = _weakref_ddel; break; - default: return false; - } - return ddel->Get(key,dest); -} - - -SQInteger SQVM::FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest) -{ - switch(sq_type(self)){ - case OT_TABLE: - case OT_USERDATA: - //delegation - if(_delegable(self)->_delegate) { - if(Get(SQObjectPtr(_delegable(self)->_delegate),key,dest, GET_FLAG_DO_NOT_RAISE_ERROR,DONT_FALL_BACK)) return FALLBACK_OK; - } - else { - return FALLBACK_NO_MATCH; - } - //go through - case OT_INSTANCE: { - SQObjectPtr closure; - if(_delegable(self)->GetMetaMethod(this, MT_GET, closure)) { - Push(self);Push(key); - _nmetamethodscall++; - AutoDec ad(&_nmetamethodscall); - if(Call(closure, 2, _top - 2, dest, SQFalse)) { - Pop(2); - return FALLBACK_OK; - } - else { - Pop(2); - if(sq_type(_lasterror) != OT_NULL) { //NULL means "clean failure" (not found) - return FALLBACK_ERROR; - } - } - } - } - break; - default: break;//shutup GCC 4.x - } - // no metamethod or no fallback type - return FALLBACK_NO_MATCH; -} - -bool SQVM::Set(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,SQInteger selfidx) -{ - switch(sq_type(self)){ - case OT_TABLE: - if(_table(self)->Set(key,val)) return true; - break; - case OT_INSTANCE: - if(_instance(self)->Set(key,val)) return true; - break; - case OT_ARRAY: - if(!sq_isnumeric(key)) { Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); return false; } - if(!_array(self)->Set(tointeger(key),val)) { - Raise_IdxError(key); - return false; - } - return true; - case OT_USERDATA: break; // must fall back - default: - Raise_Error(_SC("trying to set '%s'"),GetTypeName(self)); - return false; - } - - switch(FallBackSet(self,key,val)) { - case FALLBACK_OK: return true; //okie - case FALLBACK_NO_MATCH: break; //keep falling back - case FALLBACK_ERROR: return false; // the metamethod failed - } - if(selfidx == 0) { - if(_table(_roottable)->Set(key,val)) - return true; - } - Raise_IdxError(key); - return false; -} - -SQInteger SQVM::FallBackSet(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val) -{ - switch(sq_type(self)) { - case OT_TABLE: - if(_table(self)->_delegate) { - if(Set(_table(self)->_delegate,key,val,DONT_FALL_BACK)) return FALLBACK_OK; - } - //keeps on going - case OT_INSTANCE: - case OT_USERDATA:{ - SQObjectPtr closure; - SQObjectPtr t; - if(_delegable(self)->GetMetaMethod(this, MT_SET, closure)) { - Push(self);Push(key);Push(val); - _nmetamethodscall++; - AutoDec ad(&_nmetamethodscall); - if(Call(closure, 3, _top - 3, t, SQFalse)) { - Pop(3); - return FALLBACK_OK; - } - else { - Pop(3); - if(sq_type(_lasterror) != OT_NULL) { //NULL means "clean failure" (not found) - return FALLBACK_ERROR; - } - } - } - } - break; - default: break;//shutup GCC 4.x - } - // no metamethod or no fallback type - return FALLBACK_NO_MATCH; -} - -bool SQVM::Clone(const SQObjectPtr &self,SQObjectPtr &target) -{ - SQObjectPtr temp_reg; - SQObjectPtr newobj; - switch(sq_type(self)){ - case OT_TABLE: - newobj = _table(self)->Clone(); - goto cloned_mt; - case OT_INSTANCE: { - newobj = _instance(self)->Clone(_ss(this)); -cloned_mt: - SQObjectPtr closure; - if(_delegable(newobj)->_delegate && _delegable(newobj)->GetMetaMethod(this,MT_CLONED,closure)) { - Push(newobj); - Push(self); - if(!CallMetaMethod(closure,MT_CLONED,2,temp_reg)) - return false; - } - } - target = newobj; - return true; - case OT_ARRAY: - target = _array(self)->Clone(); - return true; - default: - Raise_Error(_SC("cloning a %s"), GetTypeName(self)); - return false; - } -} - -bool SQVM::NewSlotA(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,const SQObjectPtr &attrs,bool bstatic,bool raw) -{ - if(sq_type(self) != OT_CLASS) { - Raise_Error(_SC("object must be a class")); - return false; - } - SQClass *c = _class(self); - if(!raw) { - SQObjectPtr &mm = c->_metamethods[MT_NEWMEMBER]; - if(sq_type(mm) != OT_NULL ) { - Push(self); Push(key); Push(val); - Push(attrs); - Push(bstatic); - return CallMetaMethod(mm,MT_NEWMEMBER,5,temp_reg); - } - } - if(!NewSlot(self, key, val,bstatic)) - return false; - if(sq_type(attrs) != OT_NULL) { - c->SetAttributes(key,attrs); - } - return true; -} - -bool SQVM::NewSlot(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic) -{ - if(sq_type(key) == OT_NULL) { Raise_Error(_SC("null cannot be used as index")); return false; } - switch(sq_type(self)) { - case OT_TABLE: { - bool rawcall = true; - if(_table(self)->_delegate) { - SQObjectPtr res; - if(!_table(self)->Get(key,res)) { - SQObjectPtr closure; - if(_delegable(self)->_delegate && _delegable(self)->GetMetaMethod(this,MT_NEWSLOT,closure)) { - Push(self);Push(key);Push(val); - if(!CallMetaMethod(closure,MT_NEWSLOT,3,res)) { - return false; - } - rawcall = false; - } - else { - rawcall = true; - } - } - } - if(rawcall) _table(self)->NewSlot(key,val); //cannot fail - - break;} - case OT_INSTANCE: { - SQObjectPtr res; - SQObjectPtr closure; - if(_delegable(self)->_delegate && _delegable(self)->GetMetaMethod(this,MT_NEWSLOT,closure)) { - Push(self);Push(key);Push(val); - if(!CallMetaMethod(closure,MT_NEWSLOT,3,res)) { - return false; - } - break; - } - Raise_Error(_SC("class instances do not support the new slot operator")); - return false; - break;} - case OT_CLASS: - if(!_class(self)->NewSlot(_ss(this),key,val,bstatic)) { - if(_class(self)->_locked) { - Raise_Error(_SC("trying to modify a class that has already been instantiated")); - return false; - } - else { - SQObjectPtr oval = PrintObjVal(key); - Raise_Error(_SC("the property '%s' already exists"),_stringval(oval)); - return false; - } - } - break; - default: - Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); - return false; - break; - } - return true; -} - - - -bool SQVM::DeleteSlot(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &res) -{ - switch(sq_type(self)) { - case OT_TABLE: - case OT_INSTANCE: - case OT_USERDATA: { - SQObjectPtr t; - //bool handled = false; - SQObjectPtr closure; - if(_delegable(self)->_delegate && _delegable(self)->GetMetaMethod(this,MT_DELSLOT,closure)) { - Push(self);Push(key); - return CallMetaMethod(closure,MT_DELSLOT,2,res); - } - else { - if(sq_type(self) == OT_TABLE) { - if(_table(self)->Get(key,t)) { - _table(self)->Remove(key); - } - else { - Raise_IdxError((const SQObject &)key); - return false; - } - } - else { - Raise_Error(_SC("cannot delete a slot from %s"),GetTypeName(self)); - return false; - } - } - res = t; - } - break; - default: - Raise_Error(_SC("attempt to delete a slot from a %s"),GetTypeName(self)); - return false; - } - return true; -} - -bool SQVM::Call(SQObjectPtr &closure,SQInteger nparams,SQInteger stackbase,SQObjectPtr &outres,SQBool raiseerror) -{ -#ifdef _DEBUG -SQInteger prevstackbase = _stackbase; -#endif - switch(sq_type(closure)) { - case OT_CLOSURE: - return Execute(closure, nparams, stackbase, outres, raiseerror); - break; - case OT_NATIVECLOSURE:{ - bool dummy; - return CallNative(_nativeclosure(closure), nparams, stackbase, outres, -1, dummy, dummy); - - } - break; - case OT_CLASS: { - SQObjectPtr constr; - SQObjectPtr temp; - CreateClassInstance(_class(closure),outres,constr); - SQObjectType ctype = sq_type(constr); - if (ctype == OT_NATIVECLOSURE || ctype == OT_CLOSURE) { - _stack[stackbase] = outres; - return Call(constr,nparams,stackbase,temp,raiseerror); - } - return true; - } - break; - default: - Raise_Error(_SC("attempt to call '%s'"), GetTypeName(closure)); - return false; - } -#ifdef _DEBUG - if(!_suspended) { - assert(_stackbase == prevstackbase); - } -#endif - return true; -} - -bool SQVM::CallMetaMethod(SQObjectPtr &closure,SQMetaMethod SQ_UNUSED_ARG(mm),SQInteger nparams,SQObjectPtr &outres) -{ - //SQObjectPtr closure; - - _nmetamethodscall++; - if(Call(closure, nparams, _top - nparams, outres, SQFalse)) { - _nmetamethodscall--; - Pop(nparams); - return true; - } - _nmetamethodscall--; - //} - Pop(nparams); - return false; -} - -void SQVM::FindOuter(SQObjectPtr &target, SQObjectPtr *stackindex) -{ - SQOuter **pp = &_openouters; - SQOuter *p; - SQOuter *otr; - - while ((p = *pp) != NULL && p->_valptr >= stackindex) { - if (p->_valptr == stackindex) { - target = SQObjectPtr(p); - return; - } - pp = &p->_next; - } - otr = SQOuter::Create(_ss(this), stackindex); - otr->_next = *pp; - otr->_idx = (stackindex - _stack._vals); - __ObjAddRef(otr); - *pp = otr; - target = SQObjectPtr(otr); -} - -bool SQVM::EnterFrame(SQInteger newbase, SQInteger newtop, bool tailcall) -{ - if( !tailcall ) { - if( _callsstacksize == _alloccallsstacksize ) { - GrowCallStack(); - } - ci = &_callsstack[_callsstacksize++]; - ci->_prevstkbase = (SQInt32)(newbase - _stackbase); - ci->_prevtop = (SQInt32)(_top - _stackbase); - ci->_etraps = 0; - ci->_ncalls = 1; - ci->_generator = NULL; - ci->_root = SQFalse; - } - else { - ci->_ncalls++; - } - - _stackbase = newbase; - _top = newtop; - if(newtop + MIN_STACK_OVERHEAD > (SQInteger)_stack.size()) { - if(_nmetamethodscall) { - Raise_Error(_SC("stack overflow, cannot resize stack while in a metamethod")); - return false; - } - _stack.resize(newtop + (MIN_STACK_OVERHEAD << 2)); - RelocateOuters(); - } - return true; -} - -void SQVM::LeaveFrame() { - SQInteger last_top = _top; - SQInteger last_stackbase = _stackbase; - SQInteger css = --_callsstacksize; - - /* First clean out the call stack frame */ - ci->_closure.Null(); - _stackbase -= ci->_prevstkbase; - _top = _stackbase + ci->_prevtop; - ci = (css) ? &_callsstack[css-1] : NULL; - - if(_openouters) CloseOuters(&(_stack._vals[last_stackbase])); - while (last_top >= _top) { - _stack._vals[last_top--].Null(); - } -} - -void SQVM::RelocateOuters() -{ - SQOuter *p = _openouters; - while (p) { - p->_valptr = _stack._vals + p->_idx; - p = p->_next; - } -} - -void SQVM::CloseOuters(SQObjectPtr *stackindex) { - SQOuter *p; - while ((p = _openouters) != NULL && p->_valptr >= stackindex) { - p->_value = *(p->_valptr); - p->_valptr = &p->_value; - _openouters = p->_next; - __ObjRelease(p); - } -} - -void SQVM::Remove(SQInteger n) { - n = (n >= 0)?n + _stackbase - 1:_top + n; - for(SQInteger i = n; i < _top; i++){ - _stack[i] = _stack[i+1]; - } - _stack[_top].Null(); - _top--; -} - -void SQVM::Pop() { - _stack[--_top].Null(); -} - -void SQVM::Pop(SQInteger n) { - for(SQInteger i = 0; i < n; i++){ - _stack[--_top].Null(); - } -} - -void SQVM::PushNull() { _stack[_top++].Null(); } -void SQVM::Push(const SQObjectPtr &o) { _stack[_top++] = o; } -SQObjectPtr &SQVM::Top() { return _stack[_top-1]; } -SQObjectPtr &SQVM::PopGet() { return _stack[--_top]; } -SQObjectPtr &SQVM::GetUp(SQInteger n) { return _stack[_top+n]; } -SQObjectPtr &SQVM::GetAt(SQInteger n) { return _stack[n]; } - -#ifdef _DEBUG_DUMP -void SQVM::dumpstack(SQInteger stackbase,bool dumpall) -{ - SQInteger size=dumpall?_stack.size():_top; - SQInteger n=0; - scprintf(_SC("\n>>>>stack dump<<<<\n")); - CallInfo &ci=_callsstack[_callsstacksize-1]; - scprintf(_SC("IP: %p\n"),ci._ip); - scprintf(_SC("prev stack base: %d\n"),ci._prevstkbase); - scprintf(_SC("prev top: %d\n"),ci._prevtop); - for(SQInteger i=0;i"));else scprintf(_SC(" ")); - scprintf(_SC("[" _PRINT_INT_FMT "]:"),n); - switch(sq_type(obj)){ - case OT_FLOAT: scprintf(_SC("FLOAT %.3f"),_float(obj));break; - case OT_INTEGER: scprintf(_SC("INTEGER " _PRINT_INT_FMT),_integer(obj));break; - case OT_BOOL: scprintf(_SC("BOOL %s"),_integer(obj)?"true":"false");break; - case OT_STRING: scprintf(_SC("STRING %s"),_stringval(obj));break; - case OT_NULL: scprintf(_SC("NULL")); break; - case OT_TABLE: scprintf(_SC("TABLE %p[%p]"),_table(obj),_table(obj)->_delegate);break; - case OT_ARRAY: scprintf(_SC("ARRAY %p"),_array(obj));break; - case OT_CLOSURE: scprintf(_SC("CLOSURE [%p]"),_closure(obj));break; - case OT_NATIVECLOSURE: scprintf(_SC("NATIVECLOSURE"));break; - case OT_USERDATA: scprintf(_SC("USERDATA %p[%p]"),_userdataval(obj),_userdata(obj)->_delegate);break; - case OT_GENERATOR: scprintf(_SC("GENERATOR %p"),_generator(obj));break; - case OT_THREAD: scprintf(_SC("THREAD [%p]"),_thread(obj));break; - case OT_USERPOINTER: scprintf(_SC("USERPOINTER %p"),_userpointer(obj));break; - case OT_CLASS: scprintf(_SC("CLASS %p"),_class(obj));break; - case OT_INSTANCE: scprintf(_SC("INSTANCE %p"),_instance(obj));break; - case OT_WEAKREF: scprintf(_SC("WEAKREF %p"),_weakref(obj));break; - default: - assert(0); - break; - }; - scprintf(_SC("\n")); - ++n; - } -} - - - -#endif diff --git a/src/modules/app_sqlang/squirrel/squirrel/sqvm.h b/src/modules/app_sqlang/squirrel/squirrel/sqvm.h deleted file mode 100644 index 135930449..000000000 --- a/src/modules/app_sqlang/squirrel/squirrel/sqvm.h +++ /dev/null @@ -1,282 +0,0 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQVM_H_ -#define _SQVM_H_ - -#include "sqopcodes.h" -#include "sqobject.h" -#define MAX_NATIVE_CALLS 100 -#define MIN_STACK_OVERHEAD 15 - -#define SQ_SUSPEND_FLAG -666 -#define SQ_TAILCALL_FLAG -777 -#define DONT_FALL_BACK 666 -//#define EXISTS_FALL_BACK -1 - -#define GET_FLAG_RAW 0x00000001 -#define GET_FLAG_DO_NOT_RAISE_ERROR 0x00000002 -//base lib -void sq_base_register(HSQUIRRELVM v); - -struct SQExceptionTrap -{ - SQExceptionTrap() - { - } - SQExceptionTrap(SQInteger ss, SQInteger stackbase, SQInstruction *ip, - SQInteger ex_target) - { - _stacksize = ss; - _stackbase = stackbase; - _ip = ip; - _extarget = ex_target; - } - SQExceptionTrap(const SQExceptionTrap &et) - { - (*this) = et; - } - SQInteger _stackbase; - SQInteger _stacksize; - SQInstruction *_ip; - SQInteger _extarget; -}; - -#define _INLINE - -typedef sqvector ExceptionsTraps; - -struct SQVM : public CHAINABLE_OBJ -{ - struct CallInfo - { - //CallInfo() { _generator = NULL;} - SQInstruction *_ip; - SQObjectPtr *_literals; - SQObjectPtr _closure; - SQGenerator *_generator; - SQInt32 _etraps; - SQInt32 _prevstkbase; - SQInt32 _prevtop; - SQInt32 _target; - SQInt32 _ncalls; - SQBool _root; - }; - - typedef sqvector CallInfoVec; - -public: - void DebugHookProxy(SQInteger type, const SQChar *sourcename, - SQInteger line, const SQChar *funcname); - static void _DebugHookProxy(HSQUIRRELVM v, SQInteger type, - const SQChar *sourcename, SQInteger line, const SQChar *funcname); - enum ExecutionType - { - ET_CALL, - ET_RESUME_GENERATOR, - ET_RESUME_VM, - ET_RESUME_THROW_VM - }; - SQVM(SQSharedState *ss); - ~SQVM(); - bool Init(SQVM *friendvm, SQInteger stacksize); - bool Execute(SQObjectPtr &func, SQInteger nargs, SQInteger stackbase, - SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL); - //starts a native call return when the NATIVE closure returns - bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, - SQInteger newbase, SQObjectPtr &retval, SQInt32 target, - bool &suspend, bool &tailcall); - bool TailCall(SQClosure *closure, SQInteger firstparam, SQInteger nparams); - //starts a SQUIRREL call in the same "Execution loop" - bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, - SQInteger stackbase, bool tailcall); - bool CreateClassInstance( - SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor); - //call a generic closure pure SQUIRREL or NATIVE - bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, - SQObjectPtr &outres, SQBool raiseerror); - SQRESULT Suspend(); - - void CallDebugHook(SQInteger type, SQInteger forcedline = 0); - void CallErrorHandler(SQObjectPtr &e); - bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, - SQUnsignedInteger getflags, SQInteger selfidx); - SQInteger FallBackGet( - const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest); - bool InvokeDefaultDelegate( - const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest); - bool Set(const SQObjectPtr &self, const SQObjectPtr &key, - const SQObjectPtr &val, SQInteger selfidx); - SQInteger FallBackSet(const SQObjectPtr &self, const SQObjectPtr &key, - const SQObjectPtr &val); - bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, - const SQObjectPtr &val, bool bstatic); - bool NewSlotA(const SQObjectPtr &self, const SQObjectPtr &key, - const SQObjectPtr &val, const SQObjectPtr &attrs, bool bstatic, - bool raw); - bool DeleteSlot( - const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res); - bool Clone(const SQObjectPtr &self, SQObjectPtr &target); - bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2, SQInteger &res); - bool StringCat( - const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest); - static bool IsEqual( - const SQObjectPtr &o1, const SQObjectPtr &o2, bool &res); - bool ToString(const SQObjectPtr &o, SQObjectPtr &res); - SQString *PrintObjVal(const SQObjectPtr &o); - - - void Raise_Error(const SQChar *s, ...); - void Raise_Error(const SQObjectPtr &desc); - void Raise_IdxError(const SQObjectPtr &o); - void Raise_CompareError(const SQObject &o1, const SQObject &o2); - void Raise_ParamTypeError( - SQInteger nparam, SQInteger typemask, SQInteger type); - - void FindOuter(SQObjectPtr &target, SQObjectPtr *stackindex); - void RelocateOuters(); - void CloseOuters(SQObjectPtr *stackindex); - - bool TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest); - bool CallMetaMethod(SQObjectPtr &closure, SQMetaMethod mm, - SQInteger nparams, SQObjectPtr &outres); - bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, - const SQObjectPtr &o2, SQObjectPtr &dest); - bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval); - //new stuff - _INLINE bool ARITH_OP(SQUnsignedInteger op, SQObjectPtr &trg, - const SQObjectPtr &o1, const SQObjectPtr &o2); - _INLINE bool BW_OP(SQUnsignedInteger op, SQObjectPtr &trg, - const SQObjectPtr &o1, const SQObjectPtr &o2); - _INLINE bool NEG_OP(SQObjectPtr &trg, const SQObjectPtr &o1); - _INLINE bool CMP_OP(CmpOP op, const SQObjectPtr &o1, const SQObjectPtr &o2, - SQObjectPtr &res); - bool CLOSURE_OP( - SQObjectPtr &target, SQFunctionProto *func, SQInteger boundtarget); - bool CLASS_OP(SQObjectPtr &target, SQInteger base, SQInteger attrs); - //return true if the loop is finished - bool FOREACH_OP(SQObjectPtr &o1, SQObjectPtr &o2, SQObjectPtr &o3, - SQObjectPtr &o4, SQInteger arg_2, int exitpos, int &jump); - //_INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr); - _INLINE bool PLOCAL_INC(SQInteger op, SQObjectPtr &target, SQObjectPtr &a, - SQObjectPtr &incr); - _INLINE bool DerefInc(SQInteger op, SQObjectPtr &target, SQObjectPtr &self, - SQObjectPtr &key, SQObjectPtr &incr, bool postfix, SQInteger arg0); -#ifdef _DEBUG_DUMP - void dumpstack(SQInteger stackbase = -1, bool dumpall = false); -#endif - -#ifndef NO_GARBAGE_COLLECTOR - void Mark(SQCollectable **chain); - SQObjectType GetType() - { - return OT_THREAD; - } -#endif - void Finalize(); - void GrowCallStack() - { - SQInteger newsize = _alloccallsstacksize * 2; - _callstackdata.resize(newsize); - _callsstack = &_callstackdata[0]; - _alloccallsstacksize = newsize; - } - bool EnterFrame(SQInteger newbase, SQInteger newtop, bool tailcall); - void LeaveFrame(); - void Release() - { - sq_delete(this, SQVM); - } - //////////////////////////////////////////////////////////////////////////// - //stack functions for the api - void Remove(SQInteger n); - - static bool IsFalse(SQObjectPtr &o); - - void Pop(); - void Pop(SQInteger n); - void Push(const SQObjectPtr &o); - void PushNull(); - SQObjectPtr &Top(); - SQObjectPtr &PopGet(); - SQObjectPtr &GetUp(SQInteger n); - SQObjectPtr &GetAt(SQInteger n); - - SQObjectPtrVec _stack; - - SQInteger _top; - SQInteger _stackbase; - SQOuter *_openouters; - SQObjectPtr _roottable; - SQObjectPtr _lasterror; - SQObjectPtr _errorhandler; - - bool _debughook; - SQDEBUGHOOK _debughook_native; - SQObjectPtr _debughook_closure; - - SQObjectPtr temp_reg; - - - CallInfo *_callsstack; - SQInteger _callsstacksize; - SQInteger _alloccallsstacksize; - sqvector _callstackdata; - - ExceptionsTraps _etraps; - CallInfo *ci; - SQUserPointer _foreignptr; - //VMs sharing the same state - SQSharedState *_sharedstate; - SQInteger _nnativecalls; - SQInteger _nmetamethodscall; - SQRELEASEHOOK _releasehook; - //suspend infos - SQBool _suspended; - SQBool _suspended_root; - SQInteger _suspended_target; - SQInteger _suspended_traps; -}; - -struct AutoDec -{ - AutoDec(SQInteger *n) - { - _n = n; - } - ~AutoDec() - { - (*_n)--; - } - SQInteger *_n; -}; - -inline SQObjectPtr &stack_get(HSQUIRRELVM v, SQInteger idx) -{ - return ((idx >= 0) ? (v->GetAt(idx + v->_stackbase - 1)) : (v->GetUp(idx))); -} - -#define _ss(_vm_) (_vm_)->_sharedstate - -#ifndef NO_GARBAGE_COLLECTOR -#define _opt_ss(_vm_) (_vm_)->_sharedstate -#else -#define _opt_ss(_vm_) NULL -#endif - -#define PUSH_CALLINFO(v, nci) \ - { \ - SQInteger css = v->_callsstacksize; \ - if(css == v->_alloccallsstacksize) { \ - v->GrowCallStack(); \ - } \ - v->ci = &v->_callsstack[css]; \ - *(v->ci) = nci; \ - v->_callsstacksize++; \ - } - -#define POP_CALLINFO(v) \ - { \ - SQInteger css = --v->_callsstacksize; \ - v->ci->_closure.Null(); \ - v->ci = css ? &v->_callsstack[css - 1] : NULL; \ - } -#endif //_SQVM_H_ diff --git a/src/modules/app_sqlang/utils/app_sqlang_ctl b/src/modules/app_sqlang/utils/app_sqlang_ctl deleted file mode 100755 index 006dc8232..000000000 --- a/src/modules/app_sqlang/utils/app_sqlang_ctl +++ /dev/null @@ -1,146 +0,0 @@ -#!/bin/bash - -# generate the .h file - -KEMI_MAX_SIZE=1024 - -cat > ../app_sqlang_kemi_export.h < -#include "../../core/kemi.h" - -#define SR_KEMI_SQLANG_EXPORT_SIZE ${KEMI_MAX_SIZE} - -typedef struct sr_kemi_sqlang_export { - SQFUNCTION pfunc; - sr_kemi_t *ket; -} sr_kemi_sqlang_export_t; - -sr_kemi_t *sr_kemi_sqlang_export_get(int idx); -SQFUNCTION sr_kemi_sqlang_export_associate(sr_kemi_t *ket); - -#endif -EOF - -# generate the .c file - -cat > ../app_sqlang_kemi_export.c < -#include -#include - -#include "../../core/dprint.h" - -#include "app_sqlang_api.h" -#include "app_sqlang_kemi_export.h" - -EOF - -CEND=${KEMI_MAX_SIZE} - -for (( c=0; c>../app_sqlang_kemi_export.c - echo "/**" >>../app_sqlang_kemi_export.c - echo " *" >>../app_sqlang_kemi_export.c - echo " */" >>../app_sqlang_kemi_export.c - echo "static SQInteger sr_kemi_sqlang_exec_func_${c}(HSQUIRRELVM J)" >>../app_sqlang_kemi_export.c - echo "{" >>../app_sqlang_kemi_export.c - echo " return sr_kemi_sqlang_exec_func(J, ${c});" >>../app_sqlang_kemi_export.c - echo "}" >>../app_sqlang_kemi_export.c -done - -echo >>../app_sqlang_kemi_export.c -echo "/**" >>../app_sqlang_kemi_export.c -echo " *" >>../app_sqlang_kemi_export.c -echo " */" >>../app_sqlang_kemi_export.c - -echo "static sr_kemi_sqlang_export_t _sr_kemi_sqlang_export_list[] = {" >>../app_sqlang_kemi_export.c -for (( c=0; c>../app_sqlang_kemi_export.c -done -echo " {NULL, NULL}" >>../app_sqlang_kemi_export.c -echo "};" >>../app_sqlang_kemi_export.c - -cat >> ../app_sqlang_kemi_export.c <=SR_KEMI_SQLANG_EXPORT_SIZE) - return NULL; - return _sr_kemi_sqlang_export_list[idx].ket; -} - -/** - * - */ -SQFUNCTION sr_kemi_sqlang_export_associate(sr_kemi_t *ket) -{ - int i; - for(i=0; i= 0); /*FIXME*/ + assert(*nonce_len >= 0); return 0; } diff --git a/src/modules/auth_ephemeral/authorize.c b/src/modules/auth_ephemeral/authorize.c index eab4cd678..32864e737 100644 --- a/src/modules/auth_ephemeral/authorize.c +++ b/src/modules/auth_ephemeral/authorize.c @@ -156,7 +156,7 @@ static inline int do_auth(struct sip_msg *_m, struct hdr_field *_h, str *_realm, int autheph_verify_timestamp(str *_username) { - int pos = 0, cur_time = (int)time(NULL); + int pos = 0, cur_time = (int)(unsigned long long)time(NULL); unsigned int expires; str time_str = {0, 0}; diff --git a/src/modules/auth_identity/Makefile b/src/modules/auth_identity/Makefile deleted file mode 100644 index 80791d708..000000000 --- a/src/modules/auth_identity/Makefile +++ /dev/null @@ -1,46 +0,0 @@ - -include ../../Makefile.defs -auto_gen= -NAME=auth_identity.so - -ifeq ($(CROSS_COMPILE),) -CURL_BUILDER=$(shell \ - if pkg-config --exists libcurl; then \ - echo 'pkg-config libcurl'; \ - else \ - which curl-config; \ - fi) -SSL_BUILDER=$(shell \ - if pkg-config --exists libssl; then \ - echo 'pkg-config libssl'; \ - fi) -endif - -ifneq ($(CURL_BUILDER),) - DEFS += $(shell $(CURL_BUILDER) --cflags ) - LIBS += $(shell $(CURL_BUILDER) --libs) -else - DEFS+=-I$(LOCALBASE)/include - LIBS+=-L$(LOCALBASE)/lib -lcurl -endif - -ifneq ($(SSL_BUILDER),) - DEFS += $(shell $(SSL_BUILDER) --cflags) - LIBS += $(shell $(SSL_BUILDER) --libs) -else - DEFS += -I$(LOCALBASE)/ssl/include - LIBS += -L$(LOCALBASE)/lib -L$(LOCALBASE)/ssl/lib \ - -L$(LOCALBASE)/lib64 -L$(LOCALBASE)/ssl/lib64 \ - -lssl -lcrypto - # NOTE: depending on the way in which libssl was compiled you might - # have to add -lz -lkrb5 (zlib and kerberos5). - # E.g.: make TLS_HOOKS=1 TLS_EXTRA_LIBS="-lz -lkrb5" -endif -LIBS+= $(TLS_EXTRA_LIBS) - -# Static linking, if you'd like to use TLS and AUTH_IDENTITY at the same time -# -#LIBS+= /usr/lib/libcurl.a /usr/lib/libssl.a /usr/lib/libcrypto.a -lkrb5 -lidn -lz -lgssapi_krb5 -lrt -lldap - -include ../../Makefile.modules - diff --git a/src/modules/auth_identity/README b/src/modules/auth_identity/README deleted file mode 100644 index b56c1dc47..000000000 --- a/src/modules/auth_identity/README +++ /dev/null @@ -1,548 +0,0 @@ -SIP Authenticated Identity Module - -Gergely Kovacs - - Iptel.org - - Copyright © 2007 Iptel.org - __________________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1. Overview - 2. Dependencies - 3. Compilation - 4. Installation And Running - 5. Parameters - - 5.1. privatekey_path (string) - 5.2. certificate_path (string) - 5.3. certificate_url (string) - 5.4. msg_timeout (integer) - 5.5. auth_validity_time (integer) - 5.6. callid_cache_limit (integer) - 5.7. certificate_cache_limit (integer) - 5.8. cainfo_path (string) - 5.9. accept_pem_certs (int) - - 6. Functions - - 6.1. auth_date_proc() - - 6.1.1. Dependencies - - 6.2. auth_add_identity() - - 6.2.1. Dependencies - - 6.3. vrfy_check_date() - - 6.3.1. Dependencies - - 6.4. vrfy_get_certificate() - - 6.4.1. Dependencies - - 6.5. vrfy_check_certificate() - - 6.5.1. Dependencies - - 6.6. vrfy_check_msgvalidity() - - 6.6.1. Dependencies - - 6.7. vrfy_check_callid() - - 6.7.1. Dependencies - - 7. Authorizer service examples - 8. Verifier service examples - 9. Remarks - - List of Examples - - 1.1. Set privatekey_path parameter - 1.2. Set certificate_path parameter - 1.3. Set certificate_url parameter - 1.4. Set msg_timeout parameter - 1.5. Set auth_validity_time parameter - 1.6. Set auth_validity_time parameter - 1.7. Set certificate_cache_limit parameter - 1.8. Set cainfo_path parameter - 1.9. Set accept_pem_certs parameter - -Chapter 1. Admin Guide - - Table of Contents - - 1. Overview - 2. Dependencies - 3. Compilation - 4. Installation And Running - 5. Parameters - - 5.1. privatekey_path (string) - 5.2. certificate_path (string) - 5.3. certificate_url (string) - 5.4. msg_timeout (integer) - 5.5. auth_validity_time (integer) - 5.6. callid_cache_limit (integer) - 5.7. certificate_cache_limit (integer) - 5.8. cainfo_path (string) - 5.9. accept_pem_certs (int) - - 6. Functions - - 6.1. auth_date_proc() - - 6.1.1. Dependencies - - 6.2. auth_add_identity() - - 6.2.1. Dependencies - - 6.3. vrfy_check_date() - - 6.3.1. Dependencies - - 6.4. vrfy_get_certificate() - - 6.4.1. Dependencies - - 6.5. vrfy_check_certificate() - - 6.5.1. Dependencies - - 6.6. vrfy_check_msgvalidity() - - 6.6.1. Dependencies - - 6.7. vrfy_check_callid() - - 6.7.1. Dependencies - - 7. Authorizer service examples - 8. Verifier service examples - 9. Remarks - -1. Overview - - Auth Identity module provides functionalities for securely identifying - originators of SIP messages. It implements the SIP Identity standard - where a SIP proxy signs messages that is sent to other domains. This - module has two basic services: - * authorizer - authorizes a message and adds Identity and - Identity-Info headers - * verifier - verifies an authorized message - - Known limitations in this version: - * authorizer and verifier support all SIP requests except for CANCEL - and REGISTER - * verifier does not support the subjectAltName extension of - certificates - -2. Dependencies - - This module does not depend any other module. - -3. Compilation - - This module needs the following headers and libraries: - * OpenSSL (version 0.9.8 or higher) for cryptographic functions - * libcurl for HTTP, HTTPS functions - - If you'd like to use TLS module too then use the corresponding LIB line - in auth_identity's Makefile - -4. Installation And Running - - the Authorizer service needs to make the public key, which conveyed in - a certificate, available over HTTPS or HTTP for verifiers. The domain - the authorizer is responsible for and the domain part of the URL of the - certificate must be the same. This service needs access to the private - key too. - -5. Parameters - - 5.1. privatekey_path (string) - 5.2. certificate_path (string) - 5.3. certificate_url (string) - 5.4. msg_timeout (integer) - 5.5. auth_validity_time (integer) - 5.6. callid_cache_limit (integer) - 5.7. certificate_cache_limit (integer) - 5.8. cainfo_path (string) - 5.9. accept_pem_certs (int) - -5.1. privatekey_path (string) - - Note: this parameter is for authorizer service. - - The path of private key of the authentication service. The key must be - in PEM format. - - This parameter is required by authentication service. - - Example 1.1. Set privatekey_path parameter -... -modparam("auth_identity","privatekey_path","/etc/ssl/private/key.pem") -... - -5.2. certificate_path (string) - - Note: this parameter is for authorizer service. - - The path of certificate of the authentication service. The certificate - must be in PEM format. - - This parameter is required by authentication service. - - Example 1.2. Set certificate_path parameter -... -modparam("auth_identity","certificate_path","/var/www/ssl/mycert.pem") -... - -5.3. certificate_url (string) - - Note: this parameter is for authorizer service. - - The url where certificate is available for other verifier services. - (value of Identity-info header) The certificate should be in DER - format. - - This parameter is required by authentication service. - - Example 1.3. Set certificate_url parameter -... -modparam("auth_identity","certificate_url","https://foo.bar/mycert.der") -... - -5.4. msg_timeout (integer) - - Note: this parameter is for authorizer service. - - If the Date header of message which is needed to be authenticated - contains a time different by more than this seconds from the current - time noted by the authentication service then it rejects the message. - - This parameter is optional. The default value is "600". - - Example 1.4. Set msg_timeout parameter -... -modparam("auth_identity","msg_timeout",600) -... - -5.5. auth_validity_time (integer) - - Note: this parameter is for verifier service. - - The validity time of an authenticated message. The message will be - refused if it contains a time different by more than this seconds from - the current time noted by the verification service. - - This parameter is optional. The default value is "3600". - - Example 1.5. Set auth_validity_time parameter -... -modparam("auth_identity","auth_validity_time",3600) -... - -5.6. callid_cache_limit (integer) - - Note: this parameter is for verifier service. - - The number of Call-IDs stored in order to recognize call replay - attacks. A Call-ID is stored auth_validity_time long and uses - approximately 100 bytes memory. - - This parameter is optional. The default value is "32768". (you should - increase the size of shared memory with -m command line switch if you - liked to store more callid than 10000) - - Example 1.6. Set auth_validity_time parameter -... -modparam("auth_identity","callid_cache_limit",32768) -... - -5.7. certificate_cache_limit (integer) - - Note: this parameter is for verifier service. - - The number of certificates stored in order to avoid needless download. - A certificate is stored until its expiration date and uses - approximately 600 bytes memory. - - This parameter is optional. The default value is "4096". - - Example 1.7. Set certificate_cache_limit parameter -... -modparam("auth_identity","certificate_cache_limit",4096) -... - -5.8. cainfo_path (string) - - Note: this parameter is for verifier service. - - A file of trusted certificates. The file should contain multiple - certificates in PEM format concatenated together. It could be useful - for verifying a certificate signed by a private CA. - - This parameter is optional. It has not got default value. - - Example 1.8. Set cainfo_path parameter -... -modparam("auth_identity","cainfo_path","/etc/ssl/certs/ca-certificates.crt") -... - -5.9. accept_pem_certs (int) - - Note: this parameter is for verifier service. - - Enables the acquired certificate processing if it is in PEM format. - Value can be 0 or 1. - - This parameter is optional. The default value is "0". - - Example 1.9. Set accept_pem_certs parameter -... -modparam("auth_identity","accept_pem_certs",1) -... - -6. Functions - - 6.1. auth_date_proc() - - 6.1.1. Dependencies - - 6.2. auth_add_identity() - - 6.2.1. Dependencies - - 6.3. vrfy_check_date() - - 6.3.1. Dependencies - - 6.4. vrfy_get_certificate() - - 6.4.1. Dependencies - - 6.5. vrfy_check_certificate() - - 6.5.1. Dependencies - - 6.6. vrfy_check_msgvalidity() - - 6.6.1. Dependencies - - 6.7. vrfy_check_callid() - - 6.7.1. Dependencies - -6.1. auth_date_proc() - - Note: this function is for authorizer service. - - If a message, the auth service should authorize, contains Date header - then this function checks whether it falls in message timeout (set by - msg_timeout parameter). If there is not any Date header then the module - adds one. This function also checks whether the certificate of the - authentication service (set by certificate_path parameter) has expired. - -6.1.1. Dependencies - - No dependencies - -6.2. auth_add_identity() - - Note: this function is for authorizer service. - - Assembles digest-string from the message, calculates its SHA1 hash, - encrypts it with the private key (set by privatekey_path parameter) of - the authorizer service, base64 encodes it and adds to the outgoing - message as the value of Identity header. This function also adds - Identity-Info header which contains an URI (set by certificate_url - parameter) from which the certificate of auth service can be acquired. - - Note: this function needs the final outgoing message for authorization, - so no module may modify any digest string related headers (From, To, - Call-ID, CSeq, Date, Contact) and body after auth_add_identity()'s been - called - -6.2.1. Dependencies - - auth_date_proc() must be called before - -6.3. vrfy_check_date() - - Note: this function is for verifier service. - - Checks Date header of the incoming message whether falls in validity - time (set by auth_validity_time parameter) - -6.3.1. Dependencies - - No dependencies - -6.4. vrfy_get_certificate() - - Note: this function is for verifier service. - - Tries to get certificate defined by the value of Identity-info header - from certificate table (which size is set by certificate_cache_limit - parameter). If the required certificate is not found there then this - function downloads it. - -6.4.1. Dependencies - - No dependencies - -6.5. vrfy_check_certificate() - - Note: this function is for verifier service. - - Checks whether the downloaded certificate is valid (is not expired, its - subject and the domain part of the URL are the same) and adds it to - certificate table. - -6.5.1. Dependencies - - vrfy_get_certificate() must be called before - -6.6. vrfy_check_msgvalidity() - - Note: this function is for verifier service. - - Assembles digest-string from the message, create SHA1 hash and compares - it with the decrypted value of Identity header. - -6.6.1. Dependencies - - vrfy_get_certificate() must be called before and - vrfy_check_certificate() should be called before - -6.7. vrfy_check_callid() - - Note: this function is for verifier service. - - Checks whether the current call's been already processed in validity - time (set by auth_validity_time) to recognize call replay attacks. If - this call (identified by Call-id, Cseq, and tag of From header triple) - has not been replayed then adds it to callid table (which size is set - by callid_cache_limit parameter). - -6.7.1. Dependencies - - This function should be called for the last time. - -7. Authorizer service examples - -... -route[INIT] -{ - # we process new transactions only - if (!t_newtran()) { - sl_reply("500", "Internal error newtran"); - drop; - } -... -route[OUTBOUND] -{ - # If we are responsible for the domain of the sender of this message - if ($f.did && !$t.did) { - # Authentication service - if (method=="INVITE" || method=="BYE" - || method=="OPTION" || method=="ACK") { - # Identity and Identity-info headers must not exist - if (@identity) { - t_reply("403", "Invalid Identity header"); - drop; - } - if (@identity_info) { - t_reply("403", "Invalid Identity-info header"); - drop; - } - - if (!auth_date_proc()) { - t_reply("403", "Invalid Date value"); - drop; - } - - if (!auth_add_identity()) { - t_reply("480", "Authentication error"); - drop; - } - } - route(FORWARD); - } -} -... - -8. Verifier service examples - -... -route[INIT] -{ - # we process new transactions only - if (!t_newtran()) { - sl_reply("500", "Internal error newtran"); - drop; - } -... -route[VERIFY] -{ - # if we've already processed this message then we drop it - if (!t_newtran()) { - sl_reply("500", "Internal error newtran"); - drop; - } - - if (method=="INVITE" || method=="BYE" - || method=="OPTION" || method=="ACK") { - # Identity and Identity-info are required for verification - if (!@identity) { - t_reply("428", "Use Identity Header"); - drop; - } - if (!@identity_info) { - t_reply("436", "Bad Identity-Info"); - drop; - } - - if (!vrfy_check_date()) { - t_reply("403", "Outdated Date header value"); - drop; - } - - if (!vrfy_get_certificate()) { - t_reply("436", "Bad Identity-Info"); - drop; - } - - if (!vrfy_check_certificate()) { - t_reply("437", "Unsupported Certificate"); - drop; - } - - if (!vrfy_check_msgvalidity()) { - t_reply("438", "Invalid Identity Header"); - drop; - } - - if (!vrfy_check_callid()) { - t_reply("403", "Message is replayed"); - drop; - } - } -} -... - -9. Remarks - - Note: libcurl leak in CentOS 6 - this module uses libcurl library and - in case if you are using CentOS 6, be aware that standard - libcurl-7.19.7-52 has a memory leak. To fix this memory, install - libcurl from city-fan repository. More details at: - https://www.digitalocean.com/community/questions/how-to-upgrade-curl-in - -centos6 diff --git a/src/modules/auth_identity/auth_crypt.c b/src/modules/auth_identity/auth_crypt.c deleted file mode 100644 index 934c9cca3..000000000 --- a/src/modules/auth_identity/auth_crypt.c +++ /dev/null @@ -1,437 +0,0 @@ -/* - * Copyright (c) 2007 iptelorg GmbH - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/*! - * \file - * \brief Kamailio auth-identity :: Crypt - * \ingroup auth-identity - * Module: \ref auth-identity - */ - - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../../core/mem/mem.h" -#include "../../core/parser/parse_uri.h" - -#include "auth_identity.h" - - -int retrieve_x509(X509 **pcert, str *scert, int bacceptpem) -{ - BIO *bcer = NULL; - char serr[160]; - int iRet = 0; - - - if(!(bcer = BIO_new(BIO_s_mem()))) { - LOG(L_ERR, "AUTH_IDENTITY:retrieve_x509: Unable to create BIO\n"); - - return -1; - } - - do { - if(BIO_write(bcer, scert->s, scert->len) != scert->len) { - LOG(L_ERR, "AUTH_IDENTITY:retrieve_x509: Unable to write BIO\n"); - iRet = -2; - break; - } - - /* RFC 4474 only accepts certs in the DER form but it can not harm - * to be a little bit more flexible and accept PEM as well. */ - if(bacceptpem && scert->len > BEGIN_PEM_CERT_LEN - && memmem(scert->s, scert->len, BEGIN_PEM_CERT, - BEGIN_PEM_CERT_LEN)) { - if(!(*pcert = PEM_read_bio_X509(bcer, NULL, NULL, NULL))) { - ERR_error_string_n(ERR_get_error(), serr, sizeof(serr)); - LOG(L_ERR, "AUTH_IDENTITY:retrieve_x509: PEM Certificate %s\n", - serr); - iRet = -4; - } - } else { - if(!(*pcert = d2i_X509_bio(bcer, NULL))) { - ERR_error_string_n(ERR_get_error(), serr, sizeof(serr)); - LOG(L_ERR, "AUTH_IDENTITY:retrieve_x509: DER Certificate %s\n", - serr); - iRet = -3; - } - } - } while(0); - - BIO_free(bcer); - - return iRet; -} - -int check_x509_subj(X509 *pcert, str *sdom) -{ - STACK_OF(GENERAL_NAME) * altnames; - int ialts, i1, ilen, altlen; - const GENERAL_NAME *actname; - char scname[AUTH_DOMAIN_LENGTH]; - char *altptr; - struct sip_uri suri; - int ret = 0; - - - /* we're looking for subjectAltName for the first time */ - altnames = X509_get_ext_d2i(pcert, NID_subject_alt_name, NULL, NULL); - - if(altnames) { - ialts = sk_GENERAL_NAME_num(altnames); - - for(i1 = 0; i1 < ialts; i1++) { - actname = sk_GENERAL_NAME_value(altnames, i1); - - if(actname->type == GEN_DNS || actname->type == GEN_URI) { - /* we've found one */ -#if OPENSSL_VERSION_NUMBER >= 0x010100000L - altptr = (char *)ASN1_STRING_get0_data(actname->d.ia5); -#else - altptr = (char *)ASN1_STRING_data(actname->d.ia5); -#endif - if(actname->type == GEN_URI) { - if(parse_uri(altptr, strlen(altptr), &suri) != 0) { - continue; - } - if(!(suri.type == SIP_URI_T || suri.type == SIPS_URI_T)) { - continue; - } - if(suri.user.len != 0 || suri.passwd.len != 0) { - continue; - } - altptr = suri.host.s; - altlen = suri.host.len; - } else { - altlen = strlen(altptr); - } - if(sdom->len != altlen - || strncasecmp(altptr, sdom->s, sdom->len)) { - LOG(L_INFO, "AUTH_IDENTITY VERIFIER: subAltName of " - "certificate doesn't match host name\n"); - ret = -1; - } else { - ret = 1; - break; - } - } - } - GENERAL_NAMES_free(altnames); - } - - if(ret != 0) { - return ret == 1 ? 0 : ret; - } - - /* certificate supplier host and certificate subject match check */ - ilen = X509_NAME_get_text_by_NID(X509_get_subject_name(pcert), - NID_commonName, scname, sizeof(scname)); - if(sdom->len != ilen || strncasecmp(scname, sdom->s, sdom->len)) { - LOG(L_INFO, "AUTH_IDENTITY VERIFIER: common name of certificate " - "doesn't match host name\n"); - return -2; - } - - return 0; -} - -int verify_x509(X509 *pcert, X509_STORE *pcacerts) -{ - X509_STORE_CTX *ca_ctx = NULL; - char *strerr; - - ca_ctx = X509_STORE_CTX_new(); - if(ca_ctx == NULL) { - LM_ERR("cannot get a x509 context\n"); - return -1; - } - - if(X509_STORE_CTX_init(ca_ctx, pcacerts, pcert, NULL) != 1) { - LOG(L_ERR, - "AUTH_IDENTITY:verify_x509: Unable to init X509 store ctx\n"); - X509_STORE_CTX_free(ca_ctx); - return -1; - } - - if(X509_verify_cert(ca_ctx) != 1) { - strerr = (char *)X509_verify_cert_error_string( - X509_STORE_CTX_get_error(ca_ctx)); - LOG(L_ERR, - "AUTH_IDENTITY VERIFIER: Certificate verification error: %s\n", - strerr); - X509_STORE_CTX_cleanup(ca_ctx); - X509_STORE_CTX_free(ca_ctx); - return -2; - } - X509_STORE_CTX_cleanup(ca_ctx); - X509_STORE_CTX_free(ca_ctx); - - LOG(AUTH_DBG_LEVEL, "AUTH_IDENTITY VERIFIER: Certificate is valid\n"); - - return 0; -} - -int rsa_sha1_enc( - dynstr *sdigeststr, dynstr *senc, dynstr *sencb64, RSA *hmyprivkey) -{ - unsigned char sstrcrypted[SHA_DIGEST_LENGTH]; - int ires; - char serr[160]; - - - SHA1((unsigned char *)getstr_dynstr(sdigeststr).s, - getstr_dynstr(sdigeststr).len, sstrcrypted); - -#ifdef NEW_RSA_PROC - ires = senc->size; - if(RSA_sign(NID_sha1, sstrcrypted, sizeof sstrcrypted, - (unsigned char *)getstr_dynstr(senc).s, (unsigned int *)&ires, - hmyprivkey) - != 1) { - ERR_error_string_n(ERR_get_error(), serr, sizeof serr); - LOG(L_ERR, "AUTH_IDENTITY:rsa_sha1_enc: '%s'\n", serr); - return -2; - } -#else - ires = RSA_private_encrypt(sizeof sstrcrypted, sstrcrypted, - (unsigned char *)getstr_dynstr(senc).s, hmyprivkey, - RSA_PKCS1_PADDING); - if(ires < 0) { - ERR_error_string_n(ERR_get_error(), serr, sizeof serr); - LOG(L_ERR, "AUTH_IDENTITY:rsa_sha1_enc: '%s'\n", serr); - return -1; - } -#endif - - base64encode(getstr_dynstr(senc).s, senc->size, getstr_dynstr(sencb64).s, - &getstr_dynstr(sencb64).len); - - return 0; -} - -int rsa_sha1_dec(char *sencedsha, int iencedshalen, char *ssha, int sshasize, - int *ishalen, X509 *pcertx509) -{ - EVP_PKEY *pkey; - RSA *hpubkey; - unsigned long lerr; - char serr[160]; - - - pkey = X509_get_pubkey(pcertx509); - if(pkey == NULL) { - lerr = ERR_get_error(); - ERR_error_string_n(lerr, serr, sizeof(serr)); - LOG(L_ERR, "AUTH_IDENTITY:decrypt_identity: Pubkey %s\n", serr); - return -1; - } - - X509_free(pcertx509); - - hpubkey = EVP_PKEY_get1_RSA(pkey); - EVP_PKEY_free(pkey); - if(hpubkey == NULL) { - LOG(L_ERR, "AUTH_IDENTITY:decrypt_identity: Error getting RSA key\n"); - return -2; - } - -#ifdef NEW_RSA_PROC - if(RSA_verify(NID_sha1, (unsigned char *)ssha, sshasize, - (unsigned char *)sencedsha, iencedshalen, hpubkey) - != 1) { - LOG(L_INFO, "AUTH_IDENTITY VERIFIER: RSA verify returned: '%s'\n", - ERR_error_string(ERR_get_error(), NULL)); - LOG(L_INFO, "AUTH_IDENTITY VERIFIER: RSA verify failed -> Invalid " - "Identity Header\n"); - RSA_free(hpubkey); - return -5; - } -#else - /* it is bigger than the output buffer */ - if(RSA_size(hpubkey) > sshasize) { - LOG(L_ERR, - "AUTH_IDENTITY:decrypt_identity: Unexpected Identity hash " - "length (%d > %d)\n", - RSA_size(hpubkey), sshasize); - RSA_free(hpubkey); - return -3; - } - *ishalen = RSA_public_decrypt(iencedshalen, (unsigned char *)sencedsha, - (unsigned char *)ssha, hpubkey, RSA_PKCS1_PADDING); - if(*ishalen <= 0) { - lerr = ERR_get_error(); - ERR_error_string_n(lerr, serr, sizeof(serr)); - LOG(L_ERR, "AUTH_IDENTITY:decrypt_identity: RSA operation error %s\n", - serr); - RSA_free(hpubkey); - return -4; - } -#endif - - RSA_free(hpubkey); - - return 0; -} - -/* copypasted from ser/modules/rr/avp_cookie.c + this adds '=' sign! ) */ -void base64encode(char *src_buf, int src_len, char *tgt_buf, int *tgt_len) -{ - static char code64[64 + 1] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - int pos; - for(pos = 0, *tgt_len = 0; pos < src_len; pos += 3, *tgt_len += 4) { - tgt_buf[*tgt_len + 0] = code64[(unsigned char)src_buf[pos + 0] >> 2]; - tgt_buf[*tgt_len + 1] = - code64[(((unsigned char)src_buf[pos + 0] & 0x03) << 4) - | ((pos + 1 < src_len) - ? ((unsigned char)src_buf[pos + 1] >> 4) - : 0)]; - if(pos + 1 < src_len) - tgt_buf[*tgt_len + 2] = - code64[(((unsigned char)src_buf[pos + 1] & 0x0F) << 2) - | ((pos + 2 < src_len) ? ( - (unsigned char)src_buf[pos + 2] >> 6) - : 0)]; - else - tgt_buf[*tgt_len + 2] = '='; - if(pos + 2 < src_len) - tgt_buf[*tgt_len + 3] = - code64[(unsigned char)src_buf[pos + 2] & 0x3F]; - else - tgt_buf[*tgt_len + 3] = '='; - } -} - - -/* copypasted from ser/modules/rr/avp_cookie.c */ -void base64decode(char *src_buf, int src_len, char *tgt_buf, int *tgt_len) -{ - int pos, i, n; - unsigned char c[4]; - for(pos = 0, i = 0, *tgt_len = 0; pos < src_len; pos++) { - if(src_buf[pos] >= 'A' && src_buf[pos] <= 'Z') - c[i] = src_buf[pos] - 65; /* <65..90> --> <0..25> */ - else if(src_buf[pos] >= 'a' && src_buf[pos] <= 'z') - c[i] = src_buf[pos] - 71; /* <97..122> --> <26..51> */ - else if(src_buf[pos] >= '0' && src_buf[pos] <= '9') - c[i] = src_buf[pos] + 4; /* <48..56> --> <52..61> */ - else if(src_buf[pos] == '+') - c[i] = 62; - else if(src_buf[pos] == '/') - c[i] = 63; - else /* '=' */ - c[i] = 64; - i++; - if(pos == src_len - 1) { - while(i < 4) { - c[i] = 64; - i++; - } - } - if(i == 4) { - if(c[0] == 64) - n = 0; - else if(c[2] == 64) - n = 1; - else if(c[3] == 64) - n = 2; - else - n = 3; - switch(n) { - case 3: - tgt_buf[*tgt_len + 2] = (char)(((c[2] & 0x03) << 6) | c[3]); - /* no break */ - case 2: - tgt_buf[*tgt_len + 1] = - (char)(((c[1] & 0x0F) << 4) | (c[2] >> 2)); - /* no break */ - case 1: - tgt_buf[*tgt_len + 0] = (char)((c[0] << 2) | (c[1] >> 4)); - break; - } - i = 0; - *tgt_len += n; - } - } -} - -int x509_get_validitytime(time_t *tout, ASN1_UTCTIME *tin) -{ - char *sasn1; - int i1; - struct tm tmptm; - - - memset(&tmptm, 0, sizeof(tmptm)); - i1 = tin->length; - sasn1 = (char *)tin->data; - - if(i1 < 10) - return -1; - /* if (sasn1[i1-1]!='Z') - return -1;*/ - for(i1 = 0; i1 < 10; i1++) - if((sasn1[i1] > '9') || (sasn1[i1] < '0')) - return -2; - - tmptm.tm_year = (sasn1[0] - '0') * 10 + (sasn1[1] - '0'); - if(tmptm.tm_year < 50) - tmptm.tm_year += 100; - - tmptm.tm_mon = (sasn1[2] - '0') * 10 + (sasn1[3] - '0') - 1; - if((tmptm.tm_mon > 11) || (tmptm.tm_mon < 0)) - return -3; - - tmptm.tm_mday = (sasn1[4] - '0') * 10 + (sasn1[5] - '0'); - tmptm.tm_hour = (sasn1[6] - '0') * 10 + (sasn1[7] - '0'); - tmptm.tm_min = (sasn1[8] - '0') * 10 + (sasn1[9] - '0'); - - if((sasn1[10] >= '0') && (sasn1[10] <= '9') && (sasn1[11] >= '0') - && (sasn1[11] <= '9')) - tmptm.tm_sec = (sasn1[10] - '0') * 10 + (sasn1[11] - '0'); - -#ifdef HAVE_TIMEGM - *tout = timegm(&tmptm); -#else - *tout = _timegm(&tmptm); -#endif - - return 0; -} - -int x509_get_notbefore(time_t *tout, X509 *pcert) -{ - return (x509_get_validitytime(tout, X509_get_notBefore(pcert))); -} - -int x509_get_notafter(time_t *tout, X509 *pcert) -{ - return (x509_get_validitytime(tout, X509_get_notAfter(pcert))); -} diff --git a/src/modules/auth_identity/auth_dynstr.c b/src/modules/auth_identity/auth_dynstr.c deleted file mode 100644 index dac091146..000000000 --- a/src/modules/auth_identity/auth_dynstr.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Copyright (c) 2007 iptelorg GmbH - * - */ - -/*! - * \file - * \brief Kamailio auth-identity :: Dynamic strings - * \ingroup auth-identity - * Module: \ref auth-identity - */ - -#include - -#include "../../core/parser/parse_from.h" -#include "../../core/parser/parse_cseq.h" -#include "../../core/parser/parse_content.h" -#include "../../core/parser/parse_uri.h" -#include "../../core/parser/contact/parse_contact.h" - -#include "../../core/data_lump.h" -#include "../../core/msg_translator.h" -#include "auth_identity.h" - -/* - * Dynamic string functions - */ - -int initdynstr(dynstr *sout, int isize) -{ - memset(sout, 0, sizeof(*sout)); - getstr_dynstr(sout).s = pkg_malloc(isize); - if(!getstr_dynstr(sout).s) { - PKG_MEM_ERROR; - return -1; - } - sout->size = isize; - - return 0; -} - -int cpy2dynstr(dynstr *sout, str *s2app) -{ - char *stmp; - int isize = s2app->len; - - if(isize > sout->size) { - stmp = pkg_realloc(sout->sd.s, isize); - if(!stmp) { - LOG(L_ERR, "AUTH_IDENTITY:cpy2dynstr: Not enough memory error\n"); - return -1; - } - sout->sd.s = stmp; - sout->size = isize; - } - - memcpy(sout->sd.s, s2app->s, s2app->len); - sout->sd.len = isize; - - return 0; -} - -int app2dynchr(dynstr *sout, char capp) -{ - char *stmp; - int isize = sout->sd.len + 1; - - if(isize > sout->size) { - stmp = pkg_realloc(sout->sd.s, isize); - if(!stmp) { - LOG(L_ERR, "AUTH_IDENTITY:app2dynchr: Not enough memory error\n"); - return -1; - } - sout->sd.s = stmp; - sout->size++; - } - - sout->sd.s[sout->sd.len] = capp; - sout->sd.len++; - - return 0; -} - -int app2dynstr(dynstr *sout, str *s2app) -{ - char *stmp; - int isize = sout->sd.len + s2app->len; - - if(isize > sout->size) { - stmp = pkg_realloc(sout->sd.s, isize); - if(!stmp) { - LOG(L_ERR, "AUTH_IDENTITY:app2dynstr: Not enough memory error\n"); - return -1; - } - sout->sd.s = stmp; - sout->size = isize; - } - - memcpy(&sout->sd.s[sout->sd.len], s2app->s, s2app->len); - sout->sd.len = isize; - - return 0; -} diff --git a/src/modules/auth_identity/auth_hdrs.c b/src/modules/auth_identity/auth_hdrs.c deleted file mode 100644 index c3b38d59f..000000000 --- a/src/modules/auth_identity/auth_hdrs.c +++ /dev/null @@ -1,790 +0,0 @@ -/* - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Copyright (c) 2007 iptelorg GmbH - * - */ - -/*! - * \file - * \brief Kamailio auth-identity :: Authentication headers - * \ingroup auth-identity - * Module: \ref auth-identity - */ - -#include - -#include "../../core/parser/parser_f.h" -#include "../../core/parser/parse_from.h" -#include "../../core/parser/parse_cseq.h" -#include "../../core/parser/parse_content.h" -#include "../../core/parser/parse_uri.h" -#include "../../core/parser/keys.h" -#include "../../core/parser/contact/parse_contact.h" - -#include "../../modules/tm/ut.h" -#include "../../core/data_lump.h" -#include "../../core/msg_translator.h" -#include "auth_identity.h" - - -struct hdr_field glb_contact; -char *glb_siphdr = NULL; -char *glb_msgbody = NULL; - -static int tohdr_proc(str *sout, str *soutopt, struct sip_msg *msg); -static int in_contacthdr_proc(str *sout, str *soutopt, struct sip_msg *msg); -static int out_contacthdr_proc(str *sout, str *soutopt, struct sip_msg *msg); -static int in_msgbody_proc(str *sout, str *soutopt, struct sip_msg *msg); -static int out_msgbody_proc(str *sout, str *soutopt, struct sip_msg *msg); -static void free_out_contacthdr(void); -static void free_out_msgbody(void); - - -/* macros from the core parser */ -#define LOWER_BYTE(b) ((b) | 0x20) -#define LOWER_DWORD(d) ((d) | 0x20202020) - -#define READ(val) \ - (*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24)) - -static char *auth_next_line(char *buf, char *buf_end); -static inline char *skip_ws(char *p, unsigned int size); -static char *auth_get_hf_name(char *begin, char *end, enum _hdr_types_t *type); -static int get_contact_body(char *buf, unsigned int len, str *sout); - - -/* - * Header parsing functions - */ - -/* From */ -int fromhdr_proc(str *sout, str *soutopt, struct sip_msg *msg) -{ - if((!msg->from) && (parse_headers(msg, HDR_FROM_F, 0) == -1)) { - LOG(L_ERR, "AUTH_IDENTITY:fromhdr_proc: Error while parsing FROM " - "header\n"); - return AUTH_ERROR; - } - if(!msg->from) { - LOG(L_ERR, - "AUTH_IDENTITY:fromhdr_proc: FROM header field is not found\n"); - return AUTH_NOTFOUND; - } - /* we must call parse_from_header explicitly */ - if((!(msg->from)->parsed) && (parse_from_header(msg) < 0)) { - LOG(L_ERR, - "AUTH_IDENTITY:fromhdr_proc: Error while parsing FROM body\n"); - return AUTH_ERROR; - } - - if(sout) - *sout = get_from(msg)->uri; - - if(soutopt) - *soutopt = get_from(msg)->tag_value; - - return AUTH_OK; -} - -/* To */ -static int tohdr_proc(str *sout, str *soutopt, struct sip_msg *msg) -{ - if(!msg->to && (parse_headers(msg, HDR_TO_F, 0) == -1)) { - LOG(L_ERR, "AUTH_IDENTITY:tohdr_proc: Error while parsing TO header\n"); - return AUTH_ERROR; - } - if(!msg->to) { - LOG(L_ERR, "AUTH_IDENTITY:tohdr_proc: TO header field is not found\n"); - return AUTH_NOTFOUND; - } - if(!msg->to->parsed) { - LOG(L_ERR, "AUTH_IDENTITY:tohdr_proc: TO is not parsed\n"); - return AUTH_ERROR; - } - - if(sout) - *sout = ((struct to_body *)msg->to->parsed)->uri; - - return AUTH_OK; -} - -/* Call-ID */ -int callidhdr_proc(str *sout, str *soutopt, struct sip_msg *msg) -{ - if(!msg->callid && (parse_headers(msg, HDR_CALLID_F, 0) == -1)) { - LOG(L_ERR, "AUTH_IDENTITY:callidhdr_proc: error while parsing CALLID " - "header\n"); - return AUTH_ERROR; - } - if(!msg->callid) { - LOG(L_ERR, "AUTH_IDENTITY:callidhdr_proc: CALLID header field is not " - "found\n"); - return AUTH_NOTFOUND; - } - - if(sout) - *sout = msg->callid->body; - - return AUTH_OK; -} - -/* CSeq */ -int cseqhdr_proc(str *sout, str *soutopt, struct sip_msg *msg) -{ - if(!msg->cseq && (parse_headers(msg, HDR_CSEQ_F, 0) == -1)) { - LOG(L_ERR, "AUTH_IDENTITY:cseqhdr_proc: Error while parsing CSEQ " - "header\n"); - return AUTH_ERROR; - } - if(!msg->cseq) { - LOG(L_ERR, - "AUTH_IDENTITY:cseqhdr_proc: CSEQ header field is not found\n"); - return AUTH_NOTFOUND; - } - if(!msg->cseq->parsed) { - LOG(L_ERR, "AUTH_IDENTITY:cseqhdr_proc: CSEQ is not parsed\n"); - return AUTH_ERROR; - } - - if(sout) - *sout = get_cseq(msg)->number; - if(soutopt) - *soutopt = get_cseq(msg)->method; - - return AUTH_OK; -} - -/* Date */ -int datehdr_proc(str *sout, str *soutopt, struct sip_msg *msg) -{ - if((!msg->date) && (parse_headers(msg, HDR_DATE_F, 0) == -1)) { - LOG(L_ERR, "AUTH_IDENTITY:datehdr_proc: Error while parsing DATE " - "header\n"); - return AUTH_ERROR; - } - if(!msg->date) { - LOG(AUTH_DBG_LEVEL, - "AUTH_IDENTITY:datehdr_proc: DATE header field is not found\n"); - return AUTH_NOTFOUND; - } - /* we must call parse_date_header explicitly */ - if((!(msg->date)->parsed) && (parse_date_header(msg) < 0)) { - LOG(L_ERR, - "AUTH_IDENTITY:datehdr_proc: Error while parsing DATE body\n"); - return AUTH_ERROR; - } - - if(sout) - *sout = msg->date->body; - - return AUTH_OK; -} - -/* Contact header of the incoming SIP message */ -static int in_contacthdr_proc(str *sout, str *soutopt, struct sip_msg *msg) -{ - if(!msg->contact && (parse_headers(msg, HDR_CONTACT_F, 0) == -1)) { - LOG(L_ERR, "AUTH_IDENTITY:in_contacthdr_proc: Error while parsing " - "CONTACT header\n"); - return AUTH_ERROR; - } - if(!msg->contact) { - return AUTH_NOTFOUND; - } - /* we must call parse_contact explicitly */ - if(!msg->contact->parsed && (parse_contact(msg->contact) < 0)) { - LOG(L_ERR, "AUTH_IDENTITY:in_contacthdr_proc: Error while parsing " - "CONTACT body\n"); - return AUTH_ERROR; - } - - if(sout) - *sout = ((contact_body_t *)msg->contact->parsed)->contacts->uri; - - return AUTH_OK; -} - -/* Contact header of the outgoing SIP message */ -static int out_contacthdr_proc(str *sout, str *soutopt, struct sip_msg *msg) -{ - unsigned int ulen; - int ierror; - struct dest_info dst; - int ires; - - -#ifdef USE_DNS_FAILOVER - /* get info about outbound socket */ - if((uri2dst(NULL, &dst, msg, GET_NEXT_HOP(msg), PROTO_NONE) == 0) -#else - if((uri2dst(&dst, msg, GET_NEXT_HOP(msg), PROTO_NONE) == 0) -#endif - || (dst.send_sock == 0)) { - LOG(L_ERR, "AUTH_IDENTITY:out_contacthdr_proc: Can't determinate " - "destination socket\n"); - return -1; - } - - /* we save it to global variable because we'll process it later */ - glb_siphdr = build_only_headers(msg, 1, &ulen, &ierror, &dst); - - if(ierror) - return -2; - - memset(&glb_contact, 0, sizeof(glb_contact)); - - /* parse_contact() needs only the body element of "struct hdr_field" */ - ires = get_contact_body(glb_siphdr, ulen, &glb_contact.body); - if(ires == AUTH_NOTFOUND) { - pkg_free(glb_siphdr); - glb_siphdr = NULL; - return AUTH_NOTFOUND; - } - if(ires != AUTH_OK) { - pkg_free(glb_siphdr); - glb_siphdr = NULL; - return AUTH_ERROR; - } - - if(parse_contact(&glb_contact) < 0) { - pkg_free(glb_siphdr); - glb_siphdr = NULL; - return AUTH_ERROR; - } - - if(sout) - *sout = ((contact_body_t *)glb_contact.parsed)->contacts->uri; - - return AUTH_OK; -} - -/* Identity */ -int identityhdr_proc(str *sout, str *soutopt, struct sip_msg *msg) -{ - if(!msg->identity && (parse_headers(msg, HDR_IDENTITY_F, 0) == -1)) { - LOG(L_ERR, "AUTH_IDENTITY:identityhdr_proc: Error while parsing " - "IDENTITY header\n"); - return AUTH_ERROR; - } - if(!msg->identity) { - return AUTH_NOTFOUND; - } - /* we must call parse_identityinfo_header explicitly */ - if((!(msg->identity)->parsed) && (parse_identity_header(msg) < 0)) { - LOG(L_ERR, "AUTH_IDENTITY:identityhdr_proc: Error while parsing " - "IDENTITY body\n"); - return AUTH_ERROR; - } - - if(sout) - *sout = get_identity(msg)->hash; - - return AUTH_OK; -} - -/* Identity-info */ -int identityinfohdr_proc(str *sout, str *soutopt, struct sip_msg *msg) -{ - if(!msg->identity_info - && (parse_headers(msg, HDR_IDENTITY_INFO_F, 0) == -1)) { - LOG(L_ERR, "AUTH_IDENTITY:identityinfohdr_proc: Error while parsing " - "IDENTITY-INFO header\n"); - return AUTH_ERROR; - } - if(!msg->identity_info) { - LOG(L_ERR, "AUTH_IDENTITY:identityinfohdr_proc: IDENTITY-INFO header " - "field is not found\n"); - return AUTH_NOTFOUND; - } - /* we must call parse_identityinfo_header explicitly */ - if((!(msg->identity_info)->parsed) - && (parse_identityinfo_header(msg) < 0)) { - LOG(L_ERR, "AUTH_IDENTITY:identityinfohdr_proc: Error while parsing " - "IDENTITY-INFO body\n"); - return AUTH_ERROR; - } - - if(sout) - *sout = get_identityinfo(msg)->uri; - if(soutopt) - *soutopt = get_identityinfo(msg)->domain; - - return AUTH_OK; -} - -/* body of the incoming SIP message */ -static int in_msgbody_proc(str *sout, str *soutopt, struct sip_msg *msg) -{ - if(!sout) - return AUTH_OK; - - sout->s = get_body(msg); - if(!sout->s || sout->s[0] == 0) { - sout->len = 0; - } else { - if(!msg->content_length) { - LOG(L_ERR, "AUTH_IDENTITY:route_msgbody_proc: no Content-Length " - "header found!\n"); - return AUTH_ERROR; - } - sout->len = get_content_length(msg); - } - - return AUTH_OK; -} - -/* body of the outgoing SIP message */ -static int out_msgbody_proc(str *sout, str *soutopt, struct sip_msg *msg) -{ - - unsigned int len; - int err; - struct dest_info dst; - char scontentlen[AUTH_CONTENTLENGTH_LENGTH]; - - - if(!sout) - return AUTH_OK; - -#ifdef USE_DNS_FAILOVER - /* get info about outbound socket */ - if((uri2dst(NULL, &dst, msg, GET_NEXT_HOP(msg), PROTO_NONE) == 0) -#else - if((uri2dst(&dst, msg, GET_NEXT_HOP(msg), PROTO_NONE) == 0) -#endif - || (dst.send_sock == 0)) { - LOG(L_ERR, "AUTH_IDENTITY:rtend_msgbody_proc: Can't determinate " - "destination socket\n"); - return -1; - } - - /* we save it to global variable too to be able to free it later */ - sout->s = glb_msgbody = build_body(msg, &len, &err, &dst); - if(err) { - LOG(L_ERR, "AUTH_IDENTITY:rtend_msgbody_proc: Can't build body (%d)\n", - err); - return -2; - } - - sout->len = (int)len; - - /* authentication services MUST add a Content-Length header field to - * SIP requests if one is not already present - * - * content-length (if present) must be already parsed and if destination - * protocol is not UDP then core will append Content-Length - */ - if(!msg->content_length && dst.proto == PROTO_UDP) { - snprintf(scontentlen, sizeof(scontentlen), "Content-Length: %d\r\n", - len); - scontentlen[sizeof(scontentlen) - 1] = 0; - /* if HDR_CONTENTLENGTH_T's specified then the header won't be added! */ - if(append_hf(msg, scontentlen, HDR_OTHER_T)) { - pkg_free(glb_msgbody); - glb_msgbody = NULL; - return -3; - } - } - - return AUTH_OK; -} - -/* Contact header deinitializer of outgoing message */ -static void free_out_contacthdr(void) -{ - void **h_parsed; - - h_parsed = &glb_contact.parsed; /*strict aliasing warnings workaround */ - if(glb_siphdr) { - pkg_free(glb_siphdr); - glb_siphdr = NULL; - } - - if(glb_contact.parsed) - free_contact((contact_body_t **)h_parsed); -} - -/* body deinitializer of the outgoing message */ -static void free_out_msgbody(void) -{ - if(glb_msgbody) { - pkg_free(glb_msgbody); - glb_msgbody = NULL; - } -} - -/* Digest-string assebmler function (RFC 4474 [9] */ -int digeststr_asm(dynstr *sout, struct sip_msg *msg, str *sdate, int iflags) -{ - /* incoming SIP message parser describer */ - dgst_part incoming_sip_digest_desc[] = { - {DS_FROM, fromhdr_proc, NULL, DS_REQUIRED}, - {DS_TO, tohdr_proc, NULL, DS_REQUIRED}, - {DS_CALLID, callidhdr_proc, NULL, DS_REQUIRED}, - {DS_CSEQ, cseqhdr_proc, NULL, DS_REQUIRED}, - {DS_DATE, datehdr_proc, NULL, DS_NOTREQUIRED}, - {DS_CONTACT, in_contacthdr_proc, NULL, DS_NOTREQUIRED}, - {DS_BODY, in_msgbody_proc, NULL, DS_NOTREQUIRED}, - {0, NULL, NULL, 0}}; - /* outgoing SIP message parser describer */ - dgst_part outgoing_sip_digest_desc[] = { - {DS_FROM, fromhdr_proc, NULL, DS_REQUIRED}, - {DS_TO, tohdr_proc, NULL, DS_REQUIRED}, - {DS_CALLID, callidhdr_proc, NULL, DS_REQUIRED}, - {DS_CSEQ, cseqhdr_proc, NULL, DS_REQUIRED}, - {DS_DATE, datehdr_proc, NULL, DS_NOTREQUIRED}, - {DS_CONTACT, out_contacthdr_proc, free_out_contacthdr, - DS_NOTREQUIRED}, - {DS_BODY, out_msgbody_proc, free_out_msgbody, DS_NOTREQUIRED}, - {0, NULL, NULL, 0}}; - dgst_part *pactpart; - dgst_part *sip_digest_desc; - str sact, sactopt; - int i1; - int iRes; - - - if((iflags & AUTH_INCOMING_BODY) ^ (iflags & AUTH_OUTGOING_BODY)) { - (iflags & AUTH_INCOMING_BODY) - ? (sip_digest_desc = incoming_sip_digest_desc) - : (sip_digest_desc = outgoing_sip_digest_desc); - } else - /* AUTH_INCOMING_BODY or AUTH_OUTGOING_BODY flag must set */ - return -1; - - resetstr_dynstr(sout); - - for(pactpart = &sip_digest_desc[0], i1 = 0; pactpart[i1].itype; i1++) { - iRes = pactpart[i1].pfunc(&sact, &sactopt, msg); - - /* there was an error or the required header is missing */ - if(iRes == AUTH_ERROR - || (iRes == AUTH_NOTFOUND - && (pactpart[i1].iflag & DS_REQUIRED))) - return -1; - - switch(pactpart[i1].itype) { - /* Cseq handle (we need SP instead of LWS (RFC4474 [9])) */ - case DS_CSEQ: - if(app2dynstr(sout, &sact)) - return -1; - if(app2dynchr(sout, ' ')) - return -2; - if(app2dynstr(sout, &sactopt)) - return -3; - break; - case DS_DATE: - if(iRes == AUTH_NOTFOUND) { - if(iflags & AUTH_ADD_DATE) { - if(app2dynstr(sout, sdate)) - return -8; - } else { - /* Date header must exist */ - LOG(L_ERR, "AUTH_IDENTITY:digeststr_asm: DATE header " - "is not found\n"); - return -9; - } - break; - } - if(app2dynstr(sout, &sact)) - return -10; - break; - default: - if(iRes == AUTH_NOTFOUND) - break; - if(app2dynstr(sout, &sact)) - return -10; - } - - /* if there is desctructor function available then we call it */ - if(pactpart[i1].pfreefunc) - pactpart[i1].pfreefunc(); - - /* we don't add separator after message body */ - if(pactpart[i1 + 1].itype) { - /* we append the separator */ - if(app2dynchr(sout, '|')) - return -11; - } - } - - return 0; -} - -/* copypasted and ripped from ser/modules/textops/textops.c) */ -int append_hf(struct sip_msg *msg, char *str1, enum _hdr_types_t type) -{ - struct lump *anchor; - char *s; - int len; - - if(parse_headers(msg, HDR_EOH_F, 0) == -1) { - LOG(L_ERR, "AUTH_IDENTITY:append_hf: Error while parsing message\n"); - return -1; - } - - anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, type); - if(anchor == 0) { - LOG(L_ERR, "AUTH_IDENTITY:append_hf: Can't get anchor\n"); - return -1; - } - - len = strlen(str1); - - s = (char *)pkg_malloc(len + 1); - if(!s) { - PKG_MEM_ERROR; - return -1; - } - - memcpy(s, str1, len); - s[len] = '\0'; - - if(insert_new_lump_before(anchor, s, len, type) == 0) { - LOG(L_ERR, "AUTH_IDENTITY:append_hf: Can't insert lump\n"); - pkg_free(s); - return -1; - } - return 0; -} - -/* get the current system date and appends it to the message */ -int append_date(str *sdate, int idatesize, time_t *tout, struct sip_msg *msg) -{ - char date_hf[AUTH_TIME_LENGTH]; - char date_str[AUTH_TIME_LENGTH]; - time_t tdate_now; - struct tm *bd_time; - size_t ilen; - int istrlen; - - - if((tdate_now = time(0)) < 0) { - LOG(L_ERR, "AUTH_IDENTITY:append_date: time error %s\n", - strerror(errno)); - return -1; - } - if(!(bd_time = gmtime(&tdate_now))) { - LOG(L_ERR, "AUTH_IDENTITY:append_date: gmtime error\n"); - return -2; - } - - ilen = strftime(date_str, sizeof(date_str), AUTH_TIME_FORMAT, bd_time); - if(ilen >= sizeof(date_hf) - strlen("Date: \r\n.") || ilen == 0) { - LOG(L_ERR, "AUTH_IDENTITY:append_date: unexpected time length\n"); - return -3; - } - - /* we append the date header to the message too */ - istrlen = strlen("Date: "); - memcpy(date_hf, "Date: ", istrlen); - memcpy(date_hf + istrlen, date_str, ilen); - istrlen += ilen; - date_hf[istrlen] = '\r'; - date_hf[istrlen + 1] = '\n'; - date_hf[istrlen + 2] = 0; - if(append_hf(msg, date_hf, HDR_DATE_T)) - return -4; - - if(sdate && idatesize >= ilen) { - memcpy(sdate->s, date_str, ilen); - sdate->len = ilen; - } else { - return -5; - } - - if(tout) - *tout = tdate_now; - - return 0; -} - -/* - * - * "Contact" header parser part - * - */ - - -/* returns a pointer to the next line */ -static char *auth_next_line(char *buf, char *buf_end) -{ - char *c; - - c = buf; - do { - while((c < buf_end) && (*c != '\n')) - c++; - if(c < buf_end) - c++; - if((c < buf_end) && (*c == '\r')) - c++; - - } while((c < buf_end) - && ((*c == ' ') - || (*c == '\t'))); /* next line begins with whitespace line folding */ - - return c; -} - -/* - * Skip all white-chars and return position of the first - * non-white char - */ -static inline char *skip_ws(char *p, unsigned int size) -{ - char *end; - - end = p + size; - for(; p < end; p++) { - if((*p != ' ') && (*p != '\t')) - return p; - } - return p; -} - -/* looks for "Contact" header */ -static char *auth_get_hf_name(char *begin, char *end, enum _hdr_types_t *type) -{ - char *p; - unsigned int val; - - - if(end - begin < 4) { - *type = HDR_ERROR_T; - return begin; - } - - p = begin; - val = LOWER_DWORD(READ(p)); - - switch(val) { - case _cont_: /* Content-Length */ - p += 4; - switch(LOWER_DWORD(READ(p))) { - case _act1_: - *type = HDR_CONTACT_T; - return (p + 4); - case _act2_: - *type = HDR_CONTACT_T; - p += 4; - goto dc_end; - } - *type = HDR_OTHER_T; - break; - default: - /* compact headers */ - switch(LOWER_BYTE(*p)) { - case 'm': - switch(*(p + 1)) { - case ' ': - *type = HDR_CONTACT_T; - p += 2; - goto dc_end; - case ':': - *type = HDR_CONTACT_T; - return (p + 2); - } - *type = HDR_OTHER_T; - break; - default: - *type = HDR_OTHER_T; - break; - } - } - -dc_end: - p = skip_ws(p, end - p); - if(*p != ':') { - goto other; - } else { - return (p + 1); - } - - /* Unknown header type */ -other: - p = q_memchr(p, ':', end - p); - if(!p) { /* No double colon found, error.. */ - *type = HDR_ERROR_T; - return 0; - } else { - *type = HDR_OTHER_T; - return (p + 1); - } - - return p; -} - -/* parses buffer that contains a SIP message header, looks for "Contact" - * header field and returns the value of that */ -static int get_contact_body(char *buf, unsigned int len, str *sout) -{ - char *end, *s, *tmp, *match; - enum _hdr_types_t hf_type; - - - end = buf + len; - s = buf; - - memset(sout, 0, sizeof(*sout)); - - while(s < end) { - if((*s == '\n') || (*s == '\r')) { - /* end of SIP msg */ - hf_type = HDR_EOH_T; - } else { - /* parse HF name */ - if(!(s = auth_get_hf_name(s, end, &hf_type))) - return AUTH_ERROR; - } - - switch(hf_type) { - case HDR_CONTACT_T: - tmp = eat_lws_end(s, end); - if(tmp >= end) { - LOG(L_ERR, "AUTH_IDENTITY:get_contact_body: get_hdr_field: " - "HF empty\n"); - return AUTH_ERROR; - } - sout->s = tmp; - /* find lf */ - do { - match = q_memchr(tmp, '\n', end - tmp); - if(match) { - match++; - } else { - LOG(L_ERR, "AUTH_IDENTITY:get_contact_body: bad msg " - "body\n"); - return AUTH_ERROR; - } - tmp = match; - } while(match < end && ((*match == ' ') || (*match == '\t'))); - tmp = match; - sout->len = match - sout->s; - trim_r(*sout); - return AUTH_OK; - break; - case HDR_ERROR_T: - return AUTH_ERROR; - default: - s = auth_next_line(s, end); - } - } - - return AUTH_NOTFOUND; -} diff --git a/src/modules/auth_identity/auth_http.c b/src/modules/auth_identity/auth_http.c deleted file mode 100644 index 0f03a7ef0..000000000 --- a/src/modules/auth_identity/auth_http.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2007 iptelorg GmbH - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -/*! - * \file - * \brief Kamailio auth-identity :: HTTP - * \ingroup auth-identity - * Module: \ref auth-identity - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include "../../core/mem/mem.h" -#include "../../core/data_lump.h" - -#include "auth_identity.h" - -size_t curlmem_cb(void *ptr, size_t size, size_t nmemb, void *data) -{ - size_t irealsize = size * nmemb; - - /* too big certificate */ - if(((str *)data)->len + irealsize >= CERTIFICATE_LENGTH) - return 0; - - memcpy(&(((str *)data)->s[((str *)data)->len]), ptr, irealsize); - ((str *)data)->len += irealsize; - - return irealsize; -} - -int download_cer(str *suri, CURL *hcurl) -{ - CURLcode iRes; - long lerr = 200; - char snulled[CERTIFICATE_URL_LENGTH], *snulledptr = NULL; - int iRet = 0; - - if(suri->len < sizeof(snulled)) { - memcpy(snulled, suri->s, suri->len); - snulled[suri->len] = 0; - } else { - /* +1 for the terminating \0 byte */ - if(!(snulledptr = pkg_malloc(suri->len + 1))) { - PKG_MEM_ERROR; - return -1; - } - memcpy(snulledptr, suri->s, suri->len); - snulledptr[suri->len] = 0; - } - - do { - if((iRes = curl_easy_setopt( - hcurl, CURLOPT_URL, snulledptr ? snulledptr : snulled)) - != 0) { - LOG(L_ERR, - "AUTH_IDENTITY:download_cer: Unable to set the url of " - "certificate: %s\n", - curl_easy_strerror(iRes)); - iRet = -2; - break; - } - - if((iRes = curl_easy_perform(hcurl)) != 0) { - LOG(L_ERR, - "AUTH_IDENTITY:download_cer: Error while downloading " - "certificate '%s'\n", - curl_easy_strerror(iRes)); - iRet = -3; - break; - } - - curl_easy_getinfo(hcurl, CURLINFO_RESPONSE_CODE, &lerr); - if(lerr / 100 != 2) { - LOG(L_ERR, "AUTH_IDENTITY:download_cer: Bad HTTP response: %ld\n", - lerr); - iRet = -4; - } - } while(0); - - if(snulledptr) - pkg_free(snulledptr); - - return iRet; -} diff --git a/src/modules/auth_identity/auth_identity.c b/src/modules/auth_identity/auth_identity.c deleted file mode 100644 index 911323cbb..000000000 --- a/src/modules/auth_identity/auth_identity.c +++ /dev/null @@ -1,878 +0,0 @@ -/* - * Copyright (c) 2007 iptelorg GmbH - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/*! - * \file - * \brief Kamailio auth-identity :: Module interface - * \ingroup auth-identity - * Module: \ref auth-identity - */ - -/*! \defgroup auth-identity Kamailio SIP identity support - * - * Auth Identity module provides functionalities for securely identifying - * originators of SIP messages. This module has two basic service: - * - authorizer - authorizes a message and adds Identity and Identity-Info headers - * - verifier - verifies an authorized message - * - */ - - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include "../../core/dprint.h" -#include "../../core/ut.h" -#include "../../core/sr_module.h" -#include "../../core/mem/mem.h" -#include "../../core/parser/parse_from.h" -#include "../../core/parser/parse_cseq.h" -#include "../../core/parser/parse_content.h" -#include "../../core/parser/parse_uri.h" -#include "../../core/parser/contact/parse_contact.h" -#include "../../core/timer.h" - -#include "auth_identity.h" - -MODULE_VERSION; - -static int mod_init(void); /* Module initialization function */ -static void mod_deinit(void); -static int add_identity(struct sip_msg *msg, char *srt1, char *str2); -static int get_certificate(struct sip_msg *msg, char *srt1, char *str2); -static int check_validity(struct sip_msg *msg, char *srt1, char *str2); -static int check_date(struct sip_msg *msg, char *srt1, char *str2); -static int check_callid(struct sip_msg *msg, char *srt1, char *str2); -static int date_proc(struct sip_msg *msg, char *srt1, char *str2); -static int check_certificate(struct sip_msg *msg, char *srt1, char *str2); -void callid_gc(unsigned int tick, void *param); - -/* - * Module parameter variables - */ -char *glb_sprivkeypath = ""; /* private key of the authentication service */ -char *glb_sservercerturl = - ""; /* URL of the certificate of the authentication service */ -char *glb_sservercertpath = - ""; /* Path of the certificate of the authentication service */ -int glb_icertlimit = CERTIFICATE_TABLE_ITEM_LIMIT; -char *glb_scainfo = ""; -int glb_iauthval = - AUTH_MSG_VALIDITY_TIME; /* Message validity time in seconds (verification service)*/ -int glb_imsgtime = - AUTH_MSG_TO_AUTH_VALIDITY_TIME; /* Message validity time in seconds (authentication service)*/ -int glb_icallidlimit = CALLID_TABLE_ITEM_LIMIT; - -CURL *glb_hcurl; /* global cURL handle */ -X509 *glb_pcertx509 = NULL; -X509_STORE *glb_cacerts = NULL; - -RSA *glb_hmyprivkey = NULL; /* private key of the authentication service */ -time_t glb_imycertnotafter = 0; - -int glb_authservice_disabled = 0; -int glb_acceptpem = 0; - -dynstr glb_sdgst = {{0, 0}, 0}; /* Digest string */ -dynstr glb_sidentity = {{0, 0}, 0}; /* Identity message header */ -dynstr glb_sidentityinfo = {{0, 0}, 0}; /* Identity-info message header */ -dynstr glb_sdate = {{0, 0}, 0}; /* Date message header */ - -dynstr glb_encedmsg = {{0, 0}, 0}; /* buffer for rsa encrypted string */ -dynstr glb_b64encedmsg = { - {0, 0}, 0}; /* buffer for base64, rsa encrypted string */ - -ttable *glb_tcert_table = 0; /* Certificate Table */ -char glb_certisdownloaded = 0; -tcert_item glb_tcert = {{0, 0}, {0, 0}, 0}; /* Actually Used Certificate */ - -ttable *glb_tcallid_table = 0; /* Certificate Table */ -typedef struct timeparams -{ /* sturct of the callid garbage collector */ - int ibnow; /* the actual bucket we've not checked yet */ - int ibnum; /* number of the buckets we've to check */ - int ibcir; /* timer function's called this times during the whole table check */ -} ttimeparams; -ttimeparams glb_ttimeparams = {0, 0, 0}; - -/* - * Exported functions - */ -static cmd_export_t glb_cmds[] = { - {"auth_date_proc", date_proc, 0, 0, 0, REQUEST_ROUTE}, - {"auth_add_identity", add_identity, 0, 0, 0, REQUEST_ROUTE}, - {"vrfy_get_certificate", get_certificate, 0, 0, 0, REQUEST_ROUTE}, - {"vrfy_check_msgvalidity", check_validity, 0, 0, 0, REQUEST_ROUTE}, - {"vrfy_check_certificate", check_certificate, 0, 0, 0, REQUEST_ROUTE}, - {"vrfy_check_date", check_date, 0, 0, 0, REQUEST_ROUTE}, - {"vrfy_check_callid", check_callid, 0, 0, 0, REQUEST_ROUTE}, - {0, 0, 0, 0, 0, 0}}; - - -/* - * Exported parameters - */ -static param_export_t glb_params[] = { - {"privatekey_path", PARAM_STRING, &glb_sprivkeypath}, - {"certificate_url", PARAM_STRING, &glb_sservercerturl}, - {"certificate_cache_limit", PARAM_INT, &glb_icertlimit}, - {"callid_cache_limit", PARAM_INT, &glb_icallidlimit}, - {"certificate_path", PARAM_STRING, &glb_sservercertpath}, - {"auth_validity_time", PARAM_INT, &glb_iauthval}, - {"msg_timeout", PARAM_INT, &glb_imsgtime}, - {"cainfo_path", PARAM_STRING, &glb_scainfo}, - {"accept_pem_certs", PARAM_INT, &glb_acceptpem}, {0, 0, 0}}; - - -/* - * Module interface - */ -struct module_exports exports = { - "auth_identity", DEFAULT_DLFLAGS, /* dlopen flags */ - glb_cmds, /* Exported functions */ - glb_params, /* Exported parameters */ - 0, /* RPC methods */ - 0, /* pseudo-variables exports */ - 0, /* response function */ - mod_init, /* module initialization function */ - 0, /* child initialization function */ - mod_deinit /* destroy function */ -}; - - -static int mod_init(void) -{ - CURLcode iRet; - str sstr; - FILE *hpemfile; - char serr[160]; - X509 *pmycert = NULL; /* certificate of the authentication service */ - time_t tnow, ttmp; - - /* - * - * Parameter check - * - */ - if(glb_sprivkeypath[0] == 0) { - LOG(L_WARN, "AUTH_IDENTITY:mod_init: Private key path is missing! " - "Authorization service is disabled\n"); - glb_authservice_disabled = 1; - } - if(!glb_authservice_disabled && glb_sservercerturl[0] == 0) { - LOG(L_WARN, "AUTH_IDENTITY:mod_init: URL of certificate of the server " - "is missing! Authorization service is disabled\n"); - glb_authservice_disabled = 1; - } - if(!glb_authservice_disabled && glb_sservercertpath[0] == 0) { - LOG(L_WARN, "AUTH_IDENTITY:mod_init: Path of certificate of the server " - "is missing! Authorization service is disabled\n"); - glb_authservice_disabled = 1; - } - - /* - * - * Init the curl session and download buffer - * - */ - curl_global_init(CURL_GLOBAL_ALL); - if((glb_hcurl = curl_easy_init()) == NULL) { - LOG(L_ERR, "AUTH_IDENTITY:mod_init: Unable to init cURL library!\n"); - return -1; - } - /* send all data to this function */ - if((iRet = curl_easy_setopt(glb_hcurl, CURLOPT_WRITEFUNCTION, curlmem_cb)) - != 0) { - LOG(L_ERR, - "AUTH_IDENTITY:mod_init: Unable to set cURL write function " - "option: %s\n", - curl_easy_strerror(iRet)); - return -2; - } - /* we pass our 'glb_tcert' struct to the callback function */ - if((iRet = curl_easy_setopt( - glb_hcurl, CURLOPT_WRITEDATA, (void *)(&glb_tcert.scertpem))) - != 0) { - LOG(L_ERR, - "AUTH_IDENTITY:mod_init: Unable to set cURL writedata option: " - "%s\n", - curl_easy_strerror(iRet)); - return -4; - } - if(!(glb_tcert.scertpem.s = pkg_malloc(CERTIFICATE_LENGTH))) { - PKG_MEM_ERROR; - return -3; - } - /* some servers don't like requests that are made without a user-agent - field, so we provide one */ - if((iRet = curl_easy_setopt( - glb_hcurl, CURLOPT_USERAGENT, NAME "-Agent/1.0")) - != 0) { - LOG(L_WARN, - "AUTH_IDENTITY:mod_init: Unable to set cURL useragent option: " - "%s\n", - curl_easy_strerror(iRet)); - } - if((iRet = curl_easy_setopt(glb_hcurl, CURLOPT_SSL_VERIFYPEER, 1)) != 0) { - LOG(L_WARN, - "AUTH_IDENTITY:mod_init: Unable to set cURL verifypeer option: " - "%s\n", - curl_easy_strerror(iRet)); - } - if((iRet = curl_easy_setopt(glb_hcurl, CURLOPT_SSL_VERIFYHOST, 2)) != 0) { - LOG(L_WARN, - "AUTH_IDENTITY:mod_init: Unable to set cURL verifyhost option: " - "%s\n", - curl_easy_strerror(iRet)); - } - - /* cainfo_path module parameter's been set */ - if(glb_scainfo[0]) { - if((iRet = curl_easy_setopt(glb_hcurl, CURLOPT_CAINFO, glb_scainfo)) - != 0) { - LOG(L_WARN, - "AUTH_IDENTITY:mod_init: Unable to set cURL cainfo option: " - "%s\n", - curl_easy_strerror(iRet)); - } - } - - - /* - * - * OpenSSL certificate verification initialization - * - */ - OpenSSL_add_all_algorithms(); - if(!(glb_cacerts = X509_STORE_new())) { - LOG(L_ERR, "AUTH_IDENTITY:mod_init: unable to initialize X509 store\n"); - return -16; - } - if(X509_STORE_set_default_paths(glb_cacerts) != 1) { - LOG(L_ERR, "AUTH_IDENTITY:mod_init: unable to set X509 store default " - "path\n"); - return -17; - } - if(glb_scainfo[0] - && X509_STORE_load_locations(glb_cacerts, glb_scainfo, NULL) != 1) - LOG(L_WARN, - "AUTH_IDENTITY:mod_init: unable to load X509 store location\n"); - - - /* - * - * Init the Date, Digest-String, Identity and Identity-Info - * - */ - if(initdynstr(&glb_sdgst, DGST_STR_INIT_SIZE)) - return -5; - - /* - * Init certificate table - */ - if(init_table(&glb_tcert_table, CERTIFICATE_TABLE_ENTRIES, glb_icertlimit, - cert_item_cmp, cert_item_init, cert_item_least, cert_item_free, - NULL)) - return -5; - - /* - * Init call-id table - */ - if(init_table(&glb_tcallid_table, CALLID_TABLE_ITEM_LIMIT, glb_icallidlimit, - cid_item_cmp, cid_item_init, cid_item_least, cid_item_free, - cid_item_gc)) - return -5; - - glb_ttimeparams.ibnow = 0; - /* we've to check the whole table in glb_imsgtime, so the number of - buckets we've to check in every timer call is - CALLID_TABLE_ENTRIES/glb_imsgtime/CALLID_GARBAGE_COLLECTOR_INTERVAL */ - glb_ttimeparams.ibcir = glb_iauthval / CALLID_GARBAGE_COLLECTOR_INTERVAL; - if(!glb_ttimeparams.ibcir) - glb_ttimeparams.ibcir = 1; - glb_ttimeparams.ibnum = CALLID_TABLE_ENTRIES / glb_ttimeparams.ibcir; - - if(register_timer(callid_gc, (void *)&glb_ttimeparams /* param*/, - CALLID_GARBAGE_COLLECTOR_INTERVAL /* period */) - < 0) { - LOG(L_ERR, "AUTH_IDENTITY:mod_init: Can not register timer\n"); - return -5; - } - - /* - * If there were not enough parameter set then we could not initialize - * the authorizer part - */ - if(glb_authservice_disabled) - return 0; - - - if(initdynstr(&glb_sidentity, DGST_STR_INIT_SIZE)) - return -6; - - if(initdynstr(&glb_sdate, AUTH_TIME_LENGTH)) - return -7; - - if(initdynstr(&glb_sidentityinfo, AUTH_URL_LENGTH)) - return -8; - - /* we initialize indentity info header */ - sstr.s = IDENTITY_INFO_FIRST_PART; - sstr.len = strlen(IDENTITY_INFO_FIRST_PART); - if(cpy2dynstr(&glb_sidentityinfo, &sstr)) - return -9; - sstr.s = glb_sservercerturl; - sstr.len = strlen(glb_sservercerturl); - if(app2dynstr(&glb_sidentityinfo, &sstr)) - return -10; - sstr.s = IDENTITY_INFO_LAST_PART; - /* we copy the trailing \0 because append_hf expects strings */ - sstr.len = strlen(IDENTITY_INFO_LAST_PART) + 1; - if(app2dynstr(&glb_sidentityinfo, &sstr)) - return -11; - - /* - * Get my certificate - */ - if(!(hpemfile = fopen(glb_sservercertpath, "r"))) { - LOG(L_ERR, "AUTH_IDENTITY:mod_init: unable to open certificate '%s'\n", - strerror(errno)); - return -12; - } - if(!(pmycert = PEM_read_X509(hpemfile, NULL, NULL, NULL))) { - ERR_error_string_n(ERR_get_error(), serr, sizeof serr); - LOG(L_ERR, "AUTH_IDENTITY:mod_init: '%s'\n", serr); - fclose(hpemfile); - return -13; - } - if(x509_get_notafter(&glb_imycertnotafter, pmycert)) { - LOG(L_ERR, "AUTH_IDENTITY:mod_init: Error getting certificate " - "expiration date\n"); - fclose(hpemfile); - return -13; - } - if(x509_get_notbefore(&ttmp, pmycert)) { - LOG(L_ERR, "AUTH_IDENTITY:mod_init: Error getting certificate validity " - "date\n"); - fclose(hpemfile); - return -13; - } - if((tnow = time(0)) < 0) { - LOG(L_ERR, "AUTH_IDENTITY:mod_init: time error %s\n", strerror(errno)); - fclose(hpemfile); - return -13; - } - if(tnow < ttmp || tnow > glb_imycertnotafter) { - LOG(L_ERR, - "AUTH_IDENTITY:mod_init: Date of certificate is invalid (%s)\n", - glb_sservercertpath); - fclose(hpemfile); - return -14; - } - - if(fclose(hpemfile)) - LOG(L_ERR, "AUTH_IDENTITY:mod_init: unable to close file\n"); - X509_free(pmycert); - - /* - * - * Init RSA-SHA1 encoder - * - */ - hpemfile = fopen(glb_sprivkeypath, "r"); - if(!hpemfile) { - LOG(L_ERR, "AUTH_IDENTITY:mod_init: unable to open private key '%s'\n", - strerror(errno)); - return -12; - } - glb_hmyprivkey = PEM_read_RSAPrivateKey(hpemfile, NULL, NULL, NULL); - if(!glb_hmyprivkey) { - ERR_error_string_n(ERR_get_error(), serr, sizeof serr); - LOG(L_ERR, "AUTH_IDENTITY:mod_init: '%s'\n", serr); - fclose(hpemfile); - return -13; - } - if(fclose(hpemfile)) - LOG(L_ERR, "AUTH_IDENTITY:mod_init: unable to close file\n"); - - /* we encrypt the digest string hash to this buffer */ - if(initdynstr(&glb_encedmsg, RSA_size(glb_hmyprivkey))) - return -14; - - /* we base64 encode the encrypted digest string hash to this buffer */ - if(initdynstr(&glb_b64encedmsg, (RSA_size(glb_hmyprivkey) / 3 + 1) * 4)) - return -15; - - return 0; -} - - -static void mod_deinit(void) -{ - curl_easy_cleanup(glb_hcurl); - if(glb_tcert.scertpem.s) - pkg_free(glb_tcert.scertpem.s); - free_dynstr(&glb_sdgst); - free_dynstr(&glb_sidentity); - free_dynstr(&glb_sdate); - free_table(glb_tcert_table); - free_table(glb_tcallid_table); - - if(glb_cacerts) - X509_STORE_free(glb_cacerts); -} - - -/* - * - * VERIFIER FUNCTIONS - * - */ - - -static int get_certificate(struct sip_msg *msg, char *srt1, char *str2) -{ - if(identityinfohdr_proc(&glb_tcert.surl, NULL, msg)) - return -3; - - /* we support rsa-sha1 only (alg.len==0 then we use rsa-sha1) */ - if(get_identityinfo(msg)->alg.len - && (get_identityinfo(msg)->alg.len != strlen("rsa-sha1") - || strncasecmp("rsa-sha1", get_identityinfo(msg)->alg.s, - get_identityinfo(msg)->alg.len))) { - LOG(L_ERR, "AUTH_IDENTITY:get_certificate: Unsupported Identity-Info " - "algorithm\n"); - return -5; - } - - /* this case ivalidbefore==0 signs that this certificate was downloaded */ - glb_tcert.ivalidbefore = 0; - - /* check whether this certificate is our certificate table */ - if(get_cert_from_table(glb_tcert_table, &glb_tcert.surl, &glb_tcert)) { - /* we did not found it in the table, so we've to download it */ - /* we reset the PEM buffer */ - glb_tcert.scertpem.len = 0; - if(download_cer(&glb_tcert.surl, glb_hcurl)) - return -6; - glb_certisdownloaded = 1; - } else - glb_certisdownloaded = 0; - - if(retrieve_x509(&glb_pcertx509, &glb_tcert.scertpem, glb_acceptpem)) - return -7; - - - return 1; -} - -/* - * If the digest-string, assembled from the message, corresponds to the string - * decoded from the Identity header by the acquired public key then the message - * is valid. RFC 4474 [6] Step 3 - */ -static int check_validity(struct sip_msg *msg, char *srt1, char *str2) -{ - str sidentity; - char sencedsha[HASH_STR_SIZE]; - int iencedshalen; -#ifndef NEW_RSA_PROC - char ssha[HASH_STR_SIZE]; -#endif - int ishalen; - unsigned char sstrcrypted[SHA_DIGEST_LENGTH]; - int iRet = 1; - - - if(!glb_pcertx509) { - LOG(L_ERR, "AUTH_IDENTITY:check_validity: Certificate uninitialized! " - "(has vrfy_get_certificate been called?)\n"); - return -1; - } - - do { - /* get the value of identity header parsed */ - if(identityhdr_proc(&sidentity, NULL, msg)) { - iRet = -1; - break; - } - - /* the length of identity value should be 172 octets long */ - if(sidentity.len > sizeof(sencedsha)) { - LOG(L_ERR, - "AUTH_IDENTITY:check_validity: Unexpected Identity length " - "(%d)\n", - sidentity.len); - iRet = -2; - break; - } - - /* base64 decode the value of Identity header */ - base64decode(sidentity.s, sidentity.len, sencedsha, &iencedshalen); - - /* assemble the digest string to be able to compare it with decrypted one */ - if(digeststr_asm(&glb_sdgst, msg, NULL, AUTH_INCOMING_BODY)) { - iRet = -5; - break; - } - /* calculate hash */ - SHA1((unsigned char *)getstr_dynstr(&glb_sdgst).s, - getstr_dynstr(&glb_sdgst).len, sstrcrypted); - -#ifdef NEW_RSA_PROC - /* decrypt with public key retrieved from the downloaded certificate - and compare it with the calculated digest hash */ - if(rsa_sha1_dec(sencedsha, iencedshalen, (char *)sstrcrypted, - sizeof(sstrcrypted), &ishalen, glb_pcertx509)) { - iRet = -3; - break; - } else - LOG(AUTH_DBG_LEVEL, "AUTH_IDENTITY VERIFIER: Identity OK\n"); -#else - /* decrypt with public key retrieved from the downloaded certificate */ - if(rsa_sha1_dec(sencedsha, iencedshalen, ssha, sizeof(ssha), &ishalen, - glb_pcertx509)) { - iRet = -3; - break; - } - - /* check size */ - if(ishalen != sizeof(sstrcrypted)) { - LOG(L_ERR, - "AUTH_IDENTITY:check_validity: Unexpected decrypted hash " - "length (%d != %d)\n", - ishalen, SHA_DIGEST_LENGTH); - iRet = -4; - break; - } - /* compare */ - if(memcmp(sstrcrypted, ssha, ishalen)) { - LOG(L_INFO, "AUTH_IDENTITY VERIFIER: comparing hashes failed -> " - "Invalid Identity Header\n"); - iRet = -6; - break; - } else - LOG(AUTH_DBG_LEVEL, "AUTH_IDENTITY VERIFIER: Identity OK\n"); -#endif - } while(0); - - glb_pcertx509 = NULL; - - return iRet; -} - -/* - * The Date header must indicate a time within 3600 seconds of the receipt of a - * message. RFC 4474 [6] Step 4 - */ -static int check_date(struct sip_msg *msg, char *srt1, char *str2) -{ - time_t tnow, tmsg; - int ires; - - ires = datehdr_proc(NULL, NULL, msg); - if(ires) - return -1; - - -#ifdef HAVE_TIMEGM - tmsg = timegm(&get_date(msg)->date); -#else - tmsg = _timegm(&get_date(msg)->date); -#endif - if(tmsg < 0) { - LOG(L_ERR, "AUTH_IDENTITY:check_date: timegm error\n"); - return -2; - } - - if((tnow = time(0)) < 0) { - LOG(L_ERR, "AUTH_IDENTITY:check_date: time error %s\n", - strerror(errno)); - return -3; - } - - if(tnow > tmsg + glb_iauthval) { - LOG(L_INFO, - "AUTH_IDENTITY VERIFIER: Outdated date header value " - "(%" TIME_T_FMT " sec)\n", - TIME_T_CAST(tnow - tmsg + glb_iauthval)); - return -4; - } else - LOG(AUTH_DBG_LEVEL, "AUTH_IDENTITY VERIFIER: Date header value OK\n"); - - return 1; -} - - -int check_certificate(struct sip_msg *msg, char *srt1, char *str2) -{ - struct sip_uri tfrom_uri; - str suri; - - if(!glb_pcertx509) { - LOG(L_ERR, "AUTH_IDENTITY:check_certificate: Certificate " - "uninitialized! (has vrfy_get_certificate been called?)\n"); - return -1; - } - /* this certificate was downloaded so we've to verify and add it to table */ - if(glb_certisdownloaded) { - if(fromhdr_proc(&suri, NULL, msg)) - return -1; - - if(parse_uri(suri.s, suri.len, &tfrom_uri)) { - LOG(L_ERR, "AUTH_IDENTITY:get_certificate: Error while parsing " - "FROM URI\n"); - return -2; - } - - if(verify_x509(glb_pcertx509, glb_cacerts)) - return -3; - - if(check_x509_subj(glb_pcertx509, &tfrom_uri.host)) - return -4; - - /* we retrieve expiration date from the certificate (it needs for - certificate table garbage collector) */ - if(x509_get_notafter(&glb_tcert.ivalidbefore, glb_pcertx509)) - return -5; - - if(addcert2table(glb_tcert_table, &glb_tcert)) - return -6; - } - return 1; -} - -static int check_callid(struct sip_msg *msg, char *srt1, char *str2) -{ - str scid, sftag, scseqnum; - unsigned int ucseq; - int ires; - time_t ivalidbefore; - - - if(callidhdr_proc(&scid, NULL, msg)) - return -1; - - if(cseqhdr_proc(&scseqnum, NULL, msg)) - return -2; - if(str2int(&scseqnum, &ucseq)) - return -3; - - if(fromhdr_proc(NULL, &sftag, msg)) - return -4; - - if((ivalidbefore = time(0)) < 0) { - LOG(L_ERR, "AUTH_IDENTITY:check_callid: time error %s\n", - strerror(errno)); - return -5; - } - - ires = proc_cid(glb_tcallid_table, &scid, &sftag, ucseq, - ivalidbefore + glb_iauthval); - if(ires) { - if(ires == AUTH_FOUND) - LOG(L_INFO, "AUTH_IDENTITY VERIFIER: Call is replayed!\n"); - return -6; - } - - return 1; -} - - -void callid_gc(unsigned int tick, void *param) -{ - /* check the last slice */ - if(((ttimeparams *)param)->ibnow + 1 == ((ttimeparams *)param)->ibcir) { - garbage_collect(glb_tcallid_table, - (((ttimeparams *)param)->ibnow) * ((ttimeparams *)param)->ibnum, - CALLID_TABLE_ENTRIES - 1); - /* we step to the first slice */ - ((ttimeparams *)param)->ibnow = 0; - } else { - garbage_collect(glb_tcallid_table, - (((ttimeparams *)param)->ibnow) * ((ttimeparams *)param)->ibnum, - ((((ttimeparams *)param)->ibnow + 1) - * ((ttimeparams *)param)->ibnum) - - 1); - /* we step to the next slice */ - ((ttimeparams *)param)->ibnow++; - } -} - -/* - * - * AUTHORIZER FUNCTIONS - * - */ - -/* Checks the Date header of the message. RFC4474 [5] Step 3 */ -static int date_proc(struct sip_msg *msg, char *srt1, char *str2) -{ - str sdate; - int iRes; - time_t tmsg, tnow; - - if(glb_authservice_disabled) { - LOG(L_WARN, "AUTH_IDENTITY:date_proc: Authentication Service is " - "disabled\n"); - return -1; - } - - getstr_dynstr(&glb_sdate).len = 0; - - /* we'd like to get the DATE header of the message */ - iRes = datehdr_proc(&sdate, NULL, msg); - switch(iRes) { - case AUTH_ERROR: - return -1; - case AUTH_NOTFOUND: - if(append_date( - &getstr_dynstr(&glb_sdate), glb_sdate.size, &tmsg, msg)) - return -2; - break; - /* Message has Date header so we check that */ - case AUTH_OK: -#ifdef HAVE_TIMEGM - tmsg = timegm(&get_date(msg)->date); -#else - tmsg = _timegm(&get_date(msg)->date); -#endif - if(tmsg < 0) { - LOG(L_ERR, "AUTH_IDENTITY:date_proc: timegm error\n"); - return -3; - } - if((tnow = time(NULL)) < 0) { - LOG(L_ERR, "AUTH_IDENTITY:date_proc: time error\n"); - return -4; - } - /* - * If the value of this field contains a time different by more than - * ten minutes from the current time noted by the authentication - * service then it should reject the message. - */ - if(tmsg + glb_imsgtime < tnow || tnow + glb_imsgtime < tmsg) { - LOG(L_INFO, "AUTH_IDENTITY AUTHORIZER: Date header overdue\n"); - return -6; - } - break; - default: - /* unknown result */ - return -7; - } - - /* - * The authentication service MUST verify that the Date header - * falls within the validity period of its certificate - * RFC 4474 [6] Step 3 - */ - if(glb_imycertnotafter < tmsg) { - LOG(L_INFO, "AUTH_IDENTITY AUTHORIZER: My certificate has expired\n"); - return -8; - } - - return 1; -} - -/* - * Concates the message From, To, Call-ID, Cseq, Date, Contact header fields - * and the message body to digest-string, signs with the domain private-key, - * BASE64 encodes that, and finally adds it to the message as the 'Identity' - * header value. RFC4474 [5] Step 4 - * - * Adds Identity-Info header to the message which contains an URI from which - * its certificate can be acquired. RFC4474 [5] Step 4 - */ -static int add_identity(struct sip_msg *msg, char *srt1, char *str2) -{ - int iRes; - str sstr; - - - if(glb_authservice_disabled) { - LOG(L_WARN, "AUTH_IDENTITY:add_identity: Authentication Service is " - "disabled\n"); - return -1; - } - - /* check Date */ - iRes = datehdr_proc(NULL, NULL, msg); - switch(iRes) { - case AUTH_ERROR: - return -1; - case AUTH_NOTFOUND: - if(!getstr_dynstr(&glb_sdate).len) { - /* - * date_proc() must be called before add_identity() because - * that function initializes the Date if that not exists - * in the SIP message - */ - LOG(L_ERR, "AUTH_IDENTITY:add_identity: Date header is not " - "found (has auth_date_proc been called?)\n"); - return -2; - } - /* assemble the digest string and the DATE header is missing in the original message */ - if(digeststr_asm(&glb_sdgst, msg, &getstr_dynstr(&glb_sdate), - AUTH_OUTGOING_BODY | AUTH_ADD_DATE)) - return -3; - break; - default: - /* assemble the digest string and the DATE header is available in the message */ - if(digeststr_asm(&glb_sdgst, msg, NULL, AUTH_OUTGOING_BODY)) - return -4; - break; - } - - /* calculate the SHA1 hash and encrypt with our provate key */ - if(rsa_sha1_enc( - &glb_sdgst, &glb_encedmsg, &glb_b64encedmsg, glb_hmyprivkey)) - return -5; - - /* we assemble the value of the Identity haader */ - sstr.s = IDENTITY_FIRST_PART; - sstr.len = strlen(IDENTITY_FIRST_PART); - if(cpy2dynstr(&glb_sidentity, &sstr)) - return -6; - - if(app2dynstr(&glb_sidentity, &getstr_dynstr(&glb_b64encedmsg))) - return -7; - - sstr.s = IDENTITY_LAST_PART; - /* +1 : we need the trailing \0 character too */ - sstr.len = strlen(IDENTITY_LAST_PART) + 1; - if(app2dynstr(&glb_sidentity, &sstr)) - return -8; - - if(append_hf(msg, getstr_dynstr(&glb_sidentity).s, HDR_IDENTITY_T)) - return -9; - - if(append_hf(msg, getstr_dynstr(&glb_sidentityinfo).s, HDR_IDENTITY_INFO_T)) - return -10; - - return 1; -} diff --git a/src/modules/auth_identity/auth_identity.h b/src/modules/auth_identity/auth_identity.h deleted file mode 100644 index 1ee7c34de..000000000 --- a/src/modules/auth_identity/auth_identity.h +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (c) 2007 iptelorg GmbH - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -/*! - * \file - * \brief SIP-router auth-identity :: Module interface - * \ingroup auth-identity - * Module: \ref auth-identity - */ - -#ifndef AUTH_IDENT_H -#define AUTH_IDENT_H - -#include -#include - -#include "../../core/locking.h" -#include "../../core/mem/mem.h" -#include "../../core/parser/msg_parser.h" /* struct sip_msg */ -#include "../../core/str.h" /* struct str */ -#include "../../core/parser/parse_identity.h" -#include "../../core/parser/parse_identityinfo.h" -#include "../../core/parser/parse_date.h" - -#define NEW_RSA_PROC - -#define AUTH_DBG_LEVEL L_DBG - -#define AUTH_URL_LENGTH 512 -#define CERTIFICATE_URL_LENGTH AUTH_URL_LENGTH -#define CERTIFICATE_LENGTH 8 * 1024 -#define DGST_STR_INIT_SIZE 8 * 1024 -#define HASH_STR_SIZE 1024 -#define AUTH_TIME_FORMAT "%a, %d %b %Y %H:%M:%S GMT" -#define AUTH_TIME_LENGTH 64 -#define AUTH_CONTENTLENGTH_LENGTH AUTH_TIME_LENGTH -#define AUTH_DOMAIN_LENGTH 256 -#define IDENTITY_INFO_FIRST_PART "Identity-Info: <" -#define IDENTITY_INFO_LAST_PART ">;alg=rsa-sha1\r\n" - -#define IDENTITY_FIRST_PART "Identity: \"" -#define IDENTITY_LAST_PART "\"\r\n" - -#define ITEM_IN_BUCKET_LIMIT 8 - -#define CERTIFICATE_TABLE_ENTRIES (2 << 10) -#define CERTIFICATE_TABLE_ITEM_LIMIT \ - CERTIFICATE_TABLE_ENTRIES *ITEM_IN_BUCKET_LIMIT * 2 - -/* callid table garbage collector defines */ -#define CALLID_GARBAGE_COLLECTOR_INTERVAL 10 - -#define CALLID_TABLE_ENTRIES (2 << 13) -#define CALLID_TABLE_ITEM_LIMIT CALLID_TABLE_ENTRIES *ITEM_IN_BUCKET_LIMIT * 2 - -#define AUTH_MSG_VALIDITY_TIME 3600 -#define AUTH_MSG_TO_AUTH_VALIDITY_TIME 600 - -#define BEGIN_PEM_CERT "-----BEGIN CERTIFICATE-----" -#define BEGIN_PEM_CERT_LEN (sizeof(BEGIN_PEM_CERT) - 1) - -enum msg_part -{ - DS_FROM = 1, - DS_TO, - DS_CALLID, - DS_CSEQ, - DS_DATE, - DS_CONTACT, - DS_BODY -}; - -enum msg_part_flag -{ - DS_REQUIRED = 0, - DS_NOTREQUIRED = 1 -}; - -typedef int(msg_part_proc)(str *, str *, struct sip_msg *); -typedef void(msg_part_free_proc)(void); - -typedef struct _dgst_part -{ - int itype; - msg_part_proc *pfunc; - msg_part_free_proc *pfreefunc; - int iflag; -} dgst_part; - -enum dgststr_asm_flags -{ - AUTH_ADD_DATE = 1, - AUTH_INCOMING_BODY = 1 << 1, - AUTH_OUTGOING_BODY = 1 << 2 -}; - -enum proc_ret_val -{ - AUTH_OK, - AUTH_NOTFOUND, - AUTH_FOUND, - AUTH_ERROR -}; - - -typedef struct _dstr -{ - str sd; - int size; -} dynstr; - -int app2dynstr(dynstr *sout, str *s2app); -int app2dynchr(dynstr *sout, char capp); -int cpy2dynstr(dynstr *sout, str *s2app); -int initdynstr(dynstr *sout, int isize); -#define free_dynstr(sdyn) \ - if((sdyn)->sd.s) { \ - pkg_free((sdyn)->sd.s); \ - (sdyn)->size = 0; \ - } -#define resetstr_dynstr(sdyn) (sdyn)->sd.len = 0 -#define getstr_dynstr(sdyn) (sdyn)->sd - - -/* Table declarations */ -/* -fleast(s1, s2) return values: - 1 s2 is less than s1 - 0 s1 and s2 are equal --1 s1 is less than s2 --2 s1 is the least --3 s2 is the least - -fcmp(s1, s2) return values: - 0 s1 and s2 are the same - any other s1 and s2 are not the same - -fgc(s1) return values: - 1 s1 is garbage - 0 s1 is not garbage -*/ -typedef int(table_item_cmp)(const void *, const void *); -typedef void(table_item_free)(const void *); -typedef void(table_item_searchinit)(); -typedef int(table_item_gc)(const void *); /* garbage collector function */ -typedef struct item -{ - void *pdata; - unsigned int uhash; - struct item *pnext; - struct item *pprev; -} titem; -typedef struct bucket -{ - titem *pfirst; - titem *plast; - gen_lock_t lock; -} tbucket; -typedef struct table -{ - unsigned int unum; /* number of items */ - unsigned int ubuckets; /* number of buckets */ - unsigned int uitemlim; /* maximum of items */ - gen_lock_t lock; /* lock for unum modifiing */ - table_item_cmp *fcmp; /* compare function (used by search) */ - table_item_searchinit * - fsearchinit; /* init function (used by least item search, garbage collect) */ - table_item_cmp *fleast; /* init function (used by least item search) */ - table_item_free *ffree; /* free function */ - table_item_gc *fgc; /* garbage signer function */ - tbucket *entries; -} ttable; - - -int init_table(ttable **ptable, unsigned int ubucknum, unsigned int uitemlim, - table_item_cmp *fcmp, table_item_searchinit *searchinit, - table_item_cmp *fleast, table_item_free *ffree, table_item_gc *fgc); -void free_table(ttable *ptable); -void garbage_collect(ttable *ptable, int ihashstart, int ihashend); - -/* Certificate table declarations */ -typedef struct cert_item -{ - str surl; - str scertpem; - time_t ivalidbefore; /* expiration time */ - unsigned int uaccessed; -} tcert_item; -int cert_item_cmp(const void *s1, const void *s2); -void cert_item_init(); -int cert_item_least(const void *s1, const void *s2); -void cert_item_free(const void *sitem); -int get_cert_from_table(ttable *ptable, str *skey, tcert_item *ptarget); -int addcert2table(ttable *ptable, tcert_item *pcert); - -/* Call-ID table declarations */ -typedef struct dlg_item -{ - str sftag; /* tag of the From header */ - unsigned int ucseq; /* number part of the cseq */ - struct dlg_item *pnext; /* next dialog concerned the same call-id */ -} tdlg_item; - -typedef struct cid_item -{ - str scid; /* call-id of the message */ - time_t ivalidbefore; /* the later expiration time among dialogs concerned this call-id*/ - tdlg_item *pdlgs; /* Cseqs and From tags */ -} tcid_item; -int proc_cid(ttable *ptable, str *scid, str *sftag, unsigned int ucseq, - time_t ivalidbefore); -int cid_item_cmp(const void *s1, const void *s2); -int cid_item_least(const void *s1, const void *s2); -void cid_item_free(const void *sitem); -void cid_item_init(); -int cid_item_gc(); - -/* cURL functions */ -size_t curlmem_cb(void *ptr, size_t size, size_t nmemb, void *data); -int download_cer(str *suri, CURL *hcurl); - -/* OpenSSL, Base64 functions */ -int retrieve_x509(X509 **pcert, str *scert, int bacceptpem); -int check_x509_subj(X509 *pcert, str *sdom); -int verify_x509(X509 *pcert, X509_STORE *pcacerts); -int rsa_sha1_dec(char *sencedsha, int iencedshalen, char *ssha, int sshasize, - int *ishalen, X509 *pcertx509); -int rsa_sha1_enc( - dynstr *sdigeststr, dynstr *senc, dynstr *sencb64, RSA *hmyprivkey); -void base64decode(char *src_buf, int src_len, char *tgt_buf, int *tgt_len); -void base64encode(char *src_buf, int src_len, char *tgt_buf, int *tgt_len); -int x509_get_notafter(time_t *tout, X509 *pcert); -int x509_get_notbefore(time_t *tout, X509 *pcert); - -/* Common functions */ -int digeststr_asm(dynstr *sout, struct sip_msg *msg, str *sdate, int iflags); - -int fromhdr_proc(str *sout, str *soutopt, struct sip_msg *msg); -int cseqhdr_proc(str *sout, str *soutopt, struct sip_msg *msg); -int callidhdr_proc(str *sout, str *soutopt, struct sip_msg *msg); -int datehdr_proc(str *sout, str *soutopt, struct sip_msg *msg); -int identityhdr_proc(str *sout, str *soutopt, struct sip_msg *msg); -int identityinfohdr_proc(str *sout, str *soutopt, struct sip_msg *msg); - -int append_date(str *sdate, int idatesize, time_t *tout, struct sip_msg *msg); -int append_hf(struct sip_msg *msg, char *str1, enum _hdr_types_t type); - -#endif diff --git a/src/modules/auth_identity/auth_tables.c b/src/modules/auth_identity/auth_tables.c deleted file mode 100644 index 280f59829..000000000 --- a/src/modules/auth_identity/auth_tables.c +++ /dev/null @@ -1,577 +0,0 @@ -/* - * Copyright (c) 2007 iptelorg GmbH - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/*! - * \file - * \brief Kamailio auth-identity :: Tables - * \ingroup auth-identity - * Module: \ref auth-identity - */ - -#include -#include -#include -#include - -#include -#include -#include - -#include "../../core/mem/shm_mem.h" -#include "../../core/hashes.h" -#include "auth_identity.h" - -#define lock_element(_cell) lock_get(&((_cell)->lock)) -#define release_element(_cell) lock_release(&((_cell)->lock)) - -static int insert_into_table(ttable *ptable, void *pdata, unsigned int uhash); -static void remove_from_table_unsafe(ttable *ptable, titem *pitem); -static void remove_least(ttable *ptable, unsigned int uhash); -static void *search_item_in_table_unsafe( - ttable *ptable, const void *pneedle, unsigned int uhash); - -time_t glb_tnow = 0; /* we need for this for certificate expiration check when - * we've to remove the least item from a table */ - -int init_table(ttable **ptable, /* table we'd like to init */ - unsigned int ubucknum, /* number of buckets */ - unsigned int uitemlim, /* maximum number of table intems */ - table_item_cmp *fcmp, /* compare function used by search */ - table_item_searchinit - *fsinit, /* inits the least item searcher function */ - table_item_cmp *fleast, /* returns the less item; - * used by item remover */ - table_item_free *ffree, /* frees the data part of an item */ - table_item_gc *fgc) /* tells whether an item is garbage */ -{ - int i1; - - if(!(*ptable = (ttable *)shm_malloc(sizeof(**ptable)))) { - SHM_MEM_ERROR; - return -1; - } - memset(*ptable, 0, sizeof(**ptable)); - - if(!((*ptable)->entries = - (tbucket *)shm_malloc(sizeof(tbucket) * ubucknum))) { - SHM_MEM_ERROR; - shm_free(*ptable); - return -1; - } - memset((*ptable)->entries, 0, sizeof(tbucket) * ubucknum); - for(i1 = 0; i1 < ubucknum; i1++) { - (*ptable)->entries[i1].pfirst = NULL; - lock_init(&(*ptable)->entries[i1].lock); - } - - (*ptable)->uitemlim = uitemlim; - (*ptable)->ubuckets = ubucknum; - - (*ptable)->fcmp = fcmp; - (*ptable)->fsearchinit = fsinit; - (*ptable)->fleast = fleast; - (*ptable)->ffree = ffree; - (*ptable)->fgc = fgc; - - return 0; -} - -void free_table(ttable *ptable) -{ - unsigned int u1; - titem *pitem, *previtem; - - if(ptable) { - for(u1 = 0; u1 < ptable->ubuckets; u1++) { - pitem = ptable->entries[u1].pfirst; - while(pitem) { - previtem = pitem; - pitem = pitem->pnext; - - ptable->ffree(previtem->pdata); - shm_free(previtem); - } - } - shm_free(ptable->entries); - shm_free(ptable); - } -} - -/* appends an item at the end of the bucket specified by uhash */ -static int insert_into_table(ttable *ptable, void *pdata, unsigned int uhash) -{ - tbucket *pbucket; - titem *pitem; - char bneed2remove = 0; - - if(!(pitem = (titem *)shm_malloc(sizeof(*pitem)))) { - SHM_MEM_ERROR; - return -1; - } - - memset(pitem, 0, sizeof(*pitem)); - pitem->uhash = uhash; - pitem->pdata = pdata; - - lock_element(ptable); - /* if there is not enough room for this item then we'll remove one */ - if(ptable->unum >= ptable->uitemlim) - bneed2remove = 1; - ptable->unum++; - release_element(ptable); - - if(bneed2remove) - remove_least(ptable, uhash); - - /* locates the appropriate bucket */ - pbucket = &ptable->entries[uhash]; - - /* insert into that bucket */ - lock_element(pbucket); - if(pbucket->plast) { - pbucket->plast->pnext = pitem; - pitem->pprev = pbucket->plast; - } else - pbucket->pfirst = pitem; - pbucket->plast = pitem; - release_element(pbucket); - - return 0; -} - - -/* Un-link a cell from hash_table */ -static void remove_from_table_unsafe(ttable *ptable, titem *pitem) -{ - tbucket *pbucket = &(ptable->entries[pitem->uhash]); - - /* unlink the cell from entry list */ - if(pitem->pprev) - pitem->pprev->pnext = pitem->pnext; - else - pbucket->pfirst = pitem->pnext; - - if(pitem->pnext) - pitem->pnext->pprev = pitem->pprev; - else - pbucket->plast = pitem->pprev; - - if(ptable->ffree) - ptable->ffree(pitem->pdata); - - shm_free(pitem); -} - -/* removes the least important item from its bucket or from the following first - bucket which contains item */ -static void remove_least(ttable *ptable, unsigned int uhash) -{ - tbucket *pbucket; - unsigned int u1, uhashnow; - titem *pleastitem = NULL, *pnow; - int ires; - - if(!ptable->fleast) - return; - if(ptable->fsearchinit) - ptable->fsearchinit(); - - for(uhashnow = uhash, u1 = 0, pbucket = &(ptable->entries[uhash]); - u1 < ptable->ubuckets; - u1++, pbucket = &(ptable->entries[uhashnow])) { - - lock_element(pbucket); - /* if there any item in this bucket */ - for(pnow = pbucket->pfirst; pnow; pnow = pnow->pnext) { - if(!pleastitem) { - pleastitem = pnow; - continue; - } - - /* - fleast() return values: - 1 s2 is less than s1 - 0 s1 and s2 are equal - -1 s1 is less than s2 - -2 s1 is the least - -3 s2 is the least - */ - ires = ptable->fleast(pleastitem->pdata, pnow->pdata); - if(ires == 1) - pleastitem = pnow; - if(ires == -2) - break; - if(ires == -3) { - pleastitem = pnow; - break; - } - } - /* we found the least item in this bucket */ - if(pleastitem) { - - lock_element(ptable); - ptable->unum--; - release_element(ptable); - - remove_from_table_unsafe(ptable, pleastitem); - release_element(pbucket); - return; - } - release_element(pbucket); - - - /* we're in the last bucket so we start with the first one */ - if(uhashnow + 1 == ptable->ubuckets) - uhashnow = 0; - else - /* we step to the next bucket */ - uhashnow++; - } -} - -/* looks for an item in the scepifiad bucket */ -static void *search_item_in_table_unsafe( - ttable *ptable, const void *pneedle, unsigned int uhash) -{ - tbucket *pbucket = &(ptable->entries[uhash]); - titem *pnow; - void *pret = NULL; - - if(!ptable->fcmp) - return NULL; - - for(pnow = pbucket->pfirst; pnow; pnow = pnow->pnext) { - if(!ptable->fcmp(pneedle, pnow->pdata)) { - pret = pnow->pdata; - break; - } - } - - return pret; -} - -/* looks for garbage in the hash interval specified by ihashstart and ihashend */ -void garbage_collect(ttable *ptable, int ihashstart, int ihashend) -{ - unsigned int unum, uremoved; - int i1; - tbucket *pbucket; - titem *pnow; - - - /* there is not any garbage collector function available */ - if(!ptable->fgc) - return; - - if(ptable->fsearchinit) - ptable->fsearchinit(); - - lock_element(ptable); - unum = ptable->unum; - release_element(ptable); - - /* if the half of the table is used or there is not so many items in a bucket - then we return */ - // if (unum < ptable->uitemlim/2 && unum < ptable->ubuckets*ITEM_IN_BUCKET_LIMIT) - // return ; - if(!unum) - return; - - for(i1 = ihashstart; i1 <= ihashend; i1++) { - uremoved = 0; - pbucket = &(ptable->entries[i1]); - - lock_element(pbucket); - for(pnow = pbucket->pfirst; pnow; pnow = pnow->pnext) { - if(ptable->fgc(pnow->pdata)) { - remove_from_table_unsafe(ptable, pnow); - uremoved++; - } - } - /* if we removed any item from table then we would update the item counter */ - if(uremoved) { - lock_element(ptable); - ptable->unum -= uremoved; - release_element(ptable); - } - release_element(pbucket); - } -} - - -/* - * Make a copy of a str structure using shm_malloc - */ -static int str_duplicate(str *_d, str *_s) -{ - - _d->s = (char *)shm_malloc(sizeof(char) * (_s->len)); - if(!_d->s) { - SHM_MEM_ERROR; - return -1; - } - - memcpy(_d->s, _s->s, _s->len); - _d->len = _s->len; - return 0; -} - -/* - * - * Certificate table specific functions - * - */ -int cert_item_cmp(const void *s1, const void *s2) -{ - tcert_item *p1 = (tcert_item *)s1, *p2 = (tcert_item *)s2; - - return !(p1->surl.len == p2->surl.len - && !memcmp(p1->surl.s, p2->surl.s, p2->surl.len)); -} - -void cert_item_init() -{ - /* we need for this for certificate expiration check when - * we've to remove an item from the table */ - glb_tnow = time(0); -} - -/* we remove a certificate if expired or if accessed less than another */ -int cert_item_least(const void *s1, const void *s2) -{ - if(((tcert_item *)s1)->ivalidbefore < glb_tnow) - return -2; - if(((tcert_item *)s2)->ivalidbefore < glb_tnow) - return -3; - return (((tcert_item *)s1)->uaccessed < ((tcert_item *)s2)->uaccessed) ? -1 - : 1; -} - -/* frees a certificate item */ -void cert_item_free(const void *sitem) -{ - shm_free(((tcert_item *)sitem)->surl.s); - shm_free(((tcert_item *)sitem)->scertpem.s); - shm_free((tcert_item *)sitem); -} - -/* looks for a certificate in a table and increases access counter of that - table item */ -int get_cert_from_table(ttable *ptable, str *skey, tcert_item *ptarget) -{ - tcert_item *tmp_tcert_item; - unsigned int uhash; - int iret = 0; - - uhash = get_hash1_raw(skey->s, skey->len) & (CERTIFICATE_TABLE_ENTRIES - 1); - - /* we lock the whole bucket */ - lock_element(&ptable->entries[uhash]); - - tmp_tcert_item = - search_item_in_table_unsafe(ptable, (const void *)skey, uhash); - /* make a copy of found certificate and after the certificate - * verification we'll add it to certificate table */ - if(tmp_tcert_item) { - memcpy(ptarget->scertpem.s, tmp_tcert_item->scertpem.s, - tmp_tcert_item->scertpem.len); - ptarget->scertpem.len = tmp_tcert_item->scertpem.len; - /* we accessed this certificate */ - tmp_tcert_item->uaccessed++; - } else - iret = 1; - - release_element(&ptable->entries[uhash]); - - return iret; -} - -/* inserts an item to table, and removes the least item if the table is full */ -int addcert2table(ttable *ptable, tcert_item *pcert) -{ - tcert_item *pshmcert; - unsigned int uhash; - - if(!(pshmcert = (tcert_item *)shm_malloc(sizeof(*pshmcert)))) { - SHM_MEM_ERROR; - return -1; - } - memset(pshmcert, 0, sizeof(*pshmcert)); - if(str_duplicate(&pshmcert->surl, &pcert->surl)) - return -2; - - if(str_duplicate(&pshmcert->scertpem, &pcert->scertpem)) - return -3; - - pshmcert->ivalidbefore = pcert->ivalidbefore; - pshmcert->uaccessed = 1; - - uhash = get_hash1_raw(pcert->surl.s, pcert->surl.len) - & (CERTIFICATE_TABLE_ENTRIES - 1); - - if(insert_into_table(ptable, (void *)pshmcert, uhash)) - return -4; - - return 0; -} - -/* - * - * Call-ID table specific functions - * - */ - -int cid_item_cmp(const void *s1, const void *s2) -{ - tcid_item *p1 = (tcid_item *)s1, *p2 = (tcid_item *)s2; - - return !(p1->scid.len == p2->scid.len - && !memcmp(p1->scid.s, p2->scid.s, p2->scid.len)); -} - -void cid_item_init() -{ - glb_tnow = time(0); -} - -/* we remove a call-id if older than another */ -int cid_item_least(const void *s1, const void *s2) -{ - if(((tcid_item *)s1)->ivalidbefore < glb_tnow) - return -2; - if(((tcid_item *)s2)->ivalidbefore < glb_tnow) - return -3; - - return (((tcid_item *)s1)->ivalidbefore < ((tcid_item *)s2)->ivalidbefore) - ? -1 - : 1; -} - -/* tells whether an item is garbage */ -int cid_item_gc(const void *s1) -{ - return (((tcid_item *)s1)->ivalidbefore < glb_tnow); -} - -/* frees a call-id item */ -void cid_item_free(const void *sitem) -{ - tcid_item *pcid = (tcid_item *)sitem; - tdlg_item *pdlgs, *pdlgs_next; - - shm_free(pcid->scid.s); - - pdlgs_next = pcid->pdlgs; - while(pdlgs_next) { - pdlgs = pdlgs_next; - pdlgs_next = pdlgs_next->pnext; - shm_free(pdlgs->sftag.s); - shm_free(pdlgs); - } - - shm_free((tcert_item *)sitem); -} - -/* inserts a callid item to table, and removes the least item if the table is full */ -int proc_cid(ttable *ptable, str *scid, str *sftag, unsigned int ucseq, - time_t ivalidbefore) -{ - tcid_item *pshmcid, *pcid_item; - tdlg_item *pshmdlg, *pdlg_item, *pdlg_item_prev; - unsigned int uhash; - - /* we suppose that this SIP request is not replayed so it doesn't exist in - the table so we prepare to insert */ - if(!(pshmdlg = (tdlg_item *)shm_malloc(sizeof(*pshmdlg)))) { - SHM_MEM_ERROR; - return -1; - } - memset(pshmdlg, 0, sizeof(*pshmdlg)); - if(str_duplicate(&pshmdlg->sftag, sftag)) - return -2; - pshmdlg->ucseq = ucseq; - - - /* we're looking for this call-id item if exists */ - uhash = get_hash1_raw(scid->s, scid->len) & (CALLID_TABLE_ENTRIES - 1); - - lock_element(&ptable->entries[uhash]); - - pcid_item = search_item_in_table_unsafe(ptable, - (const void *)scid, /* Call-id is the key */ - uhash); - /* we've found one call-id so we're looking for the required SIP request */ - if(pcid_item) { - for(pdlg_item = pcid_item->pdlgs, pdlg_item_prev = NULL; pdlg_item; - pdlg_item = pdlg_item->pnext) { - if(pdlg_item->sftag.len == sftag->len - && !memcmp(pdlg_item->sftag.s, sftag->s, sftag->len)) { - /* we found this call with this from tag */ - if(pdlg_item->ucseq >= ucseq) { - /* we've found this or older request in the table! - this call is replayed! */ - release_element(&ptable->entries[uhash]); - - shm_free(pshmdlg->sftag.s); - shm_free(pshmdlg); - return AUTH_FOUND; - } else { - /* this is another later request whithin this dialog so we - update the saved cseq */ - pdlg_item->ucseq = ucseq; - release_element(&ptable->entries[uhash]); - - shm_free(pshmdlg->sftag.s); - shm_free(pshmdlg); - return 0; - } - } - /* we save the previous dialog item in order to append a new item more easily */ - pdlg_item_prev ? (pdlg_item_prev = pdlg_item_prev->pnext) - : (pdlg_item_prev = pdlg_item); - } - /* we append this to item dialogs*/ - pdlg_item_prev->pnext = pshmdlg; - /* this is the latest request; we hold all request concerned this - call-id until the latest request is valid */ - pcid_item->ivalidbefore = ivalidbefore; - } - - release_element(&ptable->entries[uhash]); - - if(!pcid_item) { - /* this is the first request with this call-id */ - if(!(pshmcid = (tcid_item *)shm_malloc(sizeof(*pshmcid)))) { - SHM_MEM_ERROR; - shm_free(pshmdlg); - return -4; - } - memset(pshmcid, 0, sizeof(*pshmcid)); - if(str_duplicate(&pshmcid->scid, scid)) { - return -5; - } - pshmcid->ivalidbefore = ivalidbefore; - pshmcid->pdlgs = pshmdlg; - if(insert_into_table(ptable, (void *)pshmcid, uhash)) - return -6; - } - - return 0; -} diff --git a/src/modules/auth_identity/doc/auth_identity.xml b/src/modules/auth_identity/doc/auth_identity.xml deleted file mode 100644 index f5817bd9c..000000000 --- a/src/modules/auth_identity/doc/auth_identity.xml +++ /dev/null @@ -1,240 +0,0 @@ - - - - - %docentities; - ] -> - - - - SIP Authenticated Identity Module - - - Gergely - Kovacs - Iptel.org -
- gergo@iptel.org -
-
-
- - 2007 - Iptel.org - -
- - - - Admin Guide -
- Overview - - Auth Identity module provides functionalities for securely identifying - originators of SIP messages. It implements the SIP Identity standard where a - SIP proxy signs messages that is sent to other domains. - This module has two basic services: - - - - authorizer - authorizes a message and adds Identity and - Identity-Info headers - - - - - verifier - verifies an authorized message - - - - - - Known limitations in this version: - - - - - authorizer and verifier support all SIP requests except for - CANCEL and REGISTER - - - - - verifier does not support the subjectAltName extension of - certificates - - - -
- -
- Dependencies - - This module does not depend any other module. - -
- -
- Compilation - - This module needs the following headers and libraries: - - - - OpenSSL (version 0.9.8 or higher) for cryptographic functions - - - - - libcurl for HTTP, HTTPS functions - - - - If you'd like to use TLS module too then use the - corresponding LIB line in auth_identity's Makefile - -
- -
- Installation And Running - - the Authorizer service needs to make the public key, - which conveyed in a certificate, available over HTTPS or HTTP for - verifiers. The domain the authorizer is responsible for and the - domain part of the URL of the certificate must be the same. This - service needs access to the private key too. - -
- - - - - - -
- Authorizer service examples - - -
- - -
- Verifier service examples - - -
-
- Remarks - - Note: libcurl leak in CentOS 6 - this module uses libcurl library - and in case if you are using CentOS 6, be aware that standard - libcurl-7.19.7-52 has a memory leak. To fix this memory, install - libcurl from city-fan repository. More details at: - - https://www.digitalocean.com/community/questions/how-to-upgrade-curl-in-centos6 - -
-
-
diff --git a/src/modules/auth_identity/doc/auth_identity_functions.xml b/src/modules/auth_identity/doc/auth_identity_functions.xml deleted file mode 100644 index 3ffa4b2eb..000000000 --- a/src/modules/auth_identity/doc/auth_identity_functions.xml +++ /dev/null @@ -1,158 +0,0 @@ - - - - - %docentities; - ] -> - -
- Functions - -
- - <function>auth_date_proc()</function> - - Note: this function is for authorizer service. - - If a message, the auth service should authorize, contains Date header - then this function checks whether it falls in message timeout (set by - msg_timeout parameter). If there is not any Date - header then the module adds one. This function also checks whether the certificate - of the authentication service (set by certificate_path parameter) - has expired. - -
- Dependencies - - No dependencies - -
-
- -
- - <function>auth_add_identity()</function> - - Note: this function is for authorizer service. - - Assembles digest-string from the message, calculates its SHA1 hash, - encrypts it with the private key (set by privatekey_path - parameter) of the authorizer service, base64 encodes it and adds to the - outgoing message as the value of Identity header. - This function also adds Identity-Info header which contains an URI - (set by certificate_url parameter) from which - the certificate of auth service can be acquired. - - - Note: this function needs the final outgoing - message for authorization, so no module may modify any - digest string related headers (From, To, Call-ID, CSeq, - Date, Contact) and body after auth_add_identity()'s been called - -
- Dependencies - - auth_date_proc() must be called before - -
-
- -
- - <function>vrfy_check_date()</function> - - Note: this function is for verifier service. - - Checks Date header of the incoming message whether falls in validity - time (set by auth_validity_time parameter) - -
- Dependencies - - No dependencies - -
-
- -
- - <function>vrfy_get_certificate()</function> - - Note: this function is for verifier service. - - Tries to get certificate defined by the value of - Identity-info header from certificate table - (which size is set by certificate_cache_limit - parameter). If the required certificate is not found there then - this function downloads it. - -
- Dependencies - - No dependencies - -
-
- -
- - <function>vrfy_check_certificate()</function> - - Note: this function is for verifier service. - - Checks whether the downloaded certificate is valid (is not expired, - its subject and the domain part of the URL are the same) and adds it - to certificate table. - -
- Dependencies - - vrfy_get_certificate() must be called before - -
-
- -
- - <function>vrfy_check_msgvalidity()</function> - - Note: this function is for verifier service. - - Assembles digest-string from the message, create SHA1 hash and - compares it with the decrypted value of Identity - header. - -
- Dependencies - - vrfy_get_certificate() must be called before and - vrfy_check_certificate() should be called before - -
-
- -
- - <function>vrfy_check_callid()</function> - - Note: this function is for verifier service. - - Checks whether the current call's been already processed in validity - time (set by auth_validity_time) to recognize - call replay attacks. If this call (identified by Call-id, Cseq, - and tag of From header triple) has not been replayed then adds it to - callid table (which size is set by callid_cache_limit - parameter). - -
- Dependencies - - This function should be called for the last time. - -
-
-
diff --git a/src/modules/auth_identity/doc/auth_identity_params.xml b/src/modules/auth_identity/doc/auth_identity_params.xml deleted file mode 100644 index 057520ce3..000000000 --- a/src/modules/auth_identity/doc/auth_identity_params.xml +++ /dev/null @@ -1,213 +0,0 @@ - - - - - %docentities; - ] -> - -
- Parameters -
- <varname>privatekey_path</varname> (string) - Note: this parameter is for authorizer service. - - The path of private key of the authentication service. The key - must be in PEM format. - - - This parameter is required by authentication service. - - - Set <varname>privatekey_path</varname> parameter - -... -modparam("auth_identity","privatekey_path","/etc/ssl/private/key.pem") -... - - -
- -
- <varname>certificate_path</varname> (string) - Note: this parameter is for authorizer service. - - The path of certificate of the authentication service. The - certificate must be in PEM format. - - - This parameter is required by authentication service. - - - Set <varname>certificate_path</varname> parameter - - -... -modparam("auth_identity","certificate_path","/var/www/ssl/mycert.pem") -... - - -
- -
- <varname>certificate_url</varname> (string) - Note: this parameter is for authorizer service. - - The url where certificate is available for other verifier - services. (value of Identity-info header) The - certificate should be in DER format. - - - This parameter is required by authentication service. - - - Set <varname>certificate_url</varname> parameter - - -... -modparam("auth_identity","certificate_url","https://foo.bar/mycert.der") -... - - -
- -
- <varname>msg_timeout</varname> (integer) - Note: this parameter is for authorizer service. - - If the Date header of message which is needed to be authenticated - contains a time different by more than this seconds from the current - time noted by the authentication service then it rejects the - message. - - - This parameter is optional. The default value is "600". - - - Set <varname>msg_timeout</varname> parameter - - -... -modparam("auth_identity","msg_timeout",600) -... - - -
- -
- <varname>auth_validity_time</varname> (integer) - Note: this parameter is for verifier service. - - The validity time of an authenticated message. The message - will be refused if it contains a time different by more - than this seconds from the current time noted by the verification - service. - - - This parameter is optional. The default value is "3600". - - - Set <varname>auth_validity_time</varname> parameter - - -... -modparam("auth_identity","auth_validity_time",3600) -... - - -
- -
- <varname>callid_cache_limit</varname> (integer) - Note: this parameter is for verifier service. - - The number of Call-IDs stored in order to recognize call replay - attacks. A Call-ID is stored auth_validity_time long and - uses approximately 100 bytes memory. - - - This parameter is optional. The default value is "32768". - (you should increase the size of shared memory with -m - command line switch if you liked to store more callid than - 10000) - - - Set <varname>auth_validity_time</varname> parameter - - -... -modparam("auth_identity","callid_cache_limit",32768) -... - - -
- -
- <varname>certificate_cache_limit</varname> (integer) - Note: this parameter is for verifier service. - - The number of certificates stored in order to avoid needless - download. A certificate is stored until its expiration date and - uses approximately 600 bytes memory. - - - This parameter is optional. The default value is "4096". - - - Set <varname>certificate_cache_limit</varname> parameter - - -... -modparam("auth_identity","certificate_cache_limit",4096) -... - - -
- -
- <varname>cainfo_path</varname> (string) - Note: this parameter is for verifier service. - - A file of trusted certificates. The file should contain multiple - certificates in PEM format concatenated together. It could be useful - for verifying a certificate signed by a private CA. - - - This parameter is optional. It has not got default value. - - - Set <varname>cainfo_path</varname> parameter - - -... -modparam("auth_identity","cainfo_path","/etc/ssl/certs/ca-certificates.crt") -... - - -
- -
- <varname>accept_pem_certs</varname> (int) - Note: this parameter is for verifier service. - - Enables the acquired certificate processing if it is in PEM - format. Value can be 0 or 1. - - - This parameter is optional. The default value is "0". - - - Set <varname>accept_pem_certs</varname> parameter - - -... -modparam("auth_identity","accept_pem_certs",1) -... - - -
-
- diff --git a/src/modules/auth_radius/auth_radius.c b/src/modules/auth_radius/auth_radius.c index 387f58d30..cbf5acaa5 100644 --- a/src/modules/auth_radius/auth_radius.c +++ b/src/modules/auth_radius/auth_radius.c @@ -120,7 +120,8 @@ static int mod_init(void) int n; if ((rh = rc_read_config(radius_config)) == NULL) { - LM_ERR("failed to open configuration file \n"); + LM_ERR("failed to open configuration file: %s\n", + (radius_config)?radius_config:"none"); return -1; } diff --git a/src/modules/avp/avp.c b/src/modules/avp/avp.c index 38fa08fe1..d04fe47f8 100644 --- a/src/modules/avp/avp.c +++ b/src/modules/avp/avp.c @@ -1454,7 +1454,7 @@ static int attr_hdr_body2attrs2( static int attr_hdr_body2attrs_fixup(void **param, int param_no) { - char *c, *params; + char *c, *sparams; hdr_name_t *h = NULL; int n; str *s; @@ -1467,9 +1467,9 @@ static int attr_hdr_body2attrs_fixup(void **param, int param_no) c); return E_CFG; } else { - params = strchr(c, PARAM_DELIM); - if(params) - n = params - c; + sparams = strchr(c, PARAM_DELIM); + if(sparams) + n = sparams - c; else n = strlen(c); if(n == 0) { @@ -1486,10 +1486,10 @@ static int attr_hdr_body2attrs_fixup(void **param, int param_no) h->name.s.s = (char *)h + sizeof(hdr_name_t); memcpy(h->name.s.s, c, n + 1); } - if(params) { + if(sparams) { h->val_types = 0; - while(*params) { - switch(*params) { + while(*sparams) { + switch(*sparams) { case 'i': case 'I': h->val_types = VAL_TYPE_INT; @@ -1504,11 +1504,11 @@ static int attr_hdr_body2attrs_fixup(void **param, int param_no) LOG(L_ERR, "attr_hdr_body2attrs_fixup: bad field param " "modifier near '%s'\n", - params); + sparams); pkg_free(h); return E_CFG; } - params++; + sparams++; } if(!h->val_types) { LOG(L_ERR, "attr_hdr_body2attrs_fixup: no field param modifier " diff --git a/src/modules/avp/avp.xml b/src/modules/avp/avp.xml index 3fbbc32c4..8fcfda6f7 100644 --- a/src/modules/avp/avp.xml +++ b/src/modules/avp/avp.xml @@ -379,7 +379,7 @@ Like set_sattr, it is identical to - assinging a string using the assignment operator and is + assigning a string using the assignment operator and is deprecated. @@ -399,7 +399,7 @@ If the attribute does not yet exist, it is created. - This function is identical to assinging an integer using the + This function is identical to assigning an integer using the assignment operator and is only kept to retain compatibility with earlier versions of SER. It therefore is deprecated and may be removed in the future. @@ -421,7 +421,7 @@ attribute does not yet exist, it is created. - This function is identical to assinging a string using the + This function is identical to assigning a string using the assignment operator and is only kept to retain compatibility with earlier versions of SER. It therefore is deprecated and may be removed in the future. diff --git a/src/modules/benchmark/benchmark.c b/src/modules/benchmark/benchmark.c index d28f8ea38..45cbe38c3 100644 --- a/src/modules/benchmark/benchmark.c +++ b/src/modules/benchmark/benchmark.c @@ -37,8 +37,9 @@ * configuration sections. * */ - +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include #include diff --git a/src/modules/blst/blst.c b/src/modules/blst/blst.c index 6a2c1d625..148a9a9d9 100644 --- a/src/modules/blst/blst.c +++ b/src/modules/blst/blst.c @@ -49,37 +49,44 @@ static int blst_rpl_set_ignore_f(struct sip_msg *, char *, char *); static int blst_rpl_clear_ignore_f(struct sip_msg *, char *, char *); -static cmd_export_t cmds[] = {{"blst_add", blst_add0_f, 0, 0, 0, ANY_ROUTE}, - {"blst_add", blst_add1_f, 1, fixup_var_int_1, 0, ANY_ROUTE}, - {"blst_add_retry_after", blst_add_retry_after_f, 2, fixup_var_int_12, 0, +/* clang-format off */ +static cmd_export_t cmds[] = { + {"blst_add", blst_add0_f, 0, 0, 0, ANY_ROUTE}, + {"blst_add", blst_add1_f, 1, fixup_var_int_1, 0, ANY_ROUTE}, + {"blst_add_retry_after", blst_add_retry_after_f, 2, fixup_var_int_12, 0, ANY_ROUTE}, - {"blst_del", blst_del_f, 0, 0, 0, ANY_ROUTE}, - {"blst_is_blocklisted", blst_is_blocklisted_f, 0, 0, 0, ANY_ROUTE}, - {"blst_set_ignore", blst_set_ignore_f, 0, 0, 0, ANY_ROUTE}, - {"blst_set_ignore", blst_set_ignore_f, 1, fixup_var_int_1, 0, + {"blst_del", blst_del_f, 0, 0, 0, ANY_ROUTE}, + {"blst_is_blocklisted", blst_is_blocklisted_f, 0, 0, 0, ANY_ROUTE}, + {"blst_set_ignore", blst_set_ignore_f, 0, 0, 0, ANY_ROUTE}, + {"blst_set_ignore", blst_set_ignore_f, 1, fixup_var_int_1, 0, ANY_ROUTE}, - {"blst_clear_ignore", blst_clear_ignore_f, 0, 0, 0, ANY_ROUTE}, - {"blst_clear_ignore", blst_clear_ignore_f, 1, fixup_var_int_1, 0, + {"blst_clear_ignore", blst_clear_ignore_f, 0, 0, 0, ANY_ROUTE}, + {"blst_clear_ignore", blst_clear_ignore_f, 1, fixup_var_int_1, 0, ANY_ROUTE}, - {"blst_rpl_set_ignore", blst_rpl_set_ignore_f, 0, 0, 0, ANY_ROUTE}, - {"blst_rpl_set_ignore", blst_rpl_set_ignore_f, 1, fixup_var_int_1, 0, + {"blst_rpl_set_ignore", blst_rpl_set_ignore_f, 0, 0, 0, ANY_ROUTE}, + {"blst_rpl_set_ignore", blst_rpl_set_ignore_f, 1, fixup_var_int_1, 0, ANY_ROUTE}, - {"blst_rpl_clear_ignore", blst_rpl_clear_ignore_f, 0, 0, 0, ANY_ROUTE}, - {"blst_rpl_clear_ignore", blst_rpl_clear_ignore_f, 1, fixup_var_int_1, + {"blst_rpl_clear_ignore", blst_rpl_clear_ignore_f, 0, 0, 0, ANY_ROUTE}, + {"blst_rpl_clear_ignore", blst_rpl_clear_ignore_f, 1, fixup_var_int_1, 0, ANY_ROUTE}, - {0, 0, 0, 0, 0, 0}}; + {0, 0, 0, 0, 0, 0} +}; static param_export_t params[] = {{0, 0, 0}}; /* no params */ struct module_exports exports = { - "blst", DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, params, 0, /* RPC methods */ - 0, /* pseudo-variables exports */ - 0, /* response function */ - 0, /* module initialization function */ - 0, /* per-child init function */ - 0 /* destroy function */ + "blst", + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, + params, + 0, /* RPC methods */ + 0, /* pseudo-variables exports */ + 0, /* response function */ + 0, /* module initialization function */ + 0, /* per-child init function */ + 0 /* destroy function */ }; +/* clang-format on */ /** diff --git a/src/modules/cdp/Makefile b/src/modules/cdp/Makefile index e2d0211f6..d95d0831c 100644 --- a/src/modules/cdp/Makefile +++ b/src/modules/cdp/Makefile @@ -26,6 +26,8 @@ endif ifneq ($(OS),darwin) LIBS += -lrt LIBS += -lpthread + LIBS += -lssl + LIBS += -lcrypto endif include ../../Makefile.modules diff --git a/src/modules/cdp/README b/src/modules/cdp/README index 253ec85a4..79e4f8512 100644 --- a/src/modules/cdp/README +++ b/src/modules/cdp/README @@ -39,6 +39,11 @@ Carsten Bock 4.3. workerq_latency_threshold (int) 4.4. workerq_length_threshold_percentage (int) 4.5. debug_heavy (int) + 4.6. enable_tls (int) + 4.7. tls_method (string) + 4.8. private_key (string) + 4.9. certificate (string) + 4.10. ca_list (string) 5. Functions @@ -136,10 +141,15 @@ Carsten Bock 1.3. Set workerq_latency_threshold parameter 1.4. Set workerq_length_threshold_percentage parameter 1.5. Set debug_heavy parameter - 1.6. cdp_check_peer usage - 1.7. cdp_check_peer usage - 1.8. cdp_check_peer usage - 1.9. DiameterPeer.xml example + 1.6. Set enable_tls parameter + 1.7. Set tls_method parameter + 1.8. Set private_key parameter + 1.9. Set certificate parameter + 1.10. Set ca_list parameter + 1.11. cdp_check_peer usage + 1.12. cdp_check_peer usage + 1.13. cdp_check_peer usage + 1.14. DiameterPeer.xml example Chapter 1. Admin Guide @@ -159,6 +169,11 @@ Chapter 1. Admin Guide 4.3. workerq_latency_threshold (int) 4.4. workerq_length_threshold_percentage (int) 4.5. debug_heavy (int) + 4.6. enable_tls (int) + 4.7. tls_method (string) + 4.8. private_key (string) + 4.9. certificate (string) + 4.10. ca_list (string) 5. Functions @@ -232,6 +247,11 @@ Chapter 1. Admin Guide 4.3. workerq_latency_threshold (int) 4.4. workerq_length_threshold_percentage (int) 4.5. debug_heavy (int) + 4.6. enable_tls (int) + 4.7. tls_method (string) + 4.8. private_key (string) + 4.9. certificate (string) + 4.10. ca_list (string) 4.1. config_file (string) @@ -294,6 +314,83 @@ modparam("cdp", "workerq_length_threshold_percentage", 25) modparam("cdp", "debug_heavy", 1) ... +4.6. enable_tls (int) + + Flag to enable TLS for communication with all the peers. + + Default value is “0”. + + Example 1.6. Set enable_tls parameter +... +modparam("cdp", "enable_tls", 1) +... + +4.7. tls_method (string) + + Sets the TLS protocol method. Possible values are: + * TLSv1.3+ - TLSv1.3 or newer connections are accepted (available + starting with openssl/libssl v1.1.1) + * TLSv1.3 - only TLSv1.3 connections are accepted (available starting + with openssl/libssl v1.1.1) + * TLSv1.2+ - TLSv1.2 or newer (TLSv1.3, ...) connections are accepted + (available starting with openssl/libssl v1.1.1) + * TLSv1.2 - only TLSv1.2 connections are accepted (available starting + with openssl/libssl v1.0.1e) + * TLSv1.1+ - TLSv1.1 or newer (TLSv1.2, ...) connections are accepted + (available starting with openssl/libssl v1.0.1) + * TLSv1.1 - only TLSv1.1 connections are accepted (available starting + with openssl/libssl v1.0.1) + * TLSv1+ - TLSv1.0 or newer (TLSv1.1, TLSv1.2, ...) connections are + accepted. + * TLSv1 - only TLSv1 (TLSv1.0) connections are accepted. This is the + default value. + + Default value is “TLSv1.2”. + + Example 1.7. Set tls_method parameter +... +modparam("tls", "tls_method", "TLSv1") +... + +4.8. private_key (string) + + Sets the private key file name. + + Example 1.8. Set private_key parameter +... +modparam("cdp", "private_key", "/usr/local/etc/kamailio/my_pkey.pem") +... + +4.9. certificate (string) + + Sets the certificate file name. Must be in PEM format. + + Example 1.9. Set certificate parameter +... +modparam("cdp", "certificate", "/usr/local/etc/kamailio/my_certificate.pem") +... + +4.10. ca_list (string) + + Sets the CA list file name. This file contains a list of all the + trusted CAs certificates used when connecting to other SIP + implementations. If a signature in a certificate chain belongs to one + of the listed CAs, the verification of that certificate will succeed. + If not set, the PCRF sent certificate is not checked. + + The parameter must contain an absolute path. Only PEM files are + accepted. + + By default this parameter is not set. + + An easy way to create the CA list is to append each trusted trusted CA + certificate in the PEM format to one file. + + Example 1.10. Set ca_list parameter +... +modparam("cdp", "ca_list", "/usr/local/etc/kamailio/ca_list.pem") +... + 5. Functions 5.1. cdp_check_peer(fqdn) @@ -307,7 +404,7 @@ modparam("cdp", "debug_heavy", 1) * fqdn - the Fully qualified domain name of the peer, that should be checked. The parameter may contain pseudovariables. - Example 1.6. cdp_check_peer usage + Example 1.11. cdp_check_peer usage ... if(!cdp_check_peer("hss.mnc001.mcc001.3gppnetwork.org")) { send_reply("503", "HSS not ready"); @@ -324,7 +421,7 @@ if(!cdp_check_peer("hss.mnc001.mcc001.3gppnetwork.org")) { * vendorid - The Vendor ID of the App application - The Application ID - Example 1.7. cdp_check_peer usage + Example 1.12. cdp_check_peer usage ... if(!cdp_has_app("10415", "4")) { send_reply("503", "Charging Server not ready"); @@ -332,7 +429,7 @@ if(!cdp_has_app("10415", "4")) { } ... - Example 1.8. cdp_check_peer usage + Example 1.13. cdp_check_peer usage ... if(!cdp_has_app("16777216")) { send_reply("503", "Cx/Dx Interface not ready"); @@ -365,7 +462,7 @@ if(!cdp_has_app("16777216")) { This is an example CDP configuration file. The location of this file is configured as a CDP parameter (config_file) - See section 4.1 Above - Example 1.9. DiameterPeer.xml example + Example 1.14. DiameterPeer.xml example + +%docentities; + +]> + + + + file_out Module + &kamailioname; + + + Xenofon + Karamanos + + GILAWA Ltd + + xk@gilawa.com +
+ + https://gilawa.com/ + +
+
+
+ + 2024 + GILAWA Ltd + +
+ + + + +
diff --git a/src/modules/file_out/doc/file_out_admin.xml b/src/modules/file_out/doc/file_out_admin.xml new file mode 100644 index 000000000..ce02069ae --- /dev/null +++ b/src/modules/file_out/doc/file_out_admin.xml @@ -0,0 +1,237 @@ + + + +%docentities; + +]> + + + + + + &adminguide; + +
+ Overview + + This is a small module to support fast streaming output to files + and process this changes depending on an interval. It implements only one + function that streams a chunk of text to the current output file handle. + + + The module can be used to write logs for up to 10 different log files. + Each log file can be configured to have a different name and extension. + The processed string can contain pseudo-variables. The module will replace + the pseudo-variables with the actual values. The module will also rotate + the log files at a specified interval. The interval is specified in seconds. + + + Known limitations on the rotation interval are: + + + + If there is no messages coming, the rotation will not be done until the next message arrives. + + + + +
+
+ Dependencies +
+ &kamailio; Modules + + The following modules must be loaded before this module: + + + + none. + + + + +
+
+ External Libraries or Applications + + The following libraries or applications must be installed before running + &kamailio; with this module loaded: + + + + none. + + + + +
+
+ +
+ Parameters +
+ + <varname>base_folder</varname> (string) + + Absolute path to the folder where log files should be saved. + + + + Default value is /var/log/kamailio/file_out. + + + + Set <varname>base_folder</varname> parameter + +... +modparam("file_out", "base_folder", "/tmp/file_out") # trailing slash will be added. +... + + +
+ +
+ + <varname>file</varname> (string) + + The definition of a file and its properties. The value of the parameter may have the following format: + + + + + "name=accounting;extension=.out;interval=20;prefix=accounting:" + + + + + + The parameter can be set multiple times to define more files in same configuration file. + + + + + + + name (Required) - the name of the file + + + + No default value. This parameter is required. + + + + + + + extension (Optional) - the extension of the file + + + + Default value is .out. + + + + + + + interval (Optional) - the interval in seconds of the file rotation + + + + Default value is 600 (10min). + + + + + + + prefix (Optional) - the prefix for log messages + + + + Default value is "" (empty string). + + + + + + + Set <varname>file</varname> parameter + +... +modparam("file_out", "file", "name=missed_calls;interval=30;extension=.json") +modparam("file_out", "file", "name=accounting;extension=.txt") +... + + +
+ +
+ + <varname>worker_usleep</varname> (int) + + The time in microseconds which worker will sleep for until next iteration. + + + + Default value is 10000 (10 ms). + + + + Set <varname>worker_usleep</varname> parameter + +... +modparam("file_out", "worker_usleep", "1000") +... + + +
+ +
+ +
+ Functions +
+ + <function moreinfo="none">file_out(filename, string)</function> + + + This function is used to write a string to a file. The file is + determined by the filename parameter. The string parameter is the + string to be written to the file. Filename is the name of the file defined in the configuration file as name=filename. + + + + + <function>file_out</function> usage + +... +modparam("file_out", "file", "name=accounting;interval=200") +modparam("file_out", "file", "name=missed_calls;extension=.json;interval=300") + +request_route { + file_out("accounting", "Writing to accounting.out file $rm from $fu"); + file_out("missed_calls", "Writing to missed_calls.out file $rm from $fu"); +} +... + + +
+ +
+ +
+ Exported pseudo-variables + + + + none. + + + +
+ +
diff --git a/src/modules/file_out/file_out.c b/src/modules/file_out/file_out.c new file mode 100644 index 000000000..a13d3531d --- /dev/null +++ b/src/modules/file_out/file_out.c @@ -0,0 +1,597 @@ +/* + * Copyright (C) 2024 GILAWA Ltd + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "../../core/sr_module.h" +#include "../../core/route_struct.h" +#include "../../core/str.h" +#include "../../core/mod_fix.h" +#include "../../core/locking.h" +#include "../../core/cfg/cfg_struct.h" +#include "types.h" + +#include +#include +#include +#include +#include /* usleep() */ + + +MODULE_VERSION + + +#define FO_MAX_PATH_LEN 2048 +#define FO_DEFAULT_INTERVAL 10 * 60 +#define FO_DEFAULT_EXTENSION ".out" +#define FO_DEFAULT_PREFIX "" + +static int mod_init(void); +static int child_init(int rank); +static void destroy(void); + +static int fo_write_to_file(sip_msg_t *msg, char *index, char *log_message); + +static FILE *fo_get_file_handle(const int index); +static int fo_get_full_path(const int index, char *full_path); +static int fo_init_file(const int index); +static int fo_close_file(const int index); +static int fo_check_interval(int index); +static int fo_fixup_int_pvar(void **param, int param_no); +static int fo_fixup_str_index(void **param, int param_no); +static int fo_fixup_free_int_pvar(void **param, int param_no); +static int fo_count_assigned_files(); +static void fo_log_writer_process(int rank); +static int fo_add_filename(modparam_t type, void *val); +static int fo_parse_filename_params(str input); + +/* Default parameters */ +static int buf_size = 4096; + +str fo_base_folder = str_init("/var/log/kamailio/file_out"); +int fo_worker_usleep = 10000; +fo_file_properties_t fo_files[FO_MAX_FILES]; + +char *fo_prefix_buf = NULL; + +/* Shared variables */ +fo_queue_t *fo_queue = NULL; +int *fo_number_of_files = NULL; + +time_t fo_current_timestamp = 0; + +static cmd_export_t cmds[] = { + {"file_out", (cmd_function)fo_write_to_file, 2, fo_fixup_int_pvar, + fo_fixup_free_int_pvar, ANY_ROUTE}, + {0, 0, 0, 0, 0, 0}}; + +static param_export_t params[] = {{"base_folder", PARAM_STR, &fo_base_folder}, + {"file", PARAM_STR | PARAM_USE_FUNC, &fo_add_filename}, + {"worker_usleep", PARAM_INT, &fo_worker_usleep}, {0, 0, 0}}; + +struct module_exports exports = { + "file_out", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* exported functions */ + params, /* exported parameters */ + 0, /* RPC method exports */ + 0, /* exported pseudo-variables */ + 0, /* response handling function */ + mod_init, /* module initialization function */ + child_init, /* per-child init function */ + destroy /* module destroy function */ +}; + + +static int mod_init(void) +{ + int i = 0; + LM_DBG("initializing\n"); + LM_DBG("base_folder = %.*s\n", fo_base_folder.len, fo_base_folder.s); + + //* Create shared variables */ + fo_queue = (fo_queue_t *)shm_malloc(sizeof(fo_queue_t)); + if(!fo_queue) { + SHM_MEM_ERROR; + return -1; + } + fo_queue->front = NULL; + fo_queue->rear = NULL; + if(lock_init(&fo_queue->lock) == 0) { + /* error initializing the lock */ + LM_ERR("error initializing the lock\n"); + return -1; + } + + /* Count the given files */ + *fo_number_of_files = fo_count_assigned_files(); + + /* Fixup the prefix */ + for(i = 0; i < *fo_number_of_files; i++) { + str s; + s.s = fo_files[i].fo_prefix.s; + s.len = fo_files[i].fo_prefix.len; + + if(pv_parse_format(&s, &fo_files[i].fo_prefix_pvs) < 0) { + LM_ERR("wrong format[%s]\n", s.s); + return -1; + } + } + + fo_prefix_buf = (char *)pkg_malloc((buf_size + 1) * sizeof(char)); + if(fo_prefix_buf == NULL) { + PKG_MEM_ERROR; + return -1; + } + + /* Initialize per process vars */ + for(i = 0; i < *fo_number_of_files; i++) { + fo_files[i].fo_stored_timestamp = time(NULL); + } + + /* Register worker process */ + register_procs(1); + cfg_register_child(1); + LM_DBG("Initialization done\n"); + return 0; +} + +/** + * per-child init function + */ +static int child_init(int rank) +{ + int pid; + int i = 0; + if(rank != PROC_MAIN) { + return 0; + } + + pid = fork_process(PROC_NOCHLDINIT, "fo_writer", 1); + if(pid < 0) { + LM_ERR("fork failed\n"); + return -1; /* error */ + } + if(pid == 0) { + /* child */ + /* initialize the config framework */ + if(cfg_child_init()) + return -1; + + /* Initialize and open files */ + for(i = 0; i < *fo_number_of_files; i++) { + fo_init_file(i); + } + + for(;;) { + /* update the local config framework structures */ + cfg_update(); + + usleep(fo_worker_usleep); + fo_log_writer_process(rank); + } + // return 0; + } + return 0; +} + +/** + * module destroy function + */ +static void destroy(void) +{ + int result = 0; + int i = 0; + for(i = 0; i < *fo_number_of_files; i++) { + result = fo_file_properties_destroy(&fo_files[i]); + if(result < 0) { + LM_ERR("Failed to destroy file properties\n"); + } + } + + if(fo_prefix_buf) { + pkg_free(fo_prefix_buf); + } + + /* Free allocated mem */ + if(fo_number_of_files != NULL) { + shm_free(fo_number_of_files); + fo_number_of_files = NULL; + } + + if(fo_queue != NULL) { + fo_free_queue(fo_queue); + } +} + +static void fo_log_writer_process(int rank) +{ + fo_log_message_t log_message; + int result = 0; + while(!fo_is_queue_empty(fo_queue)) { + result = fo_dequeue(fo_queue, &log_message); + if(result < 0) { + LM_ERR("deque error\n"); + return; + } + if(log_message.message != NULL) { + FILE *out = fo_get_file_handle(log_message.dest_file); + if(out == NULL) { + LM_ERR("file handle is NULL\n"); + return; + } + + /* Get prefix for the file */ + if(log_message.prefix != NULL && log_message.prefix->len > 0) { + if(fprintf(out, "%.*s", log_message.prefix->len, + log_message.prefix->s) + < 0) { + LM_ERR("Failed to write prefix to file with err {%s}\n", + strerror(errno)); + } + } + if(fprintf(out, "%.*s\n", log_message.message->len, + log_message.message->s) + < 0) { + LM_ERR("Failed to write to file with err {%s}\n", + strerror(errno)); + } + if(fflush(out) < 0) { + LM_ERR("Failed to flush file with err {%s}\n", strerror(errno)); + } + } + + if(log_message.prefix != NULL) { + if(log_message.prefix->s != NULL) { + shm_free(log_message.prefix->s); + } + shm_free(log_message.prefix); + log_message.prefix = NULL; + } + + if(log_message.message != NULL) { + if(log_message.message->s != NULL) { + shm_free(log_message.message->s); + } + shm_free(log_message.message); + log_message.message = NULL; + } + } +} + +static int fo_fixup_str_index(void **param, int param_no) +{ + fparam_t *p; + int index = 0; + + if(strlen((char *)*param) == 0) { + LM_ERR("function param value is required\n"); + return -1; + } + + p = (fparam_t *)pkg_malloc(sizeof(fparam_t)); + if(!p) { + PKG_MEM_ERROR; + return E_OUT_OF_MEM; + } + memset(p, 0, sizeof(fparam_t)); + p->orig = *param; + + /* Map string to index */ + while(index < *fo_number_of_files) { + str s; + s.s = fo_files[index].fo_base_filename.s; + s.len = fo_files[index].fo_base_filename.len; + if(strncmp(s.s, (char *)*param, s.len) == 0) { + LM_DBG("Found index %d for %s\n", index, (char *)*param); + p->v.i = (int)index; + p->fixed = (void *)(long)index; + p->type = FPARAM_INT; + *param = (void *)p; + return 0; + } + index++; + } + + LM_ERR("Couldn't find %s\n", (char *)*param); + LM_ERR("Make sure the file [%s] is defined as modparam and not exceeding " + "file limit\n", + (char *)*param); + pkg_free(p); + return -1; +} +/* +* fixup function for two parameters +* 1st param: string assoicated with file (returning an index) +* 2nd param: string containing PVs +*/ +static int fo_fixup_int_pvar(void **param, int param_no) +{ + if(param_no == 1) { + return fo_fixup_str_index(param, param_no); + } else if(param_no == 2) { + return fixup_spve_all(param, param_no); + } + return 0; +} + +static int fo_fixup_free_int_pvar(void **param, int param_no) +{ + if(param_no == 1) { + return fixup_free_igp_null(param, param_no); + } else if(param_no == 2) { + return fixup_free_spve_all(param, param_no); + } + + return 0; +} + +static int fo_add_filename(modparam_t type, void *val) +{ + if(val == NULL) { + LM_ERR("modparam value is null\n"); + return -1; + } + if(strlen(((str *)val)->s) == 0) { + LM_ERR("modparam value is empty\n"); + return -1; + } + + if(fo_number_of_files == NULL) { + LM_DBG("fo_number_of_files is NULL\n"); + fo_number_of_files = (int *)shm_malloc(sizeof(int)); + if(!fo_number_of_files) { + SHM_MEM_ERROR; + return -1; + } + *fo_number_of_files = 0; + } + + if((type & PARAM_STR) == 0) { + LM_ERR("bad parameter type %d\n", type); + return -1; + } + + if(fo_number_of_files != NULL && *fo_number_of_files >= FO_MAX_FILES) { + LM_ERR("Maximum number of files [%d] reached. The rest will not be " + "processed \n", + *fo_number_of_files); + return 0; + } + + /* parse: param_name=value; ... */ + if(fo_parse_filename_params(*((str *)val)) < 0) + return -1; + + (*fo_number_of_files)++; + return 0; +} + +/* +* Parse the filename parameters +* name, extension, interval +* return 1 if successful +* return -1 if failed +*/ +static int fo_parse_filename_params(str in) +{ + LM_DBG("Parsing filename params\n"); + char *name = NULL; + char *extension = NULL; + char *interval = NULL; + char *prefix = NULL; + char *token = NULL; + char *saveptr = NULL; + char *input = in.s; + token = strtok_r(input, ";", &saveptr); + while(token != NULL) { + if(strstr(token, "name=") != NULL) { + name = token + 5; + } else if(strstr(token, "extension=") != NULL) { + extension = token + 10; + } else if(strstr(token, "interval=") != NULL) { + interval = token + 9; + } else if(strstr(token, "prefix=") != NULL) { + prefix = token + 7; + } else { + LM_ERR("Unknown parameter %s\n", token); + return -1; + } + token = strtok_r(NULL, ";", &saveptr); + } + if(name != NULL) { + LM_DBG("name = %s\n", name); + fo_files[*fo_number_of_files].fo_base_filename.s = name; + fo_files[*fo_number_of_files].fo_base_filename.len = strlen(name); + } else { + LM_ERR("name is required. Make sure you provided name= in modparam " + "value\n"); + return -1; + } + + if(extension != NULL) { + LM_DBG("extension = %s\n", extension); + fo_files[*fo_number_of_files].fo_extension.s = extension; + fo_files[*fo_number_of_files].fo_extension.len = strlen(extension); + } else { + LM_DBG("no extension= provided. Using default %s\n", + FO_DEFAULT_EXTENSION); + fo_files[*fo_number_of_files].fo_extension.s = FO_DEFAULT_EXTENSION; + fo_files[*fo_number_of_files].fo_extension.len = + strlen(FO_DEFAULT_EXTENSION); + } + + if(interval != NULL) { + LM_DBG("interval = %s\n", interval); + fo_files[*fo_number_of_files].fo_interval_seconds = atoi(interval); + } else { + LM_DBG("no interval= provided. Using default %d\n", + FO_DEFAULT_INTERVAL); + fo_files[*fo_number_of_files].fo_interval_seconds = FO_DEFAULT_INTERVAL; + } + + if(prefix != NULL) { + LM_DBG("prefix = %s\n", prefix); + fo_files[*fo_number_of_files].fo_prefix.s = prefix; + fo_files[*fo_number_of_files].fo_prefix.len = strlen(prefix); + } else { + LM_DBG("no prefix= provided. Using default %s\n", FO_DEFAULT_PREFIX); + fo_files[*fo_number_of_files].fo_prefix.s = FO_DEFAULT_PREFIX; + fo_files[*fo_number_of_files].fo_prefix.len = strlen(FO_DEFAULT_PREFIX); + } + return 1; +} + +/* +* return the number of files assigned +*/ +static int fo_count_assigned_files() +{ + return *fo_number_of_files; +} + +static int fo_init_file(const int index) +{ + char full_path[FO_MAX_PATH_LEN]; + fo_get_full_path(index, full_path); + fo_files[index].fo_file_output = fopen(full_path, "a"); + if(fo_files[index].fo_file_output == NULL) { + LM_ERR("Couldn't open file %s\n", strerror(errno)); + return -1; + } + return 1; +} + +static int fo_close_file(const int index) +{ + int result = 0; + if(fo_files[index].fo_file_output != NULL) { + result = fclose(fo_files[index].fo_file_output); + if(result != 0) { + ERR("Failed to close output file"); + return -1; + } + } + return 1; +} + +/* +* Check if the interval has passed +* return 1 if interval has passed +* return 0 if interval has not passed +*/ +static int fo_check_interval(int index) +{ + fo_current_timestamp = time(NULL); + + /* Calculate the difference between the current timestamp and the stored timestamp */ + int difference = + difftime(fo_current_timestamp, fo_files[index].fo_stored_timestamp); + if(difference >= fo_files[index].fo_interval_seconds) { + return 1; + } + return 0; +} + +/** + * Get file handle for file at index + */ +static FILE *fo_get_file_handle(const int index) +{ + int result = 0; + if(fo_check_interval(index)) { + /* Interval passed. Close all files and open new ones */ + result = fo_close_file(index); + if(result != 1) { + LM_ERR("Failed to close output file"); + return NULL; + } + fo_files[index].fo_stored_timestamp = fo_current_timestamp; + + LM_DBG("Opening new file due to interval passed\n"); + /* Initialize and open files */ + result = fo_init_file(index); + if(result != 1) { + LM_ERR("Failed to initialize output file"); + return NULL; + } + return fo_files[index].fo_file_output; + } else { + /* Interval has not passed */ + /* Assume files are correct */ + return fo_files[index].fo_file_output; + } +} + +/** + * Determine full file path + */ +static int fo_get_full_path(const int index, char *full_path) +{ + fo_file_properties_t fp = fo_files[index]; + snprintf(full_path, FO_MAX_PATH_LEN, "%.*s/%.*s_%.f%.*s", + fo_base_folder.len, fo_base_folder.s, fp.fo_base_filename.len, + fp.fo_base_filename.s, difftime(fp.fo_stored_timestamp, (time_t)0), + fp.fo_extension.len, fp.fo_extension.s); + LM_INFO("Path to write to: %s\n", full_path); + return 1; +} + +static int fo_write_to_file(sip_msg_t *msg, char *index, char *log_message) +{ + int result, file_index; + str fo_prefix_str = str_init(""); + str fo_prefix_val = str_init(""); + str value = str_init(""); + fo_log_message_t logMessage = {0, 0, 0}; + + if(index == NULL || log_message == NULL) { + LM_ERR("filename or log_messsage is NULL\n"); + return -1; + } + + result = get_int_fparam(&file_index, msg, (fparam_t *)index); + if(result < 0) { + LM_ERR("Failed to get int from param 0: %d\n", result); + return -1; + } + + result = get_str_fparam(&value, msg, (fparam_t *)log_message); + if(result < 0) { + LM_ERR("Failed to get string from param 1: %d\n", result); + return -1; + } + + fo_prefix_str.s = fo_prefix_buf; + fo_prefix_str.len = buf_size; + if(pv_printf(msg, fo_files[file_index].fo_prefix_pvs, fo_prefix_str.s, + &fo_prefix_str.len) + == 0 + && fo_prefix_str.len > 0) { + fo_prefix_val.s = fo_prefix_str.s; + fo_prefix_val.len = fo_prefix_str.len; + } + + /* Add the logging string to the global gueue */ + logMessage.prefix = &fo_prefix_val; + logMessage.message = &value; + logMessage.dest_file = file_index; + fo_enqueue(fo_queue, logMessage); + + return 1; +} diff --git a/src/modules/file_out/types.c b/src/modules/file_out/types.c new file mode 100644 index 000000000..6dedfd201 --- /dev/null +++ b/src/modules/file_out/types.c @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2024 GILAWA Ltd + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "types.h" +#include "../../core/ut.h" + +static fo_node_t *fo_new_node(fo_log_message_t data) +{ + fo_node_t *temp = (fo_node_t *)shm_malloc(sizeof(fo_node_t)); + temp->data = data; + temp->next = NULL; + return temp; +} + + +int fo_enqueue(fo_queue_t *q, fo_log_message_t data) +{ + /* + Copy the contents of data.message + */ + str *message_copy = 0; + str *prefix_copy = 0; + /* + * Allocate memory for the message and prefix + */ + message_copy = (str *)shm_malloc(sizeof(str)); + if(message_copy == 0) { + SHM_MEM_ERROR; + return -1; + } + if(shm_str_dup(message_copy, data.message) < 0) { + LM_ERR("Failed to duplicate message\n"); + return -1; + } + data.message = message_copy; + + prefix_copy = (str *)shm_malloc(sizeof(str)); + if(prefix_copy == 0) { + SHM_MEM_ERROR; + return -1; + } + if(shm_str_dup(prefix_copy, data.prefix) < 0) { + LM_ERR("Failed to duplicate prefix\n"); + return -1; + } + data.prefix = prefix_copy; + + fo_node_t *temp = fo_new_node(data); + + lock_get(&(q->lock)); + + if(q->rear == NULL) { + q->front = q->rear = temp; + lock_release(&(q->lock)); + return 1; + } + + q->rear->next = temp; + q->rear = temp; + + lock_release(&(q->lock)); + return 1; +} + +int fo_dequeue(fo_queue_t *q, fo_log_message_t *data) +{ + lock_get(&(q->lock)); + + if(q->front == NULL) { + lock_release(&(q->lock)); + return -1; + } + fo_node_t *temp = q->front; + *data = temp->data; + q->front = q->front->next; + + if(q->front == NULL) + q->rear = NULL; + + + if(temp != NULL) { + shm_free(temp); + temp = NULL; + } + lock_release(&(q->lock)); + + return 1; +} + +int fo_is_queue_empty(fo_queue_t *q) +{ + lock_get(&(q->lock)); + int result = (q->front == NULL); + lock_release(&(q->lock)); + return result; +} + +int fo_queue_size(fo_queue_t *q) +{ + lock_get(&(q->lock)); + int count = 0; + fo_node_t *temp = q->front; + while(temp != NULL) { + count++; + temp = temp->next; + } + lock_release(&(q->lock)); + return count; +} + +void fo_free_queue(fo_queue_t *q) +{ + fo_log_message_t data; + while(fo_dequeue(q, &data) > 0) { + if(data.prefix != NULL) { + if(data.prefix->s != NULL) { + shm_free(data.prefix->s); + } + shm_free(data.prefix); + } + + if(data.message != NULL) { + if(data.message->s != NULL) { + shm_free(data.message->s); + } + shm_free(data.message); + } + } + shm_free(q); +} + +int fo_file_properties_destroy(fo_file_properties_t *fp) +{ + if(fp == NULL) { + return 1; + } + if(fp->fo_prefix_pvs != NULL) { + if(pv_elem_free_all(fp->fo_prefix_pvs) < 0) { + LM_ERR("Failed to free prefix pvs\n"); + return -1; + } + } + if(fp->fo_file_output != NULL) { + if(fclose(fp->fo_file_output) != 0) { + LM_ERR("Failed to close file\n"); + return -1; + } + } + return 1; +} diff --git a/src/modules/file_out/types.h b/src/modules/file_out/types.h new file mode 100644 index 000000000..641da360d --- /dev/null +++ b/src/modules/file_out/types.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2024 GILAWA Ltd + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _FO_TYPES_H +#define _FO_TYPES_H + +#include "../../core/locking.h" +#include "../../core/pvar.h" + +#define FO_MAX_FILES 10 /* Maximum number of files */ + +typedef struct log_message +{ + str *prefix; + str *message; + int dest_file; +} fo_log_message_t; + +typedef struct node +{ + struct log_message data; + struct node *next; +} fo_node_t; + +typedef struct queue +{ + struct node *front; + struct node *rear; + gen_lock_t lock; +} fo_queue_t; + +int fo_enqueue(fo_queue_t *q, fo_log_message_t data); +int fo_dequeue(fo_queue_t *q, fo_log_message_t *data); +int fo_is_queue_empty(fo_queue_t *q); +int fo_queue_size(fo_queue_t *q); +void fo_free_queue(fo_queue_t *q); + +typedef struct fo_file_properties +{ + str fo_base_filename; + str fo_extension; + str fo_prefix; + int fo_interval_seconds; + pv_elem_t *fo_prefix_pvs; + time_t fo_stored_timestamp; + FILE *fo_file_output; +} fo_file_properties_t; + +int fo_file_properties_destroy(fo_file_properties_t *fp); + +#endif diff --git a/src/modules/gcrypt/Makefile b/src/modules/gcrypt/Makefile new file mode 100644 index 000000000..f9429bcc2 --- /dev/null +++ b/src/modules/gcrypt/Makefile @@ -0,0 +1,26 @@ +# +# +# WARNING: do not run this directly, it should be run by the main Makefile + +include ../../Makefile.defs +auto_gen= +NAME=gcrypt.so + +ifeq ($(CROSS_COMPILE),) +GCRYPT_BUILDER=$(shell \ + if pkg-config --exists libgcrypt; then \ + echo 'pkg-config libgcrypt'; \ + fi) +endif + +ifneq ($(GCRYPT_BUILDER),) + DEFS += $(shell $(GCRYPT_BUILDER) --cflags) + LIBS += $(shell $(GCRYPT_BUILDER) --libs) +else + DEFS += -I$(LOCALBASE)/include + LIBS += -L$(LOCALBASE)/lib \ + -L$(LOCALBASE)/lib64 \ + -lgcrypt +endif + +include ../../Makefile.modules diff --git a/src/modules/gcrypt/README b/src/modules/gcrypt/README new file mode 100644 index 000000000..3d7f9af42 --- /dev/null +++ b/src/modules/gcrypt/README @@ -0,0 +1,166 @@ +GCRYPT Module + +Daniel-Constantin Mierla + + + +Edited by + +Daniel-Constantin Mierla + + + + Copyright © 2024 asipto.com + __________________________________________________________________ + + Table of Contents + + 1. Admin Guide + + 1. Overview + 2. Dependencies + + 2.1. Kamailio Modules + 2.2. External Libraries or Applications + + 3. Parameters + + 3.1. init_vector (str) + 3.2. aes_mode (int) + 3.3. register_callid (int) + + 4. Functions + + 4.1. gcrypt_aes_encrypt(text, key, res) + 4.2. gcrypt_aes_decrypt(text, key, res) + + List of Examples + + 1.1. Set init_vector parameter + 1.2. Set aes_mode parameter + 1.3. Set register_callid parameter + 1.4. gcrypt_aes_encrypt usage + 1.5. gcrypt_aes_decrypt usage + +Chapter 1. Admin Guide + + Table of Contents + + 1. Overview + 2. Dependencies + + 2.1. Kamailio Modules + 2.2. External Libraries or Applications + + 3. Parameters + + 3.1. init_vector (str) + 3.2. aes_mode (int) + 3.3. register_callid (int) + + 4. Functions + + 4.1. gcrypt_aes_encrypt(text, key, res) + 4.2. gcrypt_aes_decrypt(text, key, res) + +1. Overview + + This module provides various cryptography tools for use in Kamailio + configuration file using libgcrypt. + +2. Dependencies + + 2.1. Kamailio Modules + 2.2. External Libraries or Applications + +2.1. Kamailio Modules + + The following modules must be loaded before this module: + * none. + +2.2. External Libraries or Applications + + The following libraries or applications must be installed before + running Kamailio with this module loaded: + * libgcrypt - part of GnuPG project + (https://gnupg.org/software/libgcrypt/index.html). + +3. Parameters + + 3.1. init_vector (str) + 3.2. aes_mode (int) + 3.3. register_callid (int) + +3.1. init_vector (str) + + The initialization vector used for the cryptographic operations. This + needs to be a string value with 16 bytes lengths. + + Default value is set in the C code. + + Example 1.1. Set init_vector parameter +... +modparam("gcrypt", "init_vector", "abcdefghijklmnop") +... + +3.2. aes_mode (int) + + Set it to 1 in order to do AES CBC encryption mode. By default, it does + AES ECB mode. + + Default value is 0. + + Example 1.2. Set aes_mode parameter +... +modparam("gcrypt", "aes_mode", 1) +... + +3.3. register_callid (int) + + Set it to 1 in order to register a callback to core for generation of + callid values for requests generated by Kamailio tm module. + + This callid generator uses libcrypt random and hashing functions for + generating RFC 4122 version 4 UUID with high quality entropy. It is + useful when wanting to have new callids that cannot be predicted from + previous values. + + Default value is 0. + + Example 1.3. Set register_callid parameter +... +modparam("gcrypt", "register_callid", 1) +... + +4. Functions + + 4.1. gcrypt_aes_encrypt(text, key, res) + 4.2. gcrypt_aes_decrypt(text, key, res) + +4.1. gcrypt_aes_encrypt(text, key, res) + + Encrypts the text with the key using AES256 ECB encryption algorithm. + The result is encoded in base64 format and stored in res. The parameter + res must be a read-write variables. The parameters text and key can be + static strings or strings with variables (dynamic strings). + + This function can be used from ANY_ROUTE. + + Example 1.4. gcrypt_aes_encrypt usage +... +gcrypt_aes_encrypt("$rb", "my-secret-key", "$var(encrypted)"); +... + +4.2. gcrypt_aes_decrypt(text, key, res) + + Decrypts the text with the key using AES256 ECB encryption algorithm. + The text has to be encoded in base64 format. The parameter res must be + a read-write variables. The parameters text and key can be static + strings or strings with variables (dynamic strings). + + This function can be used from ANY_ROUTE. + + Example 1.5. gcrypt_aes_decrypt usage +... +gcrypt_aes_decrypt("$var(encrypted)", "my-secret-key", "$var(text)"); +... diff --git a/src/modules/auth_identity/doc/Makefile b/src/modules/gcrypt/doc/Makefile similarity index 75% rename from src/modules/auth_identity/doc/Makefile rename to src/modules/gcrypt/doc/Makefile index ce9dc7d20..f65556d56 100644 --- a/src/modules/auth_identity/doc/Makefile +++ b/src/modules/gcrypt/doc/Makefile @@ -1,4 +1,4 @@ -docs = auth_identity.xml +docs = gcrypt.xml docbook_dir = ../../../../doc/docbook include $(docbook_dir)/Makefile.module diff --git a/src/modules/app_sqlang/doc/app_sqlang.xml b/src/modules/gcrypt/doc/gcrypt.xml similarity index 67% rename from src/modules/app_sqlang/doc/app_sqlang.xml rename to src/modules/gcrypt/doc/gcrypt.xml index e27a2ecf5..eba9bb768 100644 --- a/src/modules/app_sqlang/doc/app_sqlang.xml +++ b/src/modules/gcrypt/doc/gcrypt.xml @@ -10,27 +10,28 @@ - app_sqlang Module - &kamailioname; + GCRYPT Module + sip-router.org Daniel-Constantin Mierla - asipto.com + miconda@gmail.com Daniel-Constantin Mierla - miconda@gmail.com + miconda@gmail.com - 2017 - Daniel-Constantin Mierla (asipto.com) + 2024 + asipto.com - + + diff --git a/src/modules/gcrypt/doc/gcrypt_admin.xml b/src/modules/gcrypt/doc/gcrypt_admin.xml new file mode 100644 index 000000000..3fc03d3ea --- /dev/null +++ b/src/modules/gcrypt/doc/gcrypt_admin.xml @@ -0,0 +1,176 @@ + + + +%docentities; + +]> + + + + + &adminguide; + +
+ Overview + + This module provides various cryptography tools for use + in &kamailio; configuration file using libgcrypt. + +
+ +
+ Dependencies +
+ &kamailio; Modules + + The following modules must be loaded before this module: + + + + none. + + + + +
+
+ External Libraries or Applications + + The following libraries or applications must be installed before running + &kamailio; with this module loaded: + + + + libgcrypt - part of GnuPG project + (https://gnupg.org/software/libgcrypt/index.html). + + + + +
+
+ +
+ Parameters +
+ <varname>init_vector</varname> (str) + + The initialization vector used for the cryptographic operations. + This needs to be a string value with 16 bytes lengths. + + + + Default value is set in the C code. + + + + Set <varname>init_vector</varname> parameter + +... +modparam("gcrypt", "init_vector", "abcdefghijklmnop") +... + + +
+
+ <varname>aes_mode</varname> (int) + + Set it to 1 in order to do AES CBC encryption mode. By default, + it does AES ECB mode. + + + + Default value is 0. + + + + Set <varname>aes_mode</varname> parameter + +... +modparam("gcrypt", "aes_mode", 1) +... + + +
+ +
+ <varname>register_callid</varname> (int) + + Set it to 1 in order to register a callback to core for generation + of callid values for requests generated by &kamailio; tm module. + + + This callid generator uses libcrypt random and hashing functions + for generating RFC 4122 version 4 UUID with high quality entropy. + It is useful when wanting to have new callids that cannot be + predicted from previous values. + + + + Default value is 0. + + + + Set <varname>register_callid</varname> parameter + +... +modparam("gcrypt", "register_callid", 1) +... + + +
+ +
+ +
+ Functions +
+ + <function moreinfo="none">gcrypt_aes_encrypt(text, key, res)</function> + + + Encrypts the text with the key using AES256 ECB encryption algorithm. + The result is encoded in base64 format and stored in res. The parameter + res must be a read-write variables. The parameters text and key can + be static strings or strings with variables (dynamic strings). + + + This function can be used from ANY_ROUTE. + + + <function>gcrypt_aes_encrypt</function> usage + +... +gcrypt_aes_encrypt("$rb", "my-secret-key", "$var(encrypted)"); +... + + +
+ +
+ + <function moreinfo="none">gcrypt_aes_decrypt(text, key, res)</function> + + + Decrypts the text with the key using AES256 ECB encryption algorithm. + The text has to be encoded in base64 format. The parameter + res must be a read-write variables. The parameters text and key can + be static strings or strings with variables (dynamic strings). + + + This function can be used from ANY_ROUTE. + + + <function>gcrypt_aes_decrypt</function> usage + +... +gcrypt_aes_decrypt("$var(encrypted)", "my-secret-key", "$var(text)"); +... + + +
+
+
diff --git a/src/modules/gcrypt/gcrypt_mod.c b/src/modules/gcrypt/gcrypt_mod.c new file mode 100644 index 000000000..69be44325 --- /dev/null +++ b/src/modules/gcrypt/gcrypt_mod.c @@ -0,0 +1,472 @@ +/** + * Copyright (C) 2024 Daniel-Constantin Mierla (asipto.com) + * + * This file is part of Kamailio, a free SIP server. + * + * This file 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 + * + * + * This file 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 + * + */ + +#include +#include +#include +#include + +#include + +#include "../../core/sr_module.h" +#include "../../core/dprint.h" +#include "../../core/mod_fix.h" +#include "../../core/pvapi.h" +#include "../../core/lvalue.h" +#include "../../core/basex.h" +#include "../../core/kemi.h" + +#include "gcrypt_uuid.h" + +MODULE_VERSION + +static int mod_init(void); +static int child_init(int); +static void mod_destroy(void); + +static int w_gcrypt_aes_encrypt( + sip_msg_t *msg, char *inb, char *keyb, char *outb); +static int fixup_gcrypt_aes_encrypt(void **param, int param_no); +static int w_gcrypt_aes_decrypt( + sip_msg_t *msg, char *inb, char *keyb, char *outb); +static int fixup_gcrypt_aes_decrypt(void **param, int param_no); + +/* init vector value */ +static str _gcrypt_init_vector = str_init("SIP/2.0 is RFC3261"); +static int _gcrypt_register_callid = 0; +static int _gcrypt_aes_mode_param = 0; +static int _gcrypt_aes_mode = GCRY_CIPHER_MODE_ECB; + +/* clang-format off */ +static cmd_export_t cmds[] = { + {"gcrypt_aes_encrypt", (cmd_function)w_gcrypt_aes_encrypt, 3, + fixup_gcrypt_aes_encrypt, 0, ANY_ROUTE}, + {"gcrypt_aes_decrypt", (cmd_function)w_gcrypt_aes_decrypt, 3, + fixup_gcrypt_aes_decrypt, 0, ANY_ROUTE}, + {0, 0, 0, 0, 0, 0} +}; + +static param_export_t params[] = { + {"init_vector", PARAM_STR, &_gcrypt_init_vector}, + {"register_callid", PARAM_INT, &_gcrypt_register_callid}, + {"aes_mode", PARAM_INT, &_gcrypt_aes_mode_param}, + + {0, 0, 0} +}; + +struct module_exports exports = { + "gcrypt", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* cmd (cfg function) exports */ + params, /* param exports */ + 0, /* RPC method exports */ + 0, /* pseudo-variables exports */ + 0, /* response handling function */ + mod_init, /* module init function */ + child_init, /* per-child init function */ + mod_destroy /* module destroy function */ +}; +/* clang-format on */ + +/** + * @brief Initialize crypto module function + */ +static int mod_init(void) +{ + if(_gcrypt_init_vector.len < 16) { + LM_ERR("init vector value has to be longer\n"); + return -1; + } + if(_gcrypt_register_callid != 0) { + if(gcrypt_register_callid_func() < 0) { + LM_ERR("unable to register callid callback\n"); + return -1; + } + LM_DBG("registered crypto callid callback\n"); + } + if(_gcrypt_aes_mode_param == 1) { + _gcrypt_aes_mode = GCRY_CIPHER_MODE_CBC; + } + + return 0; +} + +/** + * @brief Initialize crypto module children + */ +static int child_init(int rank) +{ + return 0; +} + +/** + * destroy module function + */ +static void mod_destroy(void) +{ + return; +} + +/** + * + */ +static int ki_gcrypt_aes_encrypt_helper( + sip_msg_t *msg, str *ins, str *keys, pv_spec_t *dst) +{ + pv_value_t val; + gcry_error_t gcry_ret; + gcry_cipher_hd_t cipher_hd; + size_t key_length = 0; + size_t blk_length = 0; + char *encypted_txt = NULL; + + if(!gcry_control(GCRYCTL_ANY_INITIALIZATION_P)) { + /* before calling any other functions */ + gcry_check_version(NULL); + } + + gcry_ret = gcry_cipher_open(&cipher_hd, // gcry_cipher_hd_t *hd + GCRY_CIPHER_AES256, // int algo + _gcrypt_aes_mode, // int mode + 0); // unsigned int flags + if(gcry_ret) { + LM_ERR("gcry cipher open failed: %s/%s\n", gcry_strsource(gcry_ret), + gcry_strerror(gcry_ret)); + return -1; + } + key_length = gcry_cipher_get_algo_keylen(GCRY_CIPHER_AES256); + if(keys->len < key_length) { + LM_ERR("the encryption key is too short\n"); + goto error; + } + gcry_ret = gcry_cipher_setkey(cipher_hd, keys->s, key_length); + if(gcry_ret) { + LM_ERR("gcry_cipher_setkey failed: %s/%s\n", gcry_strsource(gcry_ret), + gcry_strerror(gcry_ret)); + goto error; + } + + blk_length = gcry_cipher_get_algo_blklen(GCRY_CIPHER_AES256); + if(_gcrypt_init_vector.len < blk_length) { + LM_ERR("the init vector is too short\n"); + goto error; + } + + gcry_ret = gcry_cipher_setiv(cipher_hd, _gcrypt_init_vector.s, blk_length); + if(gcry_ret) { + LM_ERR("gcry_cipher_setiv failed: %s/%s\n", gcry_strsource(gcry_ret), + gcry_strerror(gcry_ret)); + goto error; + } + + encypted_txt = malloc(ins->len + 1); + if(encypted_txt == 0) { + SYS_MEM_ERROR; + goto error; + } + encypted_txt[0] = '\0'; + gcry_ret = gcry_cipher_encrypt(cipher_hd, // gcry_cipher_hd_t h + encypted_txt, // unsigned char *out + ins->len, // size_t outsize + ins->s, // const unsigned char *in + ins->len); // size_t inlen + if(gcry_ret) { + LM_ERR("gcry_cipher_encrypt failed: %s/%s\n", gcry_strsource(gcry_ret), + gcry_strerror(gcry_ret)); + goto error; + } + + memset(&val, 0, sizeof(pv_value_t)); + val.rs.s = pv_get_buffer(); + val.rs.len = base64_enc((unsigned char *)encypted_txt, ins->len, + (unsigned char *)val.rs.s, pv_get_buffer_size() - 1); + if(val.rs.len < 0) { + LM_ERR("base64 output of encrypted value is too large (need %d)\n", + -val.rs.len); + goto error; + } + LM_DBG("base64 encrypted result: [%.*s]\n", val.rs.len, val.rs.s); + val.flags = PV_VAL_STR; + dst->setf(msg, &dst->pvp, (int)EQ_T, &val); + + free(encypted_txt); + gcry_cipher_close(cipher_hd); + return 1; + +error: + if(encypted_txt) { + free(encypted_txt); + } + gcry_cipher_close(cipher_hd); + return -1; +} + +/** + * + */ +static int ki_gcrypt_aes_encrypt(sip_msg_t *msg, str *ins, str *keys, str *dpv) +{ + pv_spec_t *dst; + + dst = pv_cache_get(dpv); + + if(dst == NULL) { + LM_ERR("failed getting pv: %.*s\n", dpv->len, dpv->s); + return -1; + } + + return ki_gcrypt_aes_encrypt_helper(msg, ins, keys, dst); +} + +/** + * + */ +static int w_gcrypt_aes_encrypt( + sip_msg_t *msg, char *inb, char *keyb, char *outb) +{ + str ins; + str keys; + pv_spec_t *dst; + + if(fixup_get_svalue(msg, (gparam_t *)inb, &ins) != 0) { + LM_ERR("cannot get input value\n"); + return -1; + } + if(fixup_get_svalue(msg, (gparam_t *)keyb, &keys) != 0) { + LM_ERR("cannot get key value\n"); + return -1; + } + dst = (pv_spec_t *)outb; + + return ki_gcrypt_aes_encrypt_helper(msg, &ins, &keys, dst); +} + +/** + * + */ +static int fixup_gcrypt_aes_encrypt(void **param, int param_no) +{ + if(param_no == 1 || param_no == 2) { + if(fixup_spve_null(param, 1) < 0) + return -1; + return 0; + } else if(param_no == 3) { + if(fixup_pvar_null(param, 1) != 0) { + LM_ERR("failed to fixup result pvar\n"); + return -1; + } + if(((pv_spec_t *)(*param))->setf == NULL) { + LM_ERR("result pvar is not writeble\n"); + return -1; + } + } + return 0; +} + +/** + * + */ +static int ki_gcrypt_aes_decrypt_helper( + sip_msg_t *msg, str *ins, str *keys, pv_spec_t *dst) +{ + pv_value_t val; + gcry_error_t gcry_ret; + gcry_cipher_hd_t cipher_hd; + size_t key_length = 0; + size_t blk_length = 0; + char *decrypted_txt = NULL; + str etext = STR_NULL; + + memset(&val, 0, sizeof(pv_value_t)); + etext.s = pv_get_buffer(); + etext.len = base64_dec((unsigned char *)ins->s, ins->len, + (unsigned char *)etext.s, pv_get_buffer_size() - 1); + if(etext.len < 0) { + LM_ERR("base64 input with encrypted value is too large (need %d)\n", + -etext.len); + return -1; + } + + if(!gcry_control(GCRYCTL_ANY_INITIALIZATION_P)) { + /* before calling any other functions */ + gcry_check_version(NULL); + } + + gcry_ret = gcry_cipher_open(&cipher_hd, // gcry_cipher_hd_t *hd + GCRY_CIPHER_AES256, // int algo + _gcrypt_aes_mode, // int mode + 0); // unsigned int flags + if(gcry_ret) { + LM_ERR("gcry cipher open failed: %s/%s\n", gcry_strsource(gcry_ret), + gcry_strerror(gcry_ret)); + return -1; + } + key_length = gcry_cipher_get_algo_keylen(GCRY_CIPHER_AES256); + if(keys->len < key_length) { + LM_ERR("the encryption key is too short\n"); + goto error; + } + gcry_ret = gcry_cipher_setkey(cipher_hd, keys->s, key_length); + if(gcry_ret) { + LM_ERR("gcry_cipher_setkey failed: %s/%s\n", gcry_strsource(gcry_ret), + gcry_strerror(gcry_ret)); + goto error; + } + + blk_length = gcry_cipher_get_algo_blklen(GCRY_CIPHER_AES256); + if(_gcrypt_init_vector.len < blk_length) { + LM_ERR("the init vector is too short\n"); + goto error; + } + + gcry_ret = gcry_cipher_setiv(cipher_hd, _gcrypt_init_vector.s, blk_length); + if(gcry_ret) { + LM_ERR("gcry_cipher_setiv failed: %s/%s\n", gcry_strsource(gcry_ret), + gcry_strerror(gcry_ret)); + goto error; + } + + decrypted_txt = malloc(etext.len + 1); + if(decrypted_txt == 0) { + SYS_MEM_ERROR; + goto error; + } + decrypted_txt[0] = '\0'; + gcry_ret = gcry_cipher_decrypt(cipher_hd, // gcry_cipher_hd_t h + decrypted_txt, // unsigned char *out + etext.len, // size_t outsize + etext.s, // const unsigned char *in + etext.len); // size_t inlen + if(gcry_ret) { + LM_ERR("gcry_cipher_decrypt failed: %s/%s\n", gcry_strsource(gcry_ret), + gcry_strerror(gcry_ret)); + goto error; + } + + val.rs.len = etext.len; + val.rs.s = decrypted_txt; + + LM_DBG("plain result: [%.*s]\n", val.rs.len, val.rs.s); + val.flags = PV_VAL_STR; + dst->setf(msg, &dst->pvp, (int)EQ_T, &val); + + free(decrypted_txt); + gcry_cipher_close(cipher_hd); + return 1; + +error: + if(decrypted_txt) { + free(decrypted_txt); + } + gcry_cipher_close(cipher_hd); + return -1; +} + +/** + * + */ +static int ki_gcrypt_aes_decrypt(sip_msg_t *msg, str *ins, str *keys, str *dpv) +{ + pv_spec_t *dst; + + dst = pv_cache_get(dpv); + + if(dst == NULL) { + LM_ERR("failed getting pv: %.*s\n", dpv->len, dpv->s); + return -1; + } + + return ki_gcrypt_aes_decrypt_helper(msg, ins, keys, dst); +} + +/** + * + */ +static int w_gcrypt_aes_decrypt( + sip_msg_t *msg, char *inb, char *keyb, char *outb) +{ + str ins; + str keys; + pv_spec_t *dst; + + if(fixup_get_svalue(msg, (gparam_t *)inb, &ins) != 0) { + LM_ERR("cannot get input value\n"); + return -1; + } + if(fixup_get_svalue(msg, (gparam_t *)keyb, &keys) != 0) { + LM_ERR("cannot get key value\n"); + return -1; + } + + dst = (pv_spec_t *)outb; + + return ki_gcrypt_aes_decrypt_helper(msg, &ins, &keys, dst); +} + +/** + * + */ +static int fixup_gcrypt_aes_decrypt(void **param, int param_no) +{ + if(param_no == 1 || param_no == 2) { + if(fixup_spve_null(param, 1) < 0) + return -1; + return 0; + } else if(param_no == 3) { + if(fixup_pvar_null(param, 1) != 0) { + LM_ERR("failed to fixup result pvar\n"); + return -1; + } + if(((pv_spec_t *)(*param))->setf == NULL) { + LM_ERR("result pvar is not writeble\n"); + return -1; + } + } + return 0; +} + + +/** + * + */ +/* clang-format off */ +static sr_kemi_t sr_kemi_gcrypt_exports[] = { + { str_init("gcrypt"), str_init("aes_encrypt"), + SR_KEMIP_INT, ki_gcrypt_aes_encrypt, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("gcrypt"), str_init("aes_decrypt"), + SR_KEMIP_INT, ki_gcrypt_aes_decrypt, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + + { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } } +}; +/* clang-format on */ + +int mod_register(char *path, int *dlflags, void *p1, void *p2) +{ + sr_kemi_modules_add(sr_kemi_gcrypt_exports); + return 0; +} diff --git a/src/modules/gcrypt/gcrypt_uuid.c b/src/modules/gcrypt/gcrypt_uuid.c new file mode 100644 index 000000000..e80d25e01 --- /dev/null +++ b/src/modules/gcrypt/gcrypt_uuid.c @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2024 Daniel-Constantin Mierla (asipto.com) + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/*! + * \file + * \brief Gcrypt :: Fast enough high entropy Call-ID generator + * + * Fast enough high entropy Call-ID generator. The Call-ID generated + * is an RFC 4122 version 4 UUID using high quality entropy from + * libgcrypt. This entropy is extracted only once at startup and is + * then combined in each child with the process ID and a counter. The + * result is whitened with SHA1 and formatted per RFC 4122. + */ + +#include +#include +#include +#include "../../core/dprint.h" +#include "../../core/srapi.h" +#include "gcrypt_uuid.h" + +#define CTR_LEN 16 +static unsigned char gcrypt_callid_counter[CTR_LEN] = {0}; + + +/** + * \brief Convert value to hex character + * \param x unsigned char byte + * \return lowercase hex charater + */ +static inline char gcrypt_byte2hex(unsigned char x) +{ + return x < 10 ? '0' + x : 'a' + (x - 10); +} + +/** + * \brief Convert array of bytes to hexidecimal string + * \param sbuf output character array + * \param sbuf_len allocated size of sbuf, must be 2x buf_len + * \param buf input byte array + * \param buf_len number of bytes of buf + * \return 0 on success, -1 on error + */ +static inline int gcrypt_bytes2hex( + char *sbuf, size_t sbuf_len, unsigned char *buf, size_t buf_len) +{ + size_t i, j; + if(sbuf_len < 2 * buf_len) + return -1; + for(i = 0, j = (2 * buf_len) - 1; i < sbuf_len; i++, j--) { + sbuf[i] = gcrypt_byte2hex((buf[j / 2] >> (j % 2 ? 0 : 4)) % 0x0f); + if(j == 0) + break; + } + return 0; +} + + +/** + * \brief Increment a counter + * \param ctr input array of bytes + * \param len length of byte array + * \return void + */ +static inline void gcrypt_inc_counter(unsigned char *ctr, size_t len) +{ + size_t i; + for(i = 0; i < len; i++) { + ctr[i] += 1; + if(ctr[i]) + break; + } +} + + +#define UUID_LEN 36 + +/** + * \brief Convert array of bytes to RFC 4122 UUID (version 4) + * \param sbuf output character array + * \param sbuf_len allocated size of sbuf, must be at least 36 + * \param buf input byte array + * \param buf_len number of bytes of buf, must be at least 16 + * \return 0 on success, -1 on error + */ +static inline int gcrypt_format_rfc4122_uuid( + char *sbuf, size_t sbuf_len, unsigned char *buf, size_t buf_len) +{ + size_t i, j; + if(sbuf_len < UUID_LEN) + return -1; + if(buf_len < UUID_LEN / 2) + return -1; + buf[6] &= 0x0f; + buf[6] |= 4 << 4; + buf[8] &= 0x3f; + buf[8] |= 2 << 6; + for(i = 0, j = 0; i < UUID_LEN; i++) { + if(i == 8 || i == 13 || i == 18 || i == 23) { + sbuf[i] = '-'; + continue; + } + sbuf[i] = gcrypt_byte2hex((buf[j / 2] >> (j % 2 ? 0 : 4)) % 0x0f); + if(!(++j / 2 < buf_len)) + break; + } + return 0; +} + +#ifndef SHA_DIGEST_LENGTH +#define SHA_DIGEST_LENGTH 20 +#endif + +/** + * \brief Get a unique Call-ID + * \param callid returned Call-ID + */ +void gcrypt_generate_callid(str *callid) +{ +#define RAND_BUF_SIZE 16 + static char rand_buf[RAND_BUF_SIZE]; + static unsigned char sha1_buf[SHA_DIGEST_LENGTH] = {0}; + static char uuid_buf[UUID_LEN] = {0}; + gcry_md_hd_t hd; + gcry_error_t err; + int lpid; + + if(!gcry_control(GCRYCTL_ANY_INITIALIZATION_P)) { + /* before calling any other functions */ + gcry_check_version(NULL); + } + + err = gcry_md_open(&hd, GCRY_MD_SHA1, 0); + if(err) { + LM_ERR("cannot get new context\n"); + callid->s = NULL; + callid->len = 0; + return; + } + + gcry_randomize(rand_buf, RAND_BUF_SIZE, GCRY_STRONG_RANDOM); + gcry_md_write(hd, rand_buf, RAND_BUF_SIZE); + lpid = my_pid(); + gcry_md_write(hd, &lpid, sizeof(int)); + gcrypt_inc_counter(gcrypt_callid_counter, CTR_LEN); + gcry_md_write(hd, gcrypt_callid_counter, CTR_LEN); + memcpy(sha1_buf, gcry_md_read(hd, GCRY_MD_SHA1), SHA_DIGEST_LENGTH); + gcry_md_close(hd); + + gcrypt_format_rfc4122_uuid(uuid_buf, UUID_LEN, sha1_buf, SHA_DIGEST_LENGTH); + + callid->s = uuid_buf; + callid->len = UUID_LEN; +} + + +/** + * + */ +int gcrypt_register_callid_func(void) +{ + if(sr_register_callid_func(gcrypt_generate_callid) < 0) { + LM_ERR("unable to register callid func\n"); + return -1; + } + return 0; +} diff --git a/src/modules/tls_wolfssl/tls_dump_vf.h b/src/modules/gcrypt/gcrypt_uuid.h similarity index 53% rename from src/modules/tls_wolfssl/tls_dump_vf.h rename to src/modules/gcrypt/gcrypt_uuid.h index fec2ba5c7..3141d4172 100644 --- a/src/modules/tls_wolfssl/tls_dump_vf.h +++ b/src/modules/gcrypt/gcrypt_uuid.h @@ -1,7 +1,6 @@ /* - * TLS module - * - * Copyright (C) 2006 enum.at + * Copyright (C) 2024 Daniel-Constantin Mierla (asipto.com) + * Copyright (C) 2016 Travis Cross * * This file is part of Kamailio, a free SIP server. * @@ -19,23 +18,43 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * Exception: permission to copy, modify, propagate, and distribute a work - * formed by combining OpenSSL toolkit software and the code in this file, - * such as linking with software components and libraries released under - * OpenSSL project license. */ -/** log the verification failure reason. - * @file tls_dump_vf.h - * @ingroup: tls - * Module: @ref tls + +/*! + * \file + * \brief Crypto :: Fast enough high entropy Call-ID generator + * \ingroup tm */ -#ifndef __tls_dump_vf_h -#define __tls_dump_vf_h +#ifndef __GRYPT_UUID_H__ +#define __GRYPT_UUID_H__ -void tls_dump_verification_failure(long verification_result); +#include "../../core/str.h" -#endif /*__tls_dump_vf_h*/ -/* vi: set ts=4 sw=4 tw=79:ai:cindent: */ +/** + * \brief Initialize the Call-ID generator + * \return 0 on success, -1 on error + */ +int gcrypt_init_callid(void); + + +/** + * \brief TM API export + */ +typedef void (*generate_callid_f)(str *); + + +/** + * \brief Get a unique Call-ID + * \param callid returned Call-ID + */ +void gcrypt_generate_callid(str *callid); + +/** + * + */ +int gcrypt_register_callid_func(void); + +#endif /* __GRYPT_UUID_H__ */ diff --git a/src/modules/geoip/geoip_mod.c b/src/modules/geoip/geoip_mod.c index f95ee001d..9c953d06d 100644 --- a/src/modules/geoip/geoip_mod.c +++ b/src/modules/geoip/geoip_mod.c @@ -45,31 +45,38 @@ static void mod_destroy(void); static int w_geoip_match(struct sip_msg *msg, char *str1, char *str2); static int geoip_match(sip_msg_t *msg, str *tomatch, str *pvclass); +/* clang-format off */ static pv_export_t mod_pvs[] = { - {{"gip", sizeof("gip") - 1}, PVT_OTHER, pv_get_geoip, 0, + {{"gip", sizeof("gip") - 1}, PVT_OTHER, pv_get_geoip, 0, pv_parse_geoip_name, 0, 0, 0}, - {{0, 0}, 0, 0, 0, 0, 0, 0, 0}}; + {{0, 0}, 0, 0, 0, 0, 0, 0, 0} +}; -static cmd_export_t cmds[] = {{"geoip_match", (cmd_function)w_geoip_match, 2, - fixup_spve_spve, 0, ANY_ROUTE}, - {0, 0, 0, 0, 0, 0}}; +static cmd_export_t cmds[] = { + {"geoip_match", (cmd_function)w_geoip_match, 2, + fixup_spve_spve, 0, ANY_ROUTE}, + {0, 0, 0, 0, 0, 0} +}; static param_export_t params[] = { - {"path", PARAM_STRING, &geoip_path}, {0, 0, 0}}; + {"path", PARAM_STRING, &geoip_path}, + {0, 0, 0} +}; struct module_exports exports = { - "geoip", /* module name */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* exported functions */ - params, /* exported parameters */ - 0, /* RPC method exports */ - mod_pvs, /* exported pseudo-variables */ - 0, /* response handling function */ - mod_init, /* module initialization function */ - 0, /* per-child init function */ - mod_destroy /* module destroy function */ + "geoip", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* exported functions */ + params, /* exported parameters */ + 0, /* RPC method exports */ + mod_pvs, /* exported pseudo-variables */ + 0, /* response handling function */ + mod_init, /* module initialization function */ + 0, /* per-child init function */ + mod_destroy /* module destroy function */ }; +/* clang-format on */ /** diff --git a/src/modules/geoip2/README b/src/modules/geoip2/README index d89372c48..70319467c 100644 --- a/src/modules/geoip2/README +++ b/src/modules/geoip2/README @@ -35,6 +35,7 @@ Henning Westerholt 4. Functions 4.1. geoip2_match(ipaddr, pvc) + 4.2. geoip2_distance(ip_addr, latitude, longitude) 5. RPC Commands @@ -47,7 +48,8 @@ Henning Westerholt 1.1. Set path parameter 1.2. Set resid parameter 1.3. geoip2_match usage - 1.4. geoip2.reload usage + 1.4. geoip2_distance usage + 1.5. geoip2.reload usage Chapter 1. Admin Guide @@ -67,6 +69,7 @@ Chapter 1. Admin Guide 4. Functions 4.1. geoip2_match(ipaddr, pvc) + 4.2. geoip2_distance(ip_addr, latitude, longitude) 5. RPC Commands @@ -151,6 +154,7 @@ if(geoip2_match("$si", "src")) { 4. Functions 4.1. geoip2_match(ipaddr, pvc) + 4.2. geoip2_distance(ip_addr, latitude, longitude) 4.1. geoip2_match(ipaddr, pvc) @@ -165,6 +169,24 @@ if(geoip2_match("$si", "src")) xlog("SIP message from: $gip2(src=>cc)\n"); ... +4.2. geoip2_distance(ip_addr, latitude, longitude) + + The function calculates the distance in miles between the + geocoordinates of the IP address passed as parameter (the coordinates + are calculated inside the function) and the geocoordinates latitude and + longitude + + Example 1.4. geoip2_distance usage +... + $var(client_ip) = "109.184.18.64"; + $var(lat_pos) = "53.200660"; + $var(lon_pos) = "45.004640"; + $var(dist) = geoip2_distance($var(client_ip), $var(lat_pos), $var(lon_po +s)); + + xlog("distance is $var(dist)\n"); +... + 5. RPC Commands 5.1. geoip2.reload @@ -174,7 +196,7 @@ if(geoip2_match("$si", "src")) Reload the internal GeoIP database. This is necessary after the database file has been changed on the disk. - Example 1.4. geoip2.reload usage + Example 1.5. geoip2.reload usage ... kamcmd geoip2.reload ... diff --git a/src/modules/geoip2/doc/geoip2_admin.xml b/src/modules/geoip2/doc/geoip2_admin.xml index b3df24ebe..cbc6ccb14 100644 --- a/src/modules/geoip2/doc/geoip2_admin.xml +++ b/src/modules/geoip2/doc/geoip2_admin.xml @@ -29,8 +29,7 @@ This database itself can be obtained on a free or commercial basis from - http://dev.maxmind.com/geoip/. The - library libmaxminddb + http://dev.maxmind.com/geoip/. The library libmaxminddb that interfaces with the Max Mind API, as well as scripts to automate downloading of the on-disk version are available at @@ -129,7 +128,7 @@ if(geoip2_match("$si", "src")) {
Functions -
+
<function moreinfo="none">geoip2_match(ipaddr, pvc)</function> @@ -149,6 +148,29 @@ if(geoip2_match("$si", "src"))
+
+ + <function moreinfo="none">geoip2_distance(ip_addr, latitude, longitude)</function> + + + The function calculates the distance in miles between the geocoordinates of + the IP address passed as parameter (the coordinates are calculated inside the function) + and the geocoordinates latitude and longitude + + + <function>geoip2_distance</function> usage + +... + $var(client_ip) = "109.184.18.64"; + $var(lat_pos) = "53.200660"; + $var(lon_pos) = "45.004640"; + $var(dist) = geoip2_distance($var(client_ip), $var(lat_pos), $var(lon_pos)); + + xlog("distance is $var(dist)\n"); +... + + +
@@ -173,7 +195,7 @@ if(geoip2_match("$si", "src"))
-
+
Exported pseudo-variables diff --git a/src/modules/geoip2/geoip2_mod.c b/src/modules/geoip2/geoip2_mod.c index 0315476c4..1131bba90 100644 --- a/src/modules/geoip2/geoip2_mod.c +++ b/src/modules/geoip2/geoip2_mod.c @@ -19,6 +19,7 @@ * */ +#include #include #include #include @@ -36,6 +37,10 @@ MODULE_VERSION +#define MAX_GEO_STR_SIZE 512 +#define EARTH_RADIUS (6371.0072 * 0.6214) +#define TORADS(degrees) (degrees * (M_PI / 180)) + static char *geoip2_path = NULL; static int mod_init(void); @@ -43,33 +48,45 @@ static void mod_destroy(void); static int geoip2_rpc_init(void); static int w_geoip2_match(struct sip_msg *msg, char *str1, char *str2); -static int geoip2_match(sip_msg_t *msg, str *tomatch, str *pvclass); static int geoip2_resid_param(modparam_t type, void *val); +static int w_geoip2_distance(struct sip_msg *msg, char *str1, char *str2, char *str3); + +/* clang-format off */ static pv_export_t mod_pvs[] = { - {{"gip2", sizeof("gip2") - 1}, PVT_OTHER, pv_get_geoip2, 0, - pv_parse_geoip2_name, 0, 0, 0}, - {{0, 0}, 0, 0, 0, 0, 0, 0, 0}}; + {{"gip2", sizeof("gip2") - 1}, PVT_OTHER, pv_get_geoip2, 0, + pv_parse_geoip2_name, 0, 0, 0}, + + {{0, 0}, 0, 0, 0, 0, 0, 0, 0} +}; -static cmd_export_t cmds[] = {{"geoip2_match", (cmd_function)w_geoip2_match, 2, - fixup_spve_spve, 0, ANY_ROUTE}, - {0, 0, 0, 0, 0, 0}}; +static cmd_export_t cmds[] = { + {"geoip2_match", (cmd_function)w_geoip2_match, 2, + fixup_spve_spve, 0, ANY_ROUTE}, + {"geoip2_distance", (cmd_function)w_geoip2_distance, 3, + fixup_spve_all, fixup_free_spve_all, ANY_ROUTE}, + {0, 0, 0, 0, 0, 0} +}; -static param_export_t params[] = {{"path", PARAM_STRING, &geoip2_path}, - {"resid", PARAM_STR | PARAM_USE_FUNC, &geoip2_resid_param}, {0, 0, 0}}; +static param_export_t params[] = { + {"path", PARAM_STRING, &geoip2_path}, + {"resid", PARAM_STR | PARAM_USE_FUNC, &geoip2_resid_param}, + {0, 0, 0} +}; struct module_exports exports = { - "geoip2", /* module name */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* exported functions */ - params, /* exported parameters */ - 0, /* RPC method exports */ - mod_pvs, /* exported pseudo-variables */ - 0, /* response handling function */ - mod_init, /* module initialization function */ - 0, /* per-child init function */ - mod_destroy /* module destroy function */ + "geoip2", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* exported functions */ + params, /* exported parameters */ + 0, /* RPC method exports */ + mod_pvs, /* exported pseudo-variables */ + 0, /* response handling function */ + mod_init, /* module initialization function */ + 0, /* per-child init function */ + mod_destroy /* module destroy function */ }; +/* clang-format on */ /** * init module function @@ -118,7 +135,7 @@ static int geoip2_resid_param(modparam_t type, void *val) return 0; } -static int geoip2_match(sip_msg_t *msg, str *tomatch, str *pvclass) +static int ki_geoip2_match(sip_msg_t *msg, str *tomatch, str *pvclass) { geoip2_pv_reset(pvclass); @@ -144,7 +161,145 @@ static int w_geoip2_match(sip_msg_t *msg, char *target, char *pvname) return -1; } - return geoip2_match(msg, &tomatch, &pvclass); + return ki_geoip2_match(msg, &tomatch, &pvclass); +} + +static int geoip2_distance(sip_msg_t *msg, str *_ip_addr, double lat, double lon) +{ + char ip_addr[MAX_GEO_STR_SIZE] = {0}; + double lat1, lon1, lat2, lon2, orig_lat2, orig_lon2; + double d_lat, d_lon, a, c; + int dist = 0; + int gai_error, mmdb_error; + MMDB_lookup_result_s record; + MMDB_entry_data_s entry_data; + gen_lock_t *lock = get_gen_lock(); + + if(lock == NULL) { + LM_ERR("error GeoIP mutex is not initialized\n"); + return -1; + } + + LM_DBG("ip_addr=%.*s lat=%f lon=%f\n", _ip_addr->len, _ip_addr->s, lat, + lon); + + strncpy(ip_addr, _ip_addr->s, _ip_addr->len); + + MMDB_s *geoip_handle = get_geoip_handle(); + if(geoip_handle == NULL) { + LM_ERR("error GeoIP handle is not initialized\n"); + return -1; + } + + lock_get(lock); + record = MMDB_lookup_string( + geoip_handle, (const char *)ip_addr, &gai_error, &mmdb_error); + + LM_DBG("attempt to match: %s\n", ip_addr); + if(gai_error || MMDB_SUCCESS != mmdb_error || !record.found_entry) { + LM_DBG("no match for: %s\n", ip_addr); + lock_release(lock); + return -2; + } + + if(MMDB_get_value(&record.entry, &entry_data, "location", "latitude", NULL) + != MMDB_SUCCESS) { + LM_ERR("no location/latitude for: %s\n", ip_addr); + lock_release(lock); + return -2; + } + if(entry_data.has_data && entry_data.type == MMDB_DATA_TYPE_DOUBLE) { + orig_lat2 = entry_data.double_value; + } else { + LM_ERR("wrong format for location/latitude\n"); + lock_release(lock); + return -3; + } + + if(MMDB_get_value(&record.entry, &entry_data, "location", "longitude", NULL) + != MMDB_SUCCESS) { + LM_ERR("no location/longitude for: %s\n", ip_addr); + lock_release(lock); + return -2; + } + lock_release(lock); + if(entry_data.has_data && entry_data.type == MMDB_DATA_TYPE_DOUBLE) { + orig_lon2 = entry_data.double_value; + } else { + LM_ERR("wrong format for location/latitude\n"); + return -3; + } + + LM_INFO("for ip_addr=%s the following coordinates: lat=%f lon=%f\n", + ip_addr, orig_lat2, orig_lon2); + + lat1 = TORADS(lat); + lon1 = TORADS(lon); + lat2 = TORADS(orig_lat2); + lon2 = TORADS(orig_lon2); + + d_lat = lat2 - lat1; + d_lon = lon2 - lon1; + + a = sin(d_lat / 2) * sin(d_lat / 2) + + cos(lat1) * cos(lat2) * sin(d_lon / 2) * sin(d_lon / 2); + c = 2 * atan2(sqrt(a), sqrt(1 - a)); + + dist = (int)(EARTH_RADIUS * c); + + LM_DBG("lat1=%f lon1=%f lat2=%f lon2=%f distance = %d\n", lat, lon, + orig_lat2, orig_lon2, dist); + + return dist; +} + +static int ki_geoip2_distance(sip_msg_t *msg, str *_ipaddr, str *_lat, str *_lon) +{ + double lat = 0; + double lon = 0; + char buf[MAX_GEO_STR_SIZE] = {0}; + + strncpy(buf, _lat->s, _lat->len); + lat = atof(buf); + if(!lat && errno == ERANGE) { + LM_ERR("cannot convert string to double: %.*s\n", _lat->len, + _lat->s); + return -1; + } + + memset(buf, 0, MAX_GEO_STR_SIZE); + strncpy(buf, _lon->s, _lon->len); + lon = atof(buf); + if(!lon && errno == ERANGE) { + LM_ERR("cannot convert string to double: %.*s\n", _lon->len, + _lon->s); + return -1; + } + + return geoip2_distance(msg, _ipaddr, lat, lon); + +} + +static int w_geoip2_distance(sip_msg_t *msg, char *ip_addr_param, char *lat_param, + char *lon_param) +{ + str ip_addr_str = STR_NULL; + str lat_str = STR_NULL; + str lon_str = STR_NULL; + if(fixup_get_svalue(msg, (gparam_t *)ip_addr_param, &ip_addr_str) < 0) { + LM_ERR("cannot get the IP address\n"); + return -1; + } + if(fixup_get_svalue(msg, (gparam_t *)lat_param, &lat_str) < 0) { + LM_ERR("cannot get latitude string\n"); + return -1; + } + if(fixup_get_svalue(msg, (gparam_t *)lon_param, &lon_str) < 0) { + LM_ERR("cannot get longitude string\n"); + return -1; + } + + return ki_geoip2_distance(msg, &ip_addr_str, &lat_str, &lon_str); } static void geoip2_rpc_reload(rpc_t *rpc, void *ctx) @@ -155,12 +310,17 @@ static void geoip2_rpc_reload(rpc_t *rpc, void *ctx) } } +/* clang-format off */ static const char *geoip2_rpc_reload_doc[2] = { - "Reload GeoIP2 database file.", 0}; + "Reload GeoIP2 database file.", + 0 +}; rpc_export_t ubl_rpc[] = { - {"geoip2.reload", geoip2_rpc_reload, geoip2_rpc_reload_doc, 0}, - {0, 0, 0, 0}}; + {"geoip2.reload", geoip2_rpc_reload, geoip2_rpc_reload_doc, 0}, + {0, 0, 0, 0} +}; +/* clang-format on */ static int geoip2_rpc_init(void) { @@ -177,10 +337,15 @@ static int geoip2_rpc_init(void) /* clang-format off */ static sr_kemi_t sr_kemi_geoip2_exports[] = { { str_init("geoip2"), str_init("match"), - SR_KEMIP_INT, geoip2_match, + SR_KEMIP_INT, ki_geoip2_match, { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, + { str_init("geoip2"), str_init("distance"), + SR_KEMIP_INT, ki_geoip2_distance, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, + 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/geoip2/geoip2_pv.c b/src/modules/geoip2/geoip2_pv.c index edd32ff6f..22789941d 100644 --- a/src/modules/geoip2/geoip2_pv.c +++ b/src/modules/geoip2/geoip2_pv.c @@ -70,6 +70,16 @@ static gen_lock_t *lock = NULL; static sr_geoip2_item_t *_sr_geoip2_list = NULL; +MMDB_s *get_geoip_handle(void) +{ + return _handle_GeoIP; +} + +gen_lock_t *get_gen_lock(void) +{ + return lock; +} + sr_geoip2_record_t *sr_geoip2_get_record(str *name) { sr_geoip2_item_t *it = NULL; diff --git a/src/modules/geoip2/geoip2_pv.h b/src/modules/geoip2/geoip2_pv.h index 3742e66d5..e50579f92 100644 --- a/src/modules/geoip2/geoip2_pv.h +++ b/src/modules/geoip2/geoip2_pv.h @@ -35,5 +35,7 @@ int geoip2_reload_pv(char *path); void geoip2_pv_reset(str *pvclass); int geoip2_update_pv(str *tomatch, str *pvclass); int sr_geoip2_add_resid(str *rname); +MMDB_s *get_geoip_handle(void); +gen_lock_t *get_gen_lock(void); #endif diff --git a/src/modules/htable/README b/src/modules/htable/README index 0252b62e0..4520bce83 100644 --- a/src/modules/htable/README +++ b/src/modules/htable/README @@ -19,7 +19,13 @@ Ovidiu Sas +Tyler Moore + + + Copyright © 2008-2011 http://www.asipto.com + + Copyright © 2023 Tyler Moore (devopsec), dOpenSource __________________________________________________________________ Table of Contents @@ -93,6 +99,8 @@ Ovidiu Sas 6.11. htable.flush htable 6.12. htable.listTables 6.13. htable.stats + 6.14. htable.dmqsync [htable] + 6.15. htable.dmqresync htable 7. Event routes @@ -212,6 +220,8 @@ Chapter 1. Admin Guide 6.11. htable.flush htable 6.12. htable.listTables 6.13. htable.stats + 6.14. htable.dmqsync [htable] + 6.15. htable.dmqresync htable 7. Event routes @@ -510,6 +520,35 @@ $ kamcmd htable.dump htable nodes (htable peers). Please note, module parameter “enable_dmq” must also be set in order for this to apply (see below). Default is 0 (no replication). + * coldelim - the character delimeter to use when packing the htable. + When set, this parameter changes the column delimeter between + columns in a multiple column hash table. This can be useful when + loading JSON data types into a hash table as they conflict with the + default “,” delimeter, allowing these values to be parsed in the + routing config. See the example below on parsing a JSON array from + an htable with “;” as the column delimeter. +... +modparam("htable", "htable", "customer=>size=8;dbtable=customer;cols='dids,descr +iption';coldelim=';'") +... +$avp(customer) = $sht(customer=>1); +$var(customer_dids) = $(avp(customer){s.select,0,;}); +$var(customer_desc) = $(avp(customer){s.select,1,;}); +... + * colnull - the character to use when packing a NULL value into the + htable from the database. This parameter can be set to the empty + string or a single character. This can be used to simplify checking + a single column in a row for emptiness, in the routing config. The + example below shows how one would do that. +... +modparam("htable", "htable", "customer=>size=8;dbtable=customer;cols='name,descr +iption';colnull=''") +... +$avp(customer) = $sht(customer=>1); +$var(customer_name) = $(avp(customer){s.select,0,;}); +if (!strempty($var(customer_name))) { +... +} Default value is NULL. @@ -1123,6 +1162,8 @@ if(sht_match_str_value("ha", "eq", "alice")) { 6.11. htable.flush htable 6.12. htable.listTables 6.13. htable.stats + 6.14. htable.dmqsync [htable] + 6.15. htable.dmqresync htable 6.1. htable.get htable key @@ -1368,6 +1409,37 @@ kamcmd htable.listTables kamcmd htable.stats ... +6.14. htable.dmqsync [htable] + + Perform a DMQ sync action. + + Name: htable.dmqsync + + Parameters: + * htable: name of the hash table to perform dmq sync for. If not + provided, sync is performed for all hash tables that have dmq sync + enabled. + + Example: +... +kamcmd htable.dmqsync +kamcmd htable.dmqsync ipban +... + +6.15. htable.dmqresync htable + + Perform a resync action (flush and dmq sync). + + Name: htable.dmqresync + + Parameters: + * htable: name of the hash table to perform resync for. + + Example: +... +kamcmd htable.dmqresync ipban +... + 7. Event routes 7.1. htable:mod-init diff --git a/src/modules/htable/doc/htable.xml b/src/modules/htable/doc/htable.xml index 70670eaec..7b5675889 100644 --- a/src/modules/htable/doc/htable.xml +++ b/src/modules/htable/doc/htable.xml @@ -39,11 +39,20 @@ Sas osas@voipembedded.com + + Tyler + Moore + tmoore@dopensource.com + 2008-2011 http://www.asipto.com + + 2023 + Tyler Moore (devopsec), dOpenSource + diff --git a/src/modules/htable/doc/htable_admin.xml b/src/modules/htable/doc/htable_admin.xml index 84f20e7b3..69ad5e645 100644 --- a/src/modules/htable/doc/htable_admin.xml +++ b/src/modules/htable/doc/htable_admin.xml @@ -412,6 +412,43 @@ $ kamcmd htable.dump htable peers). Please note, module parameter enable_dmq must also be set in order for this to apply (see below). Default is 0 (no replication). + + + + coldelim - the character delimeter to use when packing the htable. + When set, this parameter changes the column delimeter between columns in a multiple + column hash table. This can be useful when loading JSON data types into a hash table + as they conflict with the default , delimeter, allowing these values + to be parsed in the routing config. See the example below on parsing a JSON array from + an htable with ; as the column delimeter. + + +... +modparam("htable", "htable", "customer=>size=8;dbtable=customer;cols='dids,description';coldelim=';'") +... +$avp(customer) = $sht(customer=>1); +$var(customer_dids) = $(avp(customer){s.select,0,;}); +$var(customer_desc) = $(avp(customer){s.select,1,;}); +... + + + + + colnull - the character to use when packing a NULL value into + the htable from the database. This parameter can be set to the empty string or a + single character. This can be used to simplify checking a single column in a row + for emptiness, in the routing config. The example below shows how one would do that. + + +... +modparam("htable", "htable", "customer=>size=8;dbtable=customer;cols='name,description';colnull=''") +... +$avp(customer) = $sht(customer=>1); +$var(customer_name) = $(avp(customer){s.select,0,;}); +if (!strempty($var(customer_name))) { +... +} + @@ -1780,7 +1817,56 @@ kamcmd htable.stats ...
- +
+ + <function moreinfo="none">htable.dmqsync [htable]</function> + + + Perform a DMQ sync action. + + + Name: htable.dmqsync + + Parameters: + + htable: name of the hash table to perform dmq sync for. + If not provided, sync is performed for all hash tables that have + dmq sync enabled. + + + Example: + + +... +kamcmd htable.dmqsync +kamcmd htable.dmqsync ipban +... + +
+
+ + <function moreinfo="none">htable.dmqresync htable</function> + + + Perform a resync action (flush and dmq sync). + + + Name: htable.dmqresync + + Parameters: + + htable: name of the hash table to perform resync for. + + + + Example: + + +... +kamcmd htable.dmqresync ipban +... + +
diff --git a/src/modules/htable/ht_api.c b/src/modules/htable/ht_api.c index 913d03874..2391cb5c5 100644 --- a/src/modules/htable/ht_api.c +++ b/src/modules/htable/ht_api.c @@ -255,7 +255,7 @@ ht_t *ht_get_table(str *name) int ht_add_table(str *name, int autoexp, str *dbtable, str *dbcols, int size, int dbmode, int itype, int_str *ival, int updateexpire, - int dmqreplicate) + int dmqreplicate, char coldelim, char colnull) { unsigned int htid; ht_t *ht; @@ -342,8 +342,8 @@ int ht_add_table(str *name, int autoexp, str *dbtable, str *dbcols, int size, } ht->ncols = c + 1; ht->pack[0] = 'l'; - ht->pack[1] = ','; - ht->pack[2] = '*'; + ht->pack[1] = coldelim; + ht->pack[2] = colnull; } ht->next = _ht_root; @@ -931,8 +931,9 @@ int ht_dbg(void) it = ht->entries[i].first; while(it) { LM_ERR("\tcell: %.*s\n", it->name.len, it->name.s); - LM_ERR("\thid: %u msize: %u flags: %d expire: %u\n", it->cellid, - it->msize, it->flags, (unsigned int)it->expire); + LM_ERR("\thid: %u msize: %u flags: %d expire: %llu\n", + it->cellid, it->msize, it->flags, + (unsigned long long)it->expire); if(it->flags & AVP_VAL_STR) LM_ERR("\tv-s:%.*s\n", it->value.s.len, it->value.s.s); else @@ -957,6 +958,8 @@ int ht_table_spec(char *spec) unsigned int dbmode = 0; unsigned int updateexpire = 1; unsigned int dmqreplicate = 0; + char coldelim = ','; + char colnull = '*'; str in; str tok; param_t *pit = NULL; @@ -1023,13 +1026,34 @@ int ht_table_spec(char *spec) LM_DBG("htable [%.*s] - dmqreplicate [%u]\n", name.len, name.s, dmqreplicate); + } else if(pit->name.len == 8 + && strncmp(pit->name.s, "coldelim", 8) == 0) { + if(tok.len > 1) + goto error; + + coldelim = tok.s[0]; + LM_DBG("htable [%.*s] - coldelim [%c]\n", name.len, name.s, + coldelim); + } else if(pit->name.len == 7 + && strncmp(pit->name.s, "colnull", 7) == 0) { + if(tok.len > 1) + goto error; + + if(tok.len == 0) { + colnull = '\0'; + } else { + colnull = tok.s[0]; + } + + LM_DBG("htable [%.*s] - colnull [%c]\n", name.len, name.s, + colnull); } else { goto error; } } return ht_add_table(&name, autoexpire, &dbtable, &dbcols, size, dbmode, - itype, &ival, updateexpire, dmqreplicate); + itype, &ival, updateexpire, dmqreplicate, coldelim, colnull); error: LM_ERR("invalid htable parameter [%.*s]\n", in.len, in.s); @@ -1224,7 +1248,7 @@ int ht_set_cell_expire(ht_t *ht, str *name, int type, int_str *val) now = 0; if(val->n > 0) now = time(NULL) + val->n; - LM_DBG("set auto-expire to %u (%ld)\n", (unsigned int)now, val->n); + LM_DBG("set auto-expire to %llu (%ld)\n", (unsigned long long)now, val->n); ht_slot_lock(ht, idx); it = ht->entries[idx].first; diff --git a/src/modules/htable/ht_api.h b/src/modules/htable/ht_api.h index d8bdc2aab..e24a93b1f 100644 --- a/src/modules/htable/ht_api.h +++ b/src/modules/htable/ht_api.h @@ -88,7 +88,7 @@ typedef struct _ht_pv int ht_add_table(str *name, int autoexp, str *dbtable, str *dbcols, int size, int dbmode, int itype, int_str *ival, int updateexpire, - int dmqreplicate); + int dmqreplicate, char coldelim, char colnull); int ht_init_tables(void); int ht_destroy(void); int ht_set_cell(ht_t *ht, str *name, int type, int_str *val, int mode); diff --git a/src/modules/htable/ht_db.c b/src/modules/htable/ht_db.c index 631788b1a..7a22ff6c4 100644 --- a/src/modules/htable/ht_db.c +++ b/src/modules/htable/ht_db.c @@ -121,7 +121,9 @@ static int ht_pack_values( len = 0; for(c = 1; c < cols; c++) { if(VAL_NULL(&RES_ROWS(db_res)[row].values[c])) { - len += 1; + if(ht->pack[2] != '\0') { + len += 1; + } } else if(RES_ROWS(db_res)[row].values[c].type == DB1_STRING) { len += strlen(RES_ROWS(db_res)[row].values[c].val.string_val); } else if(RES_ROWS(db_res)[row].values[c].type == DB1_STR) { @@ -143,8 +145,10 @@ static int ht_pack_values( p = vbuf; for(c = 1; c < cols; c++) { if(VAL_NULL(&RES_ROWS(db_res)[row].values[c])) { - *p = ht->pack[2]; - p++; + if(ht->pack[2] != '\0') { + *p = ht->pack[2]; + p++; + } } else if(RES_ROWS(db_res)[row].values[c].type == DB1_STRING) { strcpy(p, RES_ROWS(db_res)[row].values[c].val.string_val); p += strlen(RES_ROWS(db_res)[row].values[c].val.string_val); @@ -194,7 +198,7 @@ int ht_db_load_table(ht_t *ht, str *dbtable, int mode) int i; int ret; int cnt; - int now; + long now; int ncols; int c; @@ -266,7 +270,7 @@ int ht_db_load_table(ht_t *ht, str *dbtable, int mode) pname.s = ""; n = 0; last_ktype = 0; - now = (int)time(NULL); + now = (long)time(NULL); do { for(i = 0; i < RES_ROW_N(db_res); i++) { if(VAL_NULL(&RES_ROWS(db_res)[i].values[0])) { diff --git a/src/modules/htable/ht_dmq.c b/src/modules/htable/ht_dmq.c index f010097ba..ea6b97c38 100644 --- a/src/modules/htable/ht_dmq.c +++ b/src/modules/htable/ht_dmq.c @@ -57,7 +57,7 @@ dmq_peer_t *ht_dmq_peer = NULL; dmq_resp_cback_t ht_dmq_resp_callback = {&ht_dmq_resp_callback_f, 0}; int ht_dmq_send(str *body, dmq_node_t *node); -int ht_dmq_send_sync(dmq_node_t *node); +int ht_dmq_send_sync(dmq_node_t *node, str *htname); int ht_dmq_handle_sync(srjson_doc_t *jdoc); static int ht_dmq_cell_group_init(void) @@ -217,7 +217,8 @@ int ht_dmq_initialize() } not_peer.callback = ht_dmq_handle_msg; - not_peer.init_callback = (ht_dmq_init_sync ? ht_dmq_request_sync : NULL); + not_peer.init_callback = + (ht_dmq_init_sync ? ht_dmq_request_sync_all : NULL); not_peer.description.s = "htable"; not_peer.description.len = 6; not_peer.peer_id.s = "htable"; @@ -261,7 +262,8 @@ int ht_dmq_handle_msg( int content_length; str body; ht_dmq_action_t action = HT_DMQ_NONE; - str htname, cname; + str htname = str_init(""); + str cname; int type = 0, mode = 0; int_str val; srjson_doc_t jdoc; @@ -306,7 +308,6 @@ int ht_dmq_handle_msg( if(unlikely(strcmp(jdoc.root->child->string, "cells") == 0)) { ht_dmq_handle_sync(&jdoc); } else { - for(it = jdoc.root->child; it; it = it->next) { LM_DBG("found field: %s\n", it->string); if(strcmp(it->string, "action") == 0) { @@ -333,7 +334,7 @@ int ht_dmq_handle_msg( } if(unlikely(action == HT_DMQ_SYNC)) { - ht_dmq_send_sync(dmq_node); + ht_dmq_send_sync(dmq_node, &htname); } else { if(ht_dmq_replay_action(action, &htname, &cname, type, &val, mode) != 0) { @@ -456,7 +457,7 @@ int ht_dmq_replay_action(ht_dmq_action_t action, str *htname, str *cname, } } -int ht_dmq_request_sync() +int ht_dmq_request_sync(str *htname) { srjson_doc_t jdoc; @@ -471,6 +472,10 @@ int ht_dmq_request_sync() } srjson_AddNumberToObject(&jdoc, jdoc.root, "action", HT_DMQ_SYNC); + if(htname != NULL && htname->len > 0) { + srjson_AddStrToObject( + &jdoc, jdoc.root, "htname", htname->s, htname->len); + } jdoc.buf.s = srjson_PrintUnformatted(&jdoc, jdoc.root); if(jdoc.buf.s == NULL) { LM_ERR("unable to serialize data\n"); @@ -496,7 +501,12 @@ error: return -1; } -int ht_dmq_send_sync(dmq_node_t *node) +int ht_dmq_request_sync_all() +{ + return ht_dmq_request_sync(NULL); +} + +int ht_dmq_send_sync(dmq_node_t *node, str *htname) { ht_t *ht; ht_cell_t *it; @@ -518,6 +528,12 @@ int ht_dmq_send_sync(dmq_node_t *node) if(!ht->dmqreplicate) goto skip; + if(htname != NULL && htname->len > 0) { + if(htname->len != ht->name.len + || strncmp(htname->s, ht->name.s, htname->len) != 0) { + goto skip; + } + } for(i = 0; i < ht->htsize; i++) { ht_slot_lock(ht, i); it = ht->entries[i].first; diff --git a/src/modules/htable/ht_dmq.h b/src/modules/htable/ht_dmq.h index 0be75ff20..bc5f18830 100644 --- a/src/modules/htable/ht_dmq.h +++ b/src/modules/htable/ht_dmq.h @@ -49,7 +49,8 @@ int ht_dmq_replicate_action(ht_dmq_action_t action, str *htname, str *cname, int type, int_str *val, int mode); int ht_dmq_replay_action(ht_dmq_action_t action, str *htname, str *cname, int type, int_str *val, int mode); -int ht_dmq_request_sync(); +int ht_dmq_request_sync(str *htname); +int ht_dmq_request_sync_all(); int ht_dmq_resp_callback_f( struct sip_msg *msg, int code, dmq_node_t *node, void *param); diff --git a/src/modules/htable/htable.c b/src/modules/htable/htable.c index c63ee73d0..0fcd280de 100644 --- a/src/modules/htable/htable.c +++ b/src/modules/htable/htable.c @@ -93,106 +93,112 @@ static int w_ht_setxi( int ht_param(modparam_t type, void *val); +/* clang-format off */ static pv_export_t mod_pvs[] = { - {{"sht", sizeof("sht") - 1}, PVT_OTHER, pv_get_ht_cell, pv_set_ht_cell, - pv_parse_ht_name, 0, 0, 0}, - {{"shtex", sizeof("shtex") - 1}, PVT_OTHER, pv_get_ht_cell_expire, - pv_set_ht_cell_expire, pv_parse_ht_name, 0, 0, 0}, - {{"shtcn", sizeof("shtcn") - 1}, PVT_OTHER, pv_get_ht_cn, 0, - pv_parse_ht_name, 0, 0, 0}, - {{"shtcv", sizeof("shtcv") - 1}, PVT_OTHER, pv_get_ht_cv, 0, - pv_parse_ht_name, 0, 0, 0}, - {{"shtinc", sizeof("shtinc") - 1}, PVT_OTHER, pv_get_ht_inc, 0, - pv_parse_ht_name, 0, 0, 0}, - {{"shtdec", sizeof("shtdec") - 1}, PVT_OTHER, pv_get_ht_dec, 0, - pv_parse_ht_name, 0, 0, 0}, - {{"shtrecord", sizeof("shtrecord") - 1}, PVT_OTHER, - pv_get_ht_expired_cell, 0, pv_parse_ht_expired_cell, 0, 0, 0}, - {{"shtitkey", sizeof("shtitkey") - 1}, PVT_OTHER, pv_get_iterator_key, - 0, pv_parse_iterator_name, 0, 0, 0}, - {{"shtitval", sizeof("shtitval") - 1}, PVT_OTHER, pv_get_iterator_val, - 0, pv_parse_iterator_name, 0, 0, 0}, - {{0, 0}, 0, 0, 0, 0, 0, 0, 0}}; + {{"sht", sizeof("sht") - 1}, PVT_OTHER, pv_get_ht_cell, pv_set_ht_cell, + pv_parse_ht_name, 0, 0, 0}, + {{"shtex", sizeof("shtex") - 1}, PVT_OTHER, pv_get_ht_cell_expire, + pv_set_ht_cell_expire, pv_parse_ht_name, 0, 0, 0}, + {{"shtcn", sizeof("shtcn") - 1}, PVT_OTHER, pv_get_ht_cn, 0, + pv_parse_ht_name, 0, 0, 0}, + {{"shtcv", sizeof("shtcv") - 1}, PVT_OTHER, pv_get_ht_cv, 0, + pv_parse_ht_name, 0, 0, 0}, + {{"shtinc", sizeof("shtinc") - 1}, PVT_OTHER, pv_get_ht_inc, 0, + pv_parse_ht_name, 0, 0, 0}, + {{"shtdec", sizeof("shtdec") - 1}, PVT_OTHER, pv_get_ht_dec, 0, + pv_parse_ht_name, 0, 0, 0}, + {{"shtrecord", sizeof("shtrecord") - 1}, PVT_OTHER, + pv_get_ht_expired_cell, 0, pv_parse_ht_expired_cell, 0, 0, 0}, + {{"shtitkey", sizeof("shtitkey") - 1}, PVT_OTHER, pv_get_iterator_key, + 0, pv_parse_iterator_name, 0, 0, 0}, + {{"shtitval", sizeof("shtitval") - 1}, PVT_OTHER, pv_get_iterator_val, + 0, pv_parse_iterator_name, 0, 0, 0}, + {{0, 0}, 0, 0, 0, 0, 0, 0, 0} +}; static cmd_export_t cmds[] = { - {"sht_print", (cmd_function)ht_print, 0, 0, 0, ANY_ROUTE}, - {"sht_rm", (cmd_function)w_ht_rm, 2, fixup_spve_spve, 0, ANY_ROUTE}, - {"sht_rm_name_re", (cmd_function)ht_rm_name_re, 1, fixup_ht_key, 0, - ANY_ROUTE}, - {"sht_rm_value_re", (cmd_function)ht_rm_value_re, 1, fixup_ht_key, 0, - ANY_ROUTE}, - {"sht_rm_name", (cmd_function)w_ht_rm_name, 3, fixup_spve_all, 0, - ANY_ROUTE}, - {"sht_rm_value", (cmd_function)w_ht_rm_value, 3, fixup_spve_all, 0, - ANY_ROUTE}, - {"sht_match_name", (cmd_function)w_ht_match_name, 3, fixup_spve_all, 0, - ANY_ROUTE}, - {"sht_has_name", (cmd_function)w_ht_match_name, 3, fixup_spve_all, 0, - ANY_ROUTE}, - {"sht_match_str_value", (cmd_function)w_ht_match_str_value, 3, - fixup_spve_all, 0, ANY_ROUTE}, - {"sht_has_str_value", (cmd_function)w_ht_match_str_value, 3, - fixup_spve_all, 0, ANY_ROUTE}, - {"sht_lock", (cmd_function)w_ht_slot_lock, 1, fixup_ht_key, 0, - ANY_ROUTE}, - {"sht_unlock", (cmd_function)w_ht_slot_unlock, 1, fixup_ht_key, 0, - ANY_ROUTE}, - {"sht_reset", (cmd_function)ht_reset, 1, fixup_spve_null, 0, ANY_ROUTE}, - {"sht_iterator_start", (cmd_function)w_ht_iterator_start, 2, - fixup_spve_spve, 0, ANY_ROUTE}, - {"sht_iterator_next", (cmd_function)w_ht_iterator_next, 1, - fixup_spve_null, 0, ANY_ROUTE}, - {"sht_iterator_end", (cmd_function)w_ht_iterator_end, 1, - fixup_spve_null, 0, ANY_ROUTE}, - {"sht_iterator_rm", (cmd_function)w_ht_iterator_rm, 1, fixup_spve_null, - 0, ANY_ROUTE}, - {"sht_iterator_sets", (cmd_function)w_ht_iterator_sets, 2, - fixup_spve_spve, fixup_free_spve_spve, ANY_ROUTE}, - {"sht_iterator_seti", (cmd_function)w_ht_iterator_seti, 2, - fixup_spve_igp, fixup_free_spve_igp, ANY_ROUTE}, - {"sht_iterator_setex", (cmd_function)w_ht_iterator_setex, 2, - fixup_spve_igp, fixup_free_spve_igp, ANY_ROUTE}, - {"sht_setxs", (cmd_function)w_ht_setxs, 4, fixup_sssi, fixup_free_sssi, - ANY_ROUTE}, - {"sht_setxi", (cmd_function)w_ht_setxi, 4, fixup_ssii, fixup_free_ssii, - ANY_ROUTE}, - - {"bind_htable", (cmd_function)bind_htable, 0, 0, 0, ANY_ROUTE}, - {0, 0, 0, 0, 0, 0}}; + {"sht_print", (cmd_function)ht_print, 0, 0, 0, ANY_ROUTE}, + {"sht_rm", (cmd_function)w_ht_rm, 2, fixup_spve_spve, 0, ANY_ROUTE}, + {"sht_rm_name_re", (cmd_function)ht_rm_name_re, 1, fixup_ht_key, 0, + ANY_ROUTE}, + {"sht_rm_value_re", (cmd_function)ht_rm_value_re, 1, fixup_ht_key, 0, + ANY_ROUTE}, + {"sht_rm_name", (cmd_function)w_ht_rm_name, 3, fixup_spve_all, 0, + ANY_ROUTE}, + {"sht_rm_value", (cmd_function)w_ht_rm_value, 3, fixup_spve_all, 0, + ANY_ROUTE}, + {"sht_match_name", (cmd_function)w_ht_match_name, 3, fixup_spve_all, 0, + ANY_ROUTE}, + {"sht_has_name", (cmd_function)w_ht_match_name, 3, fixup_spve_all, 0, + ANY_ROUTE}, + {"sht_match_str_value", (cmd_function)w_ht_match_str_value, 3, + fixup_spve_all, 0, ANY_ROUTE}, + {"sht_has_str_value", (cmd_function)w_ht_match_str_value, 3, + fixup_spve_all, 0, ANY_ROUTE}, + {"sht_lock", (cmd_function)w_ht_slot_lock, 1, fixup_ht_key, 0, + ANY_ROUTE}, + {"sht_unlock", (cmd_function)w_ht_slot_unlock, 1, fixup_ht_key, 0, + ANY_ROUTE}, + {"sht_reset", (cmd_function)ht_reset, 1, fixup_spve_null, 0, ANY_ROUTE}, + {"sht_iterator_start", (cmd_function)w_ht_iterator_start, 2, + fixup_spve_spve, 0, ANY_ROUTE}, + {"sht_iterator_next", (cmd_function)w_ht_iterator_next, 1, + fixup_spve_null, 0, ANY_ROUTE}, + {"sht_iterator_end", (cmd_function)w_ht_iterator_end, 1, + fixup_spve_null, 0, ANY_ROUTE}, + {"sht_iterator_rm", (cmd_function)w_ht_iterator_rm, 1, fixup_spve_null, + 0, ANY_ROUTE}, + {"sht_iterator_sets", (cmd_function)w_ht_iterator_sets, 2, + fixup_spve_spve, fixup_free_spve_spve, ANY_ROUTE}, + {"sht_iterator_seti", (cmd_function)w_ht_iterator_seti, 2, + fixup_spve_igp, fixup_free_spve_igp, ANY_ROUTE}, + {"sht_iterator_setex", (cmd_function)w_ht_iterator_setex, 2, + fixup_spve_igp, fixup_free_spve_igp, ANY_ROUTE}, + {"sht_setxs", (cmd_function)w_ht_setxs, 4, fixup_sssi, fixup_free_sssi, + ANY_ROUTE}, + {"sht_setxi", (cmd_function)w_ht_setxi, 4, fixup_ssii, fixup_free_ssii, + ANY_ROUTE}, + + {"bind_htable", (cmd_function)bind_htable, 0, 0, 0, ANY_ROUTE}, + {0, 0, 0, 0, 0, 0} +}; static param_export_t params[] = { - {"htable", PARAM_STRING | USE_FUNC_PARAM, (void *)ht_param}, - {"db_url", PARAM_STR, &ht_db_url}, - {"key_name_column", PARAM_STR, &ht_db_name_column}, - {"key_type_column", PARAM_STR, &ht_db_ktype_column}, - {"value_type_column", PARAM_STR, &ht_db_vtype_column}, - {"key_value_column", PARAM_STR, &ht_db_value_column}, - {"expires_column", PARAM_STR, &ht_db_expires_column}, - {"array_size_suffix", PARAM_STR, &ht_array_size_suffix}, - {"fetch_rows", INT_PARAM, &ht_fetch_rows}, - {"timer_interval", INT_PARAM, &ht_timer_interval}, - {"db_expires", INT_PARAM, &ht_db_expires_flag}, - {"enable_dmq", INT_PARAM, &ht_enable_dmq}, - {"dmq_init_sync", INT_PARAM, &ht_dmq_init_sync}, - {"timer_procs", PARAM_INT, &ht_timer_procs}, - {"event_callback", PARAM_STR, &ht_event_callback}, - {"event_callback_mode", PARAM_INT, &ht_event_callback_mode}, {0, 0, 0}}; + {"htable", PARAM_STRING | USE_FUNC_PARAM, (void *)ht_param}, + {"db_url", PARAM_STR, &ht_db_url}, + {"key_name_column", PARAM_STR, &ht_db_name_column}, + {"key_type_column", PARAM_STR, &ht_db_ktype_column}, + {"value_type_column", PARAM_STR, &ht_db_vtype_column}, + {"key_value_column", PARAM_STR, &ht_db_value_column}, + {"expires_column", PARAM_STR, &ht_db_expires_column}, + {"array_size_suffix", PARAM_STR, &ht_array_size_suffix}, + {"fetch_rows", INT_PARAM, &ht_fetch_rows}, + {"timer_interval", INT_PARAM, &ht_timer_interval}, + {"db_expires", INT_PARAM, &ht_db_expires_flag}, + {"enable_dmq", INT_PARAM, &ht_enable_dmq}, + {"dmq_init_sync", INT_PARAM, &ht_dmq_init_sync}, + {"timer_procs", PARAM_INT, &ht_timer_procs}, + {"event_callback", PARAM_STR, &ht_event_callback}, + {"event_callback_mode", PARAM_INT, &ht_event_callback_mode}, + {0, 0, 0} +}; /** module exports */ struct module_exports exports = { - "htable", /* module name */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* exported functions */ - params, /* exported parameters */ - 0, /* RPC method exports */ - mod_pvs, /* exported pseudo-variables */ - 0, /* response handling function */ - mod_init, /* module initialization function */ - child_init, /* per-child init function */ - destroy /* module destroy function */ + "htable", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* exported functions */ + params, /* exported parameters */ + 0, /* RPC method exports */ + mod_pvs, /* exported pseudo-variables */ + 0, /* response handling function */ + mod_init, /* module initialization function */ + child_init, /* per-child init function */ + destroy /* module destroy function */ }; +/* clang-format on */ /** * init module function @@ -1453,29 +1459,68 @@ static int ki_ht_dec(sip_msg_t *msg, str *htname, str *itname) #define RPC_DATE_BUF_LEN 21 -static const char *htable_dump_doc[2] = {"Dump the contents of hash table.", 0}; +/* clang-format off */ +static const char *htable_dump_doc[2] = { + "Dump the contents of hash table.", + 0 +}; static const char *htable_delete_doc[2] = { - "Delete one key from a hash table.", 0}; -static const char *htable_get_doc[2] = {"Get one key from a hash table.", 0}; + "Delete one key from a hash table.", + 0 +}; +static const char *htable_get_doc[2] = { + "Get one key from a hash table.", + 0 +}; static const char *htable_sets_doc[2] = { - "Set one key in a hash table to a string value.", 0}; + "Set one key in a hash table to a string value.", + 0 +}; static const char *htable_seti_doc[2] = { - "Set one key in a hash table to an integer value.", 0}; + "Set one key in a hash table to an integer value.", + 0 +}; static const char *htable_setex_doc[2] = { - "Set expire in a hash table for the item referenced by key.", 0}; + "Set expire in a hash table for the item referenced by key.", + 0 +}; static const char *htable_setxs_doc[2] = { - "Set one key in a hash table to a string value and its expire value.", - 0}; + "Set one key in a hash table to a string value and its expire value.", + 0 +}; static const char *htable_setxi_doc[2] = { - "Set one key in a hash table to an integer value and its expire value.", - 0}; -static const char *htable_list_doc[2] = {"List all htables.", 0}; -static const char *htable_stats_doc[2] = {"Statistics about htables.", 0}; -static const char *htable_flush_doc[2] = {"Flush hash table.", 0}; + "Set one key in a hash table to an integer value and its expire value.", + 0 +}; +static const char *htable_list_doc[2] = { + "List all htables.", + 0 +}; +static const char *htable_stats_doc[2] = { + "Statistics about htables.", + 0 +}; +static const char *htable_flush_doc[2] = { + "Flush hash table.", + 0 +}; static const char *htable_reload_doc[2] = { - "Reload hash table from database.", 0}; -static const char *htable_store_doc[2] = {"Store hash table to database.", 0}; - + "Reload hash table from database.", + 0 +}; +static const char *htable_store_doc[2] = { + "Store hash table to database.", + 0 +}; +static const char *htable_dmqsync_doc[2] = { + "Perform DMQ sync action.", + 0 +}; +static const char *htable_dmqresync_doc[2] = { + "Perform DMQ resync action (flush and sync).", + 0 +}; +/* clang-format on */ static void htable_rpc_delete(rpc_t *rpc, void *c) { @@ -2062,20 +2107,69 @@ static void htable_rpc_store(rpc_t *rpc, void *c) return; } +/*! \brief RPC htable.dmqsync command to sync a hash table via dmq */ +static void htable_rpc_dmqsync(rpc_t *rpc, void *c) +{ + int n = 0; + str htname = str_init(""); + + n = rpc->scan(c, "*S", &htname); + if(n != 1) { + htname.len = 0; + } + if(ht_dmq_request_sync(&htname) < 0) { + rpc->fault(c, 500, "HTable DMQ Sync Failed"); + return; + } + rpc->rpl_printf(c, "Ok"); +} + +/*! \brief RPC htable.dmgresync command to empty a hash table and sync via dmq */ +static void htable_rpc_dmqresync(rpc_t *rpc, void *c) +{ + str htname; + ht_t *ht; + + if(rpc->scan(c, "S", &htname) < 1) { + rpc->fault(c, 500, "No htable name given"); + return; + } + ht = ht_get_table(&htname); + if(ht == NULL) { + rpc->fault(c, 500, "No such htable"); + return; + } + if(ht_reset_content(ht) < 0) { + rpc->fault(c, 500, "Htable flush failed."); + return; + } + if(ht_dmq_request_sync(&htname) < 0) { + rpc->fault(c, 500, "HTable DMQ Sync Failed"); + return; + } + rpc->rpl_printf(c, "Ok"); +} + +/* clang-format off */ rpc_export_t htable_rpc[] = { - {"htable.dump", htable_rpc_dump, htable_dump_doc, RET_ARRAY}, - {"htable.delete", htable_rpc_delete, htable_delete_doc, 0}, - {"htable.get", htable_rpc_get, htable_get_doc, 0}, - {"htable.sets", htable_rpc_sets, htable_sets_doc, 0}, - {"htable.seti", htable_rpc_seti, htable_seti_doc, 0}, - {"htable.setex", htable_rpc_setex, htable_setex_doc, 0}, - {"htable.setxs", htable_rpc_setxs, htable_setxs_doc, 0}, - {"htable.setxi", htable_rpc_setxi, htable_setxi_doc, 0}, - {"htable.listTables", htable_rpc_list, htable_list_doc, RET_ARRAY}, - {"htable.reload", htable_rpc_reload, htable_reload_doc, 0}, - {"htable.store", htable_rpc_store, htable_store_doc, 0}, - {"htable.stats", htable_rpc_stats, htable_stats_doc, RET_ARRAY}, - {"htable.flush", htable_rpc_flush, htable_flush_doc, 0}, {0, 0, 0, 0}}; + {"htable.dump", htable_rpc_dump, htable_dump_doc, RET_ARRAY}, + {"htable.delete", htable_rpc_delete, htable_delete_doc, 0}, + {"htable.get", htable_rpc_get, htable_get_doc, 0}, + {"htable.sets", htable_rpc_sets, htable_sets_doc, 0}, + {"htable.seti", htable_rpc_seti, htable_seti_doc, 0}, + {"htable.setex", htable_rpc_setex, htable_setex_doc, 0}, + {"htable.setxs", htable_rpc_setxs, htable_setxs_doc, 0}, + {"htable.setxi", htable_rpc_setxi, htable_setxi_doc, 0}, + {"htable.listTables", htable_rpc_list, htable_list_doc, RET_ARRAY}, + {"htable.reload", htable_rpc_reload, htable_reload_doc, 0}, + {"htable.store", htable_rpc_store, htable_store_doc, 0}, + {"htable.stats", htable_rpc_stats, htable_stats_doc, RET_ARRAY}, + {"htable.flush", htable_rpc_flush, htable_flush_doc, 0}, + {"htable.dmqsync", htable_rpc_dmqsync, htable_dmqsync_doc, 0}, + {"htable.dmqresync", htable_rpc_dmqresync, htable_dmqresync_doc, 0}, + {0, 0, 0, 0} +}; +/* clang-format on */ static int htable_init_rpc(void) { 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 e9f6cb0d2..8ffc2a48b 100644 --- a/src/modules/http_async_client/http_async_client_mod.c +++ b/src/modules/http_async_client/http_async_client_mod.c @@ -50,6 +50,9 @@ #include "../../core/cfg/cfg_struct.h" #include "../../core/fmsg.h" #include "../../core/kemi.h" +#define KSR_RTHREAD_NEED_V +#define KSR_RTHREAD_SKIP_P +#include "../../core/rthreads.h" #include "../../modules/tm/tm_load.h" #include "../../modules/pv/pv_api.h" @@ -160,66 +163,72 @@ enum http_time_name_t E_HT_STARTTRANSFER }; +/* clang-format off */ static cmd_export_t cmds[] = { - {"http_async_query", (cmd_function)w_http_async_query, 2, - fixup_spve_spve, 0, ANY_ROUTE}, - {0, 0, 0, 0, 0, 0}}; - -static param_export_t params[] = {{"workers", INT_PARAM, &num_workers}, - {"connection_timeout", INT_PARAM, &http_timeout}, - {"hash_size", INT_PARAM, &hash_size}, - {"tls_version", INT_PARAM, &tls_version}, - {"tls_verify_host", INT_PARAM, &tls_verify_host}, - {"tls_verify_peer", INT_PARAM, &tls_verify_peer}, - {"curl_verbose", INT_PARAM, &curl_verbose}, - {"curl_follow_redirect", INT_PARAM, &curl_follow_redirect}, - {"tls_client_cert", PARAM_STRING, &tls_client_cert}, - {"tls_client_key", PARAM_STRING, &tls_client_key}, - {"tls_ca_path", PARAM_STRING, &tls_ca_path}, - {"memory_manager", PARAM_STRING, &memory_manager}, - {"authmethod", PARAM_INT, &default_authmethod}, - {"tcp_keepalive", INT_PARAM, &tcp_keepalive}, - {"tcp_ka_idle", INT_PARAM, &tcp_ka_idle}, - {"tcp_ka_interval", INT_PARAM, &tcp_ka_interval}, {0, 0, 0}}; + {"http_async_query", (cmd_function)w_http_async_query, 2, + fixup_spve_spve, 0, ANY_ROUTE}, + {0, 0, 0, 0, 0, 0} +}; + +static param_export_t params[] = { + {"workers", INT_PARAM, &num_workers}, + {"connection_timeout", INT_PARAM, &http_timeout}, + {"hash_size", INT_PARAM, &hash_size}, + {"tls_version", INT_PARAM, &tls_version}, + {"tls_verify_host", INT_PARAM, &tls_verify_host}, + {"tls_verify_peer", INT_PARAM, &tls_verify_peer}, + {"curl_verbose", INT_PARAM, &curl_verbose}, + {"curl_follow_redirect", INT_PARAM, &curl_follow_redirect}, + {"tls_client_cert", PARAM_STRING, &tls_client_cert}, + {"tls_client_key", PARAM_STRING, &tls_client_key}, + {"tls_ca_path", PARAM_STRING, &tls_ca_path}, + {"memory_manager", PARAM_STRING, &memory_manager}, + {"authmethod", PARAM_INT, &default_authmethod}, + {"tcp_keepalive", INT_PARAM, &tcp_keepalive}, + {"tcp_ka_idle", INT_PARAM, &tcp_ka_idle}, + {"tcp_ka_interval", INT_PARAM, &tcp_ka_interval}, + {0, 0, 0} +}; /*! \brief We expose internal variables via the statistic framework below.*/ -stat_export_t mod_stats[] = {{"requests", STAT_NO_RESET, &requests}, - {"replies", STAT_NO_RESET, &replies}, - {"errors", STAT_NO_RESET, &errors}, - {"timeouts", STAT_NO_RESET, &timeouts}, {0, 0, 0}}; +stat_export_t mod_stats[] = { + {"requests", STAT_NO_RESET, &requests}, + {"replies", STAT_NO_RESET, &replies}, + {"errors", STAT_NO_RESET, &errors}, + {"timeouts", STAT_NO_RESET, &timeouts}, {0, 0, 0}}; static pv_export_t pvs[] = { - {STR_STATIC_INIT("http_hdr"), PVT_HDR, ah_get_hdr, 0, - w_pv_parse_hdr_name, pv_parse_index, 0, 0}, - {STR_STATIC_INIT("http_rr"), PVT_OTHER, ah_get_reason, 0, 0, 0, 0, 0}, - {STR_STATIC_INIT("http_rs"), PVT_OTHER, ah_get_status, 0, 0, 0, 0, 0}, - {STR_STATIC_INIT("http_rb"), PVT_MSG_BODY, ah_get_msg_body, 0, 0, 0, 0, - 0}, - {STR_STATIC_INIT("http_bs"), PVT_OTHER, ah_get_body_size, 0, 0, 0, 0, - 0}, - {STR_STATIC_INIT("http_mb"), PVT_OTHER, ah_get_msg_buf, 0, 0, 0, 0, 0}, - {STR_STATIC_INIT("http_ml"), PVT_OTHER, ah_get_msg_len, 0, 0, 0, 0, 0}, - {STR_STATIC_INIT("http_ok"), PVT_OTHER, ah_get_ok, 0, 0, 0, 0, 0}, - {STR_STATIC_INIT("http_err"), PVT_OTHER, ah_get_err, 0, 0, 0, 0, 0}, - {STR_STATIC_INIT("http_time"), PVT_OTHER, ah_get_time, 0, - ah_parse_time_name, 0, 0, 0}, - {STR_STATIC_INIT("http_req"), PVT_OTHER, pv_get_null, ah_set_req, - ah_parse_req_name, 0, 0, 0}, - {STR_STATIC_INIT("http_req_id"), PVT_OTHER, ah_get_id, 0, 0, 0, 0, 0}, - {{0, 0}, 0, 0, 0, 0, 0, 0, 0}}; + {STR_STATIC_INIT("http_hdr"), PVT_HDR, ah_get_hdr, 0, + w_pv_parse_hdr_name, pv_parse_index, 0, 0}, + {STR_STATIC_INIT("http_rr"), PVT_OTHER, ah_get_reason, 0, 0, 0, 0, 0}, + {STR_STATIC_INIT("http_rs"), PVT_OTHER, ah_get_status, 0, 0, 0, 0, 0}, + {STR_STATIC_INIT("http_rb"), PVT_MSG_BODY, ah_get_msg_body, 0, 0, 0, 0, 0}, + {STR_STATIC_INIT("http_bs"), PVT_OTHER, ah_get_body_size, 0, 0, 0, 0, 0}, + {STR_STATIC_INIT("http_mb"), PVT_OTHER, ah_get_msg_buf, 0, 0, 0, 0, 0}, + {STR_STATIC_INIT("http_ml"), PVT_OTHER, ah_get_msg_len, 0, 0, 0, 0, 0}, + {STR_STATIC_INIT("http_ok"), PVT_OTHER, ah_get_ok, 0, 0, 0, 0, 0}, + {STR_STATIC_INIT("http_err"), PVT_OTHER, ah_get_err, 0, 0, 0, 0, 0}, + {STR_STATIC_INIT("http_time"), PVT_OTHER, ah_get_time, 0, + ah_parse_time_name, 0, 0, 0}, + {STR_STATIC_INIT("http_req"), PVT_OTHER, pv_get_null, ah_set_req, + ah_parse_req_name, 0, 0, 0}, + {STR_STATIC_INIT("http_req_id"), PVT_OTHER, ah_get_id, 0, 0, 0, 0, 0}, + {{0, 0}, 0, 0, 0, 0, 0, 0, 0} +}; struct module_exports exports = { - "http_async_client", /* module name */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* exported functions */ - params, /* exported parameters */ - 0, /* RPC method exports */ - pvs, /* exported pseudo-variables */ - 0, /* response handling function */ - mod_init, /* module initialization function */ - child_init, /* per-child init function */ - mod_destroy /* module destroy function */ + "http_async_client", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* exported functions */ + params, /* exported parameters */ + 0, /* RPC method exports */ + pvs, /* exported pseudo-variables */ + 0, /* response handling function */ + mod_init, /* module initialization function */ + child_init, /* per-child init function */ + mod_destroy /* module destroy function */ }; +/* clang-format on */ /** @@ -285,7 +294,7 @@ static int mod_init(void) return -1; } - set_curl_mem_callbacks(); + run_threadV((_thread_protoV)&set_curl_mem_callbacks); /* init faked sip msg */ if(faked_msg_init() < 0) { @@ -294,7 +303,7 @@ static int mod_init(void) } if(load_tm_api(&tmb) < 0) { - LM_INFO("cannot load the TM-functions - async relay disabled\n"); + LM_ERR("cannot load the TM-functions - async relay disabled\n"); return -1; } diff --git a/src/modules/http_client/README b/src/modules/http_client/README index bb11b1a1d..6ffe4cab0 100644 --- a/src/modules/http_client/README +++ b/src/modules/http_client/README @@ -47,20 +47,21 @@ Hugh Waite 3.4. useragent (string) 3.5. maxdatasize (int) 3.6. connection_timeout (int) - 3.7. client_cert (string) - 3.8. client_key (string) - 3.9. cacert (string) - 3.10. cipher_suites (string) - 3.11. verify_peer (int) - 3.12. verify_host (int) - 3.13. tlsversion (int) - 3.14. authmethod (int) - 3.15. keep_connections (int) - 3.16. query_result (int) - 3.17. query_maxdatasize (int) - 3.18. httpcon (string) - 3.19. config_file (string) - 3.20. netinterface (string) + 3.7. timeout_mode (int) + 3.8. client_cert (string) + 3.9. client_key (string) + 3.10. cacert (string) + 3.11. cipher_suites (string) + 3.12. verify_peer (int) + 3.13. verify_host (int) + 3.14. tlsversion (int) + 3.15. authmethod (int) + 3.16. keep_connections (int) + 3.17. query_result (int) + 3.18. query_maxdatasize (int) + 3.19. httpcon (string) + 3.20. config_file (string) + 3.21. netinterface (string) 4. Functions @@ -110,26 +111,27 @@ Hugh Waite 1.4. Set useragent parameter 1.5. Set maxdatasize parameter 1.6. Set connection_timeout parameter - 1.7. Set client_cert parameter - 1.8. Set client_key parameter - 1.9. Set cacert parameter - 1.10. Set cipher_suites parameter - 1.11. Set verify_peer parameter - 1.12. Set verify_host parameter - 1.13. Set tlsversion parameter - 1.14. Set authmethod parameter - 1.15. Set keep_connections parameter - 1.16. Set query_result parameter - 1.17. Set query_maxdatasize parameter - 1.18. Set httpcon parameter - 1.19. Set config_file parameter - 1.20. Short http_client config file - 1.21. Set netinterface parameter - 1.22. http_connect() usage - 1.23. http_connect_raw() usage - 1.24. http_get_redirect() usage - 1.25. http_client_query() usage - 1.26. http_client_get() usage + 1.7. Set timeout_mode parameter + 1.8. Set client_cert parameter + 1.9. Set client_key parameter + 1.10. Set cacert parameter + 1.11. Set cipher_suites parameter + 1.12. Set verify_peer parameter + 1.13. Set verify_host parameter + 1.14. Set tlsversion parameter + 1.15. Set authmethod parameter + 1.16. Set keep_connections parameter + 1.17. Set query_result parameter + 1.18. Set query_maxdatasize parameter + 1.19. Set httpcon parameter + 1.20. Set config_file parameter + 1.21. Short http_client config file + 1.22. Set netinterface parameter + 1.23. http_connect() usage + 1.24. http_connect_raw() usage + 1.25. http_get_redirect() usage + 1.26. http_client_query() usage + 1.27. http_client_get() usage Chapter 1. Admin Guide @@ -149,20 +151,21 @@ Chapter 1. Admin Guide 3.4. useragent (string) 3.5. maxdatasize (int) 3.6. connection_timeout (int) - 3.7. client_cert (string) - 3.8. client_key (string) - 3.9. cacert (string) - 3.10. cipher_suites (string) - 3.11. verify_peer (int) - 3.12. verify_host (int) - 3.13. tlsversion (int) - 3.14. authmethod (int) - 3.15. keep_connections (int) - 3.16. query_result (int) - 3.17. query_maxdatasize (int) - 3.18. httpcon (string) - 3.19. config_file (string) - 3.20. netinterface (string) + 3.7. timeout_mode (int) + 3.8. client_cert (string) + 3.9. client_key (string) + 3.10. cacert (string) + 3.11. cipher_suites (string) + 3.12. verify_peer (int) + 3.13. verify_host (int) + 3.14. tlsversion (int) + 3.15. authmethod (int) + 3.16. keep_connections (int) + 3.17. query_result (int) + 3.18. query_maxdatasize (int) + 3.19. httpcon (string) + 3.20. config_file (string) + 3.21. netinterface (string) 4. Functions @@ -247,20 +250,21 @@ Chapter 1. Admin Guide 3.4. useragent (string) 3.5. maxdatasize (int) 3.6. connection_timeout (int) - 3.7. client_cert (string) - 3.8. client_key (string) - 3.9. cacert (string) - 3.10. cipher_suites (string) - 3.11. verify_peer (int) - 3.12. verify_host (int) - 3.13. tlsversion (int) - 3.14. authmethod (int) - 3.15. keep_connections (int) - 3.16. query_result (int) - 3.17. query_maxdatasize (int) - 3.18. httpcon (string) - 3.19. config_file (string) - 3.20. netinterface (string) + 3.7. timeout_mode (int) + 3.8. client_cert (string) + 3.9. client_key (string) + 3.10. cacert (string) + 3.11. cipher_suites (string) + 3.12. verify_peer (int) + 3.13. verify_host (int) + 3.14. tlsversion (int) + 3.15. authmethod (int) + 3.16. keep_connections (int) + 3.17. query_result (int) + 3.18. query_maxdatasize (int) + 3.19. httpcon (string) + 3.20. config_file (string) + 3.21. netinterface (string) The parameters are loaded in order. That can lead to unexpected behavior: If httpcon is set at first, the default values for all other @@ -332,16 +336,33 @@ modparam("http_client", "maxdatasize", 2000) 3.6. connection_timeout (int) - Defines in seconds how long Kamailio waits for response from servers. + Defines how long Kamailio waits for response from servers. Value is + expressed in seconds or milliseconds, depending on parameter + timeout_mode. - Default value is zero, i.e., the timeout function is disabled. + Default value is 4 seconds. Example 1.6. Set connection_timeout parameter ... modparam("http_client", "connection_timeout", 2) ... -3.7. client_cert (string) +3.7. timeout_mode (int) + + Defines if timeouts are enabled, and in which unit timeout values are + expressed. + + Valid values are: + * 0 - Timeouts are disabled. + * 1 - Timeout values are in seconds (default). + * 2 - Timeout values are in milliseconds. + + Example 1.7. Set timeout_mode parameter +... +modparam("http_client", "timeout_mode", 1) +... + +3.8. client_cert (string) File name for a TLS client certificate. The certificate needs to be encoded in PEM format. @@ -350,12 +371,12 @@ modparam("http_client", "connection_timeout", 2) that if you specify a client cert, you also need to specify the client_key. - Example 1.7. Set client_cert parameter + Example 1.8. Set client_cert parameter ... modparam("http_client", "client_cert", "/var/certs/sollentuna.example.com.cert") ... -3.8. client_key (string) +3.9. client_key (string) File name for a TLS client key. The key needs to be encoded in PEM format. @@ -364,12 +385,12 @@ modparam("http_client", "client_cert", "/var/certs/sollentuna.example.com.cert") used. Note that if you specify a client key, you also need to specify the client_cert. - Example 1.8. Set client_key parameter + Example 1.9. Set client_key parameter ... modparam("http_client", "client_key", "/var/certs/sollentuna.example.com.key") ... -3.9. cacert (string) +3.10. cacert (string) File name for the trusted TLS CA cert used to verify servers. The certificates need to be encoded in PEM format. @@ -378,12 +399,12 @@ modparam("http_client", "client_key", "/var/certs/sollentuna.example.com.key") the host. If tlsverifyhost is on, all TLS connections will fail without any CA certificate to validate with. - Example 1.9. Set cacert parameter + Example 1.10. Set cacert parameter ... modparam("http_client", "cacert", "/var/certs/ca/edvina-sip-ca.pem") ... -3.10. cipher_suites (string) +3.11. cipher_suites (string) List of allowed cipher suites. See http://curl.haxx.se/libcurl/c/CURLOPT_SSL_CIPHER_LIST.html for details @@ -392,13 +413,13 @@ modparam("http_client", "cacert", "/var/certs/ca/edvina-sip-ca.pem") Default value is empty string, i.e. the default list of ciphers in libcurl will be used. - Example 1.10. Set cipher_suites parameter + Example 1.11. Set cipher_suites parameter ... modparam("http_client", "cipher_suites", "ecdhe_ecdsa_aes_128_gcm_sha_256,rsa_ae s_128_gcm_sha_256") ... -3.11. verify_peer (int) +3.12. verify_peer (int) If set to 0, TLS verification of the server certificate is disabled. This means that the connection will get encrypted, but there's no @@ -412,12 +433,12 @@ s_128_gcm_sha_256") See the curl documentation for more details. http://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYPEER.html - Example 1.11. Set verify_peer parameter + Example 1.12. Set verify_peer parameter ... modparam("http_client", "verify_peer", 1) ... -3.12. verify_host (int) +3.13. verify_host (int) If set to 0, domain verification of the server certificate is disabled. This means that the connection will get encrypted but there is no check @@ -431,12 +452,12 @@ modparam("http_client", "verify_peer", 1) See the curl documentation for more details. http://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html - Example 1.12. Set verify_host parameter + Example 1.13. Set verify_host parameter ... modparam("http_client", "verify_host", 2) ... -3.13. tlsversion (int) +3.14. tlsversion (int) Sets the preferred TLS/SSL version. @@ -452,12 +473,12 @@ modparam("http_client", "verify_host", 2) SSL versions are now disabled by default. See the curl documentation for more details. http://curl.haxx.se/libcurl/c/CURLOPT_SSLVERSION.html - Example 1.13. Set tlsversion parameter + Example 1.14. Set tlsversion parameter ... modparam("http_client", "tlsversion", 6) ... -3.14. authmethod (int) +3.15. authmethod (int) Sets the preferred authentication mode for HTTP/HTTPS requests. The value is a bitmap and multiple methods can be used. Note that in this @@ -477,13 +498,13 @@ modparam("http_client", "tlsversion", 6) This is also configurable per connection in the http_client configuration file. - Example 1.14. Set authmethod parameter + Example 1.15. Set authmethod parameter ... # Use the best of BASIC and Digest authentication. modparam("http_client", "authmethod", 3) ... -3.15. keep_connections (int) +3.16. keep_connections (int) If an HTTP server is accessed multiple times keeping the connection open for reuse saves a significant amount of time, especially if TLS is @@ -498,12 +519,12 @@ modparam("http_client", "authmethod", 3) This is also configurable per connection in the http_client configuration file. - Example 1.15. Set keep_connections parameter + Example 1.16. Set keep_connections parameter ... modparam("http_client", "keep_connections", 1) ... -3.16. query_result (int) +3.17. query_result (int) Control what is returned by the http_client_query(...) in the result variable. @@ -514,24 +535,24 @@ modparam("http_client", "keep_connections", 1) Default value: 1 (return first line). - Example 1.16. Set query_result parameter + Example 1.17. Set query_result parameter ... modparam("http_client", "query_result", 0) ... -3.17. query_maxdatasize (int) +3.18. query_maxdatasize (int) Control the size in bytes of the data to be returned by the http_client_query(...) in the result variable. Default value: 0 (disabled, unlimited size). - Example 1.17. Set query_maxdatasize parameter + Example 1.18. Set query_maxdatasize parameter ... modparam("http_client", "query_maxdatasize", 2048) ... -3.18. httpcon (string) +3.19. httpcon (string) Defines a connection and credentials for the connection for use in a connection-oriented function call in this module. @@ -579,7 +600,7 @@ modparam("http_client", "query_maxdatasize", 2048) Failure is either a connection failure or a response code of 500 or above. - Example 1.18. Set httpcon parameter + Example 1.19. Set httpcon parameter ... modparam("http_client", "httpcon", "apione=>http://atlanta.example.com") modparam("http_client", "httpcon", "apitwo=>http://atlanta.example.com/api/12") @@ -589,7 +610,7 @@ modparam("http_client", "httpcon", "apifour=>http://stockholm.example.com/api/ge tstuff;timeout=12;failover=apione") ... -3.19. config_file (string) +3.20. config_file (string) The file name of a configuration file containing definitions of http connections. This is an alternative to the "httpcon" module parameter - @@ -645,12 +666,12 @@ tstuff;timeout=12;failover=apione") you can specify a value of "" - two quotation marks. In order to disable a http proxy setting you can set the port to zero. - Example 1.19. Set config_file parameter + Example 1.20. Set config_file parameter ... modparam("http_client", "config_file", "httpconnections.cfg) ... - Example 1.20. Short http_client config file + Example 1.21. Short http_client config file [authapiserver] url = https://api.runbo.example.com/v4.2/auth timeout = 1 @@ -661,7 +682,7 @@ client_key = default_key.pem client_cert = default_cert.pem http_follow_redirect = no -3.20. netinterface (string) +3.21. netinterface (string) Set local network interface to be used for HTTP queries. It can be interface name or IP address. For more details see: @@ -669,7 +690,7 @@ http_follow_redirect = no Default value not set. - Example 1.21. Set netinterface parameter + Example 1.22. Set netinterface parameter ... modparam("http_client", "netinterface", "eth0") ... @@ -705,7 +726,7 @@ modparam("http_client", "netinterface", "eth0") This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, and BRANCH_ROUTE. - Example 1.22. http_connect() usage + Example 1.23. http_connect() usage ... modparam("http_client", "httpcon", "apiserver=>https://kamailio.org/api/"); ... @@ -746,7 +767,7 @@ xlog("L_INFO", "API-server HTTP connection: $avp(route) Result code $var(res)\n" This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, and BRANCH_ROUTE. - Example 1.23. http_connect_raw() usage + Example 1.24. http_connect_raw() usage ... modparam("http_client", "httpcon", "apiserver=>https://kamailio.org/api/"); ... @@ -773,7 +794,7 @@ xlog("L_INFO", "API-server HTTP connection: $avp(route) Result code $var(res)\n" result - The name of a pseudo variable that will contain the last used URL. - Example 1.24. http_get_redirect() usage + Example 1.25. http_get_redirect() usage ... modparam("http_client", "httpredirect", 1); ... @@ -808,7 +829,7 @@ http_get_redirect("apiserver", "$var(targeturl)"); utils module. It is changed to use the same base library and settings as the rest of the functions in this module. - Example 1.25. http_client_query() usage + Example 1.26. http_client_query() usage ... # GET-Request http_client_query("http://api.com/index.php?r_uri=$(ru{s.escape.param})&f_uri=$( @@ -841,7 +862,7 @@ http_client_query("http://api.com/index.php", "src=$si", the body in HTTP GET does not affect the response, but is not explicitely forbidden. - Example 1.26. http_client_get() usage + Example 1.27. http_client_get() usage ... http_client_get("http://api.com/index.php?r_uri=$(ru{s.escape.param})&f_uri=$(fu {s.escape.param})", diff --git a/src/modules/http_client/curlcon.c b/src/modules/http_client/curlcon.c index bffd26c31..2b5a69fcd 100644 --- a/src/modules/http_client/curlcon.c +++ b/src/modules/http_client/curlcon.c @@ -424,7 +424,7 @@ int curl_parse_param(char *val) } else if(pit->name.len == 11 && strncmp(pit->name.s, "maxdatasize", 11) == 0) { if(str2int(&tok, &maxdatasize) != 0) { - /* Bad timeout */ + /* Bad value */ LM_WARN("curl connection [%.*s]: maxdatasize bad value. " "Using default\n", name.len, name.s); @@ -854,3 +854,29 @@ curl_con_t *curl_init_con(str *name) LM_DBG("CURL: Added connection [%.*s]\n", name->len, name->s); return cc; } + +/*! Fixup CURL connections - if timeout is not configured, Use as default global connection_timeout. + */ +void curl_conn_list_fixup(void) +{ + curl_con_t *cc; + cc = _curl_con_root; + while (cc) { + if (!(timeout_mode == 1 || timeout_mode == 2)) { + /* Timeout is disabled globally. Set timeout to 0 for all connections to reflect this. */ + if (cc->timeout > 0) { + LM_WARN("curl connection [%.*s]: configured timeout is ignored " + "because timeouts are disabled (timeout_mode)\n", + cc->name.len, cc->name.s); + cc->timeout = 0; + } + } + else if (cc->timeout == 0) { + /* Timeout is not configured for that connection. + * Use as default global connection_timeout (which can be seconds or milliseconds). + */ + cc->timeout = default_connection_timeout; + } + cc = cc->next; + } +} diff --git a/src/modules/http_client/curlcon.h b/src/modules/http_client/curlcon.h index ff5ebe1c8..3f7747693 100644 --- a/src/modules/http_client/curlcon.h +++ b/src/modules/http_client/curlcon.h @@ -52,4 +52,8 @@ int curl_parse_param(char *val); curl_con_t *curl_get_connection(str *name); curl_con_pkg_t *curl_get_pkg_connection(curl_con_t *con); +/*! Fixup CURL connections - if timeout is not configured, Use as default global connection_timeout. + */ +void curl_conn_list_fixup(void); + #endif diff --git a/src/modules/http_client/doc/http_client_admin.xml b/src/modules/http_client/doc/http_client_admin.xml index bddf6fa1d..0e182cc95 100644 --- a/src/modules/http_client/doc/http_client_admin.xml +++ b/src/modules/http_client/doc/http_client_admin.xml @@ -189,13 +189,12 @@ modparam("http_client", "maxdatasize", 2000)
<varname>connection_timeout</varname> (int) - Defines in seconds how long &kamailio; waits for response - from servers. + Defines how long &kamailio; waits for response from servers. + Value is expressed in seconds or milliseconds, depending on parameter timeout_mode. - Default value is zero, i.e., - the timeout function is disabled. + Default value is 4 seconds. @@ -207,6 +206,34 @@ modparam("http_client", "connection_timeout", 2)
+
+ <varname>timeout_mode</varname> (int) + + Defines if timeouts are enabled, and in which unit timeout values are expressed. + + + Valid values are: + + + + 0 - Timeouts are disabled. + + + 1 - Timeout values are in seconds (default). + + + 2 - Timeout values are in milliseconds. + + + + Set <varname>timeout_mode</varname> parameter + +... +modparam("http_client", "timeout_mode", 1) +... + + +
<varname>client_cert</varname> (string) diff --git a/src/modules/http_client/functions.c b/src/modules/http_client/functions.c index 1472da755..dda47211a 100644 --- a/src/modules/http_client/functions.c +++ b/src/modules/http_client/functions.c @@ -262,7 +262,18 @@ static int curL_request_url(struct sip_msg *_m, const char *_met, curl, CURLOPT_SSL_VERIFYHOST, (long)params->verify_host ? 2 : 0); res |= curl_easy_setopt(curl, CURLOPT_NOSIGNAL, (long)1); - res |= curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long)params->timeout); + + /* timeout_mode parameter: + * - 0 : timeout is disabled. + * - 1 (default) : timeout value is in seconds. + * - 2 : timeout value is in milliseconds. + */ + if (timeout_mode == 1) { /* timeout is in seconds (default) */ + res |= curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long)params->timeout); + } else if (timeout_mode == 2) { /* timeout is in milliseconds */ + res |= curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, (long)params->timeout); + } + res |= curl_easy_setopt( curl, CURLOPT_FOLLOWLOCATION, (long)params->http_follow_redirect); if(params->http_follow_redirect) { diff --git a/src/modules/http_client/http_client.c b/src/modules/http_client/http_client.c index 430933e23..ca605ec17 100644 --- a/src/modules/http_client/http_client.c +++ b/src/modules/http_client/http_client.c @@ -64,6 +64,9 @@ #include "../../core/lvalue.h" #include "../../core/pt.h" /* Process table */ #include "../../core/kemi.h" +#define KSR_RTHREAD_NEED_4L +#define KSR_RTHREAD_SKIP_P +#include "../../core/rthreads.h" #include "functions.h" #include "curlcon.h" @@ -76,7 +79,10 @@ MODULE_VERSION #define CURL_USER_AGENT_LEN (sizeof(CURL_USER_AGENT) - 1) /* Module parameter variables */ -unsigned int default_connection_timeout = 4; +unsigned int default_connection_timeout = + 0; /*!< 0 = not user configured - the default (4 seconds) will be used */ +unsigned int timeout_mode = + 1; /*!< 0 = timeout disabled, 1 (default) = timeout in seconds, 2 = timeout in ms */ char *default_tls_cacert = NULL; /*!< File name: Default CA cert to use for curl TLS connection */ str default_tls_clientcert = @@ -195,6 +201,7 @@ static cmd_export_t cmds[] = { /* Exported parameters */ static param_export_t params[] = { {"connection_timeout", PARAM_INT, &default_connection_timeout}, + {"timeout_mode", PARAM_INT, &timeout_mode}, {"cacert", PARAM_STRING, &default_tls_cacert }, {"client_cert", PARAM_STR, &default_tls_clientcert }, {"client_key", PARAM_STR, &default_tls_clientkey }, @@ -278,7 +285,7 @@ static int mod_init(void) LM_DBG("init curl module\n"); /* Initialize curl */ - if(curl_global_init(CURL_GLOBAL_ALL)) { + if(run_thread4L((_thread_proto4L)&curl_global_init, CURL_GLOBAL_ALL)) { LM_ERR("curl_global_init failed\n"); return -1; } @@ -310,10 +317,27 @@ static int mod_init(void) } } - if(default_connection_timeout == 0) { - LM_ERR("CURL connection timeout set to zero. Using default 4 secs\n"); - default_connection_timeout = 4; + /* timeout_mode parameter: + * - 0 : timeout is disabled. + * - 1 (default) : timeout value is in seconds. + * - 2 : timeout value is in milliseconds. + */ + if(!(timeout_mode == 1 || timeout_mode == 2)) { + if(default_connection_timeout > 0) { + LM_WARN("configured connection_timeout is ignored " + "because timeouts are disabled (timeout_mode)\n"); + } + } else if(default_connection_timeout == 0) { + LM_INFO("curl connection timeout set to zero. Using default 4 secs\n"); + if(timeout_mode == 1) { /* timeout is in seconds (default) */ + default_connection_timeout = 4; + } else if(timeout_mode == 2) { /* timeout is in milliseconds */ + default_connection_timeout = 4000; + } } + /* Fixup named connections for which no specific timeout is configured. */ + curl_conn_list_fixup(); + if(default_http_proxy_port == 0) { LM_INFO("HTTP proxy port set to 0. Disabling HTTP proxy\n"); } diff --git a/src/modules/http_client/http_client.h b/src/modules/http_client/http_client.h index 0f659f97c..c56f411df 100644 --- a/src/modules/http_client/http_client.h +++ b/src/modules/http_client/http_client.h @@ -40,6 +40,7 @@ #include "../../lib/srdb1/db.h" extern unsigned int default_connection_timeout; +extern unsigned int timeout_mode; extern char * default_tls_cacert; /*!< File name: Default CA cert to use for curl TLS connection */ extern str diff --git a/src/modules/imc/README b/src/modules/imc/README index fa467ab61..a62f56d42 100644 --- a/src/modules/imc/README +++ b/src/modules/imc/README @@ -45,6 +45,8 @@ Joey Golan 4. Functions 4.1. imc_manager() + 4.2. imc_room_active(room) + 4.3. imc_room_member(room, user) 5. RPC Commands @@ -71,7 +73,9 @@ Joey Golan 1.9. Set create_on_join parameter 1.10. Set check_on_create parameter 1.11. Usage of imc_manager() function - 1.12. List of commands + 1.12. Usage of imc_room_active() function + 1.13. Usage of imc_room_member() function + 1.14. List of commands Chapter 1. Admin Guide @@ -99,6 +103,8 @@ Chapter 1. Admin Guide 4. Functions 4.1. imc_manager() + 4.2. imc_room_active(room) + 4.3. imc_room_member(room, user) 5. RPC Commands @@ -285,6 +291,8 @@ modparam("imc", "check_on_create", 1) 4. Functions 4.1. imc_manager() + 4.2. imc_room_active(room) + 4.3. imc_room_member(room, user) 4.1. imc_manager() @@ -310,6 +318,36 @@ if(is_method("MESSAGE) } ... +4.2. imc_room_active(room) + + Return 1 (true) if the room is active, -1 (false) if the room is not + found. The parameter is the SIP URI to identify the room, it can + contain variables. + + This function can be used from ANY_ROUTE. + + Example 1.12. Usage of imc_room_active() function +... + if(imc_room_active("sip:chat-sip@$fd")) { + ... + } +... + +4.3. imc_room_member(room, user) + + Return 1 (true) if the user is member of the room, -1 (false) if the + user is not member of the room. The parameters are the SIP URIs to + identify the room and the user, they can contain variables. + + This function can be used from ANY_ROUTE. + + Example 1.13. Usage of imc_room_member() function +... + if(imc_room_member("sip:chat-sip@$fd", "sip:$rU@$rd")) { + ... + } +... + 5. RPC Commands 5.1. imc.list_rooms @@ -358,7 +396,7 @@ kamcmd imc_list_members _room_ Next picture presents the list of commands and their parameters. - Example 1.12. List of commands + Example 1.14. List of commands ... 1.create diff --git a/src/modules/imc/doc/imc_admin.xml b/src/modules/imc/doc/imc_admin.xml index f8bd5f675..a4c8471d1 100644 --- a/src/modules/imc/doc/imc_admin.xml +++ b/src/modules/imc/doc/imc_admin.xml @@ -309,6 +309,52 @@ if(is_method("MESSAGE) exit; } ... + + +
+
+ + <function moreinfo="none">imc_room_active(room)</function> + + + Return 1 (true) if the room is active, -1 (false) if the room is not + found. The parameter is the SIP URI to identify the room, it can contain + variables. + + + This function can be used from ANY_ROUTE. + + + Usage of <varname>imc_room_active()</varname> function + +... + if(imc_room_active("sip:chat-sip@$fd")) { + ... + } +... + + +
+
+ + <function moreinfo="none">imc_room_member(room, user)</function> + + + Return 1 (true) if the user is member of the room, -1 (false) if the + user is not member of the room. The parameters are the SIP URIs to + identify the room and the user, they can contain variables. + + + This function can be used from ANY_ROUTE. + + + Usage of <varname>imc_room_member()</varname> function + +... + if(imc_room_member("sip:chat-sip@$fd", "sip:$rU@$rd")) { + ... + } +...
diff --git a/src/modules/imc/imc.c b/src/modules/imc/imc.c index c406f9f0c..04cd4b3b9 100644 --- a/src/modules/imc/imc.c +++ b/src/modules/imc/imc.c @@ -43,6 +43,7 @@ #include "../../core/hashes.h" #include "../../core/rpc.h" #include "../../core/rpc_lookup.h" +#include "../../core/mod_fix.h" #include "../../core/kemi.h" #include "../../modules/tm/tm_load.h" @@ -89,6 +90,8 @@ static int mod_init(void); static int child_init(int); static int w_imc_manager(struct sip_msg *, char *, char *); +static int w_imc_room_active(sip_msg_t *, char *, char *); +static int w_imc_room_member(sip_msg_t *, char *, char *); static int imc_rpc_init(void); @@ -100,45 +103,57 @@ struct tm_binds tmb; /** TM callback function */ void inv_callback(struct cell *t, int type, struct tmcb_params *ps); +/* clang-format off */ static cmd_export_t cmds[] = { - {"imc_manager", (cmd_function)w_imc_manager, 0, 0, 0, REQUEST_ROUTE}, - {0, 0, 0, 0, 0, 0}}; - + {"imc_manager", (cmd_function)w_imc_manager, 0, 0, 0, REQUEST_ROUTE}, + {"imc_room_active", (cmd_function)w_imc_room_active, 1, + fixup_spve_null, fixup_free_spve_null, ANY_ROUTE}, + {"imc_room_member", (cmd_function)w_imc_room_member, 2, + fixup_spve_spve, fixup_free_spve_spve, ANY_ROUTE}, + {0, 0, 0, 0, 0, 0} +}; -static param_export_t params[] = {{"db_url", PARAM_STR, &db_url}, - {"db_mode", INT_PARAM, &db_mode}, - {"hash_size", INT_PARAM, &imc_hash_size}, - {"imc_cmd_start_char", PARAM_STR, &imc_cmd_start_str}, - {"rooms_table", PARAM_STR, &rooms_table}, - {"members_table", PARAM_STR, &members_table}, - {"outbound_proxy", PARAM_STR, &outbound_proxy}, - {"extra_hdrs", PARAM_STR, &extra_hdrs}, - {"create_on_join", INT_PARAM, &imc_create_on_join}, - {"check_on_create", INT_PARAM, &imc_check_on_create}, {0, 0, 0}}; +static param_export_t params[] = { + {"db_url", PARAM_STR, &db_url}, + {"db_mode", INT_PARAM, &db_mode}, + {"hash_size", INT_PARAM, &imc_hash_size}, + {"imc_cmd_start_char", PARAM_STR, &imc_cmd_start_str}, + {"rooms_table", PARAM_STR, &rooms_table}, + {"members_table", PARAM_STR, &members_table}, + {"outbound_proxy", PARAM_STR, &outbound_proxy}, + {"extra_hdrs", PARAM_STR, &extra_hdrs}, + {"create_on_join", INT_PARAM, &imc_create_on_join}, + {"check_on_create", INT_PARAM, &imc_check_on_create}, + {0, 0, 0} +}; #ifdef STATISTICS #include "../../core/counters.h" stat_var *imc_active_rooms; -stat_export_t imc_stats[] = {{"active_rooms", 0, &imc_active_rooms}, {0, 0, 0}}; +stat_export_t imc_stats[] = { + {"active_rooms", 0, &imc_active_rooms}, + {0, 0, 0} +}; #endif /** module exports */ struct module_exports exports = { - "imc", /* module name */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* exported commands */ - params, /* exported parameters */ - 0, /* exported rpc functions */ - 0, /* exported pseudo-variables */ - 0, /* response handling function */ - mod_init, /* module init function */ - child_init, /* child init function */ - destroy /* module destroy function */ + "imc", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* exported commands */ + params, /* exported parameters */ + 0, /* exported rpc functions */ + 0, /* exported pseudo-variables */ + 0, /* response handling function */ + mod_init, /* module init function */ + child_init, /* child init function */ + destroy /* module destroy function */ }; +/* clang-format on */ static int mod_init(void) { @@ -422,11 +437,102 @@ error: return ret; } +/** + * + */ static int w_imc_manager(struct sip_msg *msg, char *str1, char *str2) { return ki_imc_manager(msg); } +/** + * + */ +static int ki_imc_room_active(sip_msg_t *msg, str *room) +{ + sip_uri_t puri; + imc_room_t *rm; + + if(parse_uri(room->s, room->len, &puri) != 0) { + LM_ERR("failed to parse room uri [%.*s]\n", room->len, room->s); + return -1; + } + + rm = imc_get_room(&puri.user, &puri.host); + + if(rm != NULL) { + imc_release_room(rm); + return 1; + } + return -1; +} + +/** + * + */ +static int w_imc_room_active(sip_msg_t *msg, char *proom, char *str2) +{ + str room = STR_NULL; + + if(fixup_get_svalue(msg, (gparam_t *)proom, &room) != 0) { + LM_ERR("invalid room parameter"); + return -1; + } + + return ki_imc_room_active(msg, &room); +} + +/** + * + */ +static int ki_imc_room_member(sip_msg_t *msg, str *room, str *member) +{ + sip_uri_t puri; + imc_room_t *rm; + imc_member_t *mb; + + if(parse_uri(room->s, room->len, &puri) != 0) { + LM_ERR("failed to parse room uri [%.*s]\n", room->len, room->s); + return -1; + } + + rm = imc_get_room(&puri.user, &puri.host); + + if(rm == NULL) { + return -1; + } + + if(parse_uri(member->s, member->len, &puri) != 0) { + imc_release_room(rm); + LM_ERR("failed to parse member uri [%.*s]\n", member->len, member->s); + return -1; + } + mb = imc_get_member(rm, &puri.user, &puri.host); + imc_release_room(rm); + + return (mb != NULL) ? 1 : -1; +} + +/** + * + */ +static int w_imc_room_member(sip_msg_t *msg, char *proom, char *pmember) +{ + str room = STR_NULL; + str member = STR_NULL; + + if(fixup_get_svalue(msg, (gparam_t *)proom, &room) != 0) { + LM_ERR("invalid room parameter"); + return -1; + } + if(fixup_get_svalue(msg, (gparam_t *)pmember, &member) != 0) { + LM_ERR("invalid member parameter"); + return -1; + } + + return ki_imc_room_member(msg, &room, &member); +} + /** * destroy module */ @@ -601,10 +707,13 @@ static const char *imc_rpc_list_rooms_doc[2] = {"List imc rooms.", 0}; static const char *imc_rpc_list_members_doc[2] = { "List members in an imc room.", 0}; -rpc_export_t imc_rpc[] = {{"imc.list_rooms", imc_rpc_list_rooms, - imc_rpc_list_rooms_doc, RET_ARRAY}, - {"imc.list_members", imc_rpc_list_members, imc_rpc_list_members_doc, 0}, - {0, 0, 0, 0}}; +/* clang-format off */ +rpc_export_t imc_rpc[] = { + {"imc.list_rooms", imc_rpc_list_rooms, imc_rpc_list_rooms_doc, RET_ARRAY}, + {"imc.list_members", imc_rpc_list_members, imc_rpc_list_members_doc, 0}, + {0, 0, 0, 0} +}; +/* clang-format on */ static int imc_rpc_init(void) { @@ -625,6 +734,16 @@ static sr_kemi_t sr_kemi_imc_exports[] = { { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, + { str_init("imc"), str_init("imc_room_active"), + SR_KEMIP_INT, ki_imc_room_active, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("imc"), str_init("imc_room_member"), + SR_KEMIP_INT, ki_imc_room_member, + { 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 } } }; diff --git a/src/modules/ims_charging/README b/src/modules/ims_charging/README index bf178fac9..b37cf9ae3 100644 --- a/src/modules/ims_charging/README +++ b/src/modules/ims_charging/README @@ -45,28 +45,30 @@ Carlos Ruiz Diaz 4.5. timer_buffer(int) 4.6. ro_forced_peer(string) 4.7. ro_auth_expiry(integer) - 4.8. ro_auth_expiry(integer) - 4.9. cdp_event_latency(integer) - 4.10. cdp_event_threshold(integer) - 4.11. cdp_event_latency_log(integer) - 4.12. single_ro_session_per_dialog(integer) - 4.13. origin_host(string) - 4.14. origin_realm(string) - 4.15. destination_host(string) - 4.16. destination_realm(string) - 4.17. service_context_id_root(string) - 4.18. service_context_id_ext(string) - 4.19. service_context_id_mnc(string) - 4.20. voice_service_identifier(string) - 4.21. voice_rating_group(string) - 4.22. video_service_identifier(string) - 4.23. video_rating_group(string) - 4.24. service_context_id_mcc(string) - 4.25. service_context_id_release(string) - 4.26. custom_user_avp (avp string) - 4.27. app_provided_party_avp (avp string) - 4.28. vendor_specific_chargeinfo (int) - 4.29. vendor_specific_id (int) + 4.8. cdp_event_latency(integer) + 4.9. cdp_event_threshold(integer) + 4.10. cdp_event_latency_log(integer) + 4.11. single_ro_session_per_dialog(integer) + 4.12. origin_host(string) + 4.13. origin_realm(string) + 4.14. destination_host(string) + 4.15. destination_realm(string) + 4.16. service_context_id_root(string) + 4.17. service_context_id_ext(string) + 4.18. service_context_id_mnc(string) + 4.19. voice_service_identifier(string) + 4.20. voice_rating_group(string) + 4.21. video_service_identifier(string) + 4.22. video_rating_group(string) + 4.23. service_context_id_mcc(string) + 4.24. service_context_id_release(string) + 4.25. custom_user_avp (avp string) + 4.26. app_provided_party_avp (avp string) + 4.27. vendor_specific_chargeinfo (int) + 4.28. vendor_specific_id (int) + 4.29. strip_plus_from_e164 (int) + 4.30. use_pani_from_term_invite (int) + 4.31. node_func (int) 5. Functions @@ -103,30 +105,32 @@ Carlos Ruiz Diaz 1.5. timer_bufferparameter usage 1.6. ro_forced_peerparameter usage 1.7. ro_auth_expiryparameter usage - 1.8. ro_auth_expiryparameter usage - 1.9. cdp_event_latencyparameter usage - 1.10. cdp_event_thresholdparameter usage - 1.11. cdp_event_latency_logparameter usage - 1.12. single_ro_session_per_dialogparameter usage - 1.13. origin_hostparameter usage - 1.14. origin_realmparameter usage - 1.15. destination_hostparameter usage - 1.16. destination_realmparameter usage - 1.17. service_context_id_rootparameter usage - 1.18. service_context_id_extparameter usage - 1.19. service_context_id_mncparameter usage - 1.20. voice_service_identifierparameter usage - 1.21. voice_rating_groupparameter usage - 1.22. video_service_identifierparameter usage - 1.23. video_rating_groupparameter usage - 1.24. service_context_id_mccparameter usage - 1.25. service_context_id_releaseparameter usage - 1.26. custom_user_avpparameter usage - 1.27. app_provided_party_avpparameter usage - 1.28. vendor_specific_chargeinfoparameter usage - 1.29. vendor_specific_idparameter usage - 1.30. Ro_CCR - 1.31. Ro_set_session_id_avp + 1.8. cdp_event_latencyparameter usage + 1.9. cdp_event_thresholdparameter usage + 1.10. cdp_event_latency_logparameter usage + 1.11. single_ro_session_per_dialogparameter usage + 1.12. origin_hostparameter usage + 1.13. origin_realmparameter usage + 1.14. destination_hostparameter usage + 1.15. destination_realmparameter usage + 1.16. service_context_id_rootparameter usage + 1.17. service_context_id_extparameter usage + 1.18. service_context_id_mncparameter usage + 1.19. voice_service_identifierparameter usage + 1.20. voice_rating_groupparameter usage + 1.21. video_service_identifierparameter usage + 1.22. video_rating_groupparameter usage + 1.23. service_context_id_mccparameter usage + 1.24. service_context_id_releaseparameter usage + 1.25. custom_user_avpparameter usage + 1.26. app_provided_party_avpparameter usage + 1.27. vendor_specific_chargeinfoparameter usage + 1.28. vendor_specific_idparameter usage + 1.29. strip_plus_from_e164parameter usage + 1.30. use_pani_from_term_inviteparameter usage + 1.31. node_funcparameter usage + 1.32. Ro_CCR + 1.33. Ro_set_session_id_avp Chapter 1. Admin Guide @@ -153,28 +157,30 @@ Chapter 1. Admin Guide 4.5. timer_buffer(int) 4.6. ro_forced_peer(string) 4.7. ro_auth_expiry(integer) - 4.8. ro_auth_expiry(integer) - 4.9. cdp_event_latency(integer) - 4.10. cdp_event_threshold(integer) - 4.11. cdp_event_latency_log(integer) - 4.12. single_ro_session_per_dialog(integer) - 4.13. origin_host(string) - 4.14. origin_realm(string) - 4.15. destination_host(string) - 4.16. destination_realm(string) - 4.17. service_context_id_root(string) - 4.18. service_context_id_ext(string) - 4.19. service_context_id_mnc(string) - 4.20. voice_service_identifier(string) - 4.21. voice_rating_group(string) - 4.22. video_service_identifier(string) - 4.23. video_rating_group(string) - 4.24. service_context_id_mcc(string) - 4.25. service_context_id_release(string) - 4.26. custom_user_avp (avp string) - 4.27. app_provided_party_avp (avp string) - 4.28. vendor_specific_chargeinfo (int) - 4.29. vendor_specific_id (int) + 4.8. cdp_event_latency(integer) + 4.9. cdp_event_threshold(integer) + 4.10. cdp_event_latency_log(integer) + 4.11. single_ro_session_per_dialog(integer) + 4.12. origin_host(string) + 4.13. origin_realm(string) + 4.14. destination_host(string) + 4.15. destination_realm(string) + 4.16. service_context_id_root(string) + 4.17. service_context_id_ext(string) + 4.18. service_context_id_mnc(string) + 4.19. voice_service_identifier(string) + 4.20. voice_rating_group(string) + 4.21. video_service_identifier(string) + 4.22. video_rating_group(string) + 4.23. service_context_id_mcc(string) + 4.24. service_context_id_release(string) + 4.25. custom_user_avp (avp string) + 4.26. app_provided_party_avp (avp string) + 4.27. vendor_specific_chargeinfo (int) + 4.28. vendor_specific_id (int) + 4.29. strip_plus_from_e164 (int) + 4.30. use_pani_from_term_invite (int) + 4.31. node_func (int) 5. Functions @@ -356,28 +362,30 @@ Chapter 1. Admin Guide 4.5. timer_buffer(int) 4.6. ro_forced_peer(string) 4.7. ro_auth_expiry(integer) - 4.8. ro_auth_expiry(integer) - 4.9. cdp_event_latency(integer) - 4.10. cdp_event_threshold(integer) - 4.11. cdp_event_latency_log(integer) - 4.12. single_ro_session_per_dialog(integer) - 4.13. origin_host(string) - 4.14. origin_realm(string) - 4.15. destination_host(string) - 4.16. destination_realm(string) - 4.17. service_context_id_root(string) - 4.18. service_context_id_ext(string) - 4.19. service_context_id_mnc(string) - 4.20. voice_service_identifier(string) - 4.21. voice_rating_group(string) - 4.22. video_service_identifier(string) - 4.23. video_rating_group(string) - 4.24. service_context_id_mcc(string) - 4.25. service_context_id_release(string) - 4.26. custom_user_avp (avp string) - 4.27. app_provided_party_avp (avp string) - 4.28. vendor_specific_chargeinfo (int) - 4.29. vendor_specific_id (int) + 4.8. cdp_event_latency(integer) + 4.9. cdp_event_threshold(integer) + 4.10. cdp_event_latency_log(integer) + 4.11. single_ro_session_per_dialog(integer) + 4.12. origin_host(string) + 4.13. origin_realm(string) + 4.14. destination_host(string) + 4.15. destination_realm(string) + 4.16. service_context_id_root(string) + 4.17. service_context_id_ext(string) + 4.18. service_context_id_mnc(string) + 4.19. voice_service_identifier(string) + 4.20. voice_rating_group(string) + 4.21. video_service_identifier(string) + 4.22. video_rating_group(string) + 4.23. service_context_id_mcc(string) + 4.24. service_context_id_release(string) + 4.25. custom_user_avp (avp string) + 4.26. app_provided_party_avp (avp string) + 4.27. vendor_specific_chargeinfo (int) + 4.28. vendor_specific_id (int) + 4.29. strip_plus_from_e164 (int) + 4.30. use_pani_from_term_invite (int) + 4.31. node_func (int) 4.1. hash_size(int) @@ -402,7 +410,7 @@ modparam("ims_charging", "hash_size", 1024) Should a database be used to store dialog information. Available database modes: 0 for no database, 1 for real-time mode and 2 - for shutdown mode. Mode 2 seems to be not fully implemented. + for shutdown mode. Default value is 0 - no database is used. @@ -471,31 +479,19 @@ modparam("ims_charging", "ro_forced_peer", "ocs.ims.smilecoms.com") modparam("ims_charging", "ro_auth_expiry", 14400) ... -4.8. ro_auth_expiry(integer) - - This is the expiry length in seconds of the initiated Diameter - sessions. - - Default value is 7200. - - Example 1.8. ro_auth_expiryparameter usage -... -modparam("ims_charging", "ro_auth_expiry", 14400) -... - -4.9. cdp_event_latency(integer) +4.8. cdp_event_latency(integer) This is a flag to determine whether or slow CDP responses should be reported in the log file. 1 is enabled and 0 is disabled. Default value is 1. - Example 1.9. cdp_event_latencyparameter usage + Example 1.8. cdp_event_latencyparameter usage ... modparam("ims_charging", "cdp_event_latency", 1) ... -4.10. cdp_event_threshold(integer) +4.9. cdp_event_threshold(integer) This time in milliseconds is the limit we should report a CDP response as slow. i.e. if a CDP response exceeds this limit it will be reported @@ -504,12 +500,12 @@ modparam("ims_charging", "cdp_event_latency", 1) Default value is 500. - Example 1.10. cdp_event_thresholdparameter usage + Example 1.9. cdp_event_thresholdparameter usage ... modparam("ims_charging", "cdp_event_threshold", 500) ... -4.11. cdp_event_latency_log(integer) +4.10. cdp_event_latency_log(integer) This time log level at which we should report slow CDP responses. 0 is ERROR, 1 is WARN, 2 is INFO and 3 is DEBUG. This is only relevant is @@ -517,12 +513,12 @@ modparam("ims_charging", "cdp_event_threshold", 500) Default value is 0. - Example 1.11. cdp_event_latency_logparameter usage + Example 1.10. cdp_event_latency_logparameter usage ... modparam("ims_charging", "cdp_event_latency_log", 1) ... -4.12. single_ro_session_per_dialog(integer) +4.11. single_ro_session_per_dialog(integer) This tells the module whether it should do a single ro session per dialog no matter how many times Ro_send_CCR is called from the config @@ -533,56 +529,56 @@ modparam("ims_charging", "cdp_event_latency_log", 1) Default value is 0. - Example 1.12. single_ro_session_per_dialogparameter usage + Example 1.11. single_ro_session_per_dialogparameter usage ... modparam("ims_charging", "single_ro_session_per_dialog", 1) ... -4.13. origin_host(string) +4.12. origin_host(string) Origin host to be used in Diameter messages to charging-server. Default value is "". - Example 1.13. origin_hostparameter usage + Example 1.12. origin_hostparameter usage ... modparam("ims_charging", "origin_host", "scscf.kamailio-ims.org") ... -4.14. origin_realm(string) +4.13. origin_realm(string) Origin Realm to be used in Diameter messages to charging-server. Default value is "". - Example 1.14. origin_realmparameter usage + Example 1.13. origin_realmparameter usage ... modparam("ims_charging", "origin_realm", "kamailio-ims.org") ... -4.15. destination_host(string) +4.14. destination_host(string) Destination host to be used in Diameter messages to charging-server. Default value is "". - Example 1.15. destination_hostparameter usage + Example 1.14. destination_hostparameter usage ... modparam("ims_charging", "destination_host", "ocs.kamailio-ims.org") ... -4.16. destination_realm(string) +4.15. destination_realm(string) Destination realm to be used in Diameter messages to charging-server. Default value is "". - Example 1.16. destination_realmparameter usage + Example 1.15. destination_realmparameter usage ... modparam("ims_charging", "destination_realm", "kamailio-ims.org") ... -4.17. service_context_id_root(string) +4.16. service_context_id_root(string) This defines a root-element of the Service-Context-Id AVP used in the diameter-message @@ -613,80 +609,80 @@ modparam("ims_charging", "destination_realm", "kamailio-ims.org") Default value is "32260@3gpp.org". - Example 1.17. service_context_id_rootparameter usage + Example 1.16. service_context_id_rootparameter usage ... modparam("ims_charging", "service_context_id_root", "calls@kamailio-ims.org") ... -4.18. service_context_id_ext(string) +4.17. service_context_id_ext(string) This defines the extension of the Service-Context-Id AVP used in the diameter-message. Default value is "ext". - Example 1.18. service_context_id_extparameter usage + Example 1.17. service_context_id_extparameter usage ... modparam("ims_charging", "service_context_id_ext", "ext2") ... -4.19. service_context_id_mnc(string) +4.18. service_context_id_mnc(string) This defines Mobile-Network-Code (MNC) of the Service-Context-Id AVP used in the diameter-message. Default value is "01". - Example 1.19. service_context_id_mncparameter usage + Example 1.18. service_context_id_mncparameter usage ... modparam("ims_charging", "service_context_id_mnc", "42") ... -4.20. voice_service_identifier(string) +4.19. voice_service_identifier(string) This defines the service identifier to be used for charging voice. Default value is "1000". - Example 1.20. voice_service_identifierparameter usage + Example 1.19. voice_service_identifierparameter usage ... modparam("ims_charging", "voice_service_identifier", "1000") ... -4.21. voice_rating_group(string) +4.20. voice_rating_group(string) This defines the rating group to be used for charging voice. Default value is "100". - Example 1.21. voice_rating_groupparameter usage + Example 1.20. voice_rating_groupparameter usage ... modparam("ims_charging", "voice_rating_group", "100") ... -4.22. video_service_identifier(string) +4.21. video_service_identifier(string) This defines the service identifier to be used for charging video. Default value is "1001". - Example 1.22. video_service_identifierparameter usage + Example 1.21. video_service_identifierparameter usage ... modparam("ims_charging", "video_service_identifier", "1000") ... -4.23. video_rating_group(string) +4.22. video_rating_group(string) This defines the rating group to be used for charging video. Default value is "200". - Example 1.23. video_rating_groupparameter usage + Example 1.22. video_rating_groupparameter usage ... modparam("ims_charging", "video_rating_group", "100") ... -4.24. service_context_id_mcc(string) +4.23. service_context_id_mcc(string) This defines Mobile-Country-Code (MCC) of the Service-Context-Id AVP used in the diameter-message. @@ -696,24 +692,24 @@ modparam("ims_charging", "video_rating_group", "100") Default value is "001". - Example 1.24. service_context_id_mccparameter usage + Example 1.23. service_context_id_mccparameter usage ... modparam("ims_charging", "service_context_id_mcc", "262") ... -4.25. service_context_id_release(string) +4.24. service_context_id_release(string) This defines Release of the Service-Context-Id AVP used in the diameter-message. Default value is "8" (Release 8). - Example 1.25. service_context_id_releaseparameter usage + Example 1.24. service_context_id_releaseparameter usage ... modparam("ims_charging", "service_context_id_release", "262") ... -4.26. custom_user_avp (avp string) +4.25. custom_user_avp (avp string) When this parameter is set and the contents of the AVP is not empty, the User-AVP in the Ro-Charging-Request will be based on the this @@ -725,12 +721,12 @@ modparam("ims_charging", "service_context_id_release", "262") Default value: if not set, P-Asserted-Identity with a fallback to the From-Header is used. - Example 1.26. custom_user_avpparameter usage + Example 1.25. custom_user_avpparameter usage ... modparam("ims_charging", "custom_user_avp", "$avp(from_user)") ... -4.27. app_provided_party_avp (avp string) +4.26. app_provided_party_avp (avp string) When this parameter is set and the contents of the AVP is not empty, an Application-Provided-Called Party-Address AVP will be addedd to @@ -740,12 +736,12 @@ modparam("ims_charging", "custom_user_avp", "$avp(from_user)") Default value: if not set, the Application-Provided-Called-Party-Address AVP will be not set. - Example 1.27. app_provided_party_avpparameter usage + Example 1.26. app_provided_party_avpparameter usage ... modparam("ims_charging", "app_provided_party_avp", "$avp(app_user)") ... -4.28. vendor_specific_chargeinfo (int) +4.27. vendor_specific_chargeinfo (int) This parameter can be used to activate or deactivate the addition of Vendor-Specific-Termination-Clause and @@ -754,23 +750,64 @@ modparam("ims_charging", "app_provided_party_avp", "$avp(app_user)") Default value is "0" (deactivated). - Example 1.28. vendor_specific_chargeinfoparameter usage + Example 1.27. vendor_specific_chargeinfoparameter usage ... modparam("ims_charging", "vendor_specific_chargeinfo", 1) ... -4.29. vendor_specific_id (int) +4.28. vendor_specific_id (int) To set the ID of the Vendor-Specific information, not implemented right now. Default value is "10". - Example 1.29. vendor_specific_idparameter usage + Example 1.28. vendor_specific_idparameter usage ... modparam("ims_charging", "vendor_specific_id", 10) ... +4.29. strip_plus_from_e164 (int) + + Strip + from subscription id when E.164 format is used. This is + according to spec, but this parameter is to keep existing behavior as + the default. + + Default value is 0. + + Example 1.29. strip_plus_from_e164parameter usage +... +modparam("ims_charging", "strip_plus_from_e164", 1) +... + +4.30. use_pani_from_term_invite (int) + + P-Access-Network-Info is normally relevant for the "orig" scenario + where it's extracted from INVITE. This setting instruct Kamailio to + include it in "term" scenario too, where it might have been added to + the INVITE based on info from a REGISTER. Normally used to start a + charging session when the user is roaming. + + Default value is 0. + + Example 1.30. use_pani_from_term_inviteparameter usage +... +modparam("ims_charging", "use_pani_from_term_invite", 1) +... + +4.31. node_func (int) + + Defines what should be sent as Node-Functionality (862) in the Diameter + Ro request. Possible values are: 0 (S-CSCF), 1 (P-CSCF), 2 (I-CSCF), 3 + (MRFC), 4 (MGCF), 5 (BFCF) or 6 (AS) + + Default value is 0 (S-CSCF). + + Example 1.31. node_funcparameter usage +... +modparam("ims_charging", "node_func", 1) +... + 5. Functions 5.1. Ro_CCR(route_name, direction, reservation_units, @@ -798,7 +835,7 @@ outgoing_trunk_id) This method is executed asynchronously. See example on how to retrieve return value. - Example 1.30. Ro_CCR + Example 1.32. Ro_CCR ... xlog("L_DBG","Sending initial CCR Request for call\n"); Ro_CCR("RO_ASYNC_TERM_REPLY", "term", 30, "1", "1"); @@ -834,7 +871,7 @@ n"); This function can be used from REQUEST_ROUTE or ONREPLY_ROUTE. - Example 1.31. Ro_set_session_id_avp + Example 1.33. Ro_set_session_id_avp ... Ro_set_session_id_avp(); xlog("L_DBG","Ro session AVP has been set: $avp(ro_session_id)\n"); diff --git a/src/modules/ims_charging/Ro_data.c b/src/modules/ims_charging/Ro_data.c index 17ab3bc11..e077b474b 100644 --- a/src/modules/ims_charging/Ro_data.c +++ b/src/modules/ims_charging/Ro_data.c @@ -1,36 +1,6 @@ #include "Ro_data.h" #include "config.h" - - -#define str_dup(dst, src, mem) \ - do { \ - if((src).len) { \ - (dst).s = mem##_malloc((src).len); \ - if(!(dst).s) { \ - LM_ERR("Error allocating %d bytes in %s!\n", (src).len, #mem); \ - (dst).len = 0; \ - goto out_of_memory; \ - } \ - memcpy((dst).s, (src).s, (src).len); \ - (dst).len = (src).len; \ - } else { \ - (dst).s = 0; \ - (dst).len = 0; \ - } \ - } while(0) - -/** - * Frees a str content. - * @param x - the str to free - * @param mem - type of memory that the content is using (shm/pkg) - */ -#define str_free(x, mem) \ - do { \ - if((x).s) \ - mem##_free((x).s); \ - (x).s = 0; \ - (x).len = 0; \ - } while(0) +#include "../../lib/ims/ims_getters.h" extern client_ro_cfg cfg; @@ -118,7 +88,7 @@ ims_information_t *new_ims_information(event_type_t *event_type, mem_new(x->role_of_node, sizeof(int32_t), pkg); *(x->role_of_node) = node_role; - //x->node_functionality = cfg.node_func; + x->node_functionality = cfg.node_func; if(outgoing_session_id && outgoing_session_id->s) str_dup_ptr(x->outgoing_session_id, *outgoing_session_id, pkg); @@ -198,7 +168,8 @@ out_of_memory: } Ro_CCR_t *new_Ro_CCR(int32_t acc_record_type, str *user_name, - ims_information_t *ims_info, subscription_id_t *subscription) + ims_information_t *ims_info, subscription_id_t *subscription, + str *destination_host) { @@ -214,7 +185,9 @@ Ro_CCR_t *new_Ro_CCR(int32_t acc_record_type, str *user_name, if(cfg.origin_realm.s && cfg.origin_realm.len > 0) str_dup(x->origin_realm, cfg.origin_realm, pkg); - if(cfg.destination_host.s && cfg.destination_host.len > 0) + if(destination_host && destination_host->len > 0) + str_dup(x->destination_host, *destination_host, pkg); + else if(cfg.destination_host.s && cfg.destination_host.len > 0) str_dup(x->destination_host, cfg.destination_host, pkg); if(cfg.destination_realm.s && cfg.destination_realm.len > 0) @@ -360,5 +333,6 @@ void Ro_free_CCA(Ro_CCA_t *x) } mem_free(x->mscc->granted_service_unit, pkg); mem_free(x->mscc, pkg); + str_free(x->origin_host, pkg); mem_free(x, pkg); } diff --git a/src/modules/ims_charging/Ro_data.h b/src/modules/ims_charging/Ro_data.h index 93eb62bbf..c06f7114e 100644 --- a/src/modules/ims_charging/Ro_data.h +++ b/src/modules/ims_charging/Ro_data.h @@ -416,6 +416,7 @@ typedef struct uint32_t validity_time; final_unit_indication_t *final_unit_action; uint32_t resultcode; + uint32_t time_quota_threshold; } multiple_services_credit_control_t; typedef struct @@ -424,6 +425,7 @@ typedef struct uint32_t cc_request_type; uint32_t cc_request_number; multiple_services_credit_control_t *mscc; + str origin_host; } Ro_CCA_t; event_type_t *new_event_type(str *sip_method, str *event, uint32_t *expires); @@ -446,7 +448,8 @@ void ims_information_free(ims_information_t *x); void service_information_free(service_information_t *x); Ro_CCR_t *new_Ro_CCR(int32_t acc_record_type, str *user_name, - ims_information_t *ims_info, subscription_id_t *subscription); + ims_information_t *ims_info, subscription_id_t *subscription, + str *destination_host); void Ro_free_CCR(Ro_CCR_t *x); void Ro_free_CCA(Ro_CCA_t *x); diff --git a/src/modules/ims_charging/ccr.c b/src/modules/ims_charging/ccr.c index e040e66b8..091070b44 100644 --- a/src/modules/ims_charging/ccr.c +++ b/src/modules/ims_charging/ccr.c @@ -1,4 +1,5 @@ #include "../cdp_avp/cdp_avp_mod.h" +#include "../../lib/ims/ims_getters.h" #include "ccr.h" #include "Ro_data.h" @@ -402,6 +403,10 @@ Ro_CCA_t *Ro_parse_CCA_avps(AAAMessage *cca) case AVP_Validity_Time: mscc->validity_time = get_4bytes(mscc_avp->data.s); break; + case AVP_Time_Quota_Threshold: + mscc->time_quota_threshold = + get_4bytes(mscc_avp->data.s); + break; case AVP_Result_Code: mscc->resultcode = get_4bytes(mscc_avp->data.s); break; @@ -478,6 +483,9 @@ Ro_CCA_t *Ro_parse_CCA_avps(AAAMessage *cca) x = get_4bytes(avp->data.s); ro_cca_data->resultcode = x; break; + case AVP_Origin_Host: + str_dup(ro_cca_data->origin_host, avp->data, pkg); + break; } avp = avp->next; } diff --git a/src/modules/ims_charging/config.h b/src/modules/ims_charging/config.h index 154435c73..0de946fcd 100644 --- a/src/modules/ims_charging/config.h +++ b/src/modules/ims_charging/config.h @@ -8,6 +8,9 @@ typedef struct str destination_host; str destination_realm; str *service_context_id; + int strip_plus_from_e164; + int use_pani_from_term_invite; + int node_func; } client_ro_cfg; #endif diff --git a/src/modules/ims_charging/dialog.c b/src/modules/ims_charging/dialog.c index 9315c8577..95fa8c297 100644 --- a/src/modules/ims_charging/dialog.c +++ b/src/modules/ims_charging/dialog.c @@ -86,23 +86,27 @@ void dlg_answered(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params) "seconds since we requested\n", (int)session->reserved_secs, (int)session->valid_for, (int)time_since_last_event); - if(session->reserved_secs < (session->valid_for - time_since_last_event)) { - if(session->reserved_secs > ro_timer_buffer /*TIMEOUTBUFFER*/) { + // valid_for might not be included in the answer from the charging server + if(session->valid_for == 0 + || session->reserved_secs + < (session->valid_for - time_since_last_event)) { + if(session->reserved_secs + > session->ro_timer_buffer /*TIMEOUTBUFFER*/) { ret = insert_ro_timer(&session->ro_tl, session->reserved_secs - (session->is_final_allocation ? 0 - : ro_timer_buffer)); //subtract 5 seconds so as to get more credit before we run out + : session->ro_timer_buffer)); //subtract ro_timer_buffer to get more credit before we run out } else { ret = insert_ro_timer(&session->ro_tl, session->reserved_secs); } } else { - if(session->valid_for > ro_timer_buffer) { + if(session->valid_for > session->ro_timer_buffer) { ret = insert_ro_timer(&session->ro_tl, session->valid_for - (session->is_final_allocation ? 0 - : ro_timer_buffer)); //subtract 5 seconds so as to get more credit before we run out + : session->ro_timer_buffer)); //subtract ro_timer_buffer to get more credit before we run out } else { ret = insert_ro_timer(&session->ro_tl, session->valid_for); } @@ -116,8 +120,8 @@ void dlg_answered(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params) ref_ro_session(session, 1, 0); // lock already acquired } + session->flags |= RO_SESSION_FLAG_CHANGED; if(ro_db_mode == DB_MODE_REALTIME) { - session->flags |= RO_SESSION_FLAG_CHANGED; if(update_ro_dbinfo_unsafe(session) != 0) { LM_ERR("Failed to update ro_session in database... continuing\n"); }; @@ -202,6 +206,10 @@ void dlg_terminated(struct dlg_cell *dlg, int type, unsigned int termcode, //currently the way we are doing is a hack..... //if ((ro_session = lookup_ro_session(dlg->h_entry, &dlg->callid, 0, 0))) { ro_session_entry = &(ro_session_table->entries[ro_session->h_entry]); + if(!ro_session_entry) { + LM_ERR("ro session entry is NULL - aborting\n"); + return; + } //if the Ro session is not active we don't need to do anything. This prevents //double processing for various dialog_terminated callback events. @@ -243,8 +251,8 @@ void dlg_terminated(struct dlg_cell *dlg, int type, unsigned int termcode, ro_session->ccr_sent = 1; // counter_add(ims_charging_cnts_h.active_ro_sessions, -1); - if(ro_db_mode == DB_MODE_REALTIME) { - ro_session->flags |= RO_SESSION_FLAG_DELETED; + ro_session->flags |= RO_SESSION_FLAG_DELETED; + if(ro_db_mode) { if(update_ro_dbinfo_unsafe(ro_session) != 0) { LM_ERR("Unable to update Ro session in DB...continuing\n"); } diff --git a/src/modules/ims_charging/doc/ims_charging_admin.xml b/src/modules/ims_charging/doc/ims_charging_admin.xml index 6a43764b8..bfad17dc7 100644 --- a/src/modules/ims_charging/doc/ims_charging_admin.xml +++ b/src/modules/ims_charging/doc/ims_charging_admin.xml @@ -269,7 +269,7 @@ modparam("ims_charging", "hash_size", 1024) Should a database be used to store dialog information. Available database modes: 0 for no database, 1 for real-time mode and - 2 for shutdown mode. Mode 2 seems to be not fully implemented. + 2 for shutdown mode. Default value is 0 - no database is used. @@ -383,25 +383,6 @@ modparam("ims_charging", "ro_auth_expiry", 14400)
-
- <varname>ro_auth_expiry</varname>(integer) - - This is the expiry length in seconds of the initiated Diameter - sessions. - - Default value is 7200. - - - <varname>ro_auth_expiry</varname>parameter usage - - -... -modparam("ims_charging", "ro_auth_expiry", 14400) -... - - -
-
<varname>cdp_event_latency</varname>(integer) @@ -853,6 +834,67 @@ modparam("ims_charging", "vendor_specific_chargeinfo", 1) ... modparam("ims_charging", "vendor_specific_id", 10) +... + + +
+ +
+ <varname>strip_plus_from_e164</varname> (int) + + Strip + from subscription id when E.164 format is used. This is according + to spec, but this parameter is to keep existing behavior as the default. + + Default value is 0. + + + <varname>strip_plus_from_e164</varname>parameter + usage + + +... +modparam("ims_charging", "strip_plus_from_e164", 1) +... + + +
+ +
+ <varname>use_pani_from_term_invite</varname> (int) + + P-Access-Network-Info is normally relevant for the "orig" scenario where it's extracted from INVITE. This setting instruct Kamailio + to include it in "term" scenario too, where it might have been added to the INVITE based on info from a REGISTER. + Normally used to start a charging session when the user is roaming. + + Default value is 0. + + + <varname>use_pani_from_term_invite</varname>parameter + usage + + +... +modparam("ims_charging", "use_pani_from_term_invite", 1) +... + + +
+ +
+ <varname>node_func</varname> (int) + + Defines what should be sent as Node-Functionality (862) in the Diameter Ro request. + Possible values are: 0 (S-CSCF), 1 (P-CSCF), 2 (I-CSCF), 3 (MRFC), 4 (MGCF), 5 (BFCF) or 6 (AS) + + Default value is 0 (S-CSCF). + + + <varname>node_func</varname>parameter + usage + + +... +modparam("ims_charging", "node_func", 1) ... diff --git a/src/modules/ims_charging/ims_charging_mod.c b/src/modules/ims_charging/ims_charging_mod.c index 96c50b1c1..2d235dc3f 100644 --- a/src/modules/ims_charging/ims_charging_mod.c +++ b/src/modules/ims_charging/ims_charging_mod.c @@ -24,6 +24,8 @@ MODULE_VERSION +extern gen_lock_t *process_lock; /* lock on the process table */ + struct dlg_binds *dlgb_p; /* parameters */ @@ -57,7 +59,8 @@ int ro_db_mode = DB_MODE_NONE; char *domain = "location"; -client_ro_cfg cfg = {str_init(""), str_init(""), str_init(""), str_init(""), 0}; +client_ro_cfg cfg = { + str_init(""), str_init(""), str_init(""), str_init(""), 0, 0}; static str custom_user_spec = {NULL, 0}; static str app_provided_party_spec = {NULL, 0}; @@ -88,6 +91,9 @@ static int mod_init(void); static int mod_child_init(int); static void mod_destroy(void); +AAAMessage *callback_cdp_request(AAAMessage *request, void *param); +int *callback_singleton; /*< Callback singleton */ + static int w_ro_ccr(struct sip_msg *msg, char *route_name, char *direction, int reservation_units, char *incoming_trunk_id, char *outgoing_trunk_id); @@ -163,6 +169,11 @@ static param_export_t params[] = { &vendor_specific_id}, /* VSI for extra charing info in Ro */ {"custom_user_avp", PARAM_STR, &custom_user_spec}, {"app_provided_party_avp", PARAM_STR, &app_provided_party_spec}, + {"strip_plus_from_e164", INT_PARAM, + &cfg.strip_plus_from_e164}, /*wheter to strip or keep + sign from E164 numbers (tel: uris), according to diameter spec*/ + {"use_pani_from_term_invite", INT_PARAM, + &cfg.use_pani_from_term_invite}, /*wheter to read and use P-Access-Network-Info header from INVITE on term scenario*/ + {"node_func", INT_PARAM, &cfg.node_func}, /* node functionality */ {0, 0, 0}}; /** module exports */ @@ -223,6 +234,10 @@ int fix_parameters() return -1; } } + if(cfg.node_func < 0 || cfg.node_func > 6) { + LM_ERR("node_func: invalid value - must be between 0 and 6\n"); + return 0; + } init_custom_user(custom_user_spec.s ? &custom_user_avp : 0); init_app_provided_party( @@ -236,6 +251,9 @@ static int mod_init(void) int n; load_tm_f load_tm; + callback_singleton = shm_malloc(sizeof(int)); + *callback_singleton = 0; + if(!fix_parameters()) { LM_ERR("unable to set Ro configuration parameters correctly\n"); goto error; @@ -333,8 +351,8 @@ static int mod_child_init(int rank) { ro_db_mode = ro_db_mode_param; - if(((ro_db_mode == DB_MODE_REALTIME) && (rank > 0 || rank == PROC_TIMER)) - || (ro_db_mode == DB_MODE_SHUTDOWN && (rank == PROC_MAIN))) { + if((ro_db_mode == DB_MODE_REALTIME && (rank > 0 || rank == PROC_TIMER)) + || (ro_db_mode == DB_MODE_SHUTDOWN && rank == PROC_MAIN)) { if(ro_connect_db(&db_url)) { LM_ERR("failed to connect to database (rank=%d)\n", rank); return -1; @@ -343,17 +361,68 @@ static int mod_child_init(int rank) /* in DB_MODE_SHUTDOWN only PROC_MAIN will do a DB dump at the end, so * for the rest of the processes will be the same as DB_MODE_NONE */ - if(ro_db_mode == DB_MODE_SHUTDOWN && rank != PROC_MAIN) + if((ro_db_mode == DB_MODE_SHUTDOWN) && rank != PROC_MAIN) ro_db_mode = DB_MODE_NONE; - /* in DB_MODE_REALTIME and DB_MODE_DELAYED the PROC_MAIN have no DB handle */ - if((ro_db_mode == DB_MODE_REALTIME) && rank == PROC_MAIN) + /* in DB_MODE_REALTIME the PROC_MAIN have no DB handle */ + if(ro_db_mode == DB_MODE_REALTIME && rank == PROC_MAIN) ro_db_mode = DB_MODE_NONE; + lock_get(process_lock); + if((*callback_singleton) == 0) { + *callback_singleton = 1; + cdpb.AAAAddRequestHandler(callback_cdp_request, NULL); + } + lock_release(process_lock); + return 0; } static void mod_destroy(void) { + /* Stop timer first so no more interim updates are being sent before update to db */ + destroy_ro_timer(); + if(ro_db_mode == DB_MODE_SHUTDOWN) { + ro_update_db(0, 0); + } +} + +/** + * Handler for incoming Diameter requests. + * @param request - the received request + * @param param - generic pointer + * @returns the answer to this request + */ +AAAMessage *callback_cdp_request(AAAMessage *request, void *param) +{ + if(is_req(request)) { + switch(request->applicationId) { + case IMS_Ro: + switch(request->commandCode) { + case IMS_RAR: + return ro_process_rar(request); + break; + case IMS_ASR: + return ro_process_asr(request); + break; + default: + LM_ERR("Ro request handler(): - Received unknown " + "request for Ro command %d, flags %#1x " + "endtoend %u hopbyhop %u\n", + request->commandCode, request->flags, + request->endtoendId, request->hopbyhopId); + return 0; + break; + } + break; + default: + LM_ERR("Ro request handler(): - Received unknown request " + "for app %d command %d\n", + request->applicationId, request->commandCode); + return 0; + break; + } + } + return 0; } int create_response_avp_string(char *name, str *val) @@ -585,6 +654,9 @@ static int ki_ro_ccr(sip_msg_t *msg, str *s_route_name, str *s_direction, pani = cscf_get_access_network_info(msg, &h); } else if(dir == RO_TERM_DIRECTION) { + if(cfg.use_pani_from_term_invite) { + pani = cscf_get_access_network_info(msg, &h); + } //get callee IMPU from called part id - if not present then skip this if((identity = cscf_get_public_identity_from_called_party_id(msg, &h)) .len @@ -743,20 +815,27 @@ static int ro_fixup_stop(void **param, int param_no) return 0; } +/* clang-format off */ static sr_kemi_t ims_charging_kemi_exports[] = { - {str_init("ims_charging"), str_init("Ro_CCR"), SR_KEMIP_INT, ki_ro_ccr, - {SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_STR, - SR_KEMIP_STR, SR_KEMIP_NONE}}, - {str_init("ims_charging"), str_init("Ro_CCR_Stop"), SR_KEMIP_INT, - ki_ro_ccr_stop, - {SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init("ims_charging"), str_init("Ro_set_session_id_avp"), - SR_KEMIP_INT, ki_ro_set_session_id_avp, - {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}}}; + { str_init("ims_charging"), str_init("Ro_CCR"), + SR_KEMIP_INT, ki_ro_ccr, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_INT, + SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE } + }, + { str_init("ims_charging"), str_init("Ro_CCR_Stop"), + SR_KEMIP_INT, ki_ro_ccr_stop, + { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_STR, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("ims_charging"), str_init("Ro_set_session_id_avp"), + SR_KEMIP_INT, ki_ro_set_session_id_avp, + { 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} } +}; +/* clang-format on */ int mod_register(char *path, int *dlflags, void *p1, void *p2) { diff --git a/src/modules/ims_charging/ims_ro.c b/src/modules/ims_charging/ims_ro.c index 23cebfee2..11c741692 100644 --- a/src/modules/ims_charging/ims_ro.c +++ b/src/modules/ims_charging/ims_ro.c @@ -138,6 +138,32 @@ static int get_app_provided_party(struct sip_msg *req, str *address) return -1; } +/*! + * \brief Format subscription id according to settings + * \param subscription_id subscription id + * \param subscription_id_type format according to subscription id value + */ +static void format_subscription_id( + str *subscription_id, int *subscription_id_type) +{ + if(strncasecmp(subscription_id->s, "tel:", 4) == 0) { + *subscription_id_type = Subscription_Type_MSISDN; + subscription_id->s += 4; + subscription_id->len -= 4; + /*if stripping is not done the format should actually be Subscription_Type_IMPU/END_USER_SIP_URI, + but that could be a breaking change */ + if(cfg.strip_plus_from_e164 + && strncasecmp(subscription_id->s, "+", 1) == 0) { + //subscription should be purely digits when using MSISDN/E164 format + subscription_id->s += 1; + subscription_id->len -= 1; + } + } else { + *subscription_id_type = + Subscription_Type_IMPU; //default is END_USER_SIP_URI + } +} + void credit_control_session_callback(int event, void *session) { @@ -474,7 +500,7 @@ int get_sip_header_info(struct sip_msg *req, struct sip_msg *reply, int32_t *acc_record_type, str *sip_method, str *event, uint32_t *expires, str *callid, str *asserted_id_uri, str *to_uri) { - + int expires_header; sip_method->s = req->first_line.u.request.method.s; sip_method->len = req->first_line.u.request.method.len; @@ -486,7 +512,12 @@ int get_sip_header_info(struct sip_msg *req, struct sip_msg *reply, *acc_record_type = AAA_ACCT_EVENT; *event = cscf_get_event(req); - *expires = cscf_get_expires_hdr(req, 0); + /* return value is signed int, while *expires is uint32_t. + when -1 is returned (header not found) and assigned directly to *expires, + this is actually added as an AVP in the outgoing diameter request */ + expires_header = cscf_get_expires_hdr(req, 0); + if(expires_header > 0) + *expires = expires_header; *callid = cscf_get_call_id(req, NULL); if(get_custom_user(req, asserted_id_uri) == -1) { @@ -602,7 +633,7 @@ Ro_CCR_t *dlg_create_ro_session(struct sip_msg *req, struct sip_msg *reply, subscr.id.len = subscription_id.len; subscr.type = subscription_id_type; - ro_ccr_data = new_Ro_CCR(acc_record_type, &user_name, ims_info, &subscr); + ro_ccr_data = new_Ro_CCR(acc_record_type, &user_name, ims_info, &subscr, 0); if(!ro_ccr_data) { LM_ERR("dlg_create_ro_session: no memory left for generic\n"); goto out_of_memory; @@ -734,22 +765,15 @@ void send_ccr_interim( goto error; } - //getting subscription id type - if(strncasecmp(subscr.id.s, "tel:", 4) == 0) { - subscr.type = Subscription_Type_MSISDN; - // Strip "tel:": - subscr.id.s += 4; - subscr.id.len -= 4; - } else { - subscr.type = Subscription_Type_IMPU; //default is END_USER_SIP_URI - } + format_subscription_id(&subscr.id, &subscr.type); user_name.s = subscr.id.s; user_name.len = subscr.id.len; acc_record_type = AAA_ACCT_INTERIM; - ro_ccr_data = new_Ro_CCR(acc_record_type, &user_name, ims_info, &subscr); + ro_ccr_data = new_Ro_CCR(acc_record_type, &user_name, ims_info, &subscr, + &ro_session->origin_host); if(!ro_ccr_data) { LM_ERR("no memory left for generic\n"); goto error; @@ -844,7 +868,8 @@ error: if(auth) { cdpb.AAASessionsUnlock(auth->hash); - cdpb.AAADropCCAccSession(auth); + /*we're no longer using cdpb.AAADropCCAccSession() here, since this + session might be restarted by a re-auth request from the server or by call end*/ } shm_free(i_req); @@ -909,11 +934,41 @@ static void resume_on_interim_ccr( i_req->new_credit = ro_cca_data->mscc->granted_service_unit->cc_time; i_req->credit_valid_for = ro_cca_data->mscc->validity_time; i_req->is_final_allocation = 0; + if(ro_cca_data->mscc->time_quota_threshold > 0) { + LM_DBG("updating session ro_timer_buffer to %i from " + "time_quota_threshold in server response\n", + ro_cca_data->mscc->time_quota_threshold); + i_req->ro_session->ro_timer_buffer = + ro_cca_data->mscc->time_quota_threshold; + } if(ro_cca_data->mscc->final_unit_action && (ro_cca_data->mscc->final_unit_action->action == 0)) i_req->is_final_allocation = 1; + if(ro_cca_data->origin_host.s && ro_cca_data->origin_host.len > 0) { + if(i_req->ro_session->origin_host.s + && i_req->ro_session->origin_host.len > 0 + && (!strncasecmp(i_req->ro_session->origin_host.s, + ro_cca_data->origin_host.s, + ro_cca_data->origin_host.len) + || i_req->ro_session->origin_host.len + != ro_cca_data->origin_host.len)) { + LM_DBG("origin host for session has changed\n"); + i_req->ro_session->origin_host.s = + (char *)shm_realloc(i_req->ro_session->origin_host.s, + ro_cca_data->origin_host.len); + if(!i_req->ro_session->origin_host.s) { + LM_ERR("no more shm mem\n"); + goto error; + } + + i_req->ro_session->origin_host.len = ro_cca_data->origin_host.len; + memcpy(i_req->ro_session->origin_host.s, ro_cca_data->origin_host.s, + ro_cca_data->origin_host.len); + } + } + Ro_free_CCA(ro_cca_data); cdpb.AAAFreeMessage(&cca); @@ -1039,14 +1094,7 @@ void send_ccr_stop_with_param( goto error0; } - //getting subscription id type - if(strncasecmp(subscr.id.s, "tel:", 4) == 0) { - subscr.type = Subscription_Type_MSISDN; - subscr.id.s += 4; - subscr.id.len -= 4; - } else { - subscr.type = Subscription_Type_IMPU; //default is END_USER_SIP_URI - } + format_subscription_id(&subscr.id, &subscr.type); user_name.s = subscr.id.s; user_name.len = subscr.id.len; @@ -1054,7 +1102,8 @@ void send_ccr_stop_with_param( acc_record_type = AAA_ACCT_STOP; - ro_ccr_data = new_Ro_CCR(acc_record_type, &user_name, ims_info, &subscr); + ro_ccr_data = new_Ro_CCR(acc_record_type, &user_name, ims_info, &subscr, + &ro_session->origin_host); if(!ro_ccr_data) { LM_ERR("send_ccr_stop: no memory left for generic\n"); goto error0; @@ -1298,15 +1347,7 @@ int Ro_Send_CCR(struct sip_msg *msg, struct dlg_cell *dlg, int dir, goto error; } - //getting subscription id type - if(strncasecmp(subscription_id.s, "tel:", 4) == 0) { - subscription_id_type = Subscription_Type_MSISDN; - subscription_id.s += 4; - subscription_id.len -= 4; - } else { - subscription_id_type = - Subscription_Type_IMPU; //default is END_USER_SIP_URI - } + format_subscription_id(&subscription_id, &subscription_id_type); str mac = {0, 0}; if(get_mac_avp_value(msg, &mac) != 0) @@ -1364,7 +1405,7 @@ int Ro_Send_CCR(struct sip_msg *msg, struct dlg_cell *dlg, int dir, &asserted_identity, &called_asserted_identity, &mac, dlg->h_entry, dlg->h_id, reservation_units, 0, active_rating_group, active_service_identifier, incoming_trunk_id, outgoing_trunk_id, - pani, &app_provided_party); + pani, &app_provided_party, ro_timer_buffer); if(!new_session) { LM_ERR("Couldn't create new Ro Session - this is BAD!\n"); @@ -1654,20 +1695,41 @@ static void resume_on_initial_ccr( ro_cca_data->mscc->granted_service_unit->cc_time; ssd->ro_session->valid_for = ro_cca_data->mscc->validity_time; ssd->ro_session->is_final_allocation = 0; + if(ro_cca_data->mscc->time_quota_threshold > 0) { + LM_DBG("setting session ro_timer_buffer to %i from " + "time_quota_threshold in server response\n", + ro_cca_data->mscc->time_quota_threshold); + ssd->ro_session->ro_timer_buffer = + ro_cca_data->mscc->time_quota_threshold; + } if(ro_cca_data->mscc->final_unit_action && (ro_cca_data->mscc->final_unit_action->action == 0)) ssd->ro_session->is_final_allocation = 1; + if(ro_cca_data->origin_host.s && ro_cca_data->origin_host.len > 0) { + ssd->ro_session->origin_host.s = + (char *)shm_malloc(ro_cca_data->origin_host.len); + if(!ssd->ro_session->origin_host.s) { + LM_ERR("no more shm mem\n"); + goto error0; + } + + ssd->ro_session->origin_host.len = ro_cca_data->origin_host.len; + memcpy(ssd->ro_session->origin_host.s, ro_cca_data->origin_host.s, + ro_cca_data->origin_host.len); + } + Ro_free_CCA(ro_cca_data); + ro_cca_data = NULL; LM_DBG("Freeing CCA message\n"); cdpb.AAAFreeMessage(&cca); link_ro_session(ssd->ro_session, 0); + ssd->ro_session->flags |= RO_SESSION_FLAG_NEW; if(ro_db_mode == DB_MODE_REALTIME) { - ssd->ro_session->flags |= RO_SESSION_FLAG_NEW; if(update_ro_dbinfo(ssd->ro_session) != 0) { LM_ERR("Failed to update ro_session in database... continuing\n"); }; @@ -1696,9 +1758,11 @@ static void resume_on_initial_ccr( return; error1: - Ro_free_CCA(ro_cca_data); - error0: + if(ro_cca_data != NULL) { + Ro_free_CCA(ro_cca_data); + } + LM_DBG("Trying to reserve credit on initial INVITE failed on cdp " "callback\n"); // counter_add(ims_charging_cnts_h.active_ro_sessions, -1); /*we bumped active on the original initial ccr sent */ @@ -1866,3 +1930,108 @@ static int get_mac_avp_value(struct sip_msg *msg, str *value) *value = val.rs; return 0; } + +/*! + * \brief Process re-auth request + * \param request Diameter request + * \return diameter response + */ +AAAMessage *ro_process_rar(AAAMessage *request) +{ + AAAMessage *response; + struct ro_session *ro_session = NULL; + struct ro_session_entry *ro_session_entry; + unsigned int h_entry; + int unref = 0; + int result_code = DIAMETER_LIMITED_SUCCESS; + char x[4]; + + if(request->sessionId && request->sessionId->data.s) { + LM_INFO("Received an IMS_RAR for session id %.*s\n", + request->sessionId->data.len, request->sessionId->data.s); + + ro_session = lookup_ro_session_by_session_id(&request->sessionId->data); + if(ro_session == NULL) { + LM_WARN("no active ro_session with id %.*s - ignoring\n", + request->sessionId->data.len, request->sessionId->data.s); + result_code = DIAMETER_UNKNOWN_SESSION_ID; + goto end; + } + + h_entry = ro_session->h_entry; + ro_session_entry = &(ro_session_table->entries[h_entry]); + + ro_session_lock(ro_session_table, ro_session_entry); + + /*we might receive a re-auth request with either timer active or inactive. + first remove any existing. if success, decrement ref count.*/ + if(remove_ro_timer(&ro_session->ro_tl) == 0) { + unref++; + } + if(insert_ro_timer(&ro_session->ro_tl, 1) == 0) { + /*increment ref count on timer create success */ + ref_ro_session(ro_session, 1, 0); + } + + /*finally, unref session returned by lookup */ + unref_ro_session(ro_session, unref + 1, 0); + ro_session_unlock(ro_session_table, ro_session_entry); + } else { + LM_WARN("Received an IMS_RAR without session id\n"); + result_code = DIAMETER_UNABLE_TO_COMPLY; + } +end: + response = cdpb.AAACreateResponse(request); + if(!response) + return 0; + set_4bytes(x, result_code); + Ro_add_avp(response, x, 4, AVP_Result_Code, AAA_AVP_FLAG_MANDATORY, 0, + AVP_DUPLICATE_DATA, __FUNCTION__); + return response; +} + +/*! + * \brief Process session-abort request + * \param request Diameter request + * \return diameter response + */ +AAAMessage *ro_process_asr(AAAMessage *request) +{ + AAAMessage *response; + struct ro_session *ro_session = NULL; + int result_code = DIAMETER_LIMITED_SUCCESS; + char x[4]; + + if(request->sessionId && request->sessionId->data.s) { + LM_INFO("Received an IMS_ASR for session id %.*s\n", + request->sessionId->data.len, request->sessionId->data.s); + + ro_session = lookup_ro_session_by_session_id(&request->sessionId->data); + if(ro_session == NULL) { + LM_WARN("no active ro_session with id %.*s - ignoring\n", + request->sessionId->data.len, request->sessionId->data.s); + result_code = DIAMETER_UNKNOWN_SESSION_ID; + goto end; + } + + if(dlgb.lookup_terminate_dlg( + ro_session->dlg_h_entry, ro_session->dlg_h_id, NULL) + < 0) { + result_code = DIAMETER_UNABLE_TO_COMPLY; + } + + unref_ro_session(ro_session, 1, 0); + } else { + LM_WARN("Received an IMS_ASR without session id\n"); + result_code = DIAMETER_UNABLE_TO_COMPLY; + } +end: + response = cdpb.AAACreateResponse(request); + if(!response) + return 0; + set_4bytes(x, result_code); + Ro_add_avp(response, x, 4, AVP_Result_Code, AAA_AVP_FLAG_MANDATORY, 0, + AVP_DUPLICATE_DATA, __FUNCTION__); + + return response; +} diff --git a/src/modules/ims_charging/ims_ro.h b/src/modules/ims_charging/ims_ro.h index bda148d76..529ff18b5 100644 --- a/src/modules/ims_charging/ims_ro.h +++ b/src/modules/ims_charging/ims_ro.h @@ -36,4 +36,7 @@ int get_direction_as_int(str *direction); void init_custom_user(pv_spec_t *custom_user_avp); void init_app_provided_party(pv_spec_t *app_provided_party_avp_p); +AAAMessage *ro_process_rar(AAAMessage *rtr); +AAAMessage *ro_process_asr(AAAMessage *rtr); + #endif /* CLIENT_RF_IMS_RO_H */ diff --git a/src/modules/ims_charging/ro_db_handler.c b/src/modules/ims_charging/ro_db_handler.c index 00fe19c30..d75126e33 100644 --- a/src/modules/ims_charging/ro_db_handler.c +++ b/src/modules/ims_charging/ro_db_handler.c @@ -1,6 +1,12 @@ #include "ro_db_handler.h" +#include "ims_charging_mod.h" +#include "dialog.h" #include "../../lib/srdb1/db.h" +extern ims_dlg_api_t dlgb; +extern struct cdp_binds cdpb; +extern int ro_db_mode; + static db1_con_t *ro_db_handle = 0; /* database connection handle */ static db_func_t ro_dbf; @@ -23,6 +29,13 @@ str incoming_trunk_id_column = str_init(INCOMING_TRUNK_ID_COL); str outgoing_trunk_id_column = str_init(OUTGOING_TRUNK_ID_COL); str rating_group_column = str_init(RATING_GROUP_COL); str service_identifier_column = str_init(SERVICE_IDENTIFIER_COL); +str auth_app_id_column = str_init(AUTH_APP_ID_COL); +str auth_session_type_column = str_init(AUTH_SESSION_TYPE_COL); +str pani_column = str_init(PANI_COL); +str mac_column = str_init(MAC_COL); +str app_provided_party_column = str_init(APP_PROVIDED_PARTY_COL); +str is_final_allocation_column = str_init(IS_FINAL_ALLOCATION_COL); +str origin_host_column = str_init(ORIGIN_HOST_COL); typedef enum ro_session_field_idx { @@ -43,7 +56,14 @@ typedef enum ro_session_field_idx INCOMING_TRUNK_ID_COL_IDX, OUTGOING_TRUNK_ID_COL_IDX, RATING_GROUP_COL_IDX, - SERVICE_IDENTIFIER_COL_IDX + SERVICE_IDENTIFIER_COL_IDX, + AUTH_APP_ID_COL_IDX, + AUTH_SESSION_TYPE_COL_IDX, + PANI_COL_IDX, + MAC_COL_IDX, + APP_PROVIDED_PARTY_COL_IDX, + IS_FINAL_ALLOCATION_COL_IDX, + ORIGIN_HOST_COL_IDX } ro_session_field_idx_t; @@ -74,8 +94,8 @@ typedef enum ro_session_field_idx if(VAL_NULL((_values) + (_index))) { \ if(_not_null) { \ if(_unref) \ - unref_dlg(dlg, 1); \ - goto next_dialog; \ + unref_ro_session(session, 1, 0); \ + goto next_ro_session; \ } else { \ (_res).s = 0; \ (_res).len = 0; \ @@ -107,14 +127,8 @@ int init_ro_db(const str *db_url, int dlg_hash_size, int db_update_period, goto dberror; } - // if( (dlg_db_mode==DB_MODE_DELAYED) && - // (register_timer( dialog_update_db, 0, db_update_period)<0 )) { - // LM_ERR("failed to register update db\n"); - // return -1; - // } - if((load_ro_info_from_db(dlg_hash_size, fetch_num_rows)) != 0) { - LM_ERR("unable to load the dialog data\n"); + LM_ERR("unable to load the ro session data\n"); goto dberror; } @@ -129,10 +143,348 @@ dberror: return -1; } +static int use_ro_table(void) +{ + if(!ro_db_handle) { + LM_ERR("invalid database handle\n"); + return -1; + } + + if(ro_dbf.use_table(ro_db_handle, &ro_session_table_name) < 0) { + LM_ERR("Error in use_table\n"); + return -1; + } + + return 0; +} + +static int select_entire_ro_session_table(db1_res_t **res, int fetch_num_rows) +{ + db_key_t query_cols[RO_SESSION_TABLE_COL_NUM] = {&id_column, + &h_entry_column, &h_id_column, &session_id_column, + &dlg_h_entry_column, &dlg_h_id_column, &direction_column, + &asserted_column, &callee_column, &start_time_col, + &last_event_ts_column, &reserved_sec_column, &valid_for_column, + &state_column, &incoming_trunk_id_column, &outgoing_trunk_id_column, + &rating_group_column, &service_identifier_column, + &auth_app_id_column, &auth_session_type_column, &pani_column, + &mac_column, &app_provided_party_column, + &is_final_allocation_column, &origin_host_column}; + + if(use_ro_table() != 0) { + return -1; + } + + /* select the whole table and all the columns */ + if(DB_CAPABILITY(ro_dbf, DB_CAP_FETCH) && (fetch_num_rows > 0)) { + if(ro_dbf.query(ro_db_handle, 0, 0, 0, query_cols, 0, + RO_SESSION_TABLE_COL_NUM, 0, 0) + < 0) { + LM_ERR("Error while querying (fetch) database\n"); + return -1; + } + if(ro_dbf.fetch_result(ro_db_handle, res, fetch_num_rows) < 0) { + LM_ERR("fetching rows failed\n"); + return -1; + } + } else { + if(ro_dbf.query(ro_db_handle, 0, 0, 0, query_cols, 0, + RO_SESSION_TABLE_COL_NUM, 0, res) + < 0) { + LM_ERR("Error while querying database\n"); + return -1; + } + } + + return 0; +} + +static int get_timer_value( + struct ro_session *session, time_t time_since_last_event) +{ + int timer_value; + if(session->reserved_secs < (session->valid_for - time_since_last_event)) { + if(session->reserved_secs > session->ro_timer_buffer) { + timer_value = + session->reserved_secs - time_since_last_event + - (session->is_final_allocation ? 0 + : session->ro_timer_buffer); + } else { + timer_value = session->reserved_secs - time_since_last_event; + } + } else { + if(session->valid_for > session->ro_timer_buffer) { + timer_value = + session->valid_for - time_since_last_event + - (session->is_final_allocation ? 0 + : session->ro_timer_buffer); + } else { + timer_value = session->valid_for - time_since_last_event; + } + } + + /* let cdp connections settle a bit after startup */ + if(timer_value < 5) { + timer_value = 5; + } + + return timer_value; +} + int load_ro_info_from_db(int hash_size, int fetch_num_rows) { - LM_WARN("not supported yet\n"); + db1_res_t *res; + db_val_t *values; + db_row_t *rows; + struct dlg_cell *dlg = NULL; + struct ro_session *session = 0; + int i, nr_rows, dir, active_rating_group, active_service_identifier, + reservation_units, dlg_h_entry, dlg_h_id; + str session_id, asserted_identity, called_asserted_identity, + incoming_trunk_id, outgoing_trunk_id, pani, app_provided_party, mac, + origin_host; + time_t now = get_current_time_micro(); + time_t time_since_last_event; + AAASession *auth = 0; + unsigned int next_id; + + res = 0; + if((nr_rows = select_entire_ro_session_table(&res, fetch_num_rows)) < 0) + goto end; + + nr_rows = RES_ROW_N(res); + + LM_ALERT("the database has information about %i ro sessions\n", nr_rows); + + rows = RES_ROWS(res); + + do { + /* for every row---ro session */ + for(i = 0; i < nr_rows; i++) { + values = ROW_VALUES(rows + i); + + if(VAL_NULL(GET_FIELD_IDX(values, HASH_ID_COL_IDX)) + || VAL_NULL(GET_FIELD_IDX(values, HASH_ENTRY_COL_IDX))) { + LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n", + h_entry_column.len, h_entry_column.s, h_id_column.len, + h_id_column.s); + continue; + } + + if(VAL_NULL(GET_FIELD_IDX(values, SESSION_ID_COL_IDX)) + || VAL_NULL(GET_FIELD_IDX(values, DIRECTION_COL_IDX))) { + LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n", + session_id_column.len, session_id_column.s, + direction_column.len, direction_column.s); + continue; + } + + if(VAL_NULL(GET_FIELD_IDX(values, DLG_HASH_ENTRY_COL_IDX)) + || VAL_NULL(GET_FIELD_IDX(values, DLG_HASH_ID_COL_IDX))) { + LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n", + dlg_h_entry_column.len, dlg_h_entry_column.s, + dlg_h_id_column.len, dlg_h_id_column.s); + continue; + } + + if(VAL_NULL(GET_FIELD_IDX(values, ASSERTED_ID_COL_IDX)) + || VAL_NULL(GET_FIELD_IDX(values, CALLEE_COL_IDX))) { + LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n", + asserted_column.len, asserted_column.s, + callee_column.len, callee_column.s); + continue; + } + + if(VAL_NULL(GET_FIELD_IDX(values, AUTH_APP_ID_COL_IDX)) + || VAL_NULL( + GET_FIELD_IDX(values, AUTH_SESSION_TYPE_COL_IDX))) { + LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n", + auth_app_id_column.len, auth_app_id_column.s, + auth_session_type_column.len, + auth_session_type_column.s); + continue; + } + + if(VAL_NULL(GET_FIELD_IDX(values, IS_FINAL_ALLOCATION_COL_IDX))) { + LM_ERR("columns %.*s cannot be null -> skipping\n", + is_final_allocation_column.len, + is_final_allocation_column.s); + continue; + } + + dlg_h_entry = + VAL_INT(GET_FIELD_IDX(values, DLG_HASH_ENTRY_COL_IDX)); + dlg_h_id = VAL_INT(GET_FIELD_IDX(values, DLG_HASH_ID_COL_IDX)); + + dlg = dlgb.get_dlg_hash(dlg_h_entry, dlg_h_id); + if(!dlg) { + LM_ERR("cannot lookup dialog -> skipping\n"); + continue; + } + + /*restore the ro session info*/ + dir = VAL_INT(GET_FIELD_IDX(values, DIRECTION_COL_IDX)); + GET_STR_VALUE(session_id, values, SESSION_ID_COL_IDX, 1, 0); + GET_STR_VALUE(asserted_identity, values, ASSERTED_ID_COL_IDX, 1, 0); + GET_STR_VALUE( + called_asserted_identity, values, CALLEE_COL_IDX, 1, 0); + GET_STR_VALUE( + incoming_trunk_id, values, INCOMING_TRUNK_ID_COL_IDX, 0, 0); + GET_STR_VALUE( + outgoing_trunk_id, values, OUTGOING_TRUNK_ID_COL_IDX, 0, 0); + GET_STR_VALUE(pani, values, PANI_COL_IDX, 0, 0); + GET_STR_VALUE(mac, values, MAC_COL_IDX, 0, 0); + GET_STR_VALUE(app_provided_party, values, + APP_PROVIDED_PARTY_COL_IDX, 0, 0); + GET_STR_VALUE(origin_host, values, ORIGIN_HOST_COL_IDX, 0, 0); + active_rating_group = + VAL_INT(GET_FIELD_IDX(values, RATING_GROUP_COL_IDX)); + active_service_identifier = + VAL_INT(GET_FIELD_IDX(values, SERVICE_IDENTIFIER_COL_IDX)); + reservation_units = + VAL_INT(GET_FIELD_IDX(values, RESERVED_SECS_COL_IDX)); + + session = build_new_ro_session(dir, 0, 0, &session_id, &dlg->callid, + &asserted_identity, &called_asserted_identity, &mac, + dlg_h_entry, dlg_h_id, reservation_units, 0, + active_rating_group, active_service_identifier, + &incoming_trunk_id, &outgoing_trunk_id, &pani, + &app_provided_party, ro_timer_buffer); + + if(!session) { + LM_ERR("Couldn't restore Ro Session - this is BAD!\n"); + dlgb.release_dlg(dlg); + goto error; + } + + if(session->h_entry + != VAL_INT(GET_FIELD_IDX(values, HASH_ENTRY_COL_IDX))) { + LM_ERR("inconsistent hash data in the ro session database: " + "you may have restarted Kamailio using a different " + "hash_size: please erase %.*s database and restart\n", + ro_session_table_name.len, ro_session_table_name.s); + shm_free(session); + dlgb.release_dlg(dlg); + goto error; + } + + session->ro_session_id.s = (char *)shm_malloc(session_id.len); + if(!session->ro_session_id.s) { + LM_ERR("no more shm mem\n"); + dlgb.release_dlg(dlg); + goto error; + } + session->ro_session_id.len = session_id.len; + memcpy(session->ro_session_id.s, session_id.s, session_id.len); + + if(origin_host.s && origin_host.len > 0) { + session->origin_host.s = (char *)shm_malloc(origin_host.len); + if(!session->origin_host.s) { + LM_ERR("no more shm mem\n"); + goto error; + } + + session->origin_host.len = origin_host.len; + memcpy(session->origin_host.s, origin_host.s, origin_host.len); + } + + session->active = VAL_INT(GET_FIELD_IDX(values, STATE_COL_IDX)); + session->last_event_timestamp = + VAL_TIME(GET_FIELD_IDX(values, LAST_EVENT_TS_COL_IDX)) + * 1000000; + session->start_time = + VAL_TIME(GET_FIELD_IDX(values, START_TIME_COL_IDX)) + * 1000000; + session->valid_for = + VAL_INT(GET_FIELD_IDX(values, VALID_FOR_COL_IDX)); + session->reserved_secs = + VAL_INT(GET_FIELD_IDX(values, RESERVED_SECS_COL_IDX)); + session->is_final_allocation = + VAL_INT(GET_FIELD_IDX(values, IS_FINAL_ALLOCATION_COL_IDX)); + session->auth_appid = + VAL_INT(GET_FIELD_IDX(values, AUTH_APP_ID_COL_IDX)); + session->auth_session_type = + VAL_INT(GET_FIELD_IDX(values, AUTH_SESSION_TYPE_COL_IDX)); + session->flags |= RO_SESSION_FLAG_INSERTED; + + link_ro_session(session, 0); + session->h_id = VAL_INT(GET_FIELD_IDX(values, HASH_ID_COL_IDX)); + next_id = ro_session_table->entries[session->h_entry].next_id; + ro_session_table->entries[session->h_entry].next_id = + (next_id < session->h_id) ? (session->h_id + 1) : next_id; + + if(dlgb.register_dlgcb(dlg, + DLGCB_TERMINATED | DLGCB_FAILED | DLGCB_EXPIRED + | DLGCB_CONFIRMED, + dlg_callback_received, (void *)session, NULL) + != 0) { + LM_CRIT("cannot register callback for dialog confirmation\n"); + dlgb.release_dlg(dlg); + goto error; + } + + auth = cdpb.AAAMakeSession(session->auth_appid, + session->auth_session_type, session->ro_session_id); + if(!auth) { + LM_ERR("Could not create AAA session\n"); + dlgb.release_dlg(dlg); + continue; + } + auth->u.cc_acc.state = ACC_CC_ST_OPEN; + cdpb.AAASessionsUnlock(auth->hash); + + if(session->active) { + now = get_current_time_micro(); + time_since_last_event = + (now - session->last_event_timestamp) / 1000000; + session->event_type = answered; + session->billed = session->start_time + - session->last_event_timestamp / 1000000; + + int ret = 0; + ret = insert_ro_timer(&session->ro_tl, + get_timer_value(session, time_since_last_event)); + if(ret != 0) { + LM_CRIT("unable to insert timer for Ro Session [%.*s]\n", + session->ro_session_id.len, + session->ro_session_id.s); + } else { + ref_ro_session(session, 1, 0); + } + } + + dlgb.release_dlg(dlg); + + next_ro_session:; + } + + /* any more data to be fetched ?*/ + if(DB_CAPABILITY(ro_dbf, DB_CAP_FETCH) && (fetch_num_rows > 0)) { + if(ro_dbf.fetch_result(ro_db_handle, &res, fetch_num_rows) < 0) { + LM_ERR("re-fetching rows failed\n"); + goto error; + } + nr_rows = RES_ROW_N(res); + rows = RES_ROWS(res); + } else { + nr_rows = 0; + } + + } while(nr_rows > 0); + + if(ro_db_mode == DB_MODE_SHUTDOWN) { + if(ro_dbf.delete(ro_db_handle, 0, 0, 0, 0) < 0) { + LM_ERR("failed to clear ro session table\n"); + goto error; + } + } + +end: + ro_dbf.free_result(ro_db_handle, res); return 0; +error: + ro_dbf.free_result(ro_db_handle, res); + return -1; } int ro_connect_db(const str *db_url) @@ -177,8 +529,26 @@ void db_set_datetime_val(db_val_t *values, int index, time_t val) int update_ro_dbinfo_unsafe(struct ro_session *ro_session) { - if((ro_session->flags & RO_SESSION_FLAG_NEW) != 0 - && (ro_session->flags & RO_SESSION_FLAG_INSERTED) == 0) { + /* We check for RO_SESSION_FLAG_DELETED first. If DB_MODE_DELAYED is used, + it might not have RO_SESSION_FLAG_INSERTED flag set which would cause the + record to be inserted instead of being deleted. */ + if((ro_session->flags & RO_SESSION_FLAG_DELETED) != 0) { + db_val_t values[3]; + db_key_t match_keys[3] = { + &h_entry_column, &h_id_column, &session_id_column}; + + db_set_int_val(values, HASH_ENTRY_COL_IDX - 1, ro_session->h_entry); + db_set_int_val(values, HASH_ID_COL_IDX - 1, ro_session->h_id); + db_set_str_val( + values, SESSION_ID_COL_IDX - 1, &ro_session->ro_session_id); + + if(ro_dbf.delete(ro_db_handle, match_keys, 0, values, 3) < 0) { + LM_ERR("failed to delete ro session database information... " + "continuing\n"); + return -1; + } + } else if((ro_session->flags & RO_SESSION_FLAG_NEW) != 0 + && (ro_session->flags & RO_SESSION_FLAG_INSERTED) == 0) { db_val_t values[RO_SESSION_TABLE_COL_NUM]; db_key_t insert_keys[RO_SESSION_TABLE_COL_NUM] = {&id_column, @@ -188,7 +558,10 @@ int update_ro_dbinfo_unsafe(struct ro_session *ro_session) &last_event_ts_column, &reserved_sec_column, &valid_for_column, &state_column, &incoming_trunk_id_column, &outgoing_trunk_id_column, &rating_group_column, - &service_identifier_column}; + &service_identifier_column, &auth_app_id_column, + &auth_session_type_column, &pani_column, &mac_column, + &app_provided_party_column, &is_final_allocation_column, + &origin_host_column}; VAL_TYPE(GET_FIELD_IDX(values, ID_COL_IDX)) = DB1_INT; VAL_NULL(GET_FIELD_IDX(values, ID_COL_IDX)) = 1; @@ -218,6 +591,16 @@ int update_ro_dbinfo_unsafe(struct ro_session *ro_session) db_set_int_val(values, RATING_GROUP_COL_IDX, ro_session->rating_group); db_set_int_val(values, SERVICE_IDENTIFIER_COL_IDX, ro_session->service_identifier); + db_set_int_val(values, AUTH_APP_ID_COL_IDX, ro_session->auth_appid); + db_set_int_val(values, AUTH_SESSION_TYPE_COL_IDX, + ro_session->auth_session_type); + db_set_str_val(values, PANI_COL_IDX, &ro_session->pani); + db_set_str_val(values, MAC_COL_IDX, &ro_session->mac); + db_set_str_val(values, APP_PROVIDED_PARTY_COL_IDX, + &ro_session->app_provided_party); + db_set_int_val(values, IS_FINAL_ALLOCATION_COL_IDX, + ro_session->is_final_allocation); + db_set_str_val(values, ORIGIN_HOST_COL_IDX, &ro_session->origin_host); LM_DBG("Inserting ro_session into database\n"); @@ -240,7 +623,10 @@ int update_ro_dbinfo_unsafe(struct ro_session *ro_session) &callee_column, &start_time_col, &last_event_ts_column, &reserved_sec_column, &valid_for_column, &state_column, &incoming_trunk_id_column, &outgoing_trunk_id_column, - &rating_group_column, &service_identifier_column}; + &rating_group_column, &service_identifier_column, + &auth_app_id_column, &auth_session_type_column, &pani_column, + &mac_column, &app_provided_party_column, + &is_final_allocation_column, &origin_host_column}; db_set_int_val(values, HASH_ENTRY_COL_IDX - 1, ro_session->h_entry); db_set_int_val(values, HASH_ID_COL_IDX - 1, ro_session->h_id); @@ -270,32 +656,28 @@ int update_ro_dbinfo_unsafe(struct ro_session *ro_session) values, RATING_GROUP_COL_IDX - 1, ro_session->rating_group); db_set_int_val(values, SERVICE_IDENTIFIER_COL_IDX - 1, ro_session->service_identifier); + db_set_int_val(values, AUTH_APP_ID_COL_IDX - 1, ro_session->auth_appid); + db_set_int_val(values, AUTH_SESSION_TYPE_COL_IDX - 1, + ro_session->auth_session_type); + db_set_str_val(values, PANI_COL_IDX - 1, &ro_session->pani); + db_set_str_val(values, MAC_COL_IDX - 1, &ro_session->mac); + db_set_str_val(values, APP_PROVIDED_PARTY_COL_IDX - 1, + &ro_session->app_provided_party); + db_set_int_val(values, IS_FINAL_ALLOCATION_COL_IDX - 1, + ro_session->is_final_allocation); + db_set_str_val( + values, ORIGIN_HOST_COL_IDX - 1, &ro_session->origin_host); LM_DBG("Updating ro_session in database\n"); if((ro_dbf.update(ro_db_handle, update_keys /*match*/, 0 /*match*/, values /*match*/, update_keys /*update*/, values /*update*/, - 3 /*match*/, 13 /*update*/)) + 3 /*match*/, 24 /*update*/)) != 0) { LM_ERR("could not update Ro session information in DB... " "continuing\n"); goto error; } ro_session->flags &= ~RO_SESSION_FLAG_CHANGED; - } else if((ro_session->flags & RO_SESSION_FLAG_DELETED) != 0) { - db_val_t values[3]; - db_key_t match_keys[3] = { - &h_entry_column, &h_id_column, &session_id_column}; - - db_set_int_val(values, HASH_ENTRY_COL_IDX - 1, ro_session->h_entry); - db_set_int_val(values, HASH_ID_COL_IDX - 1, ro_session->h_id); - db_set_str_val( - values, SESSION_ID_COL_IDX - 1, &ro_session->ro_session_id); - - if(ro_dbf.delete(ro_db_handle, match_keys, 0, values, 3) < 0) { - LM_ERR("failed to delete ro session database information... " - "continuing\n"); - return -1; - } } else { LM_WARN("Asked to update Ro session in strange state [%d]\n", ro_session->flags); @@ -321,3 +703,26 @@ int update_ro_dbinfo(struct ro_session *ro_session) ro_session_unlock(ro_session_table, &entry); return 0; } + +void ro_update_db(unsigned int ticks, void *param) +{ + int index; + struct ro_session_entry ro_session_entry; + struct ro_session *ro_session; + + for(index = 0; index < ro_session_table->size; index++) { + /* lock the whole ro_session_entry */ + ro_session_entry = (ro_session_table->entries)[index]; + ro_session_lock(ro_session_table, &ro_session_entry); + + for(ro_session = ro_session_entry.first; ro_session != NULL; + ro_session = ro_session->next) { + if(update_ro_dbinfo_unsafe(ro_session) != 0) { + LM_ERR("failed to update ro_session in DB\n"); + } + } + ro_session_unlock(ro_session_table, &ro_session_entry); + } + + return; +} diff --git a/src/modules/ims_charging/ro_db_handler.h b/src/modules/ims_charging/ro_db_handler.h index c00612bf2..399ddcfce 100644 --- a/src/modules/ims_charging/ro_db_handler.h +++ b/src/modules/ims_charging/ro_db_handler.h @@ -12,9 +12,9 @@ #include "../../lib/srdb1/db.h" #include "ro_session_hash.h" -#define RO_TABLE_VERSION 1 +#define RO_TABLE_VERSION 3 #define RO_SESSION_TABLE_NAME "ro_session" -#define RO_SESSION_TABLE_COL_NUM 18 +#define RO_SESSION_TABLE_COL_NUM 25 #define ID_COL "id" #define HASH_ENTRY_COL "hash_entry" @@ -34,6 +34,13 @@ #define SERVICE_IDENTIFIER_COL "service_identifier" #define INCOMING_TRUNK_ID_COL "incoming_trunk_id" #define OUTGOING_TRUNK_ID_COL "outgoing_trunk_id" +#define AUTH_APP_ID_COL "auth_app_id" +#define AUTH_SESSION_TYPE_COL "auth_session_type" +#define PANI_COL "pani" +#define MAC_COL "mac" +#define APP_PROVIDED_PARTY_COL "app_provided_party" +#define IS_FINAL_ALLOCATION_COL "is_final_allocation" +#define ORIGIN_HOST_COL "origin_host" int init_ro_db(const str *db_url, int dlg_hash_size, int db_update_period, int fetch_num_rows); @@ -41,5 +48,6 @@ int load_ro_info_from_db(int hash_size, int fetch_num_rows); int ro_connect_db(const str *db_url); int update_ro_dbinfo_unsafe(struct ro_session *ro_session); int update_ro_dbinfo(struct ro_session *ro_session); +void ro_update_db(unsigned int ticks, void *param); #endif /* RO_DB_HANDLER_H */ diff --git a/src/modules/ims_charging/ro_session_hash.c b/src/modules/ims_charging/ro_session_hash.c index 5d9a876ac..f8725b8f3 100644 --- a/src/modules/ims_charging/ro_session_hash.c +++ b/src/modules/ims_charging/ro_session_hash.c @@ -175,6 +175,9 @@ inline void destroy_ro_session(struct ro_session *ro_session) if(ro_session->ro_session_id.s && (ro_session->ro_session_id.len > 0)) { shm_free(ro_session->ro_session_id.s); } + if(ro_session->origin_host.s && (ro_session->origin_host.len > 0)) { + shm_free(ro_session->origin_host.s); + } shm_free(ro_session); } @@ -217,7 +220,7 @@ struct ro_session *build_new_ro_session(int direction, int auth_appid, unsigned int requested_secs, unsigned int validity_timeout, int active_rating_group, int active_service_identifier, str *incoming_trunk_id, str *outgoing_trunk_id, str *pani, - str *app_provided_party) + str *app_provided_party, int ro_timer_buffer) { LM_DBG("Building Ro Session **********\n"); char *p; @@ -263,6 +266,8 @@ struct ro_session *build_new_ro_session(int direction, int auth_appid, new_ro_session->h_id = 0; new_ro_session->ref = 1; + new_ro_session->ro_timer_buffer = ro_timer_buffer; + new_ro_session->rating_group = active_rating_group; new_ro_session->service_identifier = active_service_identifier; @@ -370,3 +375,42 @@ void free_impu_data(struct impu_data *impu_data) impu_data = 0; } } + +/*! + * \brief Lookup an Ro session in the global list by session id + * \param session_id diameter session id + * \return ro_session on success, NULL on failure + */ +struct ro_session *lookup_ro_session_by_session_id(str *session_id) +{ + struct ro_session *ro_session; + struct ro_session_entry *ro_session_entry; + int h_entry; + + for(h_entry = 0; h_entry < ro_session_table->size; h_entry++) { + ro_session_entry = &(ro_session_table->entries[h_entry]); + + ro_session_lock(ro_session_table, ro_session_entry); + + for(ro_session = ro_session_entry->first; ro_session; + ro_session = ro_session->next) { + if(strncmp(ro_session->ro_session_id.s, session_id->s, + session_id->len) + == 0 + && ro_session->ro_session_id.len == session_id->len) { + ref_ro_session(ro_session, 1, 0); + LM_DBG("ref ro_session %p with 1 -> %d\n", ro_session, + ro_session->ref); + ro_session_unlock(ro_session_table, ro_session_entry); + LM_DBG("ro_session id=%u found on entry %u\n", ro_session->h_id, + h_entry); + return ro_session; + } + } + ro_session_unlock(ro_session_table, ro_session_entry); + } + + LM_DBG("no ro_session for callid=%.*s found on entry %u\n", session_id->len, + session_id->s, h_entry); + return 0; +} diff --git a/src/modules/ims_charging/ro_session_hash.h b/src/modules/ims_charging/ro_session_hash.h index 883d04f18..c76edfded 100644 --- a/src/modules/ims_charging/ro_session_hash.h +++ b/src/modules/ims_charging/ro_session_hash.h @@ -85,6 +85,8 @@ struct ro_session unsigned int is_final_allocation; long billed; unsigned int ccr_sent; + str origin_host; + int ro_timer_buffer; }; /*! entries in the main ro_session table */ @@ -229,7 +231,7 @@ struct ro_session *build_new_ro_session(int direction, int auth_appid, unsigned int requested_secs, unsigned int validity_timeout, int active_rating_group, int active_service_identifier, str *incoming_trunk_id, str *outgoing_trunk_id, str *pani, - str *app_provided_party); + str *app_provided_party, int ro_timer_buffer); /*! * \brief Refefence a ro_session with locking @@ -256,6 +258,8 @@ void unref_ro_session_helper(struct ro_session *ro_session, unsigned int cnt, struct ro_session *lookup_ro_session( unsigned int h_entry, str *callid, int direction, unsigned int *del); +struct ro_session *lookup_ro_session_by_session_id(str *session_id); + void free_impu_data(struct impu_data *impu_data); int put_ro_session_on_wait(struct ro_session *session); diff --git a/src/modules/ims_charging/ro_timer.c b/src/modules/ims_charging/ro_timer.c index 4e5620456..ea625fc8f 100644 --- a/src/modules/ims_charging/ro_timer.c +++ b/src/modules/ims_charging/ro_timer.c @@ -333,13 +333,15 @@ void resume_ro_session_ontimeout( } else { int timer_timeout = i_req->new_credit; - if(i_req->new_credit > ro_timer_buffer /*TIMEOUTBUFFER*/) { + if(i_req->new_credit + > i_req->ro_session->ro_timer_buffer /*TIMEOUTBUFFER*/) { // We haven't finished using our 1st block of units, and we need to set the timer to - // (new_credit - ro_timer_buffer[5 secs]) to ensure we get new credit before our previous + // (new_credit - i_req->ro_session->ro_timer_buffer[5 secs]) to ensure we get new credit before our previous // reservation is exhausted. This will only be done the first time, because the timer // will always be fired 5 seconds before we run out of time thanks to this operation - timer_timeout = i_req->new_credit - ro_timer_buffer; + timer_timeout = + i_req->new_credit - i_req->ro_session->ro_timer_buffer; } ret = insert_ro_timer(&i_req->ro_session->ro_tl, timer_timeout); @@ -356,8 +358,8 @@ void resume_ro_session_ontimeout( ref_ro_session(i_req->ro_session, 1, 0); } + i_req->ro_session->flags |= RO_SESSION_FLAG_CHANGED; if(ro_db_mode == DB_MODE_REALTIME) { - i_req->ro_session->flags |= RO_SESSION_FLAG_CHANGED; if(update_ro_dbinfo_unsafe(i_req->ro_session) != 0) { LM_ERR("Failed to update Ro session in DB... continuing\n"); } diff --git a/src/modules/ims_dialog/README b/src/modules/ims_dialog/README index 1940e0e8c..666736116 100644 --- a/src/modules/ims_dialog/README +++ b/src/modules/ims_dialog/README @@ -58,11 +58,10 @@ Richard Good 5.11. db_mode (integer) 5.12. db_update_period (integer) 5.13. db_fetch_rows (integer) - 5.14. table_name (string) - 5.15. profiles_with_value (string) - 5.16. profiles_no_value (string) - 5.17. bridge_controller (string) - 5.18. initial_cbs_inscript (string) + 5.14. profiles_with_value (string) + 5.15. profiles_no_value (string) + 5.16. bridge_controller (string) + 5.17. initial_cbs_inscript (string) 6. Functions @@ -143,18 +142,22 @@ Richard Good 1.5. Set default_timeout parameter 1.6. Set dlf_extra_hdrs parameter 1.7. Set detect_spirals parameter - 1.8. Set profiles_with_value parameter - 1.9. Set profiles_no_value parameter - 1.10. Set bridge_controller parameter - 1.11. set_dlg_profile usage - 1.12. unset_dlg_profile usage - 1.13. is_in_profile usage - 1.14. get_profile_size usage - 1.15. dlg_isflagset usage - 1.16. dlg_setflag usage - 1.17. dlg_resetflag usage - 1.18. dlg_terminate usage - 1.19. dlg_get usage + 1.8. Set db_url parameter + 1.9. Set db_mode parameter + 1.10. Set db_update_period parameter + 1.11. Set db_fetch_rows parameter + 1.12. Set profiles_with_value parameter + 1.13. Set profiles_no_value parameter + 1.14. Set bridge_controller parameter + 1.15. set_dlg_profile usage + 1.16. unset_dlg_profile usage + 1.17. is_in_profile usage + 1.18. get_profile_size usage + 1.19. dlg_isflagset usage + 1.20. dlg_setflag usage + 1.21. dlg_resetflag usage + 1.22. dlg_terminate usage + 1.23. dlg_get usage Chapter 1. Admin Guide @@ -183,11 +186,10 @@ Chapter 1. Admin Guide 5.11. db_mode (integer) 5.12. db_update_period (integer) 5.13. db_fetch_rows (integer) - 5.14. table_name (string) - 5.15. profiles_with_value (string) - 5.16. profiles_no_value (string) - 5.17. bridge_controller (string) - 5.18. initial_cbs_inscript (string) + 5.14. profiles_with_value (string) + 5.15. profiles_no_value (string) + 5.16. bridge_controller (string) + 5.17. initial_cbs_inscript (string) 6. Functions @@ -327,11 +329,10 @@ Chapter 1. Admin Guide 5.11. db_mode (integer) 5.12. db_update_period (integer) 5.13. db_fetch_rows (integer) - 5.14. table_name (string) - 5.15. profiles_with_value (string) - 5.16. profiles_no_value (string) - 5.17. bridge_controller (string) - 5.18. initial_cbs_inscript (string) + 5.14. profiles_with_value (string) + 5.15. profiles_no_value (string) + 5.16. bridge_controller (string) + 5.17. initial_cbs_inscript (string) 5.1. enable_stats (integer) @@ -439,58 +440,100 @@ modparam("ims_dialog", "detect_spirals", 1) 5.10. db_url (string) - Db storage not yet supported by ims_dialog - this to be done in future. + In order to store information about dialogs in a database, a database + URL must be specified. + + Default value is “mysql://kamailio:kamailiorw@localhost/kamailio”. + + Example 1.8. Set db_url parameter + ... + modparam("ims_dialog", "db_url", "dbdriver://username:password@dbhost/dbname +") + ... 5.11. db_mode (integer) - Db storage not yet supported by ims_dialog - this to be done in future. + This is the database mode to be used for dialog persistent storage. + * 0 - NO_DB - the memory content is not flushed into DB; + * 1 - REALTIME - any dialog information changes will be reflected + into the database immediately. + * 2 - DELAYED - the dialog information changes will be flushed into + DB periodically, based on a timer routine. + * 3 - SHUTDOWN - the dialog information will be flushed into DB only + at shutdown - no runtime updates. + + Default value is “0”. + + Example 1.9. Set db_mode parameter + ... + modparam("ims_dialog", "db_mode", 1) + ... 5.12. db_update_period (integer) - Db storage not yet supported by ims_dialog - this to be done in future. + The interval (seconds) at which to update dialogs' information, if the + server is configured to store the dialog information at a given + interval. A too short interval will generate intensive database + operations, while an excessively long one will miss dialogs with a + short lifetime. + + Default value is “60” seconds. + + Example 1.10. Set db_update_period parameter + ... + modparam("ims_dialog", "db_update_period", 120) + ... 5.13. db_fetch_rows (integer) - Db storage not yet supported by ims_dialog - this to be done in future. + The number of the rows to be fetched at once from database when loading + the dialog records at startup from the database. This value can be used + to tune the load time at startup. For 1MB of private memory (default), + it should be below 400. The database driver must support the + fetch_result() capability. A value of 0 means the database fetch is not + limited. -5.14. table_name (string) + Default value is “200”. - Db storage not yet supported by ims_dialog - this to be done in future. + Example 1.11. Set db_fetch_rows parameter + ... + modparam("ims_dialog", "db_fetch_rows", 500) + ... -5.15. profiles_with_value (string) +5.14. profiles_with_value (string) List of names for profiles with values. Default value is “empty”. - Example 1.8. Set profiles_with_value parameter + Example 1.12. Set profiles_with_value parameter ... modparam("ims_dialog", "profiles_with_value", "caller ; my_profile") ... -5.16. profiles_no_value (string) +5.15. profiles_no_value (string) List of names for profiles without values. Default value is “empty”. - Example 1.9. Set profiles_no_value parameter + Example 1.13. Set profiles_no_value parameter ... modparam("ims_dialog", "profiles_no_value", "inbound ; outbound") ... -5.17. bridge_controller (string) +5.16. bridge_controller (string) SIP address to be used in From header when initiating a call bridge. Default value is “sip:controller@kamailio.org”. - Example 1.10. Set bridge_controller parameter + Example 1.14. Set bridge_controller parameter ... modparam("ims_dialog", "bridge_controller", "sip:ctd@kamailio.org") ... -5.18. initial_cbs_inscript (string) +5.17. initial_cbs_inscript (string) This has been deprecated since dlg_manage has been removed. @@ -526,7 +569,7 @@ modparam("ims_dialog", "bridge_controller", "sip:ctd@kamailio.org") This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, REPLY_ROUTE and FAILURE_ROUTE. - Example 1.11. set_dlg_profile usage + Example 1.15. set_dlg_profile usage ... set_dlg_profile("inbound_call"); set_dlg_profile("caller","$fu"); @@ -545,7 +588,7 @@ set_dlg_profile("caller","$fu"); This function can be used from BRANCH_ROUTE, REPLY_ROUTE and FAILURE_ROUTE. - Example 1.12. unset_dlg_profile usage + Example 1.16. unset_dlg_profile usage ... unset_dlg_profile("inbound_call"); unset_dlg_profile("caller","$fu"); @@ -568,7 +611,7 @@ unset_dlg_profile("caller","$fu"); This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, REPLY_ROUTE and FAILURE_ROUTE. - Example 1.13. is_in_profile usage + Example 1.17. is_in_profile usage ... if (is_in_profile("inbound_call")) { log("this request belongs to an inbound call\n"); @@ -597,7 +640,7 @@ if (is_in_profile("caller","XX")) { This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, REPLY_ROUTE and FAILURE_ROUTE. - Example 1.14. get_profile_size usage + Example 1.18. get_profile_size usage ... if(get_profile_size("inbound_call","$avp(size)")) xlog("currently there are $avp(size) inbound calls\n"); @@ -616,7 +659,7 @@ if(get_profile_size("caller","$fu","$avp(size)")) This function can be used from BRANCH_ROUTE, REQUEST_ROUTE, ONREPLY_ROUTE and FAILURE_ROUTE. - Example 1.15. dlg_isflagset usage + Example 1.19. dlg_isflagset usage ... if(dlg_isflagset("1")) { @@ -634,7 +677,7 @@ if(dlg_isflagset("1")) This function can be used from BRANCH_ROUTE, REQUEST_ROUTE, ONREPLY_ROUTE and FAILURE_ROUTE. - Example 1.16. dlg_setflag usage + Example 1.20. dlg_setflag usage ... dlg_setflag("1"); ... @@ -649,7 +692,7 @@ dlg_setflag("1"); This function can be used from BRANCH_ROUTE, REQUEST_ROUTE, ONREPLY_ROUTE and FAILURE_ROUTE. - Example 1.17. dlg_resetflag usage + Example 1.21. dlg_resetflag usage ... dlg_resetflag("1"); ... @@ -667,7 +710,7 @@ dlg_resetflag("1"); This function can be used from BRANCH_ROUTE, REQUEST_ROUTE, ONREPLY_ROUTE and FAILURE_ROUTE. - Example 1.18. dlg_terminate usage + Example 1.22. dlg_terminate usage ... dlg_terminate("all", "Insufficient QoS"); ... @@ -701,7 +744,7 @@ dlg_terminate("all", "Insufficient QoS"); This function can be used from BRANCH_ROUTE, REQUEST_ROUTE, ONREPLY_ROUTE and FAILURE_ROUTE. - Example 1.19. dlg_get usage + Example 1.23. dlg_get usage ... if(dlg_get("abcdef", "123", "456")) { @@ -1076,9 +1119,11 @@ Chapter 3. Frequently Asked Questions First at all check if your question was already answered on one of our mailing lists: * User Mailing List - - https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users + https://lists.kamailio.org/mailman3/postorius/lists/sr-users.lists. + kamailio.org/ * Developer Mailing List - - https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-dev + https://lists.kamailio.org/mailman3/postorius/lists/sr-dev.lists.ka + mailio.org/ E-mails regarding any stable Kamailio release should be sent to and e-mails regarding development diff --git a/src/modules/ims_dialog/dlg_db_handler.c b/src/modules/ims_dialog/dlg_db_handler.c index 70a4247a1..e65276091 100644 --- a/src/modules/ims_dialog/dlg_db_handler.c +++ b/src/modules/ims_dialog/dlg_db_handler.c @@ -643,6 +643,13 @@ static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows) } while(nr_rows > 0); + if(dlg_db_mode == DB_MODE_SHUTDOWN) { + if(dialog_dbf.delete(dialog_db_handle, 0, 0, 0, 0) < 0) { + LM_ERR("failed to clear dialog in table\n"); + goto error; + } + } + if(dlg != NULL) { d_entry = &(d_table->entries[dlg->h_entry]); dlg = d_entry->first; @@ -655,7 +662,7 @@ static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows) if(dlg_db_mode == DB_MODE_SHUTDOWN) { if(dialog_dbf.delete(dialog_db_handle, 0, 0, 0, 0) < 0) { - LM_ERR("failed to clear dialog table\n"); + LM_ERR("failed to clear dialog out table\n"); goto error; } } diff --git a/src/modules/ims_dialog/dlg_handlers.c b/src/modules/ims_dialog/dlg_handlers.c index 023c2019e..3487d7f4c 100644 --- a/src/modules/ims_dialog/dlg_handlers.c +++ b/src/modules/ims_dialog/dlg_handlers.c @@ -93,12 +93,10 @@ void destroy_dlg_handlers(void) * \param id dialog hash id * \return 0 on success, -1 on failure */ -static inline int add_dlg_rr_param( - struct sip_msg *req, unsigned int entry, unsigned int id) +static inline int add_dlg_rr_param(struct sip_msg *req, str did) { static char buf[RR_DLG_PARAM_SIZE]; str s; - int n; char *p; s.s = p = buf; @@ -108,22 +106,56 @@ static inline int add_dlg_rr_param( p += rr_param.len; *(p++) = '='; + memcpy(p, did.s, did.len); + p += did.len; + s.len = p - buf; + + if(s.len > RR_DLG_PARAM_SIZE) { + return -1; + } + + if(d_rrb.add_rr_param(req, &s) < 0) { + LM_ERR("failed to add rr param\n"); + return -1; + } + + return 0; +} + +/*! + * \brief Generate dialog id for dialog + * \param dlg dialog + * \return 0 on success, -1 on failure + */ +static inline int generate_did(struct dlg_cell *dlg) +{ + static char buf[RR_DLG_PARAM_SIZE]; + str s; + int n; + char *p; + + s.s = p = buf; + n = RR_DLG_PARAM_SIZE - (p - buf); - if(int2reverse_hex(&p, &n, entry) == -1) + if(int2reverse_hex(&p, &n, dlg->h_entry) == -1) return -1; *(p++) = DLG_SEPARATOR; n = RR_DLG_PARAM_SIZE - (p - buf); - if(int2reverse_hex(&p, &n, id) == -1) + if(int2reverse_hex(&p, &n, dlg->h_id) == -1) return -1; s.len = p - buf; - if(d_rrb.add_rr_param(req, &s) < 0) { - LM_ERR("failed to add rr param\n"); + dlg->did.s = (char *)shm_malloc(s.len); + if(!dlg->did.s) { + LM_ERR("no more shm_mem\n"); return -1; } + memset(dlg->did.s, 0, s.len); + memcpy(dlg->did.s, s.s, s.len); + dlg->did.len = s.len; return 0; } @@ -1668,7 +1700,7 @@ int dlg_new_dialog( //Add did to rr header for all spiralled requested INVITEs if(req->first_line.u.request.method_value == METHOD_INVITE) { - if(add_dlg_rr_param(req, dlg->h_entry, dlg->h_id) < 0) { + if(add_dlg_rr_param(req, dlg->did) < 0) { LM_ERR("failed to add RR param\n"); } } @@ -1735,6 +1767,8 @@ int dlg_new_dialog( // if (dlg_send_bye != 0 || _dlg_ctx.to_bye != 0) // dlg->iflags |= DLG_IFLAG_TIMEOUTBYE; + generate_did(dlg); + if(run_initial_cbs) run_create_callbacks(dlg, req); @@ -1742,7 +1776,7 @@ int dlg_new_dialog( /* first INVITE seen (dialog created, unconfirmed) */ if(seq_match_mode != SEQ_MATCH_NO_ID - && add_dlg_rr_param(req, dlg->h_entry, dlg->h_id) < 0) { + && add_dlg_rr_param(req, dlg->did) < 0) { LM_ERR("failed to add RR param\n"); goto error; } @@ -2067,3 +2101,22 @@ struct dlg_cell *dlg_get_msg_dialog(sip_msg_t *msg) } return dlg; } + +/*! + * \brief Get dialog based on hash entry and id + * \param h_entry number of the hash table entry + * \param h_id id of the hash table entry + * \return dialog structure on success, NULL on failure + */ + +struct dlg_cell *dlg_get_hash_dialog(unsigned int h_entry, unsigned int h_id) +{ + struct dlg_cell *dlg = NULL; + + dlg = lookup_dlg(h_entry, h_id); + if(dlg == NULL) { + LM_ERR("Unable to find dlg\n"); + return NULL; + } + return dlg; +} diff --git a/src/modules/ims_dialog/dlg_handlers.h b/src/modules/ims_dialog/dlg_handlers.h index 4a6bd78a0..a4686e46d 100644 --- a/src/modules/ims_dialog/dlg_handlers.h +++ b/src/modules/ims_dialog/dlg_handlers.h @@ -210,4 +210,12 @@ void internal_print_all_dlg(struct dlg_cell *dlg); */ struct dlg_cell *dlg_get_msg_dialog(sip_msg_t *msg); +/*! + * \brief Get dialog based on hash entry and id + * \param h_entry number of the hash table entry + * \param h_id id of the hash table entry + * \return dialog structure on success, NULL on failure + */ +struct dlg_cell *dlg_get_hash_dialog(unsigned int h_entry, unsigned int h_id); + #endif diff --git a/src/modules/ims_dialog/dlg_hash.c b/src/modules/ims_dialog/dlg_hash.c index 386c3ab26..6e9059ac0 100644 --- a/src/modules/ims_dialog/dlg_hash.c +++ b/src/modules/ims_dialog/dlg_hash.c @@ -513,8 +513,9 @@ struct dlg_cell_out *build_new_dlg_out( int len; char *p; - //len = sizeof (struct dlg_cell_out) +dlg->did.len + to_tag->len + to_uri->len; - len = sizeof(struct dlg_cell_out) + to_tag->len + to_uri->len + branch->len; + //branch might be unset, according to code in dlg_onreply() + len = sizeof(struct dlg_cell_out) + to_tag->len + to_uri->len + + (branch ? branch->len : 0); dlg_out = (struct dlg_cell_out *)shm_malloc(len); if(dlg_out == 0) { diff --git a/src/modules/ims_dialog/dlg_load.h b/src/modules/ims_dialog/dlg_load.h index be2d5f61c..4f62e5acc 100644 --- a/src/modules/ims_dialog/dlg_load.h +++ b/src/modules/ims_dialog/dlg_load.h @@ -42,6 +42,10 @@ typedef int (*ims_lookup_terminate_dlg_f)( /* get the current dialog based on message function prototype */ typedef struct dlg_cell *(*ims_get_dlg_f)(struct sip_msg *msg); +/* get dialog based on hash entry and id */ +typedef struct dlg_cell *(*ims_get_dlg_hash_f)( + unsigned int h_entry, unsigned int h_id); + /* get_dlg_lifetime function prototype */ typedef time_t (*ims_get_dlg_expires_f)(str *callid, str *ftag, str *ttag); @@ -57,6 +61,7 @@ typedef struct ims_dlg_binds ims_get_dlg_variable_f get_dlg_var; ims_get_dlg_expires_f get_dlg_expires; ims_get_dlg_f get_dlg; + ims_get_dlg_hash_f get_dlg_hash; ims_release_dlg_f release_dlg; } ims_dlg_api_t; diff --git a/src/modules/ims_dialog/doc/ims_dialog_admin.xml b/src/modules/ims_dialog/doc/ims_dialog_admin.xml index 6fa69dfbd..f59568d7a 100644 --- a/src/modules/ims_dialog/doc/ims_dialog_admin.xml +++ b/src/modules/ims_dialog/doc/ims_dialog_admin.xml @@ -351,8 +351,22 @@ modparam("ims_dialog", "detect_spirals", 1) db_url (string) - Db storage not yet supported by ims_dialog - this to be done in future. + In order to store information about dialogs in a database, + a database URL must be specified. + + + Default value is &defaultdb;. + + + + Set <varname>db_url</varname> parameter + + ... + modparam("ims_dialog", "db_url", "&exampledb;") + ... + +
@@ -360,8 +374,40 @@ modparam("ims_dialog", "detect_spirals", 1) db_mode (integer) - Db storage not yet supported by ims_dialog - this to be done in future. + This is the database mode to be used for dialog persistent storage. + + + 0 - NO_DB - the memory content is not + flushed into DB; + + + 1 - REALTIME - any dialog information + changes will be reflected into the database immediately. + + + 2 - DELAYED - the dialog information + changes will be flushed into DB periodically, based on a + timer routine. + + + 3 - SHUTDOWN - the dialog information + will be flushed into DB only at shutdown - no runtime updates. + + + + + Default value is 0. + + + + Set <varname>db_mode</varname> parameter + + ... + modparam("ims_dialog", "db_mode", 1) + ... + +
@@ -369,8 +415,24 @@ modparam("ims_dialog", "detect_spirals", 1) db_update_period (integer) - Db storage not yet supported by ims_dialog - this to be done in future. + The interval (seconds) at which to update dialogs' information, + if the server is configured to store the dialog information at a given interval. + A too short interval will generate intensive database operations, + while an excessively long one will miss dialogs with a short lifetime. + + + Default value is 60 seconds. + + + + Set <varname>db_update_period</varname> parameter + + ... + modparam("ims_dialog", "db_update_period", 120) + ... + +
@@ -378,17 +440,26 @@ modparam("ims_dialog", "detect_spirals", 1) db_fetch_rows (integer) - Db storage not yet supported by ims_dialog - this to be done in future. + The number of the rows to be fetched at once from database + when loading the dialog records at startup from the database. + This value can be used to tune the load time at startup. + For 1MB of private memory (default), it should be below 400. + The database driver must support the fetch_result() capability. + A value of 0 means the database fetch is not limited. -
- -
- - <varname>table_name</varname> (string) - - Db storage not yet supported by ims_dialog - this to be done in future. + + Default value is 200. + + + Set <varname>db_fetch_rows</varname> parameter + + ... + modparam("ims_dialog", "db_fetch_rows", 500) + ... + +
diff --git a/src/modules/ims_dialog/ims_dialog.c b/src/modules/ims_dialog/ims_dialog.c index ed76b3b5b..16a76a8cb 100644 --- a/src/modules/ims_dialog/ims_dialog.c +++ b/src/modules/ims_dialog/ims_dialog.c @@ -89,101 +89,105 @@ static int w_is_known_dlg(struct sip_msg *); static int pv_get_dlg_count( struct sip_msg *msg, pv_param_t *param, pv_value_t *res); +/* clang-format off */ static cmd_export_t cmds[] = { - {"set_dlg_profile", (cmd_function)w_set_dlg_profile, 1, fixup_profile, - 0, - REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"set_dlg_profile", (cmd_function)w_set_dlg_profile, 2, fixup_profile, - 0, - REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"unset_dlg_profile", (cmd_function)w_unset_dlg_profile, 1, - fixup_profile, 0, FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"unset_dlg_profile", (cmd_function)w_unset_dlg_profile, 2, - fixup_profile, 0, FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"is_in_profile", (cmd_function)w_is_in_profile, 1, fixup_profile, 0, - REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"is_in_profile", (cmd_function)w_is_in_profile, 2, fixup_profile, 0, - REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"get_profile_size", (cmd_function)w_get_profile_size2, 2, - fixup_get_profile2, 0, - REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"get_profile_size", (cmd_function)w_get_profile_size3, 3, - fixup_get_profile3, 0, - REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"dlg_setflag", (cmd_function)w_dlg_setflag, 1, fixup_igp_null, 0, - REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"dlg_resetflag", (cmd_function)w_dlg_resetflag, 1, fixup_igp_null, 0, - REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"dlg_isflagset", (cmd_function)w_dlg_isflagset, 1, fixup_igp_null, 0, - REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"dlg_terminate", (cmd_function)w_dlg_terminate, 1, fixup_dlg_terminate, - 0, - REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"dlg_terminate", (cmd_function)w_dlg_terminate, 2, fixup_dlg_terminate, - 0, - REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"dlg_get", (cmd_function)w_dlg_get, 3, fixup_dlg_bridge, 0, ANY_ROUTE}, - {"is_known_dlg", (cmd_function)w_is_known_dlg, 0, NULL, 0, - REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"load_ims_dlg", (cmd_function)load_ims_dlg, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0}}; - -static param_export_t mod_params[] = {{"hash_size", INT_PARAM, &dlg_hash_size}, - {"rr_param", PARAM_STRING, &rr_param}, - {"dlg_flag", INT_PARAM, &dlg_flag}, - {"timeout_avp", PARAM_STR, &timeout_spec}, - {"default_timeout", INT_PARAM, &default_timeout}, - {"dlg_extra_hdrs", PARAM_STR, &dlg_extra_hdrs}, - //In this new dialog module we always match using DID - {"dlg_match_mode", INT_PARAM, &seq_match_mode}, - - {"db_url", PARAM_STR, &db_url}, - {"db_mode", INT_PARAM, &dlg_db_mode_param}, - {"db_update_period", INT_PARAM, &db_update_period}, - {"db_fetch_rows", INT_PARAM, &db_fetch_rows}, - {"detect_spirals", INT_PARAM, &detect_spirals}, - {"profiles_with_value", PARAM_STRING, &profiles_wv_s}, - {"profiles_no_value", PARAM_STRING, &profiles_nv_s}, - {"bridge_controller", PARAM_STR, &dlg_bridge_controller}, - {"ruri_pvar", PARAM_STR, &ruri_pvar_param}, - - {0, 0, 0}}; + {"set_dlg_profile", (cmd_function)w_set_dlg_profile, 1, fixup_profile, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"set_dlg_profile", (cmd_function)w_set_dlg_profile, 2, fixup_profile, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"unset_dlg_profile", (cmd_function)w_unset_dlg_profile, 1, + fixup_profile, 0, FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"unset_dlg_profile", (cmd_function)w_unset_dlg_profile, 2, + fixup_profile, 0, FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"is_in_profile", (cmd_function)w_is_in_profile, 1, fixup_profile, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"is_in_profile", (cmd_function)w_is_in_profile, 2, fixup_profile, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"get_profile_size", (cmd_function)w_get_profile_size2, 2, + fixup_get_profile2, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"get_profile_size", (cmd_function)w_get_profile_size3, 3, + fixup_get_profile3, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"dlg_setflag", (cmd_function)w_dlg_setflag, 1, fixup_igp_null, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"dlg_resetflag", (cmd_function)w_dlg_resetflag, 1, fixup_igp_null, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"dlg_isflagset", (cmd_function)w_dlg_isflagset, 1, fixup_igp_null, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"dlg_terminate", (cmd_function)w_dlg_terminate, 1, fixup_dlg_terminate, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"dlg_terminate", (cmd_function)w_dlg_terminate, 2, fixup_dlg_terminate, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"dlg_get", (cmd_function)w_dlg_get, 3, fixup_dlg_bridge, 0, ANY_ROUTE}, + {"is_known_dlg", (cmd_function)w_is_known_dlg, 0, NULL, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"load_ims_dlg", (cmd_function)load_ims_dlg, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} +}; + +static param_export_t mod_params[] = { + {"hash_size", INT_PARAM, &dlg_hash_size}, + {"rr_param", PARAM_STRING, &rr_param}, + {"dlg_flag", INT_PARAM, &dlg_flag}, + {"timeout_avp", PARAM_STR, &timeout_spec}, + {"default_timeout", INT_PARAM, &default_timeout}, + {"dlg_extra_hdrs", PARAM_STR, &dlg_extra_hdrs}, + //In this new dialog module we always match using DID + {"dlg_match_mode", INT_PARAM, &seq_match_mode}, + + {"db_url", PARAM_STR, &db_url}, + {"db_mode", INT_PARAM, &dlg_db_mode_param}, + {"db_update_period", INT_PARAM, &db_update_period}, + {"db_fetch_rows", INT_PARAM, &db_fetch_rows}, + {"detect_spirals", INT_PARAM, &detect_spirals}, + {"profiles_with_value", PARAM_STRING, &profiles_wv_s}, + {"profiles_no_value", PARAM_STRING, &profiles_nv_s}, + {"bridge_controller", PARAM_STR, &dlg_bridge_controller}, + {"ruri_pvar", PARAM_STR, &ruri_pvar_param}, + + {0, 0, 0} +}; #ifdef MI_REMOVED static mi_export_t mi_cmds[] = { - {"dlg_list", mi_print_dlgs, 0, 0, 0}, - {"dlg_terminate_dlg", mi_terminate_dlg, 0, 0, 0}, {0, 0, 0, 0, 0} - /* TODO: restore old dialog functionality later - also expose dialog_out cmds, possibly*/ + {"dlg_list", mi_print_dlgs, 0, 0, 0}, + {"dlg_terminate_dlg", mi_terminate_dlg, 0, 0, 0}, + {0, 0, 0, 0, 0} }; #endif static rpc_export_t rpc_methods[]; static pv_export_t mod_items[] = { - {{"DLG_count", sizeof("DLG_count") - 1}, PVT_OTHER, pv_get_dlg_count, 0, - 0, 0, 0, 0}, - {{"DLG_lifetime", sizeof("DLG_lifetime") - 1}, PVT_OTHER, - pv_get_dlg_lifetime, 0, 0, 0, 0, 0}, - {{"DLG_status", sizeof("DLG_status") - 1}, PVT_OTHER, pv_get_dlg_status, - 0, 0, 0, 0, 0}, - {{"dlg_ctx", sizeof("dlg_ctx") - 1}, PVT_OTHER, pv_get_dlg_ctx, - pv_set_dlg_ctx, pv_parse_dlg_ctx_name, 0, 0, 0}, - {{"dlg", sizeof("dlg") - 1}, PVT_OTHER, pv_get_dlg, 0, - pv_parse_dlg_name, 0, 0, 0}, - {{"dlg_var", sizeof("dlg_var") - 1}, PVT_OTHER, pv_get_dlg_variable, - pv_set_dlg_variable, pv_parse_dialog_var_name, 0, 0, 0}, - {{0, 0}, 0, 0, 0, 0, 0, 0, 0}}; - -struct module_exports exports = {"ims_dialog", /* module's name */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* exported functions */ - mod_params, /* param exports */ - 0, /* exported RPC methods */ - mod_items, /* exported pseudo-variables */ - 0, /* reply processing function */ - mod_init, /* module initialization function */ - child_init, /* per-child init function */ - mod_destroy}; + {{"DLG_count", sizeof("DLG_count") - 1}, PVT_OTHER, pv_get_dlg_count, 0, + 0, 0, 0, 0}, + {{"DLG_lifetime", sizeof("DLG_lifetime") - 1}, PVT_OTHER, + pv_get_dlg_lifetime, 0, 0, 0, 0, 0}, + {{"DLG_status", sizeof("DLG_status") - 1}, PVT_OTHER, pv_get_dlg_status, + 0, 0, 0, 0, 0}, + {{"dlg_ctx", sizeof("dlg_ctx") - 1}, PVT_OTHER, pv_get_dlg_ctx, + pv_set_dlg_ctx, pv_parse_dlg_ctx_name, 0, 0, 0}, + {{"dlg", sizeof("dlg") - 1}, PVT_OTHER, pv_get_dlg, 0, + pv_parse_dlg_name, 0, 0, 0}, + {{"dlg_var", sizeof("dlg_var") - 1}, PVT_OTHER, pv_get_dlg_variable, + pv_set_dlg_variable, pv_parse_dialog_var_name, 0, 0, 0}, + {{0, 0}, 0, 0, 0, 0, 0, 0, 0} +}; + +struct module_exports exports = { + "ims_dialog", /* module's name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* exported functions */ + mod_params, /* param exports */ + 0, /* exported RPC methods */ + mod_items, /* exported pseudo-variables */ + 0, /* reply processing function */ + mod_init, /* module initialization function */ + child_init, /* per-child init function */ + mod_destroy /* destroy function */ +}; +/* clang-format on */ static int fixup_profile(void **param, int param_no) { @@ -355,6 +359,7 @@ int load_ims_dlg(ims_dlg_api_t *dlgb) dlgb->lookup_terminate_dlg = w_api_lookup_terminate_dlg; dlgb->get_dlg_expires = api_get_dlg_expires; dlgb->get_dlg = dlg_get_msg_dialog; + dlgb->get_dlg_hash = dlg_get_hash_dialog; dlgb->release_dlg = dlg_release; return 1; @@ -1044,12 +1049,15 @@ static void rpc_end_all_active_dlg(rpc_t *rpc, void *c) LM_DBG("Terminated %d active dialogs from rpc call", i_count); } +/* clang-format off */ static rpc_export_t rpc_methods[] = { - {"dlg2.list", rpc_print_dlgs, rpc_print_dlgs_doc, 0}, - {"dlg2.end_dlg", rpc_end_dlg_entry_id, rpc_end_dlg_entry_id_doc, 0}, - {"dlg2.end_all_active_dlg", rpc_end_all_active_dlg, + {"dlg2.list", rpc_print_dlgs, rpc_print_dlgs_doc, 0}, + {"dlg2.end_dlg", rpc_end_dlg_entry_id, rpc_end_dlg_entry_id_doc, 0}, + {"dlg2.end_all_active_dlg", rpc_end_all_active_dlg, rpc_end_all_active_dlg_doc, 0}, - {0, 0, 0, 0}}; + {0, 0, 0, 0} +}; +/* clang-format on */ static int ki_is_known_dlg(sip_msg_t *msg) @@ -1060,7 +1068,6 @@ static int ki_is_known_dlg(sip_msg_t *msg) static int ki_set_dlg_profile(sip_msg_t *msg, str *sprofile, str *svalue) { struct dlg_profile_table *profile = NULL; - pv_elem_t *pvvalue = NULL; if(sprofile == NULL || sprofile->s == NULL || sprofile->len <= 0) { LM_ERR("invalid profile identifier\n"); @@ -1072,14 +1079,18 @@ static int ki_set_dlg_profile(sip_msg_t *msg, str *sprofile, str *svalue) LM_CRIT("profile <%.*s> not defined\n", sprofile->len, sprofile->s); return -1; } - - if(pv_parse_format(svalue, &pvvalue) || pvvalue == NULL) { - LM_ERR("wrong format [%.*s] for value param!\n", svalue->len, - svalue->s); - return -1; + if(svalue != NULL && svalue->len > 0) { + if(set_dlg_profile(msg, svalue, profile) < 0) { + LM_ERR("failed to set profile with value\n"); + return -1; + } + } else { + if(set_dlg_profile(msg, NULL, profile) < 0) { + LM_ERR("failed to set profile\n"); + return -1; + } } - - return w_set_dlg_profile(msg, (char *)profile, (char *)pvvalue); + return 1; } static int ki_get_profile_size( @@ -1087,8 +1098,9 @@ static int ki_get_profile_size( { struct dlg_profile_table *profile = NULL; - pv_elem_t *pvvalue = NULL; pv_spec_t *pvs = NULL; + unsigned int size; + pv_value_t val; if(sprofile == NULL || sprofile->s == NULL || sprofile->len <= 0) { LM_ERR("invalid profile identifier\n"); @@ -1103,11 +1115,6 @@ static int ki_get_profile_size( LM_CRIT("profile <%.*s> not defined\n", sprofile->len, sprofile->s); return -1; } - if(pv_parse_format(svalue, &pvvalue) || pvvalue == NULL) { - LM_ERR("wrong format [%.*s] for value param!\n", svalue->len, - svalue->s); - return -1; - } pvs = pv_cache_get(spv); if(pvs == NULL) { LM_ERR("cannot get pv spec for [%.*s]\n", spv->len, spv->s); @@ -1117,9 +1124,22 @@ static int ki_get_profile_size( LM_ERR("return must be an AVP or SCRIPT VAR!\n"); return -1; } + if(svalue != NULL && svalue->len > 0 && profile->has_value != 0) { + size = get_profile_size(profile, svalue); + } else { + size = get_profile_size(profile, NULL); + } - return w_get_profile_size3( - msg, (char *)profile, (char *)pvvalue, (char *)pvs); + memset(&val, 0, sizeof(pv_value_t)); + val.flags = PV_VAL_INT | PV_TYPE_INT; + val.ri = (long)size; + + if(pvs->setf(msg, &pvs->pvp, (int)EQ_T, &val) < 0) { + LM_ERR("setting profile PV failed\n"); + return -1; + } + + return 1; } /* clang-format off */ diff --git a/src/modules/ims_ipsec_pcscf/README b/src/modules/ims_ipsec_pcscf/README index 81c0cb4cb..8dd070ffe 100644 --- a/src/modules/ims_ipsec_pcscf/README +++ b/src/modules/ims_ipsec_pcscf/README @@ -58,7 +58,9 @@ Tsvetomir Dimitrov 4.1. ipsec_create(domain) 4.2. ipsec_forward(domain, flags) - 4.3. ipsec_destroy(domain) + 4.3. ipsec_destroy(domain [, aor]) + 4.4. ipsec_destroy_by_contact(domain, aor, recv_host, + recv_port) List of Examples @@ -75,6 +77,7 @@ Tsvetomir Dimitrov 1.11. ipsec_create 1.12. ipsec_forward 1.13. ipsec_destroy + 1.14. ipsec_destroy_by_contact() Chapter 1. Admin Guide @@ -103,7 +106,8 @@ Chapter 1. Admin Guide 4.1. ipsec_create(domain) 4.2. ipsec_forward(domain, flags) - 4.3. ipsec_destroy(domain) + 4.3. ipsec_destroy(domain [, aor]) + 4.4. ipsec_destroy_by_contact(domain, aor, recv_host, recv_port) 1. Overview @@ -270,7 +274,8 @@ modparam("ims_ipsec_pcscf", "ipsec_preferred_ealg", "aes-cbc") 4.1. ipsec_create(domain) 4.2. ipsec_forward(domain, flags) - 4.3. ipsec_destroy(domain) + 4.3. ipsec_destroy(domain [, aor]) + 4.4. ipsec_destroy_by_contact(domain, aor, recv_host, recv_port) 4.1. ipsec_create(domain) @@ -316,6 +321,10 @@ ipsec_create("location", "1"); requests. + 0x80 (128) - set transport parameter in the new dst uri for TCP requests. + + 0x100 (256) - use Via attributes (port and protocol) for + routing UDP reply. + + 0x200 (512) - try TCP if corresponding UDP socket is not + found. This is an optional parameter, default value - 0. Example 1.12. ipsec_forward @@ -325,15 +334,36 @@ ipsec_forward("location"); ipsec_forward("location", "1"); ... -4.3. ipsec_destroy(domain) +4.3. ipsec_destroy(domain [, aor]) The function destroys IPSec tunnel, created with ipsec_create. 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. + aor - SIP URI to match the record. If not provided, then R-URI is + used. Example 1.13. ipsec_destroy ... ipsec_destroy("location"); ... + +4.4. ipsec_destroy_by_contact(domain, aor, recv_host, recv_port) + + The function destroys IPSec tunnel, created with ipsec_create. + + 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. + aor - SIP URI to match the record. + recv_host - received host to match the record. + recv_port - received port to match the record. + + The last three parameters have to be string valies and can contain + variables. + + Example 1.14. ipsec_destroy_by_contact() +... +ipsec_destroy_by_contact("location", "...", "...", "..."); +... diff --git a/src/modules/ims_ipsec_pcscf/cmd.c b/src/modules/ims_ipsec_pcscf/cmd.c index 42db0b175..4f7301b56 100644 --- a/src/modules/ims_ipsec_pcscf/cmd.c +++ b/src/modules/ims_ipsec_pcscf/cmd.c @@ -92,6 +92,10 @@ extern struct tm_binds tmb; #define IPSEC_TCPPORT_UEC (1 << 6) /* if set - build new dst uri with transport parameter for TCP */ #define IPSEC_SETDSTURI_FULL (1 << 7) +/* if set - use Via attributes for routing reply */ +#define IPSEC_FORWARD_USEVIA (1 << 8) +/* if set - try TCP if corresponding UDP socket is not found */ +#define IPSEC_FORWARD_TRYTCP (1 << 9) /* if set - delete unused tunnels before every registration */ #define IPSEC_CREATE_DELETE_UNUSED_TUNNELS 0x01 @@ -162,12 +166,15 @@ static str get_www_auth_param(const char *param_name, str www_auth) } static int fill_contact( - pcontact_info_t *ci, sip_msg_t *m, tm_cell_t *t, int sflags) + pcontact_info_t *ci, sip_msg_t *m, tm_cell_t *t, str *ruri, int sflags) { contact_body_t *cb = NULL; struct via_body *vb = NULL; - struct sip_msg *req = NULL; char *srcip = NULL; + str aor = STR_NULL; + sip_msg_t tmsg; + char tbuf[BUF_SIZE]; + int i; if(!ci) { LM_ERR("called with null ptr\n"); @@ -183,8 +190,13 @@ static int fill_contact( memset(&uri, 0, sizeof(struct sip_uri)); - if((sflags & IPSEC_DSTADDR_SEARCH) && m->dst_uri.s != NULL - && m->dst_uri.len > 0) { + if(ruri != NULL && ruri->len > 0) { + suri.s = ruri->s; + suri.len = ruri->len; + LM_DBG("using param r-uri for contact filling: %.*s\n", suri.len, + suri.s); + } else if((sflags & IPSEC_DSTADDR_SEARCH) && m->dst_uri.s != NULL + && m->dst_uri.len > 0) { suri = m->dst_uri; LM_DBG("using dst uri for contact filling: %.*s\n", suri.len, suri.s); @@ -204,13 +216,14 @@ static int fill_contact( return -1; } - req = m; - // populate host,port, aor in CI ci->via_host = uri.host; ci->via_port = uri.port_no ? uri.port_no : 5060; ci->via_prot = 0; - ci->aor = m->first_line.u.request.uri; + if(pkg_str_dup(&aor, &suri) < 0) { + LM_ERR("failed to duplicate aor\n"); + return -1; + } ci->searchflag = SEARCH_NORMAL; if(ci->via_host.s == NULL || ci->via_host.len == 0) { @@ -218,7 +231,7 @@ static int fill_contact( vb = cscf_get_ue_via(m); if(!vb) { LM_ERR("Reply No via body headers\n"); - return -1; + goto error; } // populate CI with bare minimum @@ -233,7 +246,7 @@ static int fill_contact( } if(alias_start != NULL && *(alias_start - 1) == ';') { char *p, *port_s, *proto_s; - char portbuf[5]; + char portbuf[6]; str alias_s; LM_DBG("contact has an alias [%.*s] - use that as the received\n", @@ -248,7 +261,7 @@ static int fill_contact( if(ci->received_host.len > IP6_MAX_STR_SIZE + 2) { LM_ERR("Invalid length for source IP address\n"); - return -1; + goto error; } if((srcip = pkg_malloc(50)) == NULL) { @@ -262,12 +275,16 @@ static int fill_contact( port_s = p + 1; p = _strnistr(port_s, "~", alias_s.len - ci->received_host.len); if(p != NULL) { - memset(portbuf, 0, 5); + if((p - port_s) > 5) { + LM_ERR("invalid port value\n"); + goto error; + } + memset(portbuf, 0, 6); memcpy(portbuf, port_s, (p - port_s)); ci->received_port = atoi(portbuf); proto_s = p + 1; - memset(portbuf, 0, 5); + memset(portbuf, 0, 6); memcpy(portbuf, proto_s, 1); ci->received_proto = atoi(portbuf); @@ -281,27 +298,45 @@ static int fill_contact( } else { if((srcip = pkg_malloc(50)) == NULL) { LM_ERR("Error allocating memory for source IP address\n"); - return -1; + goto error; } - ci->received_host.len = ip_addr2sbuf(&req->rcv.src_ip, srcip, 50); + ci->received_host.len = ip_addr2sbuf(&m->rcv.src_ip, srcip, 50); ci->received_host.s = srcip; - ci->received_port = req->rcv.src_port; - ci->received_proto = req->rcv.proto; + ci->received_port = m->rcv.src_port; + ci->received_proto = m->rcv.proto; } } else if(m->first_line.type == SIP_REPLY) { if(!t || t == (void *)-1) { LM_ERR("Reply without transaction\n"); - return -1; + goto error; } - req = t->uas.request; - - cb = cscf_parse_contacts(req); + if(t->uas.request->len >= BUF_SIZE - 1) { + LM_ERR("message too long\n"); + goto error; + } + memset(&tmsg, 0, sizeof(sip_msg_t)); + tmsg.buf = tbuf; + memcpy(tmsg.buf, t->uas.request->buf, t->uas.request->len); + tmsg.buf[t->uas.request->len] = '\0'; + tmsg.len = t->uas.request->len; + if(parse_msg(tmsg.buf, tmsg.len, &tmsg) != 0) { + LM_ERR("buffer parsing failed!"); + goto error; + } + cb = cscf_parse_contacts(&tmsg); if(!cb || (!cb->contacts)) { LM_ERR("Reply No contact headers\n"); - return -1; + free_sip_msg(&tmsg); + goto error; + } + if(pkg_str_dup(&aor, &cb->contacts->uri) < 0) { + LM_ERR("failed to duplicate aor\n"); + free_sip_msg(&tmsg); + goto error; } + free_sip_msg(&tmsg); vb = cscf_get_ue_via(m); if(!vb) { @@ -313,7 +348,6 @@ static int fill_contact( ci->via_host = vb->host; ci->via_port = vb->port; ci->via_prot = vb->proto; - ci->aor = cb->contacts->uri; ci->searchflag = SEARCH_RECEIVED; if((srcip = pkg_malloc(50)) == NULL) { @@ -321,15 +355,25 @@ static int fill_contact( return -1; } - ci->received_host.len = ip_addr2sbuf(&req->rcv.src_ip, srcip, 50); + ci->received_host.len = + ip_addr2sbuf(&t->uas.request->rcv.src_ip, srcip, 50); ci->received_host.s = srcip; - ci->received_port = req->rcv.src_port; - ci->received_proto = req->rcv.proto; + ci->received_port = t->uas.request->rcv.src_port; + ci->received_proto = t->uas.request->rcv.proto; } else { LM_ERR("Unknown first line type: %d\n", m->first_line.type); - return -1; + goto error; } + for(i = 4; i < aor.len; i++) { + if(aor.s[i] == ';') { + aor.len = i; + break; + } + } + + ci->aor = aor; + LM_DBG("SIP %s fill contact with AOR [%.*s], VIA [%d://%.*s:%d], " "received_host [%d://%.*s:%d]\n", m->first_line.type == SIP_REQUEST ? "REQUEST" : "REPLY", @@ -341,8 +385,18 @@ static int fill_contact( if(ci->received_port == 0) ci->received_port = 5060; - return 0; + +error: + if(aor.s != NULL) { + pkg_free(aor.s); + } + if(srcip != NULL) { + pkg_free(srcip); + } + ci->aor.s = NULL; + ci->received_host.s = NULL; + return -1; } // Get CK and IK from WWW-Authenticate @@ -496,6 +550,35 @@ static int create_ipsec_tunnel(const struct ip_addr *remote_addr, ipsec_t *s) add_policy(sock, remote_addr, ipsec_addr, s->port_us, s->port_pc, s->spi_pc, IPSEC_POLICY_DIRECTION_IN); + /* cope with some broken In-Dialog routing */ + // SA5 UE client to P-CSCF client + // src adrr dst addr src port dst port + add_sa(sock, remote_addr, ipsec_addr, s->port_uc, s->port_pc, s->spi_ps, + s->ck, s->ik, s->r_alg, s->r_ealg); + add_policy(sock, remote_addr, ipsec_addr, s->port_uc, s->port_pc, s->spi_ps, + IPSEC_POLICY_DIRECTION_IN); + + // SA6 P-CSCF client to UE client + // src adrr dst addr src port dst port + add_sa(sock, ipsec_addr, remote_addr, s->port_pc, s->port_uc, s->spi_us, + s->ck, s->ik, s->r_alg, s->r_ealg); + add_policy(sock, ipsec_addr, remote_addr, s->port_pc, s->port_uc, s->spi_us, + IPSEC_POLICY_DIRECTION_OUT); + + // SA7 P-CSCF server to UE server + // src adrr dst addr src port dst port + add_sa(sock, ipsec_addr, remote_addr, s->port_ps, s->port_us, s->spi_uc, + s->ck, s->ik, s->r_alg, s->r_ealg); + add_policy(sock, ipsec_addr, remote_addr, s->port_ps, s->port_us, s->spi_uc, + IPSEC_POLICY_DIRECTION_OUT); + + // SA8 UE server to P-CSCF server + // src adrr dst addr src port dst port + add_sa(sock, remote_addr, ipsec_addr, s->port_us, s->port_ps, s->spi_pc, + s->ck, s->ik, s->r_alg, s->r_ealg); + add_policy(sock, remote_addr, ipsec_addr, s->port_us, s->port_ps, s->spi_pc, + IPSEC_POLICY_DIRECTION_IN); + close_mnl_socket(sock); return 0; @@ -557,6 +640,31 @@ static int destroy_ipsec_tunnel( remove_policy(sock, remote_addr, ipsec_addr, s->port_us, s->port_pc, s->spi_pc, ip_addr.af, IPSEC_POLICY_DIRECTION_IN); + /* cope with some broken In-Dialog routing */ + // SA5 UE client to P-CSCF client + remove_sa(sock, remote_addr, ipsec_addr, s->port_uc, s->port_pc, s->spi_ps, + ip_addr.af); + remove_policy(sock, remote_addr, ipsec_addr, s->port_uc, s->port_pc, + s->spi_ps, ip_addr.af, IPSEC_POLICY_DIRECTION_IN); + + // SA6 P-CSCF client to UE client + remove_sa(sock, ipsec_addr, remote_addr, s->port_pc, s->port_uc, s->spi_us, + ip_addr.af); + remove_policy(sock, ipsec_addr, remote_addr, s->port_pc, s->port_uc, + s->spi_us, ip_addr.af, IPSEC_POLICY_DIRECTION_OUT); + + // SA7 P-CSCF server to UE server + remove_sa(sock, ipsec_addr, remote_addr, s->port_ps, s->port_us, s->spi_uc, + ip_addr.af); + remove_policy(sock, ipsec_addr, remote_addr, s->port_ps, s->port_us, + s->spi_uc, ip_addr.af, IPSEC_POLICY_DIRECTION_OUT); + + // SA8 UE server to P-CSCF server + remove_sa(sock, remote_addr, ipsec_addr, s->port_us, s->port_ps, s->spi_pc, + ip_addr.af); + remove_policy(sock, remote_addr, ipsec_addr, s->port_us, s->port_ps, + s->spi_pc, ip_addr.af, IPSEC_POLICY_DIRECTION_IN); + // Release SPIs release_spi(s->spi_pc, s->spi_ps, s->port_pc, s->port_ps); @@ -665,7 +773,8 @@ int add_security_server_header(struct sip_msg *m, ipsec_t *s) memset(sec_hdr_buf, 0, sizeof(sec_hdr_buf)); sec_header->len = snprintf(sec_hdr_buf, sizeof(sec_hdr_buf) - 1, "Security-Server: " - "ipsec-3gpp;prot=esp;mod=trans;spi-c=%d;spi-s=%d;port-c=%d;port-s=%" + "ipsec-3gpp;q=0.1;prot=esp;mod=trans;spi-c=%d;spi-s=%d;port-c=%d;" + "port-s=%" "d;alg=%.*s;ealg=%.*s\r\n", s->spi_pc, s->spi_ps, s->port_pc, s->port_ps, s->r_alg.len, s->r_alg.s, s->r_ealg.len, s->r_ealg.s); @@ -697,12 +806,16 @@ int ipsec_create(struct sip_msg *m, udomain_t *d, int _cflags) struct pcontact_info ci; int ret = IPSEC_CMD_FAIL; // FAIL by default tm_cell_t *t = NULL; + sip_msg_t *req = NULL; + security_t *req_sec_params = NULL; + ipsec_t *s = NULL; + ipsec_t *old_s = NULL; if(m->first_line.type == SIP_REPLY) { t = tmb.t_gett(); } // Find the contact - if(fill_contact(&ci, m, t, _cflags) != 0) { + if(fill_contact(&ci, m, t, NULL, _cflags) != 0) { LM_ERR("Error filling in contact data\n"); return ret; } @@ -738,15 +851,15 @@ int ipsec_create(struct sip_msg *m, udomain_t *d, int _cflags) goto cleanup; } - struct sip_msg *req = t->uas.request; + req = t->uas.request; // Parse security parameters from the REGISTER request and get some data for the new tunnels - security_t *req_sec_params = cscf_get_security(req); - ipsec_t *s; - ipsec_t *old_s = NULL; + req_sec_params = cscf_get_security(req); // Update contacts only for initial registration, for re-registration the existing contacts shouldn't be updated. - if(ci.via_port == SIP_PORT) { + if(ci.via_port == SIP_PORT + || (pcontact->security_temp->data.ipsec->port_ps == 0 + && pcontact->security_temp->data.ipsec->port_pc == 0)) { LM_DBG("Registration for contact with AOR [%.*s], VIA [%d://%.*s:%d], " "received_host [%d://%.*s:%d]\n", ci.aor.len, ci.aor.s, ci.via_prot, ci.via_host.len, @@ -822,6 +935,7 @@ cleanup: // Do not free str* sec_header! It will be freed in data_lump.c -> free_lump() ul.unlock_udomain(d, &ci.via_host, ci.via_port, ci.via_prot); pkg_free(ci.received_host.s); + pkg_free(ci.aor.s); if(t) { tmb.t_uas_request_clean_parsed(t); } @@ -839,19 +953,19 @@ int ipsec_forward(struct sip_msg *m, udomain_t *d, int _cflags) unsigned short src_port = 0; ip_addr_t via_host; struct sip_msg *req = NULL; - struct cell *t = NULL; + tm_cell_t *t = NULL; struct socket_info *client_sock = NULL; + via_body_t *vb = NULL; LM_DBG("processing with flags: 0x%x\n", _cflags); if(m->first_line.type == SIP_REPLY) { // Get request from reply t = tmb.t_gett(); - if(!t) { + if(t == NULL || t == T_UNDEFINED) { LM_ERR("Error getting transaction\n"); return ret; } - req = t->uas.request; } else { req = m; @@ -860,7 +974,7 @@ int ipsec_forward(struct sip_msg *m, udomain_t *d, int _cflags) // // Find the contact // - if(fill_contact(&ci, m, t, _cflags) != 0) { + if(fill_contact(&ci, m, t, NULL, _cflags) != 0) { LM_ERR("Error filling in contact data\n"); return ret; } @@ -902,52 +1016,109 @@ int ipsec_forward(struct sip_msg *m, udomain_t *d, int _cflags) // from URI //int uri_len = 4 /* strlen("sip:") */ + ci.via_host.len + 5 /* max len of port number */ ; - if(!(_cflags & IPSEC_NODSTURI_RESET) && (m->dst_uri.s != NULL)) { - LM_DBG("resetting dst uri [%.*s]\n", m->dst_uri.len, m->dst_uri.s); - pkg_free(m->dst_uri.s); - m->dst_uri.s = NULL; - m->dst_uri.len = 0; + if(_cflags & IPSEC_FORWARD_USEVIA) { + vb = cscf_get_last_via(m); } if(m->first_line.type == SIP_REPLY) { - // for Reply get the dest proto from the received request - dst_proto = req->rcv.proto; - - // for Reply and TCP sends from P-CSCF server port, for Reply and UDP sends from P-CSCF client port - src_port = dst_proto == PROTO_TCP ? s->port_ps : s->port_pc; + if(_cflags & IPSEC_FORWARD_USEVIA) { + dst_proto = vb ? vb->proto : req->rcv.proto; + + // As per ETSI TS 133 203 V11.2.0, 7.1 Security association parameters + // https://tools.ietf.org/html/rfc3261#section-18 + // From Reply and TCP send via the same ports Request was recevied. + if(dst_proto == PROTO_TCP) { + src_port = req->rcv.dst_port; + dst_port = req->rcv.src_port; + } else { + src_port = s->port_pc; + if(vb + && ((vb->port == s->port_uc) + || (vb->port == s->port_us))) { + dst_port = vb->port; + } else { + dst_port = s->port_us; + } + } + } else { + // for Reply get the dest proto from the received request + dst_proto = req->rcv.proto; + // for Reply and TCP sends from P-CSCF server port, for Reply and UDP sends from P-CSCF client port + src_port = dst_proto == PROTO_TCP ? s->port_ps : s->port_pc; - // for Reply and TCP sends to UE client port, for Reply and UDP sends to UE server port - dst_port = dst_proto == PROTO_TCP ? s->port_uc : s->port_us; + // for Reply and TCP sends to UE client port, for Reply and UDP sends to UE server port + dst_port = dst_proto == PROTO_TCP ? s->port_uc : s->port_us; - // Check send socket - client_sock = - grep_sock_info(via_host.af == AF_INET ? &ipsec_listen_addr - : &ipsec_listen_addr6, - src_port, dst_proto); - if(!client_sock) { - src_port = s->port_pc; - dst_port = s->port_us; + // Check send socket + client_sock = + grep_sock_info(via_host.af == AF_INET ? &ipsec_listen_addr + : &ipsec_listen_addr6, + src_port, dst_proto); + if(!client_sock) { + src_port = s->port_pc; + dst_port = s->port_us; + } } } else { - // for Request get the dest proto from the saved contact - dst_proto = pcontact->received_proto; - - if(_cflags & IPSEC_TCPPORT_UEC) { - // for Request and TCP sends from P-CSCF server port, for Request and UDP sends from P-CSCF client port - src_port = dst_proto == PROTO_TCP ? s->port_ps : s->port_pc; - - // for Request and TCP sends to UE client port, for Request and UDP sends to UE server port - dst_port = dst_proto == PROTO_TCP ? s->port_uc : s->port_us; + if(_cflags & IPSEC_FORWARD_USEVIA) { + if(req->first_line.u.request.method_value == METHOD_REGISTER) { + // for Request get the dest proto from the saved contact + dst_proto = pcontact->received_proto; + } else { + if(m->dst_uri.s != NULL + && strstr(m->dst_uri.s, ";transport=tcp") != NULL) { + dst_proto = PROTO_TCP; + } else if(m->dst_uri.s != NULL + && strstr(m->dst_uri.s, ";transport=tls") != NULL) { + dst_proto = PROTO_TLS; + } else { + dst_proto = m->rcv.proto; + } + } - } else { // for Request sends from P-CSCF client port src_port = s->port_pc; - // for Request sends to UE server port dst_port = s->port_us; + } else { + // for Request get the dest proto from the saved contact + dst_proto = pcontact->received_proto; + + if(_cflags & IPSEC_TCPPORT_UEC) { + // for Request and TCP sends from P-CSCF server port, for Request and UDP sends from P-CSCF client port + src_port = dst_proto == PROTO_TCP ? s->port_ps : s->port_pc; + + // for Request and TCP sends to UE client port, for Request and UDP sends to UE server port + dst_port = dst_proto == PROTO_TCP ? s->port_uc : s->port_us; + + } else { + // for Request sends from P-CSCF client port + src_port = s->port_pc; + + // for Request sends to UE server port + dst_port = s->port_us; + } + } + } + + if(_cflags & IPSEC_FORWARD_TRYTCP) { + client_sock = + grep_sock_info(via_host.af == AF_INET ? &ipsec_listen_addr + : &ipsec_listen_addr6, + src_port, dst_proto); + if(!client_sock && dst_proto == PROTO_UDP) { + LM_ERR("UDP socket not found for IPSec forward, trying for TCP\n"); + dst_proto = PROTO_TCP; } } + if(!(_cflags & IPSEC_NODSTURI_RESET) && (m->dst_uri.s != NULL)) { + LM_DBG("resetting dst uri [%.*s]\n", m->dst_uri.len, m->dst_uri.s); + pkg_free(m->dst_uri.s); + m->dst_uri.s = NULL; + m->dst_uri.len = 0; + } + if(!(_cflags & IPSEC_NODSTURI_RESET)) { char buf[1024]; int buf_len; @@ -955,6 +1126,10 @@ int ipsec_forward(struct sip_msg *m, udomain_t *d, int _cflags) buf_len = snprintf(buf, sizeof(buf) - 1, "sip:%.*s:%d;transport=tcp", ci.via_host.len, ci.via_host.s, dst_port); + } else if((_cflags & IPSEC_SETDSTURI_FULL) && (dst_proto == PROTO_TLS)) { + buf_len = + snprintf(buf, sizeof(buf) - 1, "sip:%.*s:%d;transport=tls", + ci.via_host.len, ci.via_host.s, dst_port); } else { buf_len = snprintf(buf, sizeof(buf) - 1, "sip:%.*s:%d", ci.via_host.len, ci.via_host.s, dst_port); @@ -1002,9 +1177,9 @@ int ipsec_forward(struct sip_msg *m, udomain_t *d, int _cflags) // Update dst_info in message if(m->first_line.type == SIP_REPLY) { - if(!t) { + if(t == NULL || t == T_UNDEFINED) { t = tmb.t_gett(); - if(!t) { + if(t == NULL || t == T_UNDEFINED) { LM_ERR("Error getting transaction\n"); goto cleanup; } @@ -1034,6 +1209,7 @@ int ipsec_forward(struct sip_msg *m, udomain_t *d, int _cflags) cleanup: ul.unlock_udomain(d, &ci.via_host, ci.via_port, ci.via_prot); pkg_free(ci.received_host.s); + pkg_free(ci.aor.s); if(t) { tmb.t_uas_request_clean_parsed(t); } @@ -1041,7 +1217,7 @@ cleanup: } -int ipsec_destroy(struct sip_msg *m, udomain_t *d) +int ipsec_destroy(struct sip_msg *m, udomain_t *d, str *uri) { struct pcontact_info ci; pcontact_t *pcontact = NULL; @@ -1053,7 +1229,7 @@ int ipsec_destroy(struct sip_msg *m, udomain_t *d) } // Find the contact - if(fill_contact(&ci, m, t, 0) != 0) { + if(fill_contact(&ci, m, t, uri, 0) != 0) { LM_ERR("Error filling in contact data\n"); return ret; } @@ -1086,12 +1262,76 @@ int ipsec_destroy(struct sip_msg *m, udomain_t *d) cleanup: ul.unlock_udomain(d, &ci.via_host, ci.via_port, ci.via_prot); pkg_free(ci.received_host.s); + pkg_free(ci.aor.s); if(t) { tmb.t_uas_request_clean_parsed(t); } return ret; } +int ipsec_destroy_by_contact( + udomain_t *_d, str *uri, str *received_host, int received_port) +{ + + pcontact_t *pcontact = NULL; + int ret = IPSEC_CMD_FAIL; // FAIL by default + + pcontact_info_t search_ci; + memset(&search_ci, 0, sizeof(struct pcontact_info)); + + sip_uri_t contact_uri; + if(parse_uri(uri->s, uri->len, &contact_uri) != 0) { + LM_WARN("Failed to parse aor [%.*s]\n", uri->len, uri->s); + return ret; + } + + search_ci.received_host.s = received_host->s; + search_ci.received_host.len = received_host->len; + search_ci.received_port = received_port; + search_ci.received_proto = + contact_uri.proto ? contact_uri.proto : PROTO_UDP; + search_ci.searchflag = SEARCH_RECEIVED; + search_ci.via_host.s = received_host->s; + search_ci.via_host.len = received_host->len; + search_ci.via_port = received_port; + search_ci.via_prot = search_ci.received_proto; + search_ci.aor.s = uri->s; + search_ci.aor.len = uri->len; + search_ci.reg_state = PCONTACT_ANY; + + if(ul.get_pcontact(_d, &search_ci, &pcontact, 0) != 0) { + LM_ERR("Contact doesn't exist\n"); + return ret; + } + + /* Lock this record while working with the data: */ + ul.lock_udomain( + _d, &pcontact->via_host, pcontact->via_port, pcontact->via_proto); + + if(pcontact->security_temp == NULL) { + LM_ERR("No security parameters found in contact\n"); + goto cleanup; + } + + //get security parameters + if(pcontact->security_temp->type != SECURITY_IPSEC) { + LM_ERR("Unsupported security type: %d\n", + pcontact->security_temp->type); + goto cleanup; + } + + destroy_ipsec_tunnel(search_ci.received_host, + pcontact->security_temp->data.ipsec, pcontact->contact_port); + + ret = IPSEC_CMD_SUCCESS; // all good, set ret to SUCCESS, and exit + +cleanup: + /* Unlock domain */ + ul.unlock_udomain( + _d, &pcontact->via_host, pcontact->via_port, pcontact->via_proto); + return ret; +} + int ipsec_reconfig() { if(ul.get_number_of_contacts() != 0) { diff --git a/src/modules/ims_ipsec_pcscf/cmd.h b/src/modules/ims_ipsec_pcscf/cmd.h index 207556f0f..e22000028 100644 --- a/src/modules/ims_ipsec_pcscf/cmd.h +++ b/src/modules/ims_ipsec_pcscf/cmd.h @@ -65,9 +65,11 @@ struct udomain_t; int ipsec_create(struct sip_msg *m, udomain_t *d, int _cflags); int ipsec_forward(struct sip_msg *m, udomain_t *d, int _cflags); -int ipsec_destroy(struct sip_msg *m, udomain_t *d); +int ipsec_destroy(struct sip_msg *m, udomain_t *d, str *uri); int ipsec_cleanall(); int ipsec_reconfig(); void ipsec_on_expire(pcontact_t *c, int type, void *param); +int ipsec_destroy_by_contact( + udomain_t *_d, str *uri, str *received_host, int received_port); #endif /* IPSEC_CMD_H */ diff --git a/src/modules/ims_ipsec_pcscf/doc/ims_ipsec_pcscf_admin.xml b/src/modules/ims_ipsec_pcscf/doc/ims_ipsec_pcscf_admin.xml index 982df9bbb..ff65668e6 100644 --- a/src/modules/ims_ipsec_pcscf/doc/ims_ipsec_pcscf_admin.xml +++ b/src/modules/ims_ipsec_pcscf/doc/ims_ipsec_pcscf_admin.xml @@ -324,6 +324,16 @@ ipsec_create("location", "1"); 0x80 (128) - set transport parameter in the new dst uri for TCP requests. + + + 0x100 (256) - use Via attributes (port and protocol) for routing UDP reply. + + + + + 0x200 (512) - try TCP if corresponding UDP socket is not found. + + @@ -345,7 +355,7 @@ ipsec_forward("location", "1");
- <function moreinfo="none">ipsec_destroy(domain)</function> + <function moreinfo="none">ipsec_destroy(domain [, aor])</function> The function destroys IPSec tunnel, created with ipsec_create. Meaning of the parameters is as follows: @@ -355,6 +365,10 @@ ipsec_forward("location", "1"); If a database is used then this must be name of the table which stores the contacts. + + aor - SIP URI to match the record. If not + provided, then R-URI is used. + @@ -363,6 +377,40 @@ ipsec_forward("location", "1"); ... ipsec_destroy("location"); +... + + +
+
+ <function moreinfo="none">ipsec_destroy_by_contact(domain, aor, recv_host, recv_port)</function> + The function destroys IPSec tunnel, created with ipsec_create. + 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. + + + aor - SIP URI to match the record. + + + recv_host - received host to match the record. + + + recv_port - received port to match the record. + + + + The last three parameters have to be string valies and can contain + variables. + + ipsec_destroy_by_contact() + + +... +ipsec_destroy_by_contact("location", "...", "...", "..."); ... diff --git a/src/modules/ims_ipsec_pcscf/ims_ipsec_pcscf_mod.c b/src/modules/ims_ipsec_pcscf/ims_ipsec_pcscf_mod.c index 20e5e1c97..223f8d1aa 100644 --- a/src/modules/ims_ipsec_pcscf/ims_ipsec_pcscf_mod.c +++ b/src/modules/ims_ipsec_pcscf/ims_ipsec_pcscf_mod.c @@ -23,6 +23,7 @@ */ #include "../../core/sr_module.h" +#include "../../core/mod_fix.h" #include "../../modules/tm/tm_load.h" #include "../ims_usrloc_pcscf/usrloc.h" @@ -56,12 +57,16 @@ static int child_init(int); static void mod_destroy(void); static int w_create(struct sip_msg *_m, char *_d, char *_cflags); static int w_forward(struct sip_msg *_m, char *_d, char *_cflags); -static int w_destroy(struct sip_msg *_m, char *_d, char *_cflags); +static int w_destroy(struct sip_msg *_m, char *_d, char *_aor); +static int w_destroy_by_contact(struct sip_msg *_m, char *_d, char *_aor, + char *_received_host, char *_received_port); /*! \brief Fixup functions */ static int domain_fixup(void **param, int param_no); static int save_fixup2(void **param, int param_no); static int free_uint_fixup(void **param, int param_no); +static int unregister_fixup(void **param, int param_no); +static int unregister2_fixup(void **param, int param_no); extern int bind_ipsec_pcscf(usrloc_api_t *api); @@ -83,6 +88,10 @@ static cmd_export_t cmds[] = { free_uint_fixup, REQUEST_ROUTE | ONREPLY_ROUTE }, {"ipsec_destroy", (cmd_function)w_destroy, 1, save_fixup2, 0, REQUEST_ROUTE | ONREPLY_ROUTE }, + {"ipsec_destroy", (cmd_function)w_destroy, 2, unregister_fixup, + 0, ANY_ROUTE }, + {"ipsec_destroy_by_contact", (cmd_function)w_destroy_by_contact, 4, + unregister2_fixup, 0, ANY_ROUTE}, {"bind_ims_ipsec_pcscf", (cmd_function)bind_ipsec_pcscf, 1, 0, 0, 0}, {0, 0, 0, 0, 0, 0} @@ -448,6 +457,27 @@ static int save_fixup2(void **param, int param_no) return 0; } +/*! \brief + * Fixup for "unregister" operation - both domain and aor + */ +static int unregister_fixup(void **param, int param_no) +{ + if(param_no == 1) { + return domain_fixup(param, param_no); + } else { + return fixup_spve_all(param, param_no); + } + return E_CFG; +} + +static int unregister2_fixup(void **param, int param_no) +{ + if(param_no == 1) { + return domain_fixup(param, param_no); + } else { + return fixup_spve_all(param, param_no); + } +} /*! \brief * Wrapper to ipsec functions @@ -468,7 +498,57 @@ static int w_forward(struct sip_msg *_m, char *_d, char *_cflags) return ipsec_forward(_m, (udomain_t *)_d, 0); } -static int w_destroy(struct sip_msg *_m, char *_d, char *_cflags) +static int w_destroy(struct sip_msg *_m, char *_d, char *_aor) { - return ipsec_destroy(_m, (udomain_t *)_d); + str aor; + + if(_aor) { + if(fixup_get_svalue(_m, (gparam_t *)_aor, &aor) < 0) { + LM_ERR("failed to get aor parameter\n"); + return -1; + } + LM_DBG("URI: %.*s\n", aor.len, aor.s); + + return ipsec_destroy(_m, (udomain_t *)_d, &aor); + } + return ipsec_destroy(_m, (udomain_t *)_d, NULL); +} + +static int w_destroy_by_contact(struct sip_msg *_m, char *_d, char *_aor, + char *_received_host, char *_received_port) +{ + str aor; + str received_host; + str received_port; + int port = 0; + + if((_aor == NULL) || (_received_host == NULL) || (_received_port == NULL)) { + LM_ERR("error - bad parameters\n"); + return -1; + } + + if(fixup_get_svalue(_m, (gparam_t *)_aor, &aor) < 0) { + LM_ERR("failed to get aor parameter\n"); + return -1; + } + if(fixup_get_svalue(_m, (gparam_t *)_received_host, &received_host) < 0) { + LM_ERR("failed to get received host parameter\n"); + return -1; + } + if(fixup_get_svalue(_m, (gparam_t *)_received_port, &received_port) < 0) { + LM_ERR("failed to get received host parameter\n"); + return -1; + } + + LM_DBG("URI: %.*s\n", aor.len, aor.s); + LM_DBG("Received-Host: %.*s\n", received_host.len, received_host.s); + LM_DBG("Received-Port: %.*s\n", received_port.len, received_port.s); + if(str2sint(&received_port, &port) != 0) { + LM_ERR("error - cannot convert %.*s to an int!\n", received_port.len, + received_port.s); + return -1; + } + + return ipsec_destroy_by_contact( + (udomain_t *)_d, &aor, &received_host, port); } diff --git a/src/modules/ims_qos/README b/src/modules/ims_qos/README index 990934a6a..b08ac7fda 100644 --- a/src/modules/ims_qos/README +++ b/src/modules/ims_qos/README @@ -64,6 +64,9 @@ Carsten Bock 3.21. omit_flow_ports integer 3.22. rs_default_bandwidth integer 3.23. rr_default_bandwidth integer + 3.24. suspend_transaction integer + 3.25. recv_mode integer + 3.26. dialog_direction integer 4. Functions @@ -101,8 +104,11 @@ Carsten Bock 1.21. omit_flow_ports parameter usage 1.22. rs_default_bandwidth parameter usage 1.23. rr_default_bandwidth parameter usage - 1.24. Rx_AAR_Register - 1.25. Rx_AAR + 1.24. suspend_transaction parameter usage + 1.25. recv_mode parameter usage + 1.26. dialog_direction parameter usage + 1.27. Rx_AAR_Register + 1.28. Rx_AAR Chapter 1. Admin Guide @@ -139,6 +145,9 @@ Chapter 1. Admin Guide 3.21. omit_flow_ports integer 3.22. rs_default_bandwidth integer 3.23. rr_default_bandwidth integer + 3.24. suspend_transaction integer + 3.25. recv_mode integer + 3.26. dialog_direction integer 4. Functions @@ -167,7 +176,7 @@ Chapter 1. Admin Guide 2.1. Kamailio Modules The Following modules must be loaded before this module: - * Dialog + * IMS Dialog * Usrloc PCSCF * TM - Transaction Manager * CDP - C Diameter Peer @@ -202,6 +211,9 @@ Chapter 1. Admin Guide 3.21. omit_flow_ports integer 3.22. rs_default_bandwidth integer 3.23. rr_default_bandwidth integer + 3.24. suspend_transaction integer + 3.25. recv_mode integer + 3.26. dialog_direction integer 3.1. rx_dest_realm (string) @@ -492,6 +504,43 @@ modparam("ims_qos", "rs_default_bandwidth", 600) modparam("ims_qos", "rr_default_bandwidth", 2000) ... +3.24. suspend_transaction integer + + If enabled, suspends the tm transaction while doing the AAR. + + Default value is 1 (enabled) + + Example 1.24. suspend_transaction parameter usage +... +modparam("ims_qos", "suspend_transaction", 0) +... + +3.25. recv_mode integer + + If set to 0, rx_aar_register() takes the received-from address values + (IP, port, proto) from the IP frame. If set to 1, it takes them from + Via header. + + Default value is 0 + + Example 1.25. recv_mode parameter usage +... +modparam("ims_qos", "recv_mode", 1) +... + +3.26. dialog_direction integer + + If set to 1, DLG_MOBILE_ORIGINATING is set to + rx_add_media_component_description_avp() instead of DLG_MOBILE_REGISTER + (which corresponds to value 3). + + Default value is 3 + + Example 1.26. dialog_direction parameter usage +... +modparam("ims_qos", "dialog_direction", 1) +... + 4. Functions 4.1. Rx_AAR_Register(route_block, domain) @@ -522,7 +571,7 @@ modparam("ims_qos", "rr_default_bandwidth", 2000) p.s. this is executed asynchronously. See example on how to retrieve return value - Example 1.24. Rx_AAR_Register + Example 1.27. Rx_AAR_Register ... if(Rx_AAR_Register("REG_AAR_REPLY","location")==0){ exit; @@ -559,12 +608,14 @@ route[REG_AAR_REPLY] default. This is as per RFC 4006: END_USER_E164 0, END_USER_IMSI 1, END_USER_SIP_URI 2, END_USER_NAI 3, END_USER_PRIVATE 4 - This function can be used from REQUEST_ROUTE or ONREPLY_ROUTE. + This function can be used only from ONREPLY_ROUTE, only for replies to + INVITE, UPDATE, PRACK. The reply and request must have SDP, for this + function to work properly. p.s. this is executed asynchronously. See example on how to retrieve return value - Example 1.25. Rx_AAR + Example 1.28. Rx_AAR ... if(Rx_AAR("ORIG_SESSION_AAR_REPLY","orig","",-1)==0){ exit; diff --git a/src/modules/ims_qos/doc/ims_qos_admin.xml b/src/modules/ims_qos/doc/ims_qos_admin.xml index dd7b39dc0..bbc75a1f1 100644 --- a/src/modules/ims_qos/doc/ims_qos_admin.xml +++ b/src/modules/ims_qos/doc/ims_qos_admin.xml @@ -29,7 +29,7 @@ - Dialog + IMS Dialog @@ -513,6 +513,68 @@ modparam("ims_qos", "rs_default_bandwidth", 600) ... modparam("ims_qos", "rr_default_bandwidth", 2000) +... + + +
+ +
+ <varname>suspend_transaction</varname> integer + + If enabled, suspends the tm transaction while doing the AAR. + + Default value is 1 (enabled) + + + <varname>suspend_transaction</varname> parameter + usage + + +... +modparam("ims_qos", "suspend_transaction", 0) +... + + +
+ +
+ <varname>recv_mode</varname> integer + + If set to 0, rx_aar_register() takes the received-from address values + (IP, port, proto) from the IP frame. If set to 1, it takes them from + Via header. + + Default value is 0 + + + <varname>recv_mode</varname> parameter + usage + + +... +modparam("ims_qos", "recv_mode", 1) +... + + +
+ +
+ <varname>dialog_direction</varname> integer + + If set to 1, DLG_MOBILE_ORIGINATING is set to + rx_add_media_component_description_avp() instead of DLG_MOBILE_REGISTER + (which corresponds to value 3). + + + Default value is 3 + + + <varname>dialog_direction</varname> parameter + usage + + +... +modparam("ims_qos", "dialog_direction", 1) ... @@ -625,8 +687,8 @@ route[REG_AAR_REPLY] - This function can be used from REQUEST_ROUTE or - ONREPLY_ROUTE. + This function can be used only from ONREPLY_ROUTE, only for replies to INVITE, UPDATE, PRACK. + The reply and request must have SDP, for this function to work properly. p.s. this is executed asynchronously. See example on how to retrieve return value diff --git a/src/modules/ims_qos/ims_qos_mod.c b/src/modules/ims_qos/ims_qos_mod.c index bacb912d0..428a898df 100644 --- a/src/modules/ims_qos/ims_qos_mod.c +++ b/src/modules/ims_qos/ims_qos_mod.c @@ -142,6 +142,8 @@ int terminate_dialog_on_rx_failure = 1; //this specifies whether a dialog is torn down when a media rx session fails - in some cases you might not want the dialog torn down int delete_contact_on_rx_failure = 1; //If this is set we delete the contact if the associated signalling bearer is removed +int _ims_qos_suspend_transaction = + 1; //If this is set we suspend the transaction and continue later str early_qosrelease_reason = {"QoS released", 12}; @@ -164,6 +166,9 @@ int omit_flow_ports = 0; int rs_default_bandwidth = 0; int rr_default_bandwidth = 0; +ims_qos_params_t _imsqos_params = { + .recv_mode = 0, .dlg_direction = DLG_MOBILE_REGISTER}; + /* commands wrappers and fixups */ static int w_rx_aar(struct sip_msg *msg, char *route, char *dir, char *id, int id_type, int cfg_type); @@ -249,7 +254,11 @@ static param_export_t params[] = {{"rx_dest_realm", PARAM_STR, &rx_dest_realm}, &delete_contact_on_rx_failure}, {"regex_sdp_ip_prefix_to_maintain_in_fd", PARAM_STR, ®ex_sdp_ip_prefix_to_maintain_in_fd}, - {"include_rtcp_fd", INT_PARAM, &include_rtcp_fd}, {0, 0, 0}}; + {"include_rtcp_fd", INT_PARAM, &include_rtcp_fd}, + {"suspend_transaction", INT_PARAM, &_ims_qos_suspend_transaction}, + {"recv_mode", PARAM_INT, &_imsqos_params.recv_mode}, + {"dialog_direction", PARAM_INT, &_imsqos_params.dlg_direction}, + {0, 0, 0}}; /** module exports */ @@ -271,6 +280,10 @@ static int mod_init(void) callback_singleton = shm_malloc(sizeof(int)); *callback_singleton = 0; + if(_imsqos_params.dlg_direction != DLG_MOBILE_ORIGINATING) { + _imsqos_params.dlg_direction = DLG_MOBILE_REGISTER; + } + /*register space for event processor*/ register_procs(1); @@ -824,7 +837,7 @@ static int w_rx_aar(struct sip_msg *msg, char *route, char *dir, char *c_id, } if(t->uas.status >= 200) { - LM_DBG("transaction sent out a final response already - %d\n", + LM_WARN("transaction sent out a final response already - %d\n", t->uas.status); return result; } @@ -887,13 +900,13 @@ static int w_rx_aar(struct sip_msg *msg, char *route, char *dir, char *c_id, || memcmp(t->method.s, "UPDATE", 6) == 0))) { if(cscf_get_content_length(msg) == 0 || cscf_get_content_length(orig_sip_request_msg) == 0) { - LM_DBG("No SDP offer answer -> therefore we can not do Rx AAR"); + LM_WARN("No SDP offer answer -> therefore we can not do Rx AAR"); //goto aarna; //AAR na if we don't have offer/answer pair return result; } } else { - LM_DBG("Message is not response to INVITE, PRACK or UPDATE -> " - "therefore we do not Rx AAR"); + LM_WARN("Message is not response to INVITE, PRACK or UPDATE -> " + "therefore we do not Rx AAR"); return result; } @@ -1185,7 +1198,7 @@ static int w_rx_aar(struct sip_msg *msg, char *route, char *dir, char *c_id, int ret = create_new_callsessiondata(&callid, &ftag, &ttag, &identifier, identifier_type, &ip, ip_version, &rx_authdata_p); if(!ret) { - LM_DBG("Unable to create new media session data parcel\n"); + LM_ERR("Unable to create new media session data parcel\n"); goto error; } @@ -1234,12 +1247,17 @@ static int w_rx_aar(struct sip_msg *msg, char *route, char *dir, char *c_id, } saved_t_data->dlg = dlg; - LM_DBG("Suspending SIP TM transaction\n"); - if(tmb.t_suspend(msg, &saved_t_data->tindex, &saved_t_data->tlabel) != 0) { - LM_ERR("failed to suspend the TM processing\n"); - if(auth_session) - cdpb.AAASessionsUnlock(auth_session->hash); - goto error; + if(_ims_qos_suspend_transaction) { + LM_DBG("Suspending SIP TM transaction\n"); + if(tmb.t_suspend(msg, &saved_t_data->tindex, &saved_t_data->tlabel) + != 0) { + LM_ERR("failed to suspend the TM processing\n"); + if(auth_session) + cdpb.AAASessionsUnlock(auth_session->hash); + goto error; + } + } else { + LM_DBG("Don't suspend SIP TM transaction\n"); } LM_DBG("Sending Rx AAR"); @@ -1248,7 +1266,9 @@ static int w_rx_aar(struct sip_msg *msg, char *route, char *dir, char *c_id, if(!ret) { LM_ERR("Failed to send AAR\n"); - tmb.t_cancel_suspend(saved_t_data->tindex, saved_t_data->tlabel); + if(_ims_qos_suspend_transaction) { + tmb.t_cancel_suspend(saved_t_data->tindex, saved_t_data->tlabel); + } goto error; @@ -1431,11 +1451,16 @@ static int w_rx_aar_register( return CSCF_RETURN_ERROR; } - LM_DBG("Suspending SIP TM transaction\n"); - if(tmb.t_suspend(msg, &saved_t_data->tindex, &saved_t_data->tlabel) != 0) { - LM_ERR("failed to suspend the TM processing\n"); - free_saved_transaction_global_data(saved_t_data); - return CSCF_RETURN_ERROR; + if(_ims_qos_suspend_transaction) { + LM_DBG("Suspending SIP TM transaction\n"); + if(tmb.t_suspend(msg, &saved_t_data->tindex, &saved_t_data->tlabel) + != 0) { + LM_ERR("failed to suspend the TM processing\n"); + free_saved_transaction_global_data(saved_t_data); + return CSCF_RETURN_ERROR; + } + } else { + LM_DBG("Don't suspend SIP TM transaction\n"); } LM_DBG("Successfully suspended transaction\n"); @@ -1447,19 +1472,30 @@ static int w_rx_aar_register( goto error; } - //we use the received IP address for the framed_ip_address - recv_ip.s = ip_addr2a(&msg->rcv.src_ip); - recv_ip.len = strlen(ip_addr2a(&msg->rcv.src_ip)); + char buff[IP_ADDR_MAX_STR_SIZE]; + if(_imsqos_params.recv_mode == 0) { + //we use the received IP address for the framed_ip_address + recv_ip.s = ip_addr2a(&msg->rcv.src_ip); + recv_ip.len = strlen(ip_addr2a(&msg->rcv.src_ip)); + + recv_port = msg->rcv.src_port; + recv_proto = msg->rcv.proto; + } else { + memset(&recv_ip, 0, sizeof(str)); + memcpy(&buff, vb->host.s, vb->host.len); + buff[vb->host.len] = 0; + recv_ip.s = buff; + recv_ip.len = strlen(buff); + recv_port = via_port; + recv_proto = via_proto; + } ip_version = check_ip_version(recv_ip); if(!ip_version) { LM_ERR("check_ip_version returned 0 \n"); goto error; } - recv_port = msg->rcv.src_port; - recv_proto = msg->rcv.proto; - LM_DBG("Message received IP address is: [%.*s]\n", recv_ip.len, recv_ip.s); LM_DBG("Message via is [%d://%.*s:%d]\n", vb->proto, vb->host.len, vb->host.s, via_port); @@ -1662,7 +1698,9 @@ static int w_rx_aar_register( return CSCF_RETURN_BREAK; //on success we break - because rest of cfg file will be executed by async process } else { create_return_code(CSCF_RETURN_TRUE); - tmb.t_cancel_suspend(saved_t_data->tindex, saved_t_data->tlabel); + if(_ims_qos_suspend_transaction) { + tmb.t_cancel_suspend(saved_t_data->tindex, saved_t_data->tlabel); + } if(saved_t_data) { free_saved_transaction_global_data( saved_t_data); //no aar sent so we must free the global data @@ -1673,7 +1711,9 @@ static int w_rx_aar_register( error: LM_ERR("Error trying to send AAR\n"); if(!aar_sent) { - tmb.t_cancel_suspend(saved_t_data->tindex, saved_t_data->tlabel); + if(_ims_qos_suspend_transaction) { + tmb.t_cancel_suspend(saved_t_data->tindex, saved_t_data->tlabel); + } if(saved_t_data) { free_saved_transaction_global_data( diff --git a/src/modules/ims_qos/ims_qos_mod.h b/src/modules/ims_qos/ims_qos_mod.h index 55a5a9bb3..28d59d1d1 100644 --- a/src/modules/ims_qos/ims_qos_mod.h +++ b/src/modules/ims_qos/ims_qos_mod.h @@ -49,6 +49,12 @@ #define MOD_NAME "ims_qos" +typedef struct ims_qos_params +{ + int recv_mode; + int dlg_direction; +} ims_qos_params_t; + /** callback functions */ struct AAAMessage; diff --git a/src/modules/ims_qos/rx_aar.c b/src/modules/ims_qos/rx_aar.c index f19e51814..91ed4345a 100644 --- a/src/modules/ims_qos/rx_aar.c +++ b/src/modules/ims_qos/rx_aar.c @@ -76,11 +76,13 @@ extern usrloc_api_t ul; extern struct ims_qos_counters_h ims_qos_cnts_h; extern int authorize_video_flow; +extern int _ims_qos_suspend_transaction; extern str af_signaling_ip; extern str af_signaling_ip6; extern str component_media_type; extern str flow_protocol; +extern ims_qos_params_t _imsqos_params; str IMS_Serv_AVP_val = {"IMS Services", 12}; str IMS_Em_Serv_AVP_val = {"Emergency IMS Call", 18}; @@ -113,19 +115,21 @@ void async_aar_callback( LM_DBG("received AAA answer"); - if(tmb.t_lookup_ident(&t, data->tindex, data->tlabel) < 0) { - LM_ERR("t_continue: transaction not found\n"); - goto error; - } else { - LM_DBG("t_continue: transaction found\n"); + if(_ims_qos_suspend_transaction) { + if(tmb.t_lookup_ident(&t, data->tindex, data->tlabel) < 0) { + LM_ERR("t_continue: transaction not found\n"); + goto error; + } else { + LM_DBG("t_continue: transaction found\n"); + } + //we have T, lets restore our state (esp. for AVPs) + set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, &t->uri_avps_from); + set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, &t->uri_avps_to); + set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, &t->user_avps_from); + set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, &t->user_avps_to); + set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN, &t->domain_avps_from); + set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN, &t->domain_avps_to); } - //we have T, lets restore our state (esp. for AVPs) - set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, &t->uri_avps_from); - set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, &t->uri_avps_to); - set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, &t->user_avps_from); - set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, &t->user_avps_to); - set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN, &t->domain_avps_from); - set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN, &t->domain_avps_to); if(is_timeout != 0) { LM_ERR("Error timeout when sending AAR message via CDP\n"); @@ -228,7 +232,9 @@ done: if(aaa) cdpb.AAAFreeMessage(&aaa); - tmb.t_continue(data->tindex, data->tlabel, data->act); + if(_ims_qos_suspend_transaction) { + tmb.t_continue(data->tindex, data->tlabel, data->act); + } free_saved_transaction_global_data(data); } @@ -272,17 +278,19 @@ void async_aar_reg_callback( "failures flag is [%d]\n", data->answers_not_received, data->failed); - if(tmb.t_lookup_ident(&t, data->tindex, data->tlabel) < 0) { - LM_ERR("t_continue: transaction not found\n"); - goto error; + if(_ims_qos_suspend_transaction) { + if(tmb.t_lookup_ident(&t, data->tindex, data->tlabel) < 0) { + LM_ERR("t_continue: transaction not found\n"); + goto error; + } + //we have T, lets restore our state (esp. for AVPs) + set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, &t->uri_avps_from); + set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, &t->uri_avps_to); + set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, &t->user_avps_from); + set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, &t->user_avps_to); + set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN, &t->domain_avps_from); + set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN, &t->domain_avps_to); } - //we have T, lets restore our state (esp. for AVPs) - set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, &t->uri_avps_from); - set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, &t->uri_avps_to); - set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, &t->user_avps_from); - set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, &t->user_avps_to); - set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN, &t->domain_avps_from); - set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN, &t->domain_avps_to); if(is_timeout != 0) { LM_ERR("Error timeout when sending AAR message via CDP\n"); @@ -423,7 +431,9 @@ done: cdpb.AAAFreeMessage(&aaa); if(finalReply) { - tmb.t_continue(data->tindex, data->tlabel, data->act); + if(_ims_qos_suspend_transaction) { + tmb.t_continue(data->tindex, data->tlabel, data->act); + } free_saved_transaction_global_data(data); } free_saved_transaction_data(local_data); @@ -604,7 +614,6 @@ int add_media_components(AAAMessage *aar, struct sip_msg *req, ipA = req_sdp_session->ip_addr; portA = req_sdp_stream->port; - ipB = rpl_sdp_session->ip_addr; portB = rpl_sdp_stream->port; } @@ -1121,7 +1130,7 @@ int rx_send_aar_register(struct sip_msg *msg, AAASession *auth, &via_host, &port_from, ip_version == AF_INET ? &af_signaling_ip : &af_signaling_ip6, &port_to, &flow_protocol, &raw_stream, &raw_stream, - DLG_MOBILE_REGISTER, AVP_EPC_Flow_Usage_AF_Signaling); + _imsqos_params.dlg_direction, AVP_EPC_Flow_Usage_AF_Signaling); /* Add specific action AVP's */ rx_add_specific_action_avp(aar, 1); // CHARGING_CORRELATION_EXCHANGE diff --git a/src/modules/ims_qos/rx_avp.c b/src/modules/ims_qos/rx_avp.c index d7d6abd9b..7a64d5e97 100644 --- a/src/modules/ims_qos/rx_avp.c +++ b/src/modules/ims_qos/rx_avp.c @@ -670,7 +670,7 @@ AAA_AVP *rx_create_media_subcomponent_avp(int number, str *proto, str *ipA, str data; int len, len2; - int int_port_rctp_a, int_port_rctp_b; + int int_port_rctp_a = 0, int_port_rctp_b = 0; str port_rtcp_a = STR_NULL, port_rtcp_b = STR_NULL; AAA_AVP *flow_description1 = 0, *flow_description2 = 0, *flow_description3 = 0, *flow_description4 = 0, *flow_number = 0; diff --git a/src/modules/ims_registrar_pcscf/README b/src/modules/ims_registrar_pcscf/README index 02327a005..ff85f73fe 100644 --- a/src/modules/ims_registrar_pcscf/README +++ b/src/modules/ims_registrar_pcscf/README @@ -50,6 +50,7 @@ Carsten Bock 3.9. ignore_reg_state (int) 3.10. force_icscf_uri (string) 3.11. reginfo_queue_size_threshold (int) + 3.12. delete_delay (int) 4. Functions @@ -72,7 +73,8 @@ Carsten Bock 1.9. ignore_reg_state parameter usage 1.10. force_icscf_uri parameter usage 1.11. reginfo_queue_size_threshold parameter usage - 1.12. pcscf_save + 1.12. delete_delay parameter usage + 1.13. pcscf_save Chapter 1. Admin Guide @@ -97,6 +99,7 @@ Chapter 1. Admin Guide 3.9. ignore_reg_state (int) 3.10. force_icscf_uri (string) 3.11. reginfo_queue_size_threshold (int) + 3.12. delete_delay (int) 4. Functions @@ -139,6 +142,7 @@ Chapter 1. Admin Guide 3.9. ignore_reg_state (int) 3.10. force_icscf_uri (string) 3.11. reginfo_queue_size_threshold (int) + 3.12. delete_delay (int) 3.1. pcscf_uri (string) @@ -280,6 +284,18 @@ network.org") modparam("ims_registrar_pcscf", "reginfo_queue_size_threshold", 42) ... +3.12. delete_delay (int) + + If set greater than 0, the delete of a pcontact record is delayed with + its value instead of being done immediately. + + Default value is 0 (delete immediately). + + Example 1.12. delete_delay parameter usage +... +modparam("ims_registrar_pcscf", "delete_delay", 10) +... + 4. Functions 4.1. pcscf_save(domain) @@ -298,7 +314,7 @@ modparam("ims_registrar_pcscf", "reginfo_queue_size_threshold", 42) * domain - Logical domain within the registrar. If a database is used then this must be name of the table which stores the contacts. - Example 1.12. pcscf_save + Example 1.13. pcscf_save ... pcscf_save("location"); ... diff --git a/src/modules/ims_registrar_pcscf/doc/ims_registrar_pcscf_admin.xml b/src/modules/ims_registrar_pcscf/doc/ims_registrar_pcscf_admin.xml index 3f6b36d5c..85b532c08 100644 --- a/src/modules/ims_registrar_pcscf/doc/ims_registrar_pcscf_admin.xml +++ b/src/modules/ims_registrar_pcscf/doc/ims_registrar_pcscf_admin.xml @@ -265,6 +265,25 @@ modparam("ims_registrar_pcscf", "force_icscf_uri", "sip:icscf.mnc001.mcc001.3gpp ... modparam("ims_registrar_pcscf", "reginfo_queue_size_threshold", 42) +... + + +
+ +
+ <varname>delete_delay</varname> (int) + + If set greater than 0, the delete of a pcontact record is delayed + with its value instead of being done immediately. + + Default value is 0 (delete immediately). + + + <varname>delete_delay</varname> parameter usage + + +... +modparam("ims_registrar_pcscf", "delete_delay", 10) ... diff --git a/src/modules/ims_registrar_pcscf/ims_registrar_pcscf_mod.c b/src/modules/ims_registrar_pcscf/ims_registrar_pcscf_mod.c index 42625f945..5c265fad4 100644 --- a/src/modules/ims_registrar_pcscf/ims_registrar_pcscf_mod.c +++ b/src/modules/ims_registrar_pcscf/ims_registrar_pcscf_mod.c @@ -105,6 +105,10 @@ char *rcv_avp_param = 0; unsigned short rcv_avp_type = 0; int_str rcv_avp_name; +ims_registrar_pcscf_params_t _imsregp_params = { + .delete_delay = 0 +}; + // static str orig_prefix = {"sip:orig@",9}; /*! \brief Module init & destroy function */ @@ -186,6 +190,7 @@ static param_export_t params[] = {{"pcscf_uri", PARAM_STR, &pcscf_uri}, {"force_icscf_uri", PARAM_STR, &force_icscf_uri}, {"reginfo_queue_size_threshold", INT_PARAM, ®info_queue_size_threshold}, + {"delete_delay", PARAM_INT, &_imsregp_params.delete_delay}, // {"store_profile_dereg", INT_PARAM, &store_data_on_dereg}, {0, 0, 0}}; diff --git a/src/modules/ims_registrar_pcscf/ims_registrar_pcscf_mod.h b/src/modules/ims_registrar_pcscf/ims_registrar_pcscf_mod.h index f98814e54..74f4b72dc 100644 --- a/src/modules/ims_registrar_pcscf/ims_registrar_pcscf_mod.h +++ b/src/modules/ims_registrar_pcscf/ims_registrar_pcscf_mod.h @@ -57,6 +57,10 @@ #define USERNAME_MAX_SIZE 64 #define DOMAIN_MAX_SIZE 128 +typedef struct ims_registrar_pcscf_params { + int delete_delay; +} ims_registrar_pcscf_params_t; + extern unsigned short rcv_avp_type; extern int_str rcv_avp_name; extern int is_registered_fallback2ip; diff --git a/src/modules/ims_registrar_pcscf/notify.c b/src/modules/ims_registrar_pcscf/notify.c index 699150a94..24ed56300 100644 --- a/src/modules/ims_registrar_pcscf/notify.c +++ b/src/modules/ims_registrar_pcscf/notify.c @@ -81,6 +81,8 @@ extern time_t time_now; extern int subscribe_to_reginfo; +extern ims_registrar_pcscf_params_t _imsregp_params; + int process_contact( udomain_t *_d, int expires, str contact_uri, int contact_state) { @@ -211,14 +213,23 @@ int process_contact( // } } else { //contact exists if(contact_state == STATE_TERMINATED) { - //delete contact LM_DBG("This contact <%.*s> is in state terminated and is in " "usrloc so removing it from usrloc\n", contact_uri.len, contact_uri.s); - if(ul.delete_pcontact(_d, pcontact) != 0) { - LM_DBG("failed to delete pcscf contact <%.*s> - not a problem " - "this may have been removed by de registration", - contact_uri.len, contact_uri.s); + if(_imsregp_params.delete_delay <= 0) { + //delete contact + if(ul.delete_pcontact(_d, pcontact) != 0) { + LM_DBG("failed to delete pcscf contact <%.*s> - not a " + "problem " + "this may have been removed by de registration", + contact_uri.len, contact_uri.s); + } + } else { + // rather than delete update the pcontact with expire value + ci.expires = local_time_now + _imsregp_params.delete_delay; + if(ul.update_pcontact(_d, &ci, pcontact) != 0) { + LM_DBG("failed to update pcscf contact on de-register\n"); + } } /*TODO_LATEST - put this back */ } else { //state is active diff --git a/src/modules/ims_registrar_pcscf/save.c b/src/modules/ims_registrar_pcscf/save.c index 7594d1605..679abc99c 100644 --- a/src/modules/ims_registrar_pcscf/save.c +++ b/src/modules/ims_registrar_pcscf/save.c @@ -63,6 +63,8 @@ extern int subscription_expires; extern pua_api_t pua; extern ipsec_pcscf_api_t ipsec_pcscf; +extern ims_registrar_pcscf_params_t _imsregp_params; + struct sip_msg *get_request_from_reply(struct sip_msg *reply) { struct cell *t; @@ -247,9 +249,20 @@ static inline int update_contacts(struct sip_msg *req, struct sip_msg *rpl, <= 0) { //remove contact - de-register LM_DBG("This is a de-registration for contact <%.*s>\n", c->uri.len, c->uri.s); - if(ul.delete_pcontact(_d, pcontact) != 0) { - LM_ERR("failed to delete pcscf contact <%.*s>\n", - c->uri.len, c->uri.s); + if(_imsregp_params.delete_delay <= 0) { + if(ul.delete_pcontact(_d, pcontact) != 0) { + LM_ERR("failed to delete pcscf contact " + "<%.*s>\n", + c->uri.len, c->uri.s); + } + } else { + // rather than delete update the pcontact with expire value of 10 seconds + ci.expires = local_time_now + + _imsregp_params.delete_delay; + if(ul.update_pcontact(_d, &ci, pcontact) != 0) { + LM_DBG("failed to update pcscf contact on " + "de-register\n"); + } } //TODO_LATEST replace above } else { //update contact @@ -464,8 +477,15 @@ int save_pending(struct sip_msg *_m, udomain_t *_d) ul.unlock_udomain(_d, &ci.via_host, ci.via_port, ci.via_prot); return -2; } - } else { - LM_DBG("Contact already exists - not doing anything for now\n"); + } else if(pcontact->reg_state == PCONTACT_DEREG_PENDING_PUBLISH) { + LM_DBG("Contact already exists - Updating contact [%.*s]: setting " + "state to PCONTACT_REG_PENDING\n", + pcontact->aor.len, pcontact->aor.s); + + memset(&ci_, 0, sizeof(struct pcontact_info)); + ci_.reg_state = PCONTACT_REG_PENDING; + ci_.num_service_routes = 0; + ul.update_pcontact(_d, &ci_, pcontact); } } diff --git a/src/modules/ims_registrar_scscf/README b/src/modules/ims_registrar_scscf/README index 0c3585280..100ea1e65 100644 --- a/src/modules/ims_registrar_scscf/README +++ b/src/modules/ims_registrar_scscf/README @@ -842,9 +842,11 @@ Chapter 2. Frequently Asked Questions First at all check if your question was already answered on one of our mailing lists: * User Mailing List - - https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users + https://lists.kamailio.org/mailman3/postorius/lists/sr-users.lists. + kamailio.org/ * Developer Mailing List - - https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-dev + https://lists.kamailio.org/mailman3/postorius/lists/sr-dev.lists.ka + mailio.org/ E-mails regarding any stable Kamailio release should be sent to and e-mails regarding development diff --git a/src/modules/ims_usrloc_pcscf/README b/src/modules/ims_usrloc_pcscf/README index f1d09f897..636994061 100644 --- a/src/modules/ims_usrloc_pcscf/README +++ b/src/modules/ims_usrloc_pcscf/README @@ -308,9 +308,11 @@ Chapter 2. Frequently Asked Questions First at all check if your question was already answered on one of our mailing lists: * User Mailing List - - https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users + https://lists.kamailio.org/mailman3/postorius/lists/sr-users.lists. + kamailio.org/ * Developer Mailing List - - https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-dev + https://lists.kamailio.org/mailman3/postorius/lists/sr-dev.lists.ka + mailio.org/ E-mails regarding any stable Kamailio release should be sent to and e-mails regarding development diff --git a/src/modules/ims_usrloc_pcscf/udomain.c b/src/modules/ims_usrloc_pcscf/udomain.c index 0d7c14390..3c754a6f1 100644 --- a/src/modules/ims_usrloc_pcscf/udomain.c +++ b/src/modules/ims_usrloc_pcscf/udomain.c @@ -616,32 +616,40 @@ int get_pcontact_from_cache(udomain_t *_d, pcontact_info_t *contact_info, continue; } } - if((contact_info->aor.len > 0) && (needle_uri.user.len != 0)) { - if((needle_uri.user.len != c->contact_user.len) - || (memcmp(needle_uri.user.s, c->contact_user.s, - needle_uri.user.len) - != 0)) { - LM_ERR("user name does not match - no match here...\n"); - LM_DBG("found pcontact username [%d]: [%.*s]\n", i, - c->contact_user.len, c->contact_user.s); - LM_DBG("incoming contact username: [%.*s]\n", - needle_uri.user.len, needle_uri.user.s); - c = c->next; - continue; - } - if((contact_info->aor.len >= 4) - && (memcmp(contact_info->aor.s, c->aor.s, 4) - != 0)) { // do not mix up sip- and tel-URIs. - LM_ERR("scheme does not match - no match here...\n"); - LM_DBG("found pcontact scheme [%d]: [%.*s]\n", i, 4, - c->aor.s); - LM_DBG("incoming contact scheme: [%.*s]\n", 4, - contact_info->aor.s); - c = c->next; - continue; + + // perform full contact match + if(match_contact_host_port == 0) { + if((contact_info->aor.len > 0) + && (needle_uri.user.len != 0)) { + if((needle_uri.user.len != c->contact_user.len) + || (memcmp(needle_uri.user.s, c->contact_user.s, + needle_uri.user.len) + != 0)) { + LM_ERR("user name does not match - no match " + "here...\n"); + LM_DBG("found pcontact username [%d]: [%.*s]\n", i, + c->contact_user.len, c->contact_user.s); + LM_DBG("incoming contact username: [%.*s]\n", + needle_uri.user.len, needle_uri.user.s); + c = c->next; + continue; + } + if((contact_info->aor.len >= 4) + && (memcmp(contact_info->aor.s, c->aor.s, 4) + != 0)) { // do not mix up sip- and tel-URIs. + LM_ERR("scheme does not match - no match " + "here...\n"); + LM_DBG("found pcontact scheme [%d]: [%.*s]\n", i, 4, + c->aor.s); + LM_DBG("incoming contact scheme: [%.*s]\n", 4, + contact_info->aor.s); + c = c->next; + continue; + } + } else { + LM_DBG("No user name present - abort user name " + "check\n"); } - } else { - LM_DBG("No user name present - abort user name check\n"); } diff --git a/src/modules/ims_usrloc_scscf/README b/src/modules/ims_usrloc_scscf/README index d128b226b..b391a3409 100644 --- a/src/modules/ims_usrloc_scscf/README +++ b/src/modules/ims_usrloc_scscf/README @@ -443,9 +443,11 @@ Chapter 2. Frequently Asked Questions First at all check if your question was already answered on one of our mailing lists: * User Mailing List - - https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users + https://lists.kamailio.org/mailman3/postorius/lists/sr-users.lists. + kamailio.org/ * Developer Mailing List - - https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-dev + https://lists.kamailio.org/mailman3/postorius/lists/sr-dev.lists.ka + mailio.org/ E-mails regarding any stable Kamailio release should be sent to and e-mails regarding development diff --git a/src/modules/ims_usrloc_scscf/contact_dlg_handlers.c b/src/modules/ims_usrloc_scscf/contact_dlg_handlers.c index ad166ea65..c872fbef4 100644 --- a/src/modules/ims_usrloc_scscf/contact_dlg_handlers.c +++ b/src/modules/ims_usrloc_scscf/contact_dlg_handlers.c @@ -54,8 +54,10 @@ static inline int find_contact_from_impu( impurecord_t *impu, str *search_aor, ucontact_t **scontact) { impu_contact_t *impucontact; - short i_searchlen; + short i_searchlen, c_searchlen, alias_searchlen; char *s_term; + char *c_term; + char *alias_term; if(!search_aor) return 1; @@ -63,29 +65,57 @@ static inline int find_contact_from_impu( LM_DBG("Looking for contact [%.*s] for IMPU [%.*s]\n", search_aor->len, search_aor->s, impu->public_identity.len, impu->public_identity.s); - s_term = memchr(search_aor->s, '@', search_aor->len); + + /* Filter out sip: and anything before @ from search URI */ + s_term = strstr(search_aor->s, "@"); if(!s_term) { - LM_DBG("Malformed contact...bailing search\n"); - return 1; + s_term = strstr(search_aor->s, ":"); + } + s_term += 1; + if(s_term - search_aor->s >= search_aor->len) { + goto error; + } + i_searchlen = search_aor->len - (s_term - search_aor->s); + + /* Compare the entire contact including alias, if not until alias IP */ + alias_term = strstr(s_term, "~"); + if(!alias_term) { + alias_searchlen = i_searchlen; + } else { + alias_term += 1; + alias_searchlen = alias_term - s_term; } - i_searchlen = s_term - search_aor->s; impucontact = impu->linked_contacts.head; while(impucontact) { - if(impucontact->contact - && impucontact->contact->aor.s[i_searchlen] == '@' - && (memcmp(impucontact->contact->aor.s, search_aor->s, - i_searchlen) - == 0)) { - *scontact = impucontact->contact; - return 0; + if(impucontact->contact) { + + c_term = strstr(impucontact->contact->c.s, "@"); + if(!c_term) { + c_term = strstr(impucontact->contact->c.s, ":"); + } + c_term += 1; + c_searchlen = impucontact->contact->c.len + - (c_term - impucontact->contact->c.s); + + LM_DBG("Comparing [%.*s] and [%.*s]\n", i_searchlen, s_term, + c_searchlen, c_term); + LM_DBG("Comparing [%.*s] and [%.*s]\n", alias_searchlen, s_term, + c_searchlen, c_term); + if((strncmp(c_term, s_term, i_searchlen) == 0) + || (strncmp(c_term, s_term, alias_searchlen) == 0)) { + *scontact = impucontact->contact; + return 0; + } } if(impucontact->contact) - LM_DBG("Skipping %.*s\n", impucontact->contact->aor.len, - impucontact->contact->aor.s); + LM_DBG("Skipping %.*s\n", impucontact->contact->c.len, + impucontact->contact->c.s); impucontact = impucontact->next; } +error: + LM_INFO("malformed contact, bailing search\n"); return 1; } diff --git a/src/modules/influxdbc/Makefile b/src/modules/influxdbc/Makefile new file mode 100644 index 000000000..b08216cb2 --- /dev/null +++ b/src/modules/influxdbc/Makefile @@ -0,0 +1,9 @@ +# +# WARNING: do not run this directly, it should be run by the main Makefile + +include ../../Makefile.defs +auto_gen= +NAME=influxdbc.so +LIBS= + +include ../../Makefile.modules diff --git a/src/modules/influxdbc/README b/src/modules/influxdbc/README new file mode 100644 index 000000000..e5833a21d --- /dev/null +++ b/src/modules/influxdbc/README @@ -0,0 +1,235 @@ +ASYNC Module + +Daniel-Constantin Mierla + + + +Edited by + +Daniel-Constantin Mierla + + + + Copyright © 2024 asipto.com + __________________________________________________________________ + + Table of Contents + + 1. Admin Guide + + 1. Overview + 2. Dependencies + + 2.1. Kamailio Modules + 2.2. External Libraries or Applications + + 3. Parameters + + 3.1. server (int) + 3.2. port (int) + 3.3. database (int) + + 4. Functions + + 4.1. influxdbc_measure(name) + 4.2. influxdbc_measureend() + 4.3. influxdbc_sub(name) + 4.4. influxdbc_subend() + 4.5. influxdbc_push() + 4.6. influxdbc_long(name, value) + + List of Examples + + 1.1. Set server parameter + 1.2. Set port parameter + 1.3. Set database parameter + 1.4. influxdbc_measure() usage + 1.5. influxdbc_measureend() usage + 1.6. influxdbc_sub() usage + 1.7. influxdbc_subend() usage + 1.8. influxdbc_push() usage + 1.9. influxdbc_long() usage + +Chapter 1. Admin Guide + + Table of Contents + + 1. Overview + 2. Dependencies + + 2.1. Kamailio Modules + 2.2. External Libraries or Applications + + 3. Parameters + + 3.1. server (int) + 3.2. port (int) + 3.3. database (int) + + 4. Functions + + 4.1. influxdbc_measure(name) + 4.2. influxdbc_measureend() + 4.3. influxdbc_sub(name) + 4.4. influxdbc_subend() + 4.5. influxdbc_push() + 4.6. influxdbc_long(name, value) + +1. Overview + + This module provides a client connector for InfluxDB. + +2. Dependencies + + 2.1. Kamailio Modules + 2.2. External Libraries or Applications + +2.1. Kamailio Modules + + The following modules must be loaded before this module: + * none. + +2.2. External Libraries or Applications + + The following libraries or applications must be installed before + running Kamailio with this module loaded: + * none. + +3. Parameters + + 3.1. server (int) + 3.2. port (int) + 3.3. database (int) + +3.1. server (int) + + Address of InfluxDB server. + + Default value is empty. + + Example 1.1. Set server parameter +... +modparam("influxdbc", "server", "127.0.0.1") +... + +3.2. port (int) + + Address of InfluxDB server. + + Default value is 8086. + + Example 1.2. Set port parameter +... +modparam("influxdbc", "port", 8808) +... + +3.3. database (int) + + Database of InfluxDB server. + + Default value is empty. + + Example 1.3. Set database parameter +... +modparam("influxdbc", "database", "stats") +... + +4. Functions + + 4.1. influxdbc_measure(name) + 4.2. influxdbc_measureend() + 4.3. influxdbc_sub(name) + 4.4. influxdbc_subend() + 4.5. influxdbc_push() + 4.6. influxdbc_long(name, value) + +4.1. influxdbc_measure(name) + + Start a measure group with the given name. + + This function can be used from ANY_ROUTE. + + Example 1.4. influxdbc_measure() usage +... +request_route { + ... + influxdbc_measure("stats"); + ... +} +... + +4.2. influxdbc_measureend() + + End the current measure group. + + This function can be used from ANY_ROUTE. + + Example 1.5. influxdbc_measureend() usage +... +request_route { + ... + influxdbc_measureend(); + ... +} +... + +4.3. influxdbc_sub(name) + + Start a measure subgroup with the given name. + + This function can be used from ANY_ROUTE. + + Example 1.6. influxdbc_sub() usage +... +request_route { + ... + influxdbc_sub("grp1"); + ... +} +... + +4.4. influxdbc_subend() + + End the current measure subgroup. + + This function can be used from ANY_ROUTE. + + Example 1.7. influxdbc_subend() usage +... +request_route { + ... + influxdbc_subend(); + ... +} +... + +4.5. influxdbc_push() + + Push accumulated values to the server. + + This function can be used from ANY_ROUTE. + + Example 1.8. influxdbc_push() usage +... +request_route { + ... + influxdbc_push(); + ... +} +... + +4.6. influxdbc_long(name, value) + + Save the pair with provided name and value. Both parameters can have + variables. + + This function can be used from ANY_ROUTE. + + Example 1.9. influxdbc_long() usage +... +request_route { + ... + influxdbc_long("active", "$shv(active)"); + ... +} +... diff --git a/src/modules/influxdbc/doc/Makefile b/src/modules/influxdbc/doc/Makefile new file mode 100644 index 000000000..e86a2f80e --- /dev/null +++ b/src/modules/influxdbc/doc/Makefile @@ -0,0 +1,4 @@ +docs = influxdbc.xml + +docbook_dir = ../../../../doc/docbook +include $(docbook_dir)/Makefile.module diff --git a/src/modules/influxdbc/doc/influxdbc.xml b/src/modules/influxdbc/doc/influxdbc.xml new file mode 100644 index 000000000..35f034878 --- /dev/null +++ b/src/modules/influxdbc/doc/influxdbc.xml @@ -0,0 +1,36 @@ + + + +%docentities; + +]> + + + + ASYNC Module + kamailio.org + + + Daniel-Constantin + Mierla + miconda@gmail.com + + + Daniel-Constantin + Mierla + miconda@gmail.com + + + + 2024 + asipto.com + + + + + + + diff --git a/src/modules/influxdbc/doc/influxdbc_admin.xml b/src/modules/influxdbc/doc/influxdbc_admin.xml new file mode 100644 index 000000000..e6560bc0d --- /dev/null +++ b/src/modules/influxdbc/doc/influxdbc_admin.xml @@ -0,0 +1,256 @@ + + + +%docentities; + +]> + + + + + &adminguide; + +
+ Overview + + This module provides a client connector for InfluxDB. + +
+ +
+ Dependencies +
+ &kamailio; Modules + + The following modules must be loaded before this module: + + + + none. + + + + +
+
+ External Libraries or Applications + + The following libraries or applications must be installed before running + &kamailio; with this module loaded: + + + + none. + + + + +
+
+
+ Parameters +
+ <varname>server</varname> (int) + + Address of InfluxDB server. + + + + Default value is empty. + + + + Set <varname>server</varname> parameter + +... +modparam("influxdbc", "server", "127.0.0.1") +... + + +
+
+ <varname>port</varname> (int) + + Address of InfluxDB server. + + + + Default value is 8086. + + + + Set <varname>port</varname> parameter + +... +modparam("influxdbc", "port", 8808) +... + + +
+
+ <varname>database</varname> (int) + + Database of InfluxDB server. + + + + Default value is empty. + + + + Set <varname>database</varname> parameter + +... +modparam("influxdbc", "database", "stats") +... + + +
+
+ +
+ Functions +
+ + <function moreinfo="none">influxdbc_measure(name)</function> + + + Start a measure group with the given name. + + + This function can be used from ANY_ROUTE. + + + <function>influxdbc_measure()</function> usage + +... +request_route { + ... + influxdbc_measure("stats"); + ... +} +... + + +
+
+ + <function moreinfo="none">influxdbc_measureend()</function> + + + End the current measure group. + + + This function can be used from ANY_ROUTE. + + + <function>influxdbc_measureend()</function> usage + +... +request_route { + ... + influxdbc_measureend(); + ... +} +... + + +
+
+ + <function moreinfo="none">influxdbc_sub(name)</function> + + + Start a measure subgroup with the given name. + + + This function can be used from ANY_ROUTE. + + + <function>influxdbc_sub()</function> usage + +... +request_route { + ... + influxdbc_sub("grp1"); + ... +} +... + + +
+
+ + <function moreinfo="none">influxdbc_subend()</function> + + + End the current measure subgroup. + + + This function can be used from ANY_ROUTE. + + + <function>influxdbc_subend()</function> usage + +... +request_route { + ... + influxdbc_subend(); + ... +} +... + + +
+
+ + <function moreinfo="none">influxdbc_push()</function> + + + Push accumulated values to the server. + + + This function can be used from ANY_ROUTE. + + + <function>influxdbc_push()</function> usage + +... +request_route { + ... + influxdbc_push(); + ... +} +... + + +
+
+ + <function moreinfo="none">influxdbc_long(name, value)</function> + + + Save the pair with provided name and value. Both parameters can + have variables. + + + This function can be used from ANY_ROUTE. + + + <function>influxdbc_long()</function> usage + +... +request_route { + ... + influxdbc_long("active", "$shv(active)"); + ... +} +... + + +
+
+
diff --git a/src/modules/influxdbc/ic.c b/src/modules/influxdbc/ic.c new file mode 100644 index 000000000..dc493619f --- /dev/null +++ b/src/modules/influxdbc/ic.c @@ -0,0 +1,368 @@ +/* + * Influx C (ic) client for data capture + * Developer: Nigel Griffiths. + * (C) Copyright 2021 Nigel Griffiths + + This program 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 3 of the license, or + (at your option) any later version. + + This program 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, see . + + Compile: cc ic.c -g -O3 -o ic + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG if(debug) +#define MEGABYTE (1024 * 1024) /* USed as the default buffer sizes */ + +int debug = 0; /* 0=off, 1=on basic, 2=trace like output */ + +char influx_hostname[1024 + 1] = { + 0}; /* details of the influxdb server or telegraf */ +char influx_ip[16 + 1] = {0}; +long influx_port = 0; + +char influx_database[256 + 1]; /* the influxdb database */ +char influx_username[64 + 1]; /* optional for influxdb access */ +char influx_password[64 + 1]; /* optional for influxdb access */ + +char *output; /* all the stats must fit in this buffer */ +long output_size = 0; +long output_char = 0; + +char *influx_tags; /* saved tags for every influxdb line protocol mesurement */ + +int subended = 0; /* stop ic_subend and ic_measureend both enig the measure */ +int first_sub = + 0; /* need to remove the ic_measure measure before adding ic_sub measure */ +char saved_section[64]; +char saved_sub[64]; + +int sockfd; /* file desciptor for socket connection */ + +void error(char *buf) +{ + fprintf(stderr, "error: \"%s\" errno=%d meaning=\"%s\"\n", buf, errno, + strerror(errno)); + close(sockfd); + sleep(2); /* this can help the socket close cleanly at the remote end */ + exit(1); +} + +void ic_debug(int level) +{ + debug = level; +} + +/* ic_tags() argument is the measurement tags for influddb */ +/* example: "host=vm1234" note:the comma & hostname of the virtual machine sending the data */ +/* complex: "host=lpar42,serialnum=987654,arch=power9" note:the comma separated list */ +void ic_tags(char *t) +{ + DEBUG fprintf(stderr, "ic_tags(%s)\n", t); + if(influx_tags == (char *)0) { + if((influx_tags = (char *)malloc(MEGABYTE)) == (char *)-1) + error("failed to malloc() tags buffer"); + } + + strncpy(influx_tags, t, 256); +} + +void ic_influx_database(char *host, long port, + char *db) /* note: converts influxdb hostname to ip address */ +{ + struct hostent *he; + char errorbuf[1024 + 1]; + + influx_port = port; + strncpy(influx_database, db, 256); + + if(host[0] <= '0' && host[0] <= '9') { + DEBUG fprintf(stderr, "ic_influx(ipaddr=%s,port=%ld,database=%s))\n", + host, port, db); + strncpy(influx_ip, host, 16); + } else { + DEBUG fprintf(stderr, + "ic_influx_by_hostname(host=%s,port=%ld,database=%s))\n", host, + port, db); + strncpy(influx_hostname, host, 1024); + if(isalpha(host[0])) { + + he = gethostbyname(host); + if(he == NULL) { + snprintf(errorbuf, 1024, + "influx host=%s to ip address convertion failed " + "gethostbyname(), bailing out\n", + host); + error(errorbuf); + } + /* this could return multiple ip addresses but we assume its the first one */ + if(he->h_addr_list[0] != NULL) { + strncpy(influx_ip, + inet_ntoa(*(struct in_addr *)(he->h_addr_list[0])), 16); + influx_ip[16] = '\0'; + DEBUG fprintf(stderr, + "ic_influx_by_hostname hostname=%s converted to ip " + "address %s))\n", + host, influx_ip); + } else { + snprintf(errorbuf, 1024, + "influx host=%s to ip address convertion failed (empty " + "list), bailing out\n", + host); + error(errorbuf); + } + } else { + strncpy(influx_ip, host, + 16); /* perhaps the hostname is actually an ip address */ + influx_ip[16] = '\0'; + } + } +} + +void ic_influx_userpw(char *user, char *pw) +{ + DEBUG fprintf( + stderr, "ic_influx_userpw(username=%s,pssword=%s))\n", user, pw); + strncpy(influx_username, user, 64); + strncpy(influx_password, pw, 64); +} + +int create_socket() /* returns 1 for error and 0 for ok */ +{ + static struct sockaddr_in serv_addr; + + if(debug) + DEBUG fprintf(stderr, "socket: trying to connect to \"%s\":%ld\n", + influx_ip, influx_port); + if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + error("socket() call failed"); + return 0; + } + + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = inet_addr(influx_ip); + serv_addr.sin_port = htons(influx_port); + + /* connect tot he socket offered by the web server */ + if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { + DEBUG fprintf(stderr, " connect() call failed errno=%d", errno); + return 0; + } + return 1; +} + +void ic_check(long adding) /* Check the buffer space */ +{ + if(output == (char *)0) { /* First time create the buffer */ + /* if( (output = (char *)malloc(MEGABYTE)) == (char *)-1) + error("failed to malloc() output buffer"); + } + if(output_char + (2*adding) > output_size) */ /* When near the end of the output buffer, extend it*/ + if((output = (char *)realloc(output, output_size + MEGABYTE)) + == (char *)-1) + error("failed to realloc() output buffer"); + } +} + +void remove_ending_comma_if_any() +{ + if(output[output_char - 1] == ',') { + output[output_char - 1] = 0; /* remove the char */ + output_char--; + } +} + +void ic_measure(char *section) +{ + ic_check(strlen(section) + strlen(influx_tags) + 3); + + output_char += + sprintf(&output[output_char], "%s,%s ", section, influx_tags); + strcpy(saved_section, section); + first_sub = 1; + subended = 0; + DEBUG fprintf( + stderr, "ic_measure(\"%s\") count=%ld\n", section, output_char); +} + +void ic_measureend() +{ + ic_check(4); + remove_ending_comma_if_any(); + if(!subended) { + output_char += sprintf(&output[output_char], " \n"); + } + subended = 0; + DEBUG fprintf(stderr, "ic_measureend()\n"); +} + +/* Note this added a further tag to the measurement of the "resource_name" */ +/* measurement might be "disks" */ +/* sub might be "sda1", "sdb1", etc */ +void ic_sub(char *resource) +{ + int i; + + ic_check(strlen(saved_section) + strlen(influx_tags) + strlen(saved_sub) + + strlen(resource) + 9); + + /* remove previously added section */ + if(first_sub) { + for(i = output_char - 1; i > 0; i--) { + if(output[i] == '\n') { + output[i + 1] = 0; + output_char = i + 1; + break; + } + } + } + first_sub = 0; + + /* remove the trailing s */ + strcpy(saved_sub, saved_section); + if(saved_sub[strlen(saved_sub) - 1] == 's') { + saved_sub[strlen(saved_sub) - 1] = 0; + } + output_char += sprintf(&output[output_char], "%s,%s,%s_name=%s ", + saved_section, influx_tags, saved_sub, resource); + subended = 0; + DEBUG fprintf(stderr, "ic_sub(\"%s\") count=%ld\n", resource, output_char); +} + +void ic_subend() +{ + ic_check(4); + remove_ending_comma_if_any(); + output_char += sprintf(&output[output_char], " \n"); + subended = 1; + DEBUG fprintf(stderr, "ic_subend()\n"); +} + +void ic_long(char *name, long long value) +{ + ic_check(strlen(name) + 16 + 4); + output_char += sprintf(&output[output_char], "%s=%lldi,", name, value); + DEBUG fprintf(stderr, "ic_long(\"%s\",%lld) count=%ld\n", name, value, + output_char); +} + +void ic_double(char *name, double value) +{ + ic_check(strlen(name) + 16 + 4); + if(isnan(value) || isinf(value)) { /* not-a-number or infinity */ + DEBUG fprintf(stderr, "ic_double(%s,%.1f) - nan error\n", name, value); + } else { + output_char += sprintf(&output[output_char], "%s=%.3f,", name, value); + DEBUG fprintf(stderr, "ic_double(\"%s\",%.1f) count=%ld\n", name, value, + output_char); + } +} + +void ic_string(char *name, char *value) +{ + int i; + int len; + + ic_check(strlen(name) + strlen(value) + 4); + len = strlen(value); + for(i = 0; i < len; i++) /* replace problem characters and with a space */ + if(value[i] == '\n' || iscntrl(value[i])) + value[i] = ' '; + output_char += sprintf(&output[output_char], "%s=\"%s\",", name, value); + DEBUG fprintf(stderr, "ic_string(\"%s\",\"%s\") count=%ld\n", name, value, + output_char); +} + +void ic_push() +{ + char result[1024]; + char buffer[1024 * 8]; + int ret; + int i; + int total; + int sent; + int code; + + if(output_char == 0) /* nothing to send so skip this operation */ + return; + if(influx_port) { + DEBUG fprintf(stderr, "ic_push() size=%ld\n", output_char); + if(create_socket() == 1) { + + sprintf(buffer, + "POST /write?db=%s&u=%s&p=%s HTTP/1.1\r\nHost: " + "%s:%ld\r\nContent-Length: %ld\r\n\r\n", + influx_database, influx_username, influx_password, + influx_hostname, influx_port, output_char); + DEBUG fprintf(stderr, "buffer size=%ld\nbuffer=<%s>\n", + strlen(buffer), buffer); + if((ret = write(sockfd, buffer, strlen(buffer))) + != strlen(buffer)) { + fprintf(stderr, + "warning: \"write post to sockfd failed.\" errno=%d\n", + errno); + } + total = output_char; + sent = 0; + if(debug == 2) + fprintf(stderr, "output size=%d output=\n<%s>\n", total, + output); + while(sent < total) { + ret = write(sockfd, &output[sent], total - sent); + DEBUG fprintf(stderr, "written=%d bytes sent=%d total=%d\n", + ret, sent, total); + if(ret < 0) { + fprintf(stderr, + "warning: \"write body to sockfd failed.\" " + "errno=%d\n", + errno); + break; + } + sent = sent + ret; + } + for(i = 0; i < 1024; i++) /* empty the buffer */ + result[i] = 0; + if((ret = read(sockfd, result, sizeof(result) - 1)) > 0) { + result[ret] = 0; + DEBUG fprintf( + stderr, "received bytes=%d data=<%s>\n", ret, result); + sscanf(result, "HTTP/1.1 %d", &code); + for(i = 13; i < 1024; i++) + if(result[i] == '\r') + result[i] = 0; + if(debug == 2) + fprintf(stderr, "http-code=%d text=%s [204=Success]\n", + code, &result[13]); + if(code != 204) + fprintf(stderr, "code %d -->%s<--\n", code, result); + } + close(sockfd); + sockfd = 0; + DEBUG fprintf(stderr, "ic_push complete\n"); + } else { + DEBUG fprintf(stderr, "socket create failed\n"); + } + } else + error("influx port is not set, bailing out"); + + output[0] = 0; + output_char = 0; +} diff --git a/src/modules/influxdbc/ic.h b/src/modules/influxdbc/ic.h new file mode 100644 index 000000000..8fa18ec86 --- /dev/null +++ b/src/modules/influxdbc/ic.h @@ -0,0 +1,21 @@ +/* + * Influx C (ic) client for data capture header file + * Developer: Nigel Griffiths. + * (C) Copyright 2021 Nigel Griffiths + */ +void ic_influx_database(char *host, long port, char *db); +void ic_influx_userpw(char *user, char *pw); +void ic_tags(char *tags); + +void ic_measure(char *section); +void ic_measureend(); + +void ic_sub(char *sub_name); +void ic_subend(); + +void ic_long(char *name, long long value); +void ic_double(char *name, double value); +void ic_string(char *name, char *value); + +void ic_push(); +void ic_debug(int level); diff --git a/src/modules/influxdbc/influxdbc_mod.c b/src/modules/influxdbc/influxdbc_mod.c new file mode 100644 index 000000000..5261b5ea5 --- /dev/null +++ b/src/modules/influxdbc/influxdbc_mod.c @@ -0,0 +1,400 @@ +/** + * Copyright (C) 2024 Daniel-Constantin Mierla (asipto.com) + * + * This file is part of Kamailio, a free SIP server. + * + * This file 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 + * + * + * This file 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 + * + */ + +#include +#include +#include +#include + + +#include "../../core/sr_module.h" +#include "../../core/dprint.h" +#include "../../core/ut.h" +#include "../../core/mod_fix.h" +#include "../../core/kemi.h" +#include "../../core/utils/sruid.h" + +#include "ic.h" + +MODULE_VERSION + +static char *_infdbc_server = NULL; +static int _infdbc_port = 8086; +static char *_infdbc_database = NULL; +static int _infdbc_connected = 0; +static char *_infdbc_user = NULL; +static char *_infdbc_password = NULL; +static char *_infdbc_tags = NULL; + +static int w_influxdbc_measure(sip_msg_t *msg, char *pname, char *p2); +static int w_influxdbc_measureend(sip_msg_t *msg, char *p1, char *p2); +static int w_influxdbc_sub(sip_msg_t *msg, char *pname, char *p2); +static int w_influxdbc_subend(sip_msg_t *msg, char *p1, char *p2); +static int w_influxdbc_push(sip_msg_t *msg, char *p1, char *p2); +static int w_influxdbc_long(sip_msg_t *msg, char *pname, char *pvalue); +static int w_influxdbc_string(sip_msg_t *msg, char *pname, char *pvalue); +static int w_influxdbc_double(sip_msg_t *msg, char *pname, char *pvalue); +static int w_influxdbc_division( + sip_msg_t *msg, char *pname, char *pdividend, char *pdivisor); + +static int mod_init(void); +static int child_init(int); +static void mod_destroy(void); + +/* clang-format off */ +static cmd_export_t cmds[] = { + {"influxdbc_measure", (cmd_function)w_influxdbc_measure, + 1, fixup_spve_null, 0, ANY_ROUTE}, + {"influxdbc_measureend", (cmd_function)w_influxdbc_measureend, + 0, 0, 0, ANY_ROUTE}, + {"influxdbc_sub", (cmd_function)w_influxdbc_sub, + 1, fixup_spve_null, 0, ANY_ROUTE}, + {"influxdbc_subend", (cmd_function)w_influxdbc_subend, + 0, 0, 0, ANY_ROUTE}, + {"influxdbc_push", (cmd_function)w_influxdbc_push, + 0, 0, 0, ANY_ROUTE}, + {"influxdbc_long", (cmd_function)w_influxdbc_long, + 2, fixup_spve_igp, 0, ANY_ROUTE}, + {"influxdbc_string", (cmd_function)w_influxdbc_string, + 2, fixup_spve_spve, 0, ANY_ROUTE}, + {"influxdbc_double", (cmd_function)w_influxdbc_double, + 2, fixup_spve_spve, 0, ANY_ROUTE}, + {"influxdbc_division", (cmd_function)w_influxdbc_division, + 3, fixup_sii, fixup_free_sii, ANY_ROUTE}, + + {0, 0, 0, 0, 0, 0} +}; + +static param_export_t params[] = { + {"server", PARAM_STRING, &_infdbc_server}, + {"database", PARAM_STRING, &_infdbc_database}, + {"port", PARAM_INT, &_infdbc_port}, + {"user", PARAM_STRING, &_infdbc_user}, + {"password", PARAM_STRING, &_infdbc_password}, + {"tags", PARAM_STRING, &_infdbc_tags}, + + {0, 0, 0} +}; + +struct module_exports exports = { + "influxdbc", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* exported functions */ + params, /* exported parameters */ + 0, /* exported rpc functions */ + 0, /* exported pseudo-variables */ + 0, /* response handling function */ + mod_init, /* module init function */ + child_init, /* per child init function */ + mod_destroy /* destroy function */ +}; +/* clang-format on */ + +/** + * init module function + */ +static int mod_init(void) +{ + if(_infdbc_server == NULL) { + LM_ERR("server address not provided\n"); + return -1; + } + if(_infdbc_database == NULL) { + LM_ERR("database name not provided\n"); + return -1; + } + return 0; +} + +/** + * @brief Initialize async module children + */ +static int child_init(int rank) +{ + if(rank != PROC_MAIN) + return 0; + + return 0; +} +/** + * destroy module function + */ +static void mod_destroy(void) +{ +} + +/** + * + */ +static int w_influxdbc_measure(sip_msg_t *msg, char *pname, char *p2) +{ + str sname; + + if(fixup_get_svalue(msg, (gparam_t *)pname, &sname) != 0) { + LM_ERR("unable to get name parameter\n"); + return -1; + } + if(_infdbc_connected == 0) { + ic_influx_database(_infdbc_server, _infdbc_port, _infdbc_database); + if(_infdbc_user != NULL && _infdbc_password != NULL) { + ic_influx_userpw(_infdbc_user, _infdbc_password); + } + if(_infdbc_tags != NULL) { + ic_tags(_infdbc_tags); + } + _infdbc_connected = 1; + } + + ic_measure(sname.s); + + return 1; +} + +/** + * + */ +static int ki_influxdbc_measure(sip_msg_t *msg, str *name) +{ + ic_measure(name->s); + + return 1; +} + +/** + * + */ +static int w_influxdbc_measureend(sip_msg_t *msg, char *p1, char *p2) +{ + ic_measureend(); + + return 1; +} + +/** + * + */ +static int ki_influxdbc_measureend(sip_msg_t *msg) +{ + ic_measureend(); + + return 1; +} + +/** + * + */ +static int w_influxdbc_sub(sip_msg_t *msg, char *pname, char *p2) +{ + str sname; + + if(fixup_get_svalue(msg, (gparam_t *)pname, &sname) != 0) { + LM_ERR("unable to get name parameter\n"); + return -1; + } + + ic_sub(sname.s); + + return 1; +} + +/** + * + */ +static int w_influxdbc_subend(sip_msg_t *msg, char *p1, char *p2) +{ + ic_subend(); + + return 1; +} + +/** + * + */ +static int w_influxdbc_push(sip_msg_t *msg, char *p1, char *p2) +{ + ic_push(); + + return 1; +} + +/** + * + */ +static int ki_influxdbc_push(sip_msg_t *msg) +{ + ic_push(); + + return 1; +} + +/** + * + */ +static int w_influxdbc_long(sip_msg_t *msg, char *pname, char *pvalue) +{ + str sname; + int ival; + + if(fixup_get_svalue(msg, (gparam_t *)pname, &sname) != 0) { + LM_ERR("unable to get name parameter\n"); + return -1; + } + if(fixup_get_ivalue(msg, (gparam_t *)pvalue, &ival) != 0) { + LM_ERR("unable to get value parameter\n"); + return -1; + } + + ic_long(sname.s, ival); + + return 1; +} + +/** + * + */ +static int ki_influxdbc_long(sip_msg_t *msg, str *name, int val) +{ + ic_long(name->s, val); + + return 1; +} + +/** + * + */ +static int w_influxdbc_string(sip_msg_t *msg, char *pname, char *pvalue) +{ + str sname; + str sval; + + if(fixup_get_svalue(msg, (gparam_t *)pname, &sname) != 0) { + LM_ERR("unable to get name parameter\n"); + return -1; + } + if(fixup_get_svalue(msg, (gparam_t *)pvalue, &sval) != 0) { + LM_ERR("unable to get value parameter\n"); + return -1; + } + + ic_string(sname.s, sval.s); + + return 1; +} + + +/** + * + */ +static int w_influxdbc_double(sip_msg_t *msg, char *pname, char *pvalue) +{ + str sname; + str sval; + double dval = 0.0; + + if(fixup_get_svalue(msg, (gparam_t *)pname, &sname) != 0) { + LM_ERR("unable to get name parameter\n"); + return -1; + } + if(fixup_get_svalue(msg, (gparam_t *)pvalue, &sval) != 0) { + LM_ERR("unable to get value parameter\n"); + return -1; + } + + dval = strtod(sval.s, NULL); + + ic_double(sname.s, dval); + + return 1; +} + + +/** + * + */ +static int w_influxdbc_division( + sip_msg_t *msg, char *pname, char *pdividend, char *pdivisor) +{ + str sname; + int idividend; + int idivisor; + + if(fixup_get_svalue(msg, (gparam_t *)pname, &sname) != 0) { + LM_ERR("unable to get name parameter\n"); + return -1; + } + if(fixup_get_ivalue(msg, (gparam_t *)pdividend, &idividend) != 0) { + LM_ERR("unable to get dividend parameter\n"); + return -1; + } + if(fixup_get_ivalue(msg, (gparam_t *)pdivisor, &idivisor) != 0) { + LM_ERR("unable to get divisor parameter\n"); + return -1; + } + if(idivisor == 0) { + ic_double(sname.s, 0.0); + return 1; + } + + ic_double(sname.s, (double)idividend / (double)idivisor); + + return 1; +} + +/** + * + */ +/* clang-format off */ +static sr_kemi_t sr_kemi_influxdbc_exports[] = { + { str_init("influxdbc"), str_init("measure"), + SR_KEMIP_INT, ki_influxdbc_measure, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("influxdbc"), str_init("measureend"), + SR_KEMIP_INT, ki_influxdbc_measureend, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("influxdbc"), str_init("ic_long"), + SR_KEMIP_INT, ki_influxdbc_long, + { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("influxdbc"), str_init("push"), + SR_KEMIP_INT, ki_influxdbc_push, + { 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 } } +}; +/* clang-format on */ + + +/** + * + */ +int mod_register(char *path, int *dlflags, void *p1, void *p2) +{ + sr_kemi_modules_add(sr_kemi_influxdbc_exports); + return 0; +} diff --git a/src/modules/ipops/ipops_mod.c b/src/modules/ipops/ipops_mod.c index 77714a903..265e89625 100644 --- a/src/modules/ipops/ipops_mod.c +++ b/src/modules/ipops/ipops_mod.c @@ -114,81 +114,83 @@ static int w_naptr_query(sip_msg_t *msg, char *str1, char *str2); static int w_dns_set_local_ttl(sip_msg_t *, char *, char *); static int mod_init(void); +/* clang-format off */ static pv_export_t mod_pvs[] = { - {{"dns", sizeof("dns") - 1}, PVT_OTHER, pv_get_dns, 0, - pv_parse_dns_name, 0, 0, 0}, - {{"srvquery", sizeof("srvquery") - 1}, PVT_OTHER, pv_get_srv, 0, - pv_parse_srv_name, 0, 0, 0}, - {{"naptrquery", sizeof("naptrquery") - 1}, PVT_OTHER, pv_get_naptr, 0, - pv_parse_naptr_name, 0, 0, 0}, - {{"HN", sizeof("HN") - 1}, PVT_OTHER, pv_get_hn, 0, pv_parse_hn_name, 0, - 0, 0}, - {{0, 0}, 0, 0, 0, 0, 0, 0, 0}}; + {{"dns", sizeof("dns") - 1}, PVT_OTHER, pv_get_dns, 0, + pv_parse_dns_name, 0, 0, 0}, + {{"srvquery", sizeof("srvquery") - 1}, PVT_OTHER, pv_get_srv, 0, + pv_parse_srv_name, 0, 0, 0}, + {{"naptrquery", sizeof("naptrquery") - 1}, PVT_OTHER, pv_get_naptr, 0, + pv_parse_naptr_name, 0, 0, 0}, + {{"HN", sizeof("HN") - 1}, PVT_OTHER, pv_get_hn, 0, pv_parse_hn_name, 0, + 0, 0}, + {{0, 0}, 0, 0, 0, 0, 0, 0, 0} +}; /* * Exported functions */ static cmd_export_t cmds[] = { - {"is_ip", (cmd_function)w_is_ip, 1, fixup_spve_null, - fixup_free_spve_null, ANY_ROUTE}, - {"is_pure_ip", (cmd_function)w_is_pure_ip, 1, fixup_spve_null, - fixup_free_spve_null, ANY_ROUTE}, - {"is_ipv4", (cmd_function)w_is_ipv4, 1, fixup_spve_null, - fixup_free_spve_null, ANY_ROUTE}, - {"is_ipv6", (cmd_function)w_is_ipv6, 1, fixup_spve_null, - fixup_free_spve_null, ANY_ROUTE}, - {"is_ipv6_reference", (cmd_function)w_is_ipv6_reference, 1, - fixup_spve_null, fixup_free_spve_null, ANY_ROUTE}, - {"ip_type", (cmd_function)w_ip_type, 1, fixup_spve_null, - fixup_free_spve_null, ANY_ROUTE}, - {"detailed_ipv4_type", (cmd_function)w_detailed_ipv4_type, 2, - fixup_detailed_ip_type, fixup_free_detailed_ip_type, ANY_ROUTE}, - {"detailed_ipv6_type", (cmd_function)w_detailed_ipv6_type, 2, - fixup_detailed_ip_type, fixup_free_detailed_ip_type, ANY_ROUTE}, - {"detailed_ip_type", (cmd_function)w_detailed_ip_type, 2, - fixup_detailed_ip_type, fixup_free_detailed_ip_type, ANY_ROUTE}, - {"compare_ips", (cmd_function)w_compare_ips, 2, fixup_spve_spve, - fixup_free_spve_spve, ANY_ROUTE}, - {"compare_pure_ips", (cmd_function)w_compare_pure_ips, 2, - fixup_spve_spve, fixup_free_spve_spve, ANY_ROUTE}, - {"is_ip_rfc1918", (cmd_function)w_is_ip_rfc1918, 1, fixup_spve_null, - fixup_free_spve_null, ANY_ROUTE}, - {"is_in_subnet", (cmd_function)w_ip_is_in_subnet, 2, fixup_spve_spve, - fixup_free_spve_spve, ANY_ROUTE}, - {"dns_sys_match_ip", (cmd_function)w_dns_sys_match_ip, 2, - fixup_spve_spve, fixup_free_spve_spve, ANY_ROUTE}, - {"dns_int_match_ip", (cmd_function)w_dns_int_match_ip, 2, - fixup_spve_spve, fixup_free_spve_spve, ANY_ROUTE}, - {"dns_query", (cmd_function)w_dns_query, 2, fixup_spve_spve, - fixup_free_spve_spve, ANY_ROUTE}, - {"srv_query", (cmd_function)w_srv_query, 2, fixup_spve_spve, - fixup_free_spve_spve, ANY_ROUTE}, - {"naptr_query", (cmd_function)w_naptr_query, 2, fixup_spve_spve, - fixup_free_spve_spve, ANY_ROUTE}, - {"dns_set_local_ttl", (cmd_function)w_dns_set_local_ttl, 1, - fixup_igp_null, fixup_free_igp_null, ANY_ROUTE}, - - {"bind_ipops", (cmd_function)bind_ipops, 0, 0, 0, 0}, - - {0, 0, 0, 0, 0, 0}}; - + {"is_ip", (cmd_function)w_is_ip, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"is_pure_ip", (cmd_function)w_is_pure_ip, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"is_ipv4", (cmd_function)w_is_ipv4, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"is_ipv6", (cmd_function)w_is_ipv6, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"is_ipv6_reference", (cmd_function)w_is_ipv6_reference, 1, + fixup_spve_null, fixup_free_spve_null, ANY_ROUTE}, + {"ip_type", (cmd_function)w_ip_type, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"detailed_ipv4_type", (cmd_function)w_detailed_ipv4_type, 2, + fixup_detailed_ip_type, fixup_free_detailed_ip_type, ANY_ROUTE}, + {"detailed_ipv6_type", (cmd_function)w_detailed_ipv6_type, 2, + fixup_detailed_ip_type, fixup_free_detailed_ip_type, ANY_ROUTE}, + {"detailed_ip_type", (cmd_function)w_detailed_ip_type, 2, + fixup_detailed_ip_type, fixup_free_detailed_ip_type, ANY_ROUTE}, + {"compare_ips", (cmd_function)w_compare_ips, 2, fixup_spve_spve, + fixup_free_spve_spve, ANY_ROUTE}, + {"compare_pure_ips", (cmd_function)w_compare_pure_ips, 2, + fixup_spve_spve, fixup_free_spve_spve, ANY_ROUTE}, + {"is_ip_rfc1918", (cmd_function)w_is_ip_rfc1918, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"is_in_subnet", (cmd_function)w_ip_is_in_subnet, 2, fixup_spve_spve, + fixup_free_spve_spve, ANY_ROUTE}, + {"dns_sys_match_ip", (cmd_function)w_dns_sys_match_ip, 2, + fixup_spve_spve, fixup_free_spve_spve, ANY_ROUTE}, + {"dns_int_match_ip", (cmd_function)w_dns_int_match_ip, 2, + fixup_spve_spve, fixup_free_spve_spve, ANY_ROUTE}, + {"dns_query", (cmd_function)w_dns_query, 2, fixup_spve_spve, + fixup_free_spve_spve, ANY_ROUTE}, + {"srv_query", (cmd_function)w_srv_query, 2, fixup_spve_spve, + fixup_free_spve_spve, ANY_ROUTE}, + {"naptr_query", (cmd_function)w_naptr_query, 2, fixup_spve_spve, + fixup_free_spve_spve, ANY_ROUTE}, + {"dns_set_local_ttl", (cmd_function)w_dns_set_local_ttl, 1, + fixup_igp_null, fixup_free_igp_null, ANY_ROUTE}, + + {"bind_ipops", (cmd_function)bind_ipops, 0, 0, 0, 0}, + + {0, 0, 0, 0, 0, 0} +}; /* * Module interface */ struct module_exports exports = { - "ipops", /* module name */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* cmd (cfg function) exports */ - 0, /* param exports*/ - 0, /* RPC method exports */ - mod_pvs, /* exported pseudo-variables */ - 0, /* response handling function */ - mod_init, /* module init function */ - 0, /* per-child init function */ - 0 /* module destroy function */ + "ipops", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* cmd (cfg function) exports */ + 0, /* param exports*/ + 0, /* RPC method exports */ + mod_pvs, /* exported pseudo-variables */ + 0, /* response handling function */ + mod_init, /* module init function */ + 0, /* per-child init function */ + 0 /* module destroy function */ }; - +/* clang-format on */ static int mod_init(void) { diff --git a/src/modules/jansson/README b/src/modules/jansson/README index 815826d24..550c9d62a 100644 --- a/src/modules/jansson/README +++ b/src/modules/jansson/README @@ -29,14 +29,14 @@ Carsten Bock 3. Functions - 3.1. jansson_get(key/path, src, dst) + 3.1. jansson_get(path, src, dst) 3.2. jansson_pv_get(key/path, srcvar, dst) 3.3. jansson_set(type, key/path, value, result) 3.4. jansson_append(type, key/path, value, result) 3.5. jansson_array_size(key/path, src, dst) 3.6. jansson_xdecode(json, xavp) 3.7. jansson_xencode(xavp, pv) - 3.8. jansson_get_field(src, field_name, dst) + 3.8. jansson_get_field(field_name, src, dst) List of Examples @@ -62,14 +62,14 @@ Chapter 1. Admin Guide 3. Functions - 3.1. jansson_get(key/path, src, dst) + 3.1. jansson_get(path, src, dst) 3.2. jansson_pv_get(key/path, srcvar, dst) 3.3. jansson_set(type, key/path, value, result) 3.4. jansson_append(type, key/path, value, result) 3.5. jansson_array_size(key/path, src, dst) 3.6. jansson_xdecode(json, xavp) 3.7. jansson_xencode(xavp, pv) - 3.8. jansson_get_field(src, field_name, dst) + 3.8. jansson_get_field(field_name, src, dst) 1. Overview @@ -94,20 +94,24 @@ Chapter 1. Admin Guide 3. Functions - 3.1. jansson_get(key/path, src, dst) + 3.1. jansson_get(path, src, dst) 3.2. jansson_pv_get(key/path, srcvar, dst) 3.3. jansson_set(type, key/path, value, result) 3.4. jansson_append(type, key/path, value, result) 3.5. jansson_array_size(key/path, src, dst) 3.6. jansson_xdecode(json, xavp) 3.7. jansson_xencode(xavp, pv) - 3.8. jansson_get_field(src, field_name, dst) + 3.8. jansson_get_field(field_name, src, dst) -3.1. jansson_get(key/path, src, dst) +3.1. jansson_get(path, src, dst) Copy the value at the location 'path' from the json object 'src' and - store it in pvar 'dst'. The 'src' can be a static string or a dynamic - string with variables. + store it in variable 'dst'. The path can also be a simple field name (a + key), if it does not include any path separator. To retrieve the value + of a field that includes path separators in the name, use + jansson_get_field(). + + The 'src' can be a static string or a dynamic string with variables. The path string supports dot delimited notation (e.g. foo.bar.baz), array notation (e.g. [0]), or a combination of the two (e.g. @@ -116,8 +120,8 @@ Chapter 1. Admin Guide Returns FALSE if the data can not be parsed, TRUE otherwise. The function can put a string, integer, null, or new json string into - destination. If the key/path can't be found in the JSON data structure, - the pvar is not changed. If it had a previous value, that value remains + destination. If the path can't be found in the JSON data structure, the + pvar is not changed. If it had a previous value, that value remains unchanged. Note: For JSON-Integer values exceeding the C-Integer boundaries, a @@ -266,7 +270,7 @@ xlog("foo is $xavp(js=>foo)"); 3.7. jansson_xencode(xavp, pv) Encode the items in the xavp 'xavp' as JSON and store the result in a - pv. Nested xavps's are not supported. + pv. Nested xavp's are not supported. Example 1.8. jansson_xencode usage ... @@ -275,17 +279,21 @@ jansson_xencode("a", "$var(js)"); # $var(js) = '{"foo":"bar"}' ... -3.8. jansson_get_field(src, field_name, dst) +3.8. jansson_get_field(field_name, src, dst) - Copy field 'field_name' from json object 'src' and store it in pvar - 'dst'. + Copy the value of the field 'field_name' from json object 'src' and + store it in pvar 'dst'. The field name is not evaluated as JSON path, + therefore it has a different behaviour than jansson_get() and can be + used when the field name contains path delimiters. - This function is deprecated but kept for backwards compatibility. Right - now it is just a wrapper around jansson_get, and its functionality is - the same. + Note that till version 5.7.x, this function was similar to + jansson_get(), after that its behaviour changed to work as described + above. Also, the order of parameters changed. Example 1.9. jansson_get_field usage ... -jansson_get_field("{'foo':'bar'}", "foo", "$var(foo)"); +jansson_get_field("foo", "{'foo':'bar'}", "$var(foo)"); xlog("foo is $var(foo)"); +jansson_get_field("foo.foz", "{'foo.foz':'bar.buz'}", "$var(foofoz)"); +xlog("foo.foz is $var(foofoz)"); ... diff --git a/src/modules/jansson/doc/jansson_admin.xml b/src/modules/jansson/doc/jansson_admin.xml index 969804c96..daa5e9ea5 100644 --- a/src/modules/jansson/doc/jansson_admin.xml +++ b/src/modules/jansson/doc/jansson_admin.xml @@ -56,10 +56,16 @@ Functions
- <function moreinfo="none">jansson_get(key/path, src, dst)</function> + <function moreinfo="none">jansson_get(path, src, dst)</function> - Copy the value at the location 'path' from the json object 'src' and store it in pvar 'dst'. + Copy the value at the location 'path' from the json object 'src' + and store it in variable 'dst'. The path can also be a simple field name + (a key), if it does not include any path separator. To retrieve the + value of a field that includes path separators in the name, use + jansson_get_field(). + + The 'src' can be a static string or a dynamic string with variables. @@ -71,7 +77,7 @@ The function can put a string, integer, null, or new json string into destination. - If the key/path can't be found in the JSON data structure, the pvar is not changed. + If the path can't be found in the JSON data structure, the pvar is not changed. If it had a previous value, that value remains unchanged. @@ -265,7 +271,7 @@ xlog("foo is $xavp(js=>foo)"); Encode the items in the xavp 'xavp' as JSON and store the result in a pv. - Nested xavps's are not supported. + Nested xavp's are not supported. <function>jansson_xencode</function> usage @@ -280,22 +286,27 @@ jansson_xencode("a", "$var(js)");
- <function moreinfo="none">jansson_get_field(src, field_name, dst)</function> + <function moreinfo="none">jansson_get_field(field_name, src, dst)</function> - Copy field 'field_name' from json object 'src' and store it in pvar 'dst'. + Copy the value of the field 'field_name' from json object 'src' + and store it in pvar 'dst'. The field name is not evaluated as JSON + path, therefore it has a different behaviour than jansson_get() and + can be used when the field name contains path delimiters. - This function is deprecated but kept for backwards compatibility. - Right now it is just a wrapper around jansson_get, and its - functionality is the same. + Note that till version 5.7.x, this function was similar to jansson_get(), + after that its behaviour changed to work as described above. Also, + the order of parameters changed. <function>jansson_get_field</function> usage ... -jansson_get_field("{'foo':'bar'}", "foo", "$var(foo)"); +jansson_get_field("foo", "{'foo':'bar'}", "$var(foo)"); xlog("foo is $var(foo)"); +jansson_get_field("foo.foz", "{'foo.foz':'bar.buz'}", "$var(foofoz)"); +xlog("foo.foz is $var(foofoz)"); ... diff --git a/src/modules/jansson/jansson_funcs.c b/src/modules/jansson/jansson_funcs.c index 926ed34c2..4202cd56f 100644 --- a/src/modules/jansson/jansson_funcs.c +++ b/src/modules/jansson/jansson_funcs.c @@ -34,12 +34,15 @@ #include "jansson_utils.h" int janssonmod_get_helper( - sip_msg_t *msg, str *path_s, str *src_s, pv_spec_t *dst_pv) + sip_msg_t *msg, str *path_s, int pmode, str *src_s, pv_spec_t *dst_pv) { char c; pv_value_t dst_val; json_t *json = NULL; json_error_t parsing_error; + char *path = NULL; + char *freeme = NULL; + STR_VTOZ(src_s->s[src_s->len], c); json = json_loads(src_s->s, JSON_REJECT_DUPLICATES, &parsing_error); STR_ZTOV(src_s->s[src_s->len], c); @@ -50,14 +53,13 @@ int janssonmod_get_helper( goto fail; } - char *path = path_s->s; + path = path_s->s; - json_t *v = json_path_get(json, path); + json_t *v = json_path_get(json, path, pmode); if(!v) { goto fail; } - char *freeme = NULL; if(jansson_to_val(&dst_val, &freeme, v) < 0) goto fail; @@ -91,7 +93,26 @@ int janssonmod_get(struct sip_msg *msg, char *path_in, char *src_in, char *dst) return -1; } - return janssonmod_get_helper(msg, &path_s, &src_s, (pv_spec_t *)dst); + return janssonmod_get_helper(msg, &path_s, 0, &src_s, (pv_spec_t *)dst); +} + +int janssonmod_get_field( + struct sip_msg *msg, char *field_in, char *src_in, char *dst) +{ + str src_s; + str field_s; + + if(fixup_get_svalue(msg, (gparam_p)field_in, &field_s) != 0) { + ERR("cannot get field name string value\n"); + return -1; + } + + if(fixup_get_svalue(msg, (gparam_p)src_in, &src_s) != 0) { + ERR("cannot get json string value\n"); + return -1; + } + + return janssonmod_get_helper(msg, &field_s, 1, &src_s, (pv_spec_t *)dst); } int janssonmod_pv_get( @@ -111,7 +132,7 @@ int janssonmod_pv_get( return -1; } - ret = janssonmod_get_helper(msg, &path_s, &val.rs, (pv_spec_t *)dst); + ret = janssonmod_get_helper(msg, &path_s, 0, &val.rs, (pv_spec_t *)dst); pv_value_destroy(&val); @@ -130,6 +151,12 @@ int janssonmod_set(unsigned int append, struct sip_msg *msg, char *type_in, char c; pv_spec_t *result_pv; pv_value_t result_val; + json_t *result_json = NULL; + json_t *value = NULL; + char *freeme = NULL; + json_error_t parsing_error = {0}; + char *endptr; + char *path = NULL; if(fixup_get_svalue(msg, (gparam_p)type_in, &type_s) != 0) { ERR("cannot get type string value\n"); @@ -161,12 +188,6 @@ int janssonmod_set(unsigned int append, struct sip_msg *msg, char *type_in, LM_DBG("value is: %.*s\n", value_s.len, value_s.s); LM_DBG("result is: %.*s\n", result_val.rs.len, result_val.rs.s); - json_t *result_json = NULL; - json_t *value = NULL; - char *freeme = NULL; - json_error_t parsing_error = {0}; - char *endptr; - /* check the type */ if(STR_EQ_STATIC(type_s, "object") || STR_EQ_STATIC(type_s, "obj")) { STR_VTOZ(value_s.s[value_s.len], c); @@ -241,7 +262,8 @@ int janssonmod_set(unsigned int append, struct sip_msg *msg, char *type_in, goto fail; } - char *path = path_s.s; + path = path_s.s; + STR_VTOZ(result_val.rs.s[result_val.rs.len], c); result_json = json_loads(result_val.rs.s, JSON_REJECT_DUPLICATES, &parsing_error); @@ -252,7 +274,7 @@ int janssonmod_set(unsigned int append, struct sip_msg *msg, char *type_in, goto fail; } - if(json_path_set(result_json, path, value, append) < 0) { + if(json_path_set(result_json, path, 0, value, append) < 0) { goto fail; } @@ -281,6 +303,8 @@ int janssonmod_array_size( str path_s; pv_spec_t *dst_pv; pv_value_t dst_val; + char *path = NULL; + int size = 0; if(fixup_get_svalue(msg, (gparam_p)src_in, &src_s) != 0) { ERR("cannot get json string value\n"); @@ -305,9 +329,9 @@ int janssonmod_array_size( goto fail; } - char *path = path_s.s; + path = path_s.s; - json_t *v = json_path_get(json, path); + json_t *v = json_path_get(json, path, 0); if(!v) { ERR("failed to find %s in json\n", path); goto fail; @@ -318,7 +342,7 @@ int janssonmod_array_size( goto fail; } - int size = json_array_size(v); + size = json_array_size(v); dst_val.ri = size; dst_val.flags = PV_TYPE_INT | PV_VAL_INT; diff --git a/src/modules/jansson/jansson_funcs.h b/src/modules/jansson/jansson_funcs.h index f59074a21..829aa144c 100644 --- a/src/modules/jansson/jansson_funcs.h +++ b/src/modules/jansson/jansson_funcs.h @@ -27,6 +27,8 @@ int janssonmod_get( struct sip_msg *msg, char *path_in, char *json_in, char *result); +int janssonmod_get_field( + struct sip_msg *msg, char *field_in, char *src_in, char *dst); int janssonmod_pv_get( struct sip_msg *msg, char *path_in, char *json_in, char *result); int janssonmod_set(unsigned int append, struct sip_msg *msg, char *type_in, @@ -34,7 +36,7 @@ int janssonmod_set(unsigned int append, struct sip_msg *msg, char *type_in, int janssonmod_array_size( struct sip_msg *msg, char *json_in, char *path_in, char *dst); int janssonmod_get_helper( - sip_msg_t *msg, str *path_s, str *src_s, pv_spec_t *dst_pv); + sip_msg_t *msg, str *path_s, int pmode, str *src_s, pv_spec_t *dst_pv); int jansson_xdecode(struct sip_msg *msg, char *src_in, char *xavp_in); int jansson_xencode(struct sip_msg *msg, char *xavp, char *dst); diff --git a/src/modules/jansson/jansson_mod.c b/src/modules/jansson/jansson_mod.c index 17bf8aefd..e7dd58ee3 100644 --- a/src/modules/jansson/jansson_mod.c +++ b/src/modules/jansson/jansson_mod.c @@ -55,48 +55,45 @@ int janssonmod_set_append(struct sip_msg *msg, char *type_in, char *path_in, { return janssonmod_set(1, msg, type_in, path_in, value_in, result); } -int janssonmod_get_field( - struct sip_msg *msg, char *jansson_in, char *path_in, char *result) -{ - return janssonmod_get(msg, path_in, jansson_in, result); -} +/* clang-format off */ /* Exported functions */ static cmd_export_t cmds[] = { - {"jansson_get", (cmd_function)janssonmod_get, 3, fixup_get_params, - fixup_get_params_free, ANY_ROUTE}, - {"jansson_pv_get", (cmd_function)janssonmod_pv_get, 3, - fixup_pv_get_params, fixup_pv_get_params_free, ANY_ROUTE}, - {"jansson_array_size", (cmd_function)janssonmod_array_size, 3, - fixup_get_params, fixup_get_params_free, ANY_ROUTE}, - {"jansson_set", (cmd_function)janssonmod_set_replace, 4, - fixup_set_params, fixup_set_params_free, ANY_ROUTE}, - {"jansson_append", (cmd_function)janssonmod_set_append, 4, - fixup_set_params, fixup_set_params_free, ANY_ROUTE}, - {"jansson_xdecode", (cmd_function)jansson_xdecode, 2, fixup_spve_spve, - fixup_free_spve_spve, ANY_ROUTE}, - {"jansson_xencode", (cmd_function)jansson_xencode, 2, fixup_xencode, - fixup_xencode_free, ANY_ROUTE}, - /* for backwards compatibility */ - {"jansson_get_field", (cmd_function)janssonmod_get_field, 3, - fixup_get_params, fixup_get_params_free, ANY_ROUTE}, - /* non-script functions */ - {"jansson_to_val", (cmd_function)jansson_to_val, 0, 0, 0, 0}, - - {0, 0, 0, 0, 0, 0}}; + {"jansson_get", (cmd_function)janssonmod_get, 3, fixup_get_params, + fixup_get_params_free, ANY_ROUTE}, + {"jansson_pv_get", (cmd_function)janssonmod_pv_get, 3, + fixup_pv_get_params, fixup_pv_get_params_free, ANY_ROUTE}, + {"jansson_array_size", (cmd_function)janssonmod_array_size, 3, + fixup_get_params, fixup_get_params_free, ANY_ROUTE}, + {"jansson_set", (cmd_function)janssonmod_set_replace, 4, + fixup_set_params, fixup_set_params_free, ANY_ROUTE}, + {"jansson_append", (cmd_function)janssonmod_set_append, 4, + fixup_set_params, fixup_set_params_free, ANY_ROUTE}, + {"jansson_xdecode", (cmd_function)jansson_xdecode, 2, fixup_spve_spve, + fixup_free_spve_spve, ANY_ROUTE}, + {"jansson_xencode", (cmd_function)jansson_xencode, 2, fixup_xencode, + fixup_xencode_free, ANY_ROUTE}, + {"jansson_get_field", (cmd_function)janssonmod_get_field, 3, + fixup_get_params, fixup_get_params_free, ANY_ROUTE}, + /* non-script functions */ + {"jansson_to_val", (cmd_function)jansson_to_val, 0, 0, 0, 0}, + + {0, 0, 0, 0, 0, 0} +}; struct module_exports exports = { - "jansson", /* module name */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* cmd (cfg function) exports */ - 0, /* param exports */ - 0, /* RPC method exports */ - 0, /* pseudo-variables exports */ - 0, /* response handling function */ - mod_init, /* module init function */ - 0, /* per-child init function */ - 0 /* module destroy function */ + "jansson", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* cmd (cfg function) exports */ + 0, /* param exports */ + 0, /* RPC method exports */ + 0, /* pseudo-variables exports */ + 0, /* response handling function */ + mod_init, /* module init function */ + 0, /* per-child init function */ + 0 /* module destroy function */ }; +/* clang-format off */ static int fixup_get_params(void **param, int param_no) @@ -244,18 +241,23 @@ static int ki_jansson_get(sip_msg_t *msg, str *spath, str *sdoc, str *spv) return -1; } - return janssonmod_get_helper(msg, spath, sdoc, pvs); + return janssonmod_get_helper(msg, spath, 0, sdoc, pvs); } /** * */ +/* clang-format off */ static sr_kemi_t sr_kemi_jansson_exports[] = { - {str_init("jansson"), str_init("get"), SR_KEMIP_INT, ki_jansson_get, - {SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, + { str_init("jansson"), str_init("get"), + SR_KEMIP_INT, ki_jansson_get, + {SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE} + }, - {{0, 0}, {0, 0}, 0, NULL, {0, 0, 0, 0, 0, 0}}}; + { {0, 0}, {0, 0}, 0, NULL, {0, 0, 0, 0, 0, 0} } +}; +/* clang-format on */ /** * diff --git a/src/modules/jansson/jansson_path.c b/src/modules/jansson/jansson_path.c index cc38c3802..d4148591a 100644 --- a/src/modules/jansson/jansson_path.c +++ b/src/modules/jansson/jansson_path.c @@ -25,7 +25,7 @@ static char *jsonp_strdup(const char *str); static json_malloc_t do_malloc = malloc; static json_free_t do_free = free; -json_t *json_path_get(const json_t *json, const char *path) +json_t *json_path_get(const json_t *json, const char *path, const int pmode) { static const char array_open = '['; static const char *path_delims = ".[", *array_close = "]"; @@ -50,7 +50,11 @@ json_t *json_path_get(const json_t *json, const char *path) while(peek && *peek && cursor) { char *last_peek = peek; - peek = strpbrk(peek, expect); + if(pmode == 0) { + peek = strpbrk(peek, expect); + } else { + peek = NULL; + } if(peek) { if(!token && peek != last_peek) goto fail; @@ -85,8 +89,8 @@ fail: return NULL; } -int json_path_set( - json_t *json, const char *path, json_t *value, unsigned int append) +int json_path_set(json_t *json, const char *path, const int pmode, + json_t *value, unsigned int append) { static const char array_open = '['; static const char object_delim = '.'; @@ -117,8 +121,11 @@ int json_path_set( while(peek && *peek && cursor) { char *last_peek = peek; - peek = strpbrk(last_peek, expect); - + if(pmode == 0) { + peek = strpbrk(last_peek, expect); + } else { + peek = NULL; + } if(peek) { if(!token && peek != last_peek) { ERR("unexpected trailing chars in JSON path at pos %zu\n", diff --git a/src/modules/jansson/jansson_path.h b/src/modules/jansson/jansson_path.h index 79e1614c6..22fc562fe 100644 --- a/src/modules/jansson/jansson_path.h +++ b/src/modules/jansson/jansson_path.h @@ -10,8 +10,8 @@ #define _JANSSON_PATH_H_ #include -json_t *json_path_get(const json_t *json, const char *path); -int json_path_set( - json_t *json, const char *path, json_t *value, unsigned int append); +json_t *json_path_get(const json_t *json, const char *path, const int pmode); +int json_path_set(json_t *json, const char *path, const int pmode, + json_t *value, unsigned int append); #endif diff --git a/src/modules/jansson/jansson_utils.c b/src/modules/jansson/jansson_utils.c index c5e9a1560..61a9377c4 100644 --- a/src/modules/jansson/jansson_utils.c +++ b/src/modules/jansson/jansson_utils.c @@ -19,8 +19,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ - +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include #include diff --git a/src/modules/jsonrpcs/README b/src/modules/jsonrpcs/README index b1be2506b..d4aa520a5 100644 --- a/src/modules/jsonrpcs/README +++ b/src/modules/jsonrpcs/README @@ -354,7 +354,7 @@ modparam("jsonrpcs", "dgram_timeout", 2000) Example 1.14. Set tcp_socket parameter ... -modparam("jsonrpcs", "tcp_socket", "udp:1.2.3.4:5042") +modparam("jsonrpcs", "tcp_socket", "tcp:1.2.3.4:5042") ... 5. Functions diff --git a/src/modules/jsonrpcs/doc/jsonrpcs_admin.xml b/src/modules/jsonrpcs/doc/jsonrpcs_admin.xml index 0e39676ed..ab8aee4fc 100644 --- a/src/modules/jsonrpcs/doc/jsonrpcs_admin.xml +++ b/src/modules/jsonrpcs/doc/jsonrpcs_admin.xml @@ -413,7 +413,7 @@ modparam("jsonrpcs", "dgram_timeout", 2000) Set <varname>tcp_socket</varname> parameter ... -modparam("jsonrpcs", "tcp_socket", "udp:1.2.3.4:5042") +modparam("jsonrpcs", "tcp_socket", "tcp:1.2.3.4:5042") ... @@ -638,4 +638,3 @@ rm /tmp/kamailio_jsonrpc_reply_fifo
- diff --git a/src/modules/jsonrpcs/jsonrpcs_fifo.c b/src/modules/jsonrpcs/jsonrpcs_fifo.c index f6ff70498..906deb033 100644 --- a/src/modules/jsonrpcs/jsonrpcs_fifo.c +++ b/src/modules/jsonrpcs/jsonrpcs_fifo.c @@ -560,10 +560,10 @@ int jsonrpc_fifo_mod_init(void) LM_ERR("no more pkg\n"); return -1; } - strcpy(p, runtime_dir); + strncpy(p, runtime_dir, len); if(sep) strcat(p, "/"); - strcat(p, jsonrpc_fifo); + strncat(p, jsonrpc_fifo, len - strlen(runtime_dir) - sep); jsonrpc_fifo = p; LM_DBG("fifo path is [%s]\n", jsonrpc_fifo); } diff --git a/src/modules/jsonrpcs/jsonrpcs_sock.c b/src/modules/jsonrpcs/jsonrpcs_sock.c index 4c6eb028a..c73687a82 100644 --- a/src/modules/jsonrpcs/jsonrpcs_sock.c +++ b/src/modules/jsonrpcs/jsonrpcs_sock.c @@ -205,10 +205,10 @@ int jsonrpc_dgram_mod_init(void) LM_ERR("no more pkg\n"); return -1; } - strcpy(p, runtime_dir); + strncpy(p, runtime_dir, len); if(sep) strcat(p, "/"); - strcat(p, jsonrpc_dgram_socket); + strncat(p, jsonrpc_dgram_socket, len - strlen(runtime_dir) - sep); jsonrpc_dgram_socket = p; LM_DBG("unix socket path is [%s]\n", jsonrpc_dgram_socket); } diff --git a/src/modules/kazoo/Makefile b/src/modules/kazoo/Makefile index b7b1e1615..c0c7e9d3d 100644 --- a/src/modules/kazoo/Makefile +++ b/src/modules/kazoo/Makefile @@ -11,6 +11,10 @@ ifeq ($(BUILDER),) JSONC=$(shell ls $(SYSBASE)/include/lib/libjson*.so $(LOCALBASE)/lib/libjson*.so 2>/dev/null | grep json-c) else JSONC=$(shell pkg-config --libs json-c 2>/dev/null | grep json-c) + + ifeq ($(shell pkg-config --atleast-version=0.13.0 librabbitmq; echo $$?),0) + DEFS += -DRABBITMQ_DEPRECATION + endif endif ifneq ($(JSONC),) diff --git a/src/modules/kazoo/kazoo.c b/src/modules/kazoo/kazoo.c index 2cf34bece..757fa2cdc 100644 --- a/src/modules/kazoo/kazoo.c +++ b/src/modules/kazoo/kazoo.c @@ -386,16 +386,22 @@ static int mod_init(void) return 0; } +/* clang-format off */ static sr_kemi_t kazoo_kemi_exports[] = { - {str_init("kazoo"), str_init("kazoo_publish"), SR_KEMIP_INT, - ki_kz_amqp_publish, - {SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init("kazoo"), str_init("kazoo_subscribe"), SR_KEMIP_INT, - ki_kz_amqp_subscribe, - {SR_KEMIP_STR, 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}}}; + { str_init("kazoo"), str_init("kazoo_publish"), + SR_KEMIP_INT, ki_kz_amqp_publish, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("kazoo"), str_init("kazoo_subscribe"), + SR_KEMIP_INT, ki_kz_amqp_subscribe, + { SR_KEMIP_STR, 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} } +}; +/* clang-format on */ int mod_register(char *path, int *dlflags, void *p1, void *p2) { diff --git a/src/modules/kazoo/kz_amqp.c b/src/modules/kazoo/kz_amqp.c index a5cb42927..ed6961165 100644 --- a/src/modules/kazoo/kz_amqp.c +++ b/src/modules/kazoo/kz_amqp.c @@ -29,10 +29,19 @@ #include #include #include + +#if RABBITMQ_DEPRECATION +#include +#include +#include +#include +#else #include #include #include #include +#endif + #include #include #include "../../core/mem/mem.h" diff --git a/src/modules/kazoo/kz_amqp.h b/src/modules/kazoo/kz_amqp.h index 6cfddbed8..faca990f1 100644 --- a/src/modules/kazoo/kz_amqp.h +++ b/src/modules/kazoo/kz_amqp.h @@ -32,7 +32,12 @@ #include #include #include + +#if RABBITMQ_DEPRECATION +#include +#else #include +#endif #include "../../core/sr_module.h" #include "../../core/str.h" diff --git a/src/modules/keepalive/keepalive.h b/src/modules/keepalive/keepalive.h index d5a8fcb21..5ca1ce356 100644 --- a/src/modules/keepalive/keepalive.h +++ b/src/modules/keepalive/keepalive.h @@ -69,13 +69,15 @@ typedef struct _ka_initial_dest typedef struct _ka_dest { str uri; - str owner; // name of destination "owner" - // (module asking to monitor this destination - str uuid; // Universal id for this record + str owner; /*!< Name of destination "owner" */ + /*!< Module asking to monitor this destination */ + str uuid; /*!< Universal id for this record */ int flags; int state; - time_t last_checked, last_up, last_down; - int counter; // counts unreachable attempts + time_t last_checked; + time_t last_up; /*!< Time of last successful SIP reply */ + time_t last_down; /*!< Time of last failure SIP reply */ + int counter; /*!< Counts unreachable attempts */ ticks_t ping_interval; /*!< Actual interval between OPTIONS */ void *user_attr; diff --git a/src/modules/keepalive/keepalive_core.c b/src/modules/keepalive/keepalive_core.c index 0aaafa8c8..b1b3581cb 100644 --- a/src/modules/keepalive/keepalive_core.c +++ b/src/modules/keepalive/keepalive_core.c @@ -131,11 +131,11 @@ static void ka_options_callback( // accepting 2XX return codes if(ps->code >= 200 && ps->code <= 299) { state = KA_STATE_UP; - ka_dest->last_down = time(NULL); + ka_dest->last_up = time(NULL); ka_dest->counter = 0; } else { state = KA_STATE_DOWN; - ka_dest->last_up = time(NULL); + ka_dest->last_down = time(NULL); ka_dest->counter++; } diff --git a/src/modules/keepalive/keepalive_mod.c b/src/modules/keepalive/keepalive_mod.c index 6b49603c3..4757b4346 100644 --- a/src/modules/keepalive/keepalive_mod.c +++ b/src/modules/keepalive/keepalive_mod.c @@ -70,39 +70,45 @@ str ka_ping_from = str_init("sip:keepalive@kamailio.org"); int ka_counter_del = 5; -static cmd_export_t cmds[] = {{"ka_is_alive", (cmd_function)w_cmd_is_alive, 1, - fixup_spve_null, 0, ANY_ROUTE}, - // internal API - {"ka_add_destination", (cmd_function)w_add_destination, 2, - fixup_add_destination, 0, - REQUEST_ROUTE | BRANCH_ROUTE | ONREPLY_ROUTE}, - {"ka_del_destination", (cmd_function)w_del_destination, 2, - fixup_add_destination, 0, ANY_ROUTE}, - {"bind_keepalive", (cmd_function)bind_keepalive, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0}}; +/* clang-format off */ +static cmd_export_t cmds[] = { + {"ka_is_alive", (cmd_function)w_cmd_is_alive, 1, + fixup_spve_null, 0, ANY_ROUTE}, + // internal API + {"ka_add_destination", (cmd_function)w_add_destination, 2, + fixup_add_destination, 0, REQUEST_ROUTE | BRANCH_ROUTE | ONREPLY_ROUTE}, + {"ka_del_destination", (cmd_function)w_del_destination, 2, + fixup_add_destination, 0, ANY_ROUTE}, + {"bind_keepalive", (cmd_function)bind_keepalive, 0, 0, 0, 0}, + + {0, 0, 0, 0, 0, 0} +}; static param_export_t params[] = { - {"ping_interval", PARAM_INT, &ka_ping_interval}, - {"destination", PARAM_STRING | USE_FUNC_PARAM, - (void *)ka_mod_add_destination}, - {"ping_from", PARAM_STR, &ka_ping_from}, - {"delete_counter", PARAM_INT, &ka_counter_del}, {0, 0, 0}}; + {"ping_interval", PARAM_INT, &ka_ping_interval}, + {"destination", PARAM_STRING | USE_FUNC_PARAM, + (void *)ka_mod_add_destination}, + {"ping_from", PARAM_STR, &ka_ping_from}, + {"delete_counter", PARAM_INT, &ka_counter_del}, + {0, 0, 0} +}; /** module exports */ struct module_exports exports = { - "keepalive", /* module name */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* cmd (cfg function) exports */ - params, /* param exports */ - 0, /* RPC method exports */ - 0, /* pseudo-variables exports */ - 0, /* response handling function */ - mod_init, /* module init function */ - 0, /* per-child init function */ - mod_destroy /* module destroy function */ + "keepalive", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* cmd (cfg function) exports */ + params, /* param exports */ + 0, /* RPC method exports */ + 0, /* pseudo-variables exports */ + 0, /* response handling function */ + mod_init, /* module init function */ + 0, /* per-child init function */ + mod_destroy /* module destroy function */ }; +/* clang-format on */ /** diff --git a/src/modules/kex/README b/src/modules/kex/README index 55d341211..d0661e611 100644 --- a/src/modules/kex/README +++ b/src/modules/kex/README @@ -47,9 +47,10 @@ Ovidiu Sas 3.9. isdsturiset() 3.10. pv_printf(var, str) 3.11. is_myself(uri) - 3.12. setdebug(level) - 3.13. resetdebug() - 3.14. km_append_branch([uri]) + 3.12. is_myhost(uri) + 3.13. setdebug(level) + 3.14. resetdebug() + 3.15. km_append_branch([uri]) 4. RPC Commands @@ -102,8 +103,9 @@ Ovidiu Sas 1.9. isdsturiset usage 1.10. pv_printf usage 1.11. is_myself usage - 1.12. setdebug usage - 1.13. resetdebug usage + 1.12. is_myhost usage + 1.13. setdebug usage + 1.14. resetdebug usage Chapter 1. Admin Guide @@ -128,9 +130,10 @@ Chapter 1. Admin Guide 3.9. isdsturiset() 3.10. pv_printf(var, str) 3.11. is_myself(uri) - 3.12. setdebug(level) - 3.13. resetdebug() - 3.14. km_append_branch([uri]) + 3.12. is_myhost(uri) + 3.13. setdebug(level) + 3.14. resetdebug() + 3.15. km_append_branch([uri]) 4. RPC Commands @@ -206,9 +209,10 @@ Chapter 1. Admin Guide 3.9. isdsturiset() 3.10. pv_printf(var, str) 3.11. is_myself(uri) - 3.12. setdebug(level) - 3.13. resetdebug() - 3.14. km_append_branch([uri]) + 3.12. is_myhost(uri) + 3.13. setdebug(level) + 3.14. resetdebug() + 3.15. km_append_branch([uri]) 3.1. setsflag(flag) @@ -391,7 +395,8 @@ pv_printf("$avp(x)", "From: $fU - To: $tU"); Meaning of the parameters is as follows: * uri - Valid SIP URI or IP address to check against the list of - local IP addresses or domains. The parameter value can contain + local IP addresses or domains, matching as well the port and + protocol if they are provided. The parameter value can contain pseudo-variables. This function can be used from ANY_ROUTE. @@ -403,7 +408,27 @@ if(is_myself("$fu")) { } ... -3.12. setdebug(level) +3.12. is_myhost(uri) + + Check if the host part of the parameter matches a local domain or IP + address. + + Meaning of the parameters is as follows: + * uri - Valid SIP URI, hostname of IP address to check against the + list of local IP addresses or domains. If it is a SIP URI, the port + and protocol are ignored. The parameter value can contain + pseudo-variables. + + This function can be used from ANY_ROUTE. + + Example 1.12. is_myhost usage +... +if(is_myhost("$tu")) { + ... +} +... + +3.13. setdebug(level) Set the debug log level per process. @@ -413,7 +438,7 @@ if(is_myself("$fu")) { This function can be used from ANY_ROUTE. - Example 1.12. setdebug usage + Example 1.13. setdebug usage ... setdebug("1"); ... @@ -421,19 +446,19 @@ $var(level) = 2; setdebug("$var(level)"); ... -3.13. resetdebug() +3.14. resetdebug() Reset the local debug log level back to the value of core parameter 'debug'. This function can be used from ANY_ROUTE. - Example 1.13. resetdebug usage + Example 1.14. resetdebug usage ... resetdebug(); ... -3.14. km_append_branch([uri]) +3.15. km_append_branch([uri]) This function was replaced by append_branch() from corex module, starting with version 4.0.0. diff --git a/src/modules/kex/doc/kex_admin.xml b/src/modules/kex/doc/kex_admin.xml index 91080d8c1..9f99e6a6b 100644 --- a/src/modules/kex/doc/kex_admin.xml +++ b/src/modules/kex/doc/kex_admin.xml @@ -360,7 +360,8 @@ pv_printf("$avp(x)", "From: $fU - To: $tU"); uri - Valid SIP URI or IP address to - check against the list of local IP addresses or domains. + check against the list of local IP addresses or domains, matching + as well the port and protocol if they are provided. The parameter value can contain pseudo-variables. @@ -376,6 +377,37 @@ if(is_myself("$fu")) { ... } ... + + +
+
+ <function moreinfo="none">is_myhost(uri)</function> + + Check if the host part of the parameter matches a local domain + or IP address. + + Meaning of the parameters is as follows: + + + + uri - Valid SIP URI, hostname of IP address to + check against the list of local IP addresses or domains. If it + is a SIP URI, the port and protocol are ignored. + The parameter value can contain pseudo-variables. + + + + + This function can be used from ANY_ROUTE. + + + <function>is_myhost</function> usage + +... +if(is_myhost("$tu")) { + ... +} +...
@@ -992,4 +1024,3 @@ Module: kex
- diff --git a/src/modules/kex/kex_mod.c b/src/modules/kex/kex_mod.c index 452639c3c..515877036 100644 --- a/src/modules/kex/kex_mod.c +++ b/src/modules/kex/kex_mod.c @@ -50,6 +50,7 @@ MODULE_VERSION /** module functions */ int w_is_myself(struct sip_msg *msg, char *uri, str *s2); +int w_is_myhost(struct sip_msg *msg, char *uri, str *s2); int w_setdebug(struct sip_msg *msg, char *level, str *s2); int w_resetdebug(struct sip_msg *msg, char *uri, str *s2); @@ -63,56 +64,67 @@ static sruid_t _kex_sruid; static int pv_get_sruid_val( struct sip_msg *msg, pv_param_t *param, pv_value_t *res); -static pv_export_t mod_pvs[] = {{{"sruid", sizeof("sruid") - 1}, PVT_OTHER, - pv_get_sruid_val, 0, 0, 0, 0, 0}, - {{0, 0}, 0, 0, 0, 0, 0, 0, 0}}; +/* clang-format off */ +static pv_export_t mod_pvs[] = { + {{"sruid", sizeof("sruid") - 1}, PVT_OTHER, pv_get_sruid_val, + 0, 0, 0, 0, 0}, + {{0, 0}, 0, 0, 0, 0, 0, 0, 0} +}; static cmd_export_t cmds[] = { - {"setsflag", (cmd_function)w_setsflag, 1, fixup_igp_null, - fixup_free_igp_null, ANY_ROUTE}, - {"resetsflag", (cmd_function)w_resetsflag, 1, fixup_igp_null, - fixup_free_igp_null, ANY_ROUTE}, - {"issflagset", (cmd_function)w_issflagset, 1, fixup_igp_null, - fixup_free_igp_null, ANY_ROUTE}, - {"setbflag", (cmd_function)w_setbflag, 1, fixup_igp_null, - fixup_free_igp_null, ANY_ROUTE}, - {"setbflag", (cmd_function)w_setbflag, 2, fixup_igp_igp, - fixup_free_igp_igp, ANY_ROUTE}, - {"resetbflag", (cmd_function)w_resetbflag, 1, fixup_igp_null, - fixup_free_igp_null, ANY_ROUTE}, - {"resetbflag", (cmd_function)w_resetbflag, 2, fixup_igp_igp, - fixup_free_igp_igp, ANY_ROUTE}, - {"isbflagset", (cmd_function)w_isbflagset, 1, fixup_igp_null, - fixup_free_igp_null, ANY_ROUTE}, - {"isbflagset", (cmd_function)w_isbflagset, 2, fixup_igp_igp, - fixup_free_igp_igp, ANY_ROUTE}, - {"setdsturi", (cmd_function)w_setdsturi, 1, fixup_spve_null, - fixup_free_spve_null, ANY_ROUTE}, - {"resetdsturi", (cmd_function)w_resetdsturi, 0, 0, 0, ANY_ROUTE}, - {"isdsturiset", (cmd_function)w_isdsturiset, 0, 0, 0, ANY_ROUTE}, - {"pv_printf", (cmd_function)w_pv_printf, 2, pv_printf_fixup, 0, - ANY_ROUTE}, - {"avp_printf", (cmd_function)w_pv_printf, 2, pv_printf_fixup, 0, - ANY_ROUTE}, - {"is_myself", (cmd_function)w_is_myself, 1, fixup_spve_null, - fixup_free_spve_null, ANY_ROUTE}, - {"setdebug", (cmd_function)w_setdebug, 1, fixup_igp_null, - fixup_free_igp_null, ANY_ROUTE}, - {"resetdebug", (cmd_function)w_resetdebug, 0, 0, 0, ANY_ROUTE}, - - {0, 0, 0, 0, 0, 0}}; - -static param_export_t params[] = {{0, 0, 0}}; + {"setsflag", (cmd_function)w_setsflag, 1, fixup_igp_null, + fixup_free_igp_null, ANY_ROUTE}, + {"resetsflag", (cmd_function)w_resetsflag, 1, fixup_igp_null, + fixup_free_igp_null, ANY_ROUTE}, + {"issflagset", (cmd_function)w_issflagset, 1, fixup_igp_null, + fixup_free_igp_null, ANY_ROUTE}, + {"setbflag", (cmd_function)w_setbflag, 1, fixup_igp_null, + fixup_free_igp_null, ANY_ROUTE}, + {"setbflag", (cmd_function)w_setbflag, 2, fixup_igp_igp, + fixup_free_igp_igp, ANY_ROUTE}, + {"resetbflag", (cmd_function)w_resetbflag, 1, fixup_igp_null, + fixup_free_igp_null, ANY_ROUTE}, + {"resetbflag", (cmd_function)w_resetbflag, 2, fixup_igp_igp, + fixup_free_igp_igp, ANY_ROUTE}, + {"isbflagset", (cmd_function)w_isbflagset, 1, fixup_igp_null, + fixup_free_igp_null, ANY_ROUTE}, + {"isbflagset", (cmd_function)w_isbflagset, 2, fixup_igp_igp, + fixup_free_igp_igp, ANY_ROUTE}, + {"setdsturi", (cmd_function)w_setdsturi, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"resetdsturi", (cmd_function)w_resetdsturi, 0, 0, 0, ANY_ROUTE}, + {"isdsturiset", (cmd_function)w_isdsturiset, 0, 0, 0, ANY_ROUTE}, + {"pv_printf", (cmd_function)w_pv_printf, 2, pv_printf_fixup, 0, + ANY_ROUTE}, + {"avp_printf", (cmd_function)w_pv_printf, 2, pv_printf_fixup, 0, + ANY_ROUTE}, + {"is_myself", (cmd_function)w_is_myself, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"is_myhost", (cmd_function)w_is_myhost, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"setdebug", (cmd_function)w_setdebug, 1, fixup_igp_null, + fixup_free_igp_null, ANY_ROUTE}, + {"resetdebug", (cmd_function)w_resetdebug, 0, 0, 0, ANY_ROUTE}, + + {0, 0, 0, 0, 0, 0} +}; +static param_export_t params[] = { + {0, 0, 0} +}; /** module exports */ -struct module_exports exports = {"kex", DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, params, 0, /* exported RPC methods */ - mod_pvs, /* exported pseudo-variables */ - 0, /* response handling function */ - mod_init, /* module initialization function */ - child_init, /* per-child init function */ - destroy}; +struct module_exports exports = { + "kex", DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, params, + 0, /* exported RPC methods */ + mod_pvs, /* exported pseudo-variables */ + 0, /* response handling function */ + mod_init, /* module initialization function */ + child_init, /* per-child init function */ + destroy +}; +/* clang-format on */ /** * init module function @@ -188,6 +200,35 @@ int w_is_myself(struct sip_msg *msg, char *uri, str *s2) return 1; } +/** + * + */ +int w_is_myhost(struct sip_msg *msg, char *uri, str *s2) +{ + int ret; + str suri; + struct sip_uri puri; + + if(fixup_get_svalue(msg, (gparam_p)uri, &suri) != 0) { + LM_ERR("cannot get the URI parameter\n"); + return -1; + } + if(suri.len > 4 + && (strncmp(suri.s, "sip:", 4) == 0 + || strncmp(suri.s, "sips:", 5) == 0)) { + if(parse_uri(suri.s, suri.len, &puri) != 0) { + LM_ERR("failed to parse uri [%.*s]\n", suri.len, suri.s); + return -1; + } + ret = check_self(&puri.host, 0, 0); + } else { + ret = check_self(&suri, 0, 0); + } + if(ret != 1) + return -1; + return 1; +} + int w_setdebug(struct sip_msg *msg, char *level, str *s2) { int lval = 0; diff --git a/src/modules/lcr/Makefile b/src/modules/lcr/Makefile index 56be2e3a7..8b6bb2220 100644 --- a/src/modules/lcr/Makefile +++ b/src/modules/lcr/Makefile @@ -9,20 +9,15 @@ auto_gen= NAME=lcr.so ifeq ($(CROSS_COMPILE),) -PCRE_BUILDER = $(shell \ - if pkg-config --exists libcre; then \ - echo 'pkg-config libpcre'; \ - else \ - which pcre-config; \ - fi) +PCRE_BUILDER = $(shell command -v pcre2-config) endif ifeq ($(PCRE_BUILDER),) PCREDEFS=-I$(LOCALBASE)/include - PCRELIBS=-L$(LOCALBASE)/lib -lpcre + PCRELIBS=-L$(LOCALBASE)/lib -lpcre2-8 else PCREDEFS = $(shell $(PCRE_BUILDER) --cflags) - PCRELIBS = $(shell $(PCRE_BUILDER) --libs) + PCRELIBS = $(shell $(PCRE_BUILDER) --libs8) endif DEFS+=$(PCREDEFS) @@ -31,4 +26,3 @@ LIBS+=$(PCRELIBS) SERLIBPATH=../../lib SER_LIBS+=$(SERLIBPATH)/srdb1/srdb1 include ../../Makefile.modules - diff --git a/src/modules/lcr/README b/src/modules/lcr/README index 4411220d9..8af639e15 100644 --- a/src/modules/lcr/README +++ b/src/modules/lcr/README @@ -1240,7 +1240,7 @@ if (to_any_gw("192.55.66.2", 1)) { 5.3. lcr.dump_rules Causes lcr module to dump the contents of its in-memory lcr_rule and - lcr_rule_target tables. Rules can be filetered by lcr_id or lcr_id and + lcr_rule_target tables. Rules can be filtered by lcr_id or lcr_id and prefix. The filters are passed as optional parameters. Parameters: diff --git a/src/modules/lcr/doc/lcr_admin.xml b/src/modules/lcr/doc/lcr_admin.xml index f6461e1a2..ad5e0d4d1 100644 --- a/src/modules/lcr/doc/lcr_admin.xml +++ b/src/modules/lcr/doc/lcr_admin.xml @@ -1641,7 +1641,7 @@ if (to_any_gw("192.55.66.2", 1)) { Causes lcr module to dump the contents of its in-memory lcr_rule and lcr_rule_target tables. - Rules can be filetered by lcr_id or lcr_id and prefix. + Rules can be filtered by lcr_id or lcr_id and prefix. The filters are passed as optional parameters. Parameters: diff --git a/src/modules/lcr/hash.c b/src/modules/lcr/hash.c index 41a3b0b82..f1011a348 100644 --- a/src/modules/lcr/hash.c +++ b/src/modules/lcr/hash.c @@ -36,10 +36,10 @@ /* Add lcr entry into hash table */ int rule_hash_table_insert(struct rule_info **hash_table, unsigned int lcr_id, unsigned int rule_id, unsigned short prefix_len, char *prefix, - unsigned short from_uri_len, char *from_uri, pcre *from_uri_re, + unsigned short from_uri_len, char *from_uri, pcre2_code *from_uri_re, unsigned short mt_tvalue_len, char *mt_tvalue, - unsigned short request_uri_len, char *request_uri, pcre *request_uri_re, - unsigned short stopper) + unsigned short request_uri_len, char *request_uri, + pcre2_code *request_uri_re, unsigned short stopper) { struct rule_info *rule; str prefix_str; @@ -50,9 +50,9 @@ int rule_hash_table_insert(struct rule_info **hash_table, unsigned int lcr_id, if(rule == NULL) { SHM_MEM_ERROR_FMT("for rule hash table entry\n"); if(from_uri_re) - shm_free(from_uri_re); + pcre2_code_free(from_uri_re); if(request_uri_re) - shm_free(request_uri_re); + pcre2_code_free(request_uri_re); return 0; } memset(rule, 0, sizeof(struct rule_info)); @@ -99,9 +99,9 @@ int rule_hash_table_insert(struct rule_info **hash_table, unsigned int lcr_id, if(rid == NULL) { PKG_MEM_ERROR_FMT("for rule_id hash table entry\n"); if(from_uri_re) - shm_free(from_uri_re); + pcre2_code_free(from_uri_re); if(request_uri_re) - shm_free(request_uri_re); + pcre2_code_free(request_uri_re); shm_free(rule); return 0; } @@ -209,10 +209,10 @@ void rule_hash_table_contents_free(struct rule_info **hash_table) r = hash_table[i]; while(r) { if(r->from_uri_re) { - shm_free(r->from_uri_re); + pcre2_code_free(r->from_uri_re); } if(r->request_uri_re) - shm_free(r->request_uri_re); + pcre2_code_free(r->request_uri_re); t = r->targets; while(t) { next_t = t->next; diff --git a/src/modules/lcr/hash.h b/src/modules/lcr/hash.h index 7b29932be..5ae1ff860 100644 --- a/src/modules/lcr/hash.h +++ b/src/modules/lcr/hash.h @@ -34,10 +34,10 @@ int rule_hash_table_insert(struct rule_info **hash_table, unsigned int lcr_id, unsigned int rule_id, unsigned short prefix_len, char *prefix, - unsigned short from_uri_len, char *from_uri, pcre *from_uri_re, + unsigned short from_uri_len, char *from_uri, pcre2_code *from_uri_re, unsigned short mt_tvalue_len, char *mt_tvalue, - unsigned short request_uri_len, char *request_uri, pcre *request_uri_re, - unsigned short stopper); + unsigned short request_uri_len, char *request_uri, + pcre2_code *request_uri_re, unsigned short stopper); int rule_hash_table_insert_target(struct rule_info **hash_table, struct gw_info *gws, unsigned int rule_id, unsigned int gw_id, diff --git a/src/modules/lcr/lcr_mod.c b/src/modules/lcr/lcr_mod.c index 1d5a1ff01..dac215a9e 100644 --- a/src/modules/lcr/lcr_mod.c +++ b/src/modules/lcr/lcr_mod.c @@ -43,7 +43,8 @@ #include #include #include -#include +#define PCRE2_CODE_UNIT_WIDTH 8 +#include #include "../../core/locking.h" #include "../../core/sr_module.h" #include "../../core/dprint.h" @@ -134,7 +135,7 @@ gen_lock_t *reload_lock; /* database variables */ /* clang-format off */ -static str db_url = str_init(DEFAULT_RODB_URL); +static str lcr_db_url = str_init(DEFAULT_RODB_URL); static str lcr_rule_table = str_init(LCR_RULE_TABLE); static str lcr_rule_target_table = str_init(LCR_RULE_TARGET_TABLE); static str lcr_gw_table = str_init(LCR_GW_TABLE); @@ -188,7 +189,7 @@ unsigned int lcr_gw_count_param = DEF_LCR_GW_COUNT; /* can gws be defuncted */ static unsigned int defunct_capability_param = 0; -/* dont strip or tag param */ +/* don't strip or tag param */ static int dont_strip_or_prefix_flag_param = -1; /* ping related params */ @@ -204,6 +205,9 @@ static unsigned int priority_ordering_param = 0; /* mtree tree name */ str mtree_param = {"lcr", 3}; +static pcre2_general_context *lcr_gctx = NULL; +static pcre2_compile_context *lcr_ctx = NULL; + /* * Other module types and variables */ @@ -236,7 +240,7 @@ struct gw_info **gw_pt = (struct gw_info **)NULL; struct rule_id_info **rule_id_hash_table = (struct rule_id_info **)NULL; /* Pinging related vars */ -struct tm_binds tmb; +struct tm_binds _lcr_tmb; void ping_timer(unsigned int ticks, void *param); unsigned int ping_valid_reply_codes[MAX_NO_OF_REPLY_CODES]; str ping_method = {"OPTIONS", 7}; @@ -309,7 +313,7 @@ static cmd_export_t cmds[] = { * Exported parameters */ static param_export_t params[] = { - {"db_url", PARAM_STR, &db_url}, + {"db_url", PARAM_STR, &lcr_db_url}, {"lcr_rule_table", PARAM_STR, &lcr_rule_table}, {"lcr_rule_target_table", PARAM_STR, &lcr_rule_target_table}, {"lcr_gw_table", PARAM_STR, &lcr_gw_table}, @@ -422,6 +426,16 @@ static void lcr_db_close(void) } } +static void *pcre2_malloc(size_t size, void *ext) +{ + return shm_malloc(size); +} + +static void pcre2_free(void *ptr, void *ext) +{ + shm_free(ptr); + ptr = NULL; +} /* * Module initialization function that is called before the main process forks @@ -441,7 +455,7 @@ static int mod_init(void) } /* Bind database */ - if(lcr_db_bind(&db_url)) { + if(lcr_db_bind(&lcr_db_url)) { LM_ERR("no database module found\n"); return -1; } @@ -608,7 +622,7 @@ static int mod_init(void) return -1; } if(ping_interval_param > 0) { - if(load_tm_api(&tmb) == -1) { + if(load_tm_api(&_lcr_tmb) == -1) { LM_ERR("could not bind tm api\n"); return -1; } @@ -678,7 +692,7 @@ static int mod_init(void) } /* Check table version */ - if(lcr_db_init(&db_url) < 0) { + if(lcr_db_init(&lcr_db_url) < 0) { LM_ERR("unable to open database connection\n"); return -1; } @@ -703,7 +717,15 @@ static int mod_init(void) lcr_db_close(); /* rule shared memory */ - + if((lcr_gctx = pcre2_general_context_create(pcre2_malloc, pcre2_free, NULL)) + == NULL) { + LM_ERR("pcre2 general context creation failed\n"); + goto err; + } + if((lcr_ctx = pcre2_compile_context_create(lcr_gctx)) == NULL) { + LM_ERR("pcre2 compile context creation failed\n"); + goto err; + } /* rule hash table pointer table */ /* pointer at index 0 points to temp rule hash table */ rule_pt = (struct rule_info ***)shm_malloc( @@ -779,6 +801,12 @@ dberror: lcr_db_close(); err: + if(lcr_ctx) { + pcre2_compile_context_free(lcr_ctx); + } + if(lcr_gctx) { + pcre2_general_context_free(lcr_gctx); + } free_shared_memory(); return -1; } @@ -794,7 +822,12 @@ static int child_init(int rank) static void destroy(void) { lcr_db_close(); - + if(lcr_ctx) { + pcre2_compile_context_free(lcr_ctx); + } + if(lcr_gctx) { + pcre2_general_context_free(lcr_gctx); + } free_shared_memory(); } @@ -846,7 +879,7 @@ static int comp_matched(const void *m1, const void *m2) if(mi1->priority < mi2->priority) return 1; if(mi1->priority == mi2->priority) { - /* Sort by randomized weigth */ + /* Sort by randomized weight */ if(mi1->weight > mi2->weight) return 1; if(mi1->weight == mi2->weight) @@ -863,7 +896,7 @@ static int comp_matched(const void *m1, const void *m2) if(mi1->priority < mi2->priority) return 1; if(mi1->priority == mi2->priority) { - /* Sort by randomized weigth */ + /* Sort by randomized weight */ if(mi1->weight > mi2->weight) return 1; if(mi1->weight == mi2->weight) @@ -875,33 +908,32 @@ static int comp_matched(const void *m1, const void *m2) /* Compile pattern into shared memory and return pointer to it. */ -static pcre *reg_ex_comp(const char *pattern) +static pcre2_code *reg_ex_comp(const char *pattern) { - pcre *re, *result; - const char *error; - int rc, err_offset; - size_t size; - - re = pcre_compile(pattern, 0, &error, &err_offset, NULL); - if(re == NULL) { - LM_ERR("pcre compilation of '%s' failed at offset %d: %s\n", pattern, - err_offset, error); - return (pcre *)0; - } - rc = pcre_fullinfo(re, NULL, PCRE_INFO_SIZE, &size); - if(rc != 0) { - LM_ERR("pcre_fullinfo on compiled pattern '%s' yielded error: %d\n", - pattern, rc); - return (pcre *)0; - } - result = (pcre *)shm_malloc(size); + pcre2_code *result; + int pcre_error_num = 0; + char pcre_error[128]; + size_t pcre_erroffset; + + result = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, 0, + &pcre_error_num, &pcre_erroffset, lcr_ctx); if(result == NULL) { - pcre_free(re); - SHM_MEM_ERROR_FMT("for compiled PCRE pattern\n"); - return (pcre *)0; + switch(pcre2_get_error_message( + pcre_error_num, (PCRE2_UCHAR *)pcre_error, 128)) { + case PCRE2_ERROR_NOMEMORY: + snprintf(pcre_error, 128, + "unknown error[%d]: pcre2 error buffer too small", + pcre_error_num); + break; + case PCRE2_ERROR_BADDATA: + snprintf(pcre_error, 128, "unknown pcre2 error[%d]", + pcre_error_num); + break; + } + LM_ERR("pcre compilation of '%s' failed at offset %zu: %s\n", pattern, + pcre_erroffset, pcre_error); + return NULL; } - memcpy(result, re, size); - pcre_free(re); return result; } @@ -957,7 +989,7 @@ static int insert_gw(struct gw_info *gws, unsigned int i, unsigned int gw_id, char *gw_name, unsigned int gw_name_len, char *scheme, unsigned int scheme_len, struct ip_addr *ip_addr, unsigned int port, uri_transport transport_code, char *transport, - unsigned int transport_len, char *params, unsigned int params_len, + unsigned int transport_len, char *uparams, unsigned int uparams_len, char *hostname, unsigned int hostname_len, char *ip_string, unsigned int strip, char *prefix, unsigned int prefix_len, char *tag, unsigned int tag_len, unsigned int flags, unsigned int defunct_until) @@ -977,9 +1009,9 @@ static int insert_gw(struct gw_info *gws, unsigned int i, unsigned int gw_id, if(transport_len) memcpy(&(gws[i].transport[0]), transport, transport_len); gws[i].transport_len = transport_len; - if(params_len) - memcpy(&(gws[i].params[0]), params, params_len); - gws[i].params_len = params_len; + if(uparams_len) + memcpy(&(gws[i].params[0]), uparams, uparams_len); + gws[i].params_len = uparams_len; if(hostname_len) memcpy(&(gws[i].hostname[0]), hostname, hostname_len); gws[i].hostname_len = hostname_len; @@ -1069,10 +1101,10 @@ static int prefix_len_insert( static int insert_gws(db1_res_t *res, struct gw_info *gws, unsigned int *null_gw_ip_addr, unsigned int *gw_cnt) { - unsigned int i, gw_id, defunct_until, gw_name_len, port, params_len, + unsigned int i, gw_id, defunct_until, gw_name_len, port, uparams_len, hostname_len, strip, prefix_len, tag_len, flags, scheme_len, transport_len; - char *gw_name, *params, *hostname, *prefix, *tag, *scheme, *transport; + char *gw_name, *uparams, *hostname, *prefix, *tag, *scheme, *transport; uri_transport transport_code; db_row_t *row; struct in_addr in_addr; @@ -1257,32 +1289,32 @@ static int insert_gws(db1_res_t *res, struct gw_info *gws, return 0; } if(VAL_NULL(ROW_VALUES(row) + 5)) { - params_len = 0; - params = (char *)0; + uparams_len = 0; + uparams = (char *)0; } else { switch(VAL_TYPE(ROW_VALUES(row) + 5)) { case DB1_STR: - params = VAL_STR(ROW_VALUES(row) + 5).s; - params_len = VAL_STR(ROW_VALUES(row) + 5).len; + uparams = VAL_STR(ROW_VALUES(row) + 5).s; + uparams_len = VAL_STR(ROW_VALUES(row) + 5).len; break; case DB1_STRING: - params = (char *)VAL_STRING(ROW_VALUES(row) + 5); - params_len = strlen(params); + uparams = (char *)VAL_STRING(ROW_VALUES(row) + 5); + uparams_len = strlen(uparams); break; default: LM_ERR("lcr_gw params at row <%u> is not string\n", i); return 0; } - if((params_len > 0) && (params[0] != ';')) { + if((uparams_len > 0) && (uparams[0] != ';')) { LM_ERR("lcr_gw params at row <%u> does not start " "with ';'\n", i); return 0; } } - if(params_len > MAX_PARAMS_LEN) { + if(uparams_len > MAX_PARAMS_LEN) { LM_ERR("lcr_gw params length <%u> at row <%u> it too large\n", - params_len, i); + uparams_len, i); return 0; } if(VAL_NULL(ROW_VALUES(row) + 6)) { @@ -1385,7 +1417,7 @@ static int insert_gws(db1_res_t *res, struct gw_info *gws, (*gw_cnt)++; if(!insert_gw(gws, *gw_cnt, gw_id, gw_name, gw_name_len, scheme, scheme_len, &ip_addr, port, transport_code, transport, - transport_len, params, params_len, hostname, hostname_len, + transport_len, uparams, uparams_len, hostname, hostname_len, ip_string.s, strip, prefix, prefix_len, tag, tag_len, flags, defunct_until)) { return 0; @@ -1414,7 +1446,7 @@ int reload_tables() db_key_t gw_cols[13]; db_key_t rule_cols[7]; db_key_t target_cols[4]; - pcre *from_uri_re, *request_uri_re; + pcre2_code *from_uri_re, *request_uri_re; struct gw_info *gws, *gw_pt_tmp; struct rule_info **rules, **rule_pt_tmp; @@ -1452,7 +1484,7 @@ int reload_tables() request_uri_re = from_uri_re = 0; - if(lcr_db_init(&db_url) < 0) { + if(lcr_db_init(&lcr_db_url) < 0) { LM_ERR("unable to open database connection\n"); return -1; } @@ -1879,7 +1911,7 @@ static inline int encode_avp_value(char *value, unsigned int gw_index, char *scheme, unsigned int scheme_len, unsigned int strip, char *prefix, unsigned int prefix_len, char *tag, unsigned int tag_len, struct ip_addr *ip_addr, char *hostname, unsigned int hostname_len, - unsigned int port, char *params, unsigned int params_len, + unsigned int port, char *uparams, unsigned int uparams_len, char *transport, unsigned int transport_len, unsigned int flags, unsigned int rule_id) { @@ -1925,7 +1957,7 @@ static inline int encode_avp_value(char *value, unsigned int gw_index, } append_chr(at, '|'); /* params */ - append_str(at, params, params_len); + append_str(at, uparams, uparams_len); append_chr(at, '|'); /* transport */ append_str(at, transport, transport_len); @@ -1942,7 +1974,7 @@ static inline int encode_avp_value(char *value, unsigned int gw_index, static inline int decode_avp_value(char *value, unsigned int *gw_index, str *scheme, unsigned int *strip, str *prefix, str *tag, - struct ip_addr *addr, str *hostname, str *port, str *params, + struct ip_addr *addr, str *hostname, str *port, str *uparams, str *transport, unsigned int *flags, unsigned int *rule_id) { unsigned int u = 0; @@ -2031,13 +2063,13 @@ static inline int decode_avp_value(char *value, unsigned int *gw_index, } port->len = sep - port->s; /* params */ - params->s = sep + 1; - sep = index(params->s, '|'); + uparams->s = sep + 1; + sep = index(uparams->s, '|'); if(sep == NULL) { LM_ERR("params was not found in AVP value\n"); return 0; } - params->len = sep - params->s; + uparams->len = sep - uparams->s; /* transport */ transport->s = sep + 1; sep = index(transport->s, '|'); @@ -2068,7 +2100,7 @@ static inline int decode_avp_value(char *value, unsigned int *gw_index, void add_gws_into_avps(struct gw_info *gws, struct matched_gw_info *matched_gws, unsigned int gw_cnt, str *ruri_user) { - unsigned int i, index, strip, hostname_len, params_len, rule_id; + unsigned int i, index, strip, hostname_len, uparams_len, rule_id; int prefix_len, tag_len; str value; char encoded_value[MAX_URI_LEN]; @@ -2083,7 +2115,7 @@ void add_gws_into_avps(struct gw_info *gws, struct matched_gw_info *matched_gws, index = matched_gws[i].gw_index; rule_id = matched_gws[i].rule_id; hostname_len = gws[index].hostname_len; - params_len = gws[index].params_len; + uparams_len = gws[index].params_len; strip = gws[index].strip; if(strip > ruri_user->len) { LM_ERR("strip count of gw is too large <%u>\n", strip); @@ -2096,10 +2128,10 @@ void add_gws_into_avps(struct gw_info *gws, struct matched_gw_info *matched_gws, + ((hostname_len > IP6_MAX_STR_SIZE + 2) ? hostname_len : IP6_MAX_STR_SIZE + 2) - + 6 /* port */ + params_len /* params */ - + 15 /* transport */ + 10 /* flags */ - + 7 /* separators */ - + 10 /* rule_id */ + + 6 /* port */ + uparams_len /* params */ + + 15 /* transport */ + 10 /* flags */ + + 7 /* separators */ + + 10 /* rule_id */ > MAX_URI_LEN) { LM_ERR("too long AVP value\n"); goto skip; @@ -2108,7 +2140,7 @@ void add_gws_into_avps(struct gw_info *gws, struct matched_gw_info *matched_gws, gws[index].scheme_len, strip, gws[index].prefix, prefix_len, gws[index].tag, tag_len, &gws[index].ip_addr, gws[index].hostname, hostname_len, gws[index].port, - gws[index].params, params_len, gws[index].transport, + gws[index].params, uparams_len, gws[index].transport, gws[index].transport_len, gws[index].flags, rule_id); value.s = (char *)&(encoded_value[0]); val.s = value; @@ -2129,11 +2161,12 @@ void add_gws_into_avps(struct gw_info *gws, struct matched_gw_info *matched_gws, int load_gws_dummy(int lcr_id, str *ruri_user, str *from_uri, str *request_uri, unsigned int *gw_indexes) { - int i, j; + int i, j, rc; unsigned int gw_index, now, dex; struct rule_info **rules, *rule, *pl; struct gw_info *gws; struct target *t; + pcre2_match_data *pcre_md = NULL; struct matched_gw_info matched_gws[MAX_NO_OF_GWS + 1]; struct sip_uri furi; struct usr_avp *avp; @@ -2178,12 +2211,18 @@ int load_gws_dummy(int lcr_id, str *ruri_user, str *from_uri, str *request_uri, || strncmp(rule->prefix, ruri_user->s, pl->prefix_len)) goto next; - if((rule->from_uri_len != 0) - && (pcre_exec(rule->from_uri_re, NULL, from_uri->s, - from_uri->len, 0, 0, NULL, 0) - < 0)) - goto next; - + if(rule->from_uri_len != 0) { + pcre_md = pcre2_match_data_create_from_pattern( + rule->from_uri_re, NULL); + rc = pcre2_match(rule->from_uri_re, (PCRE2_SPTR)from_uri->s, + (PCRE2_SIZE)from_uri->len, 0, 0, pcre_md, NULL); + if(pcre_md) { + pcre2_match_data_free(pcre_md); + pcre_md = NULL; + } + if(rc < 0) + goto next; + } if((from_uri->len > 0) && (rule->mt_tvalue_len > 0)) { if(mtree_api.mt_match(&msg, &mtree_param, &(furi.user), 2) == -1) { @@ -2216,9 +2255,16 @@ int load_gws_dummy(int lcr_id, str *ruri_user, str *from_uri, str *request_uri, "param has not been given.\n"); return -1; } - if(pcre_exec(rule->request_uri_re, NULL, request_uri->s, - request_uri->len, 0, 0, NULL, 0) - < 0) + pcre_md = pcre2_match_data_create_from_pattern( + rule->request_uri_re, NULL); + rc = pcre2_match(rule->request_uri_re, + (PCRE2_SPTR)request_uri->s, + (PCRE2_SIZE)request_uri->len, 0, 0, pcre_md, NULL); + if(pcre_md) { + pcre2_match_data_free(pcre_md); + pcre_md = NULL; + } + if(rc < 0) goto next; } @@ -2282,9 +2328,10 @@ static int ki_load_gws_furi( sip_msg_t *_m, int lcr_id, str *ruri_user, str *from_uri) { str *request_uri; - int i, j; + int i, j, rc; unsigned int gw_index, now, dex; int_str val; + pcre2_match_data *pcre_md = NULL; struct matched_gw_info matched_gws[MAX_NO_OF_GWS + 1]; struct rule_info **rules, *rule, *pl; struct gw_info *gws; @@ -2343,14 +2390,22 @@ static int ki_load_gws_furi( goto next; /* Match from uri */ - if((rule->from_uri_len != 0) - && (pcre_exec(rule->from_uri_re, NULL, from_uri->s, - from_uri->len, 0, 0, NULL, 0) - < 0)) { - LM_DBG("from uri <%.*s> did not match to from regex <%.*s>\n", - from_uri->len, from_uri->s, rule->from_uri_len, - rule->from_uri); - goto next; + if(rule->from_uri_len != 0) { + pcre_md = pcre2_match_data_create_from_pattern( + rule->from_uri_re, NULL); + rc = pcre2_match(rule->from_uri_re, (PCRE2_SPTR)from_uri->s, + (PCRE2_SIZE)from_uri->len, 0, 0, pcre_md, NULL); + if(pcre_md) { + pcre2_match_data_free(pcre_md); + pcre_md = NULL; + } + if(rc < 0) { + LM_DBG("from uri <%.*s> did not match to from regex " + "<%.*s>\n", + from_uri->len, from_uri->s, rule->from_uri_len, + rule->from_uri); + goto next; + } } /* Match from uri user */ @@ -2379,15 +2434,23 @@ static int ki_load_gws_furi( } /* Match request uri */ - if((rule->request_uri_len != 0) - && (pcre_exec(rule->request_uri_re, NULL, request_uri->s, - request_uri->len, 0, 0, NULL, 0) - < 0)) { - LM_DBG("request uri <%.*s> did not match to request regex " - "<%.*s>\n", - request_uri->len, request_uri->s, rule->request_uri_len, - rule->request_uri); - goto next; + if(rule->request_uri_len != 0) { + pcre_md = pcre2_match_data_create_from_pattern( + rule->request_uri_re, NULL); + rc = pcre2_match(rule->request_uri_re, + (PCRE2_SPTR)request_uri->s, + (PCRE2_SIZE)request_uri->len, 0, 0, pcre_md, NULL); + if(pcre_md) { + pcre2_match_data_free(pcre_md); + pcre_md = NULL; + } + if(rc < 0) { + LM_DBG("request uri <%.*s> did not match to request regex " + "<%.*s>\n", + request_uri->len, request_uri->s, + rule->request_uri_len, rule->request_uri); + goto next; + } } /* Load gws associated with this rule */ @@ -2539,7 +2602,7 @@ static int generate_uris(struct sip_msg *_m, char *r_uri, str *r_uri_user, str prefix = STR_NULL; str hostname = STR_NULL; str port = STR_NULL; - str params = STR_NULL; + str uparams = STR_NULL; str transport = STR_NULL; str addr_str = STR_NULL; str tmp_tag = STR_NULL; @@ -2556,7 +2619,7 @@ static int generate_uris(struct sip_msg *_m, char *r_uri, str *r_uri_user, return 0; /* No more gateways left */ decode_avp_value(gw_uri_val.s.s, gw_index, &scheme, &strip, &prefix, - &tmp_tag, addr, &hostname, &port, ¶ms, &transport, flags, + &tmp_tag, addr, &hostname, &port, &uparams, &transport, flags, rule_id); if(addr->af != 0) { @@ -2570,7 +2633,7 @@ static int generate_uris(struct sip_msg *_m, char *r_uri, str *r_uri_user, + ((hostname.len > IP6_MAX_STR_SIZE + 2) ? hostname.len : IP6_MAX_STR_SIZE + 2) - + 1 /* : */ + port.len + params.len + transport.len + + 1 /* : */ + port.len + uparams.len + transport.len + 1 /* null */ > MAX_URI_LEN) { LM_ERR("too long Request URI or DST URI\n"); @@ -2600,8 +2663,8 @@ static int generate_uris(struct sip_msg *_m, char *r_uri, str *r_uri_user, /* both ip_addr and hostname specified: place hostname in r-uri and ip_addr in dst-uri */ append_str(at, hostname.s, hostname.len); - if(params.len > 0) { - append_str(at, params.s, params.len); + if(uparams.len > 0) { + append_str(at, uparams.s, uparams.len); } *at = '\0'; *r_uri_len = at - r_uri; @@ -2640,8 +2703,8 @@ static int generate_uris(struct sip_msg *_m, char *r_uri, str *r_uri_user, if(transport.len > 0) { append_str(at, transport.s, transport.len); } - if(params.len > 0) { - append_str(at, params.s, params.len); + if(uparams.len > 0) { + append_str(at, uparams.s, uparams.len); } *at = '\0'; *r_uri_len = at - r_uri; @@ -2888,7 +2951,8 @@ void ping_timer(unsigned int ticks, void *param) uac_r.ssock = &ping_socket_param; } - if(tmb.t_request(&uac_r, &uri, &uri, &ping_from_param, 0) < 0) { + if(_lcr_tmb.t_request(&uac_r, &uri, &uri, &ping_from_param, 0) + < 0) { LM_ERR("unable to ping [%.*s]\n", uri.len, uri.s); } } @@ -3167,7 +3231,7 @@ static int from_gw_3( { int lcr_id; str addr_str; - char *tmp; + char *tmp = NULL; uri_transport transport; /* Get and check parameter values */ @@ -3180,6 +3244,7 @@ static int from_gw_3( addr_str.s = _addr; addr_str.len = strlen(_addr); + tmp = NULL; transport = strtol(_transport, &tmp, 10); if((tmp == 0) || (*tmp) || (tmp == _transport)) { LM_ERR("invalid transport parameter %s\n", _lcr_id); @@ -3194,7 +3259,7 @@ static int from_gw_4(struct sip_msg *_m, char *_lcr_id, char *_addr, { int lcr_id; str addr_str; - char *tmp; + char *tmp = NULL; uri_transport transport; int src_port; @@ -3208,6 +3273,7 @@ static int from_gw_4(struct sip_msg *_m, char *_lcr_id, char *_addr, addr_str.s = _addr; addr_str.len = strlen(_addr); + tmp = NULL; transport = strtol(_transport, &tmp, 10); if((tmp == 0) || (*tmp) || (tmp == _transport)) { LM_ERR("invalid transport parameter %s\n", _lcr_id); @@ -3473,7 +3539,7 @@ static int to_gw_3( { int lcr_id; int transport; - char *tmp; + char *tmp = NULL; str addr_str; /* Get and check parameter values */ @@ -3486,6 +3552,7 @@ static int to_gw_3( addr_str.s = _addr; addr_str.len = strlen(_addr); + tmp = NULL; transport = strtol(_transport, &tmp, 10); if((tmp == 0) || (*tmp) || (tmp == _transport)) { LM_ERR("invalid transport parameter %s\n", _transport); diff --git a/src/modules/lcr/lcr_mod.h b/src/modules/lcr/lcr_mod.h index 421fe68f5..0255241c0 100644 --- a/src/modules/lcr/lcr_mod.h +++ b/src/modules/lcr/lcr_mod.h @@ -2,6 +2,7 @@ * Various lcr related constant, types, and external variables * * Copyright (C) 2005-2014 Juha Heinanen + * Copyright (C) 2023 Victor Seva * * This file is part of Kamailio, a free SIP server. * @@ -33,7 +34,8 @@ #define LCR_MOD_H #include -#include +#define PCRE2_CODE_UNIT_WIDTH 8 +#include #include "../../core/locking.h" #include "../../core/parser/parse_uri.h" #include "../../core/ip_addr.h" @@ -60,10 +62,10 @@ struct rule_info unsigned short from_uri_len; char mt_tvalue[MAX_MT_TVALUE_LEN + 1]; unsigned short mt_tvalue_len; - pcre *from_uri_re; + pcre2_code *from_uri_re; char request_uri[MAX_URI_LEN + 1]; unsigned short request_uri_len; - pcre *request_uri_re; + pcre2_code *request_uri_re; unsigned short stopper; unsigned int enabled; struct target *targets; diff --git a/src/modules/ldap/README b/src/modules/ldap/README index 921f45822..d69005f86 100644 --- a/src/modules/ldap/README +++ b/src/modules/ldap/README @@ -31,6 +31,7 @@ Christian Schlatter 4. Parameters 4.1. config_file (string) + 4.2. connect_mode (int) 5. Functions @@ -82,12 +83,13 @@ Christian Schlatter 1.6. ldap_client_bind_timeout example 1.7. Example LDAP Configuration File 1.8. config_file parameter usage - 1.9. Example Usage of ldap_url - 1.10. Example Usage + 1.9. Set connect_mode parameter + 1.10. Example Usage of ldap_url 1.11. Example Usage 1.12. Example Usage 1.13. Example Usage 1.14. Example Usage + 1.15. Example Usage 2.1. Example code fragment to load LDAP module API 2.2. Example LDAP module API function call @@ -114,6 +116,7 @@ Chapter 1. Admin Guide 4. Parameters 4.1. config_file (string) + 4.2. connect_mode (int) 5. Functions @@ -418,6 +421,7 @@ ldap_client_bind_timeout = 500 4. Parameters 4.1. config_file (string) + 4.2. connect_mode (int) 4.1. config_file (string) @@ -428,6 +432,17 @@ ldap_client_bind_timeout = 500 Example 1.8. config_file parameter usage modparam("ldap", "config_file", "/usr/local/etc/kamailio/ldap.ini") +4.2. connect_mode (int) + + Control if the module must stop loading when connecting to server fails + during start up. Values: 0 - stop loading; 1 - continue even if + connecting to database server fails.. + + Default value: 0 + + Example 1.9. Set connect_mode parameter +modparam("ldap", "connect_mode", 1) + 5. Functions 5.1. ldap_search(ldap_url) @@ -458,7 +473,7 @@ modparam("ldap", "config_file", "/usr/local/etc/kamailio/ldap.ini") Kamailio pseudo variables and AVPs included in ldap_url do get substituted with their value. - Example 1.9. Example Usage of ldap_url + Example 1.10. Example Usage of ldap_url Search with LDAP session named sipaccounts, base ou=sip,dc=example,dc=com, one level deep using search filter @@ -492,7 +507,7 @@ ldap://ldap_1/dc=example,dc=com? This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - Example 1.10. Example Usage + Example 1.11. Example Usage ... # ldap search if (!ldap_search("ldap://sipaccounts/ou=sip,dc=example,dc=com??one?(cn=$rU)")) @@ -570,7 +585,7 @@ ldap_result("telephoneNumber/$avp(s:tel_number)"); This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - Example 1.11. Example Usage + Example 1.12. Example Usage ... # ldap_search call @@ -639,7 +654,7 @@ ldap_result("SIPIdentitySIPURI/$avp(i:10)", "/^[^@]+@(.+)$/\1/"); This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - Example 1.12. Example Usage + Example 1.13. Example Usage ... # ldap_search call ... @@ -688,7 +703,7 @@ if (!ldap_result_check("sn/$ru", "/^sip:([^@]).*$/\1/")) This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - Example 1.13. Example Usage + Example 1.14. Example Usage ... # ldap_search call ... @@ -745,7 +760,7 @@ if (ldap_result_next()) This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - Example 1.14. Example Usage + Example 1.15. Example Usage ... if (!ldap_filter_url_encode("cn=$avp(s:name)", "$avp(s:name_esc)")) { diff --git a/src/modules/ldap/doc/ldap_admin.xml b/src/modules/ldap/doc/ldap_admin.xml index 3337dd2be..2bb2c3a5e 100644 --- a/src/modules/ldap/doc/ldap_admin.xml +++ b/src/modules/ldap/doc/ldap_admin.xml @@ -455,6 +455,23 @@ modparam("ldap", "config_file", "/usr/local/etc/&kamailiobinary;/ldap.ini")
+ +
+ <varname>connect_mode</varname> (int) + + Control if the module must stop loading when connecting to server fails during start up. Values: 0 - stop loading; 1 - continue even if connecting to database server fails.. + Default value: + 0 + + + Set <varname>connect_mode</varname> parameter + + +modparam("ldap", "connect_mode", 1) + + +
+
@@ -1079,4 +1096,3 @@ if (ldap_search(
- diff --git a/src/modules/ldap/ldap_mod.c b/src/modules/ldap/ldap_mod.c index fada29a30..de0e25b15 100644 --- a/src/modules/ldap/ldap_mod.c +++ b/src/modules/ldap/ldap_mod.c @@ -80,6 +80,7 @@ static int w_ldap_result_check_2( * Default module parameter values */ #define DEF_LDAP_CONFIG "/usr/local/etc/kamailio/ldap.cfg" +static int ldap_connect_mode = 0; /* * Module parameter variables @@ -125,6 +126,7 @@ static cmd_export_t cmds[] = { static param_export_t params[] = { {"config_file", PARAM_STR, &ldap_config}, + {"connect_mode", PARAM_INT, &ldap_connect_mode}, {0, 0, 0} }; @@ -151,6 +153,7 @@ static int child_init(int rank) { int i = 0, ld_count = 0; char *ld_name; + int ret = 0; /* don't do anything for non-worker processes */ if(rank == PROC_INIT || rank == PROC_MAIN || rank == PROC_TCP_MAIN) @@ -168,9 +171,15 @@ static int child_init(int rank) } if(oldap_connect(ld_name) != 0) { - LM_ERR("[%s]: failed to connect to LDAP host(s)\n", ld_name); - ldap_disconnect(ld_name); - return -1; + if(ldap_connect_mode == 1) { + LM_INFO("[%s]: Failed to connect to LDAP host(s) but start " + "without connection enabled - proceed", + ld_name); + } else { + LM_ERR("[%s]: failed to connect to LDAP host(s)\n", ld_name); + ldap_disconnect(ld_name); + return -1; + } } } diff --git a/src/modules/lost/README b/src/modules/lost/README index 00fa5f2ce..998518c4a 100644 --- a/src/modules/lost/README +++ b/src/modules/lost/README @@ -29,10 +29,11 @@ Wolfgang Kampichler 3.3. location_type (string) 3.4. post_request (int) 3.5. location_profile (int) - 3.6. geoheader_type (int) - 3.7. geoheader_order (int) - 3.8. recursion (int) - 3.9. verbose (int) + 3.6. location_3d (int) + 3.7. geoheader_type (int) + 3.8. geoheader_order (int) + 3.9. recursion (int) + 3.10. verbose (int) 4. Functions @@ -52,13 +53,14 @@ Wolfgang Kampichler 1.3. Set location_type parameter 1.4. Set post_request parameter 1.5. Set location_profile parameter - 1.6. Set geoheader_type parameter - 1.7. Set geoheader_order parameter - 1.8. Set recursion parameter - 1.9. Set verbose parameter - 1.10. lost_held_query() usage - 1.11. lost_held_dereference() usage - 1.12. lost() usage + 1.6. Set location_3d parameter + 1.7. Set geoheader_type parameter + 1.8. Set geoheader_order parameter + 1.9. Set recursion parameter + 1.10. Set verbose parameter + 1.11. lost_held_query() usage + 1.12. lost_held_dereference() usage + 1.13. lost() usage Chapter 1. Admin Guide @@ -77,10 +79,11 @@ Chapter 1. Admin Guide 3.3. location_type (string) 3.4. post_request (int) 3.5. location_profile (int) - 3.6. geoheader_type (int) - 3.7. geoheader_order (int) - 3.8. recursion (int) - 3.9. verbose (int) + 3.6. location_3d (int) + 3.7. geoheader_type (int) + 3.8. geoheader_order (int) + 3.9. recursion (int) + 3.10. verbose (int) 4. Functions @@ -93,14 +96,14 @@ Chapter 1. Admin Guide 1. Overview - SIP requests may be forwarded based on a location provided with the + SIP requests may be forwarded based on a location provided by the request or retrieved from a specific location server using an identity (HELD). This module implements the basic functionality to get or parse location information (civic and geodetic) and to query a mapping - service (LOST) in order to get next hop based on location and service - urn either specified or provided with the request. + service (LOST) to get the next hop based on location and service urn + either specified or provided with the request. - This module implements protocol functions that use the http_client api + This module implements protocol functions that use the http_client API to fetch data from external LOST and HELD servers. The module is using the http_client concept of "connections" to define properties of HTTP sessions. A connection has one or multiple servers and a set of @@ -126,13 +129,14 @@ Chapter 1. Admin Guide request as defined in RFC5222 (https://tools.ietf.org/html/rfc5255) to query routing information for a given (geodetic or civic) location and a service URN. Both, PIDF-LO and service URN may be provided as - function parameter, or are taken from the request message if + function parameters, or are taken from the request message if applicable. The findServiceResponse is parsed and represented as - display name and SIP URI typically used as next hop in a Route header. + display name and SIP URI typically used as the next hop in a Route + header. - The http_client module use the CURL library setting up connections. The - CURL library by default use the system configured DNS resolver, not the - Kamailio resolver. + The http_client module uses the CURL library to set up connections. The + CURL library by default uses the system-configured DNS resolver, not + the Kamailio resolver. The module is limited to using HTTP and HTTPS protocols. @@ -144,9 +148,9 @@ Chapter 1. Admin Guide 2.1. Kamailio Modules The following modules must be loaded before this module: - * HTTP_CLIENT - the http_client module should be loaded first in - order to initialize connections properly. - * TLS - if you use TLS connections (https) the tls module should be + * HTTP_CLIENT - the http_client module should be loaded first to + initialize connections properly. + * TLS - if you use TLS connections (https) the TLS module should be loaded first in order to initialize OpenSSL properly. 2.2. External Libraries or Applications @@ -163,13 +167,14 @@ Chapter 1. Admin Guide 3.3. location_type (string) 3.4. post_request (int) 3.5. location_profile (int) - 3.6. geoheader_type (int) - 3.7. geoheader_order (int) - 3.8. recursion (int) - 3.9. verbose (int) + 3.6. location_3d (int) + 3.7. geoheader_type (int) + 3.8. geoheader_order (int) + 3.9. recursion (int) + 3.10. verbose (int) Besides parameters listed, this module uses http_client therefore - according parameters may apply. + appropriate module parameters may apply. 3.1. exact_type (int) @@ -186,10 +191,10 @@ Chapter 1. Admin Guide 3.2. response_time (int) - A time value indicating to the location server how long the client is + A time value informs the location server how long the client is prepared to wait for a response. - The value is expressed as integer, either -1 'emergencyDispatch', 0 + The value is expressed as an integer, either -1 'emergencyDispatch', 0 'emergencyRouting', a non-negative integer (>0) in units of milliseconds. Note: The time value is indicative only. @@ -250,7 +255,26 @@ Chapter 1. Admin Guide modparam("lost", "location_profile, 2) ... -3.6. geoheader_type (int) +3.6. location_3d (int) + + A Presence Information Data Format Location Object (PIDF-LO) may + contain one of the shape types as listed in RFC5491 + (https://tools.ietf.org/html/rfc5491). A LoST findService request + currently contains only a profile for two-dimensional geodetic location + information, which is the default setting for this parameter. The + parameter can be set to 1 if a LoST server supports 3d, otherwise a 3d + location is reduced to 2d by the module. + * 0 - two-dimensional (2d) shape representations only + * 1 - three-dimensional (3d) volume representations allowed + + Default: 0 (2d representations). + + Example 1.6. Set location_3d parameter + ... + modparam("lost", "location_3d, 1) + ... + +3.7. geoheader_type (int) A Geolocation header may include a list of locationValues pointing to either a Presence Information Data Format Location Object (PIDF-LO) in @@ -265,40 +289,40 @@ Chapter 1. Admin Guide Default: 0 (any) - Example 1.6. Set geoheader_type parameter + Example 1.7. Set geoheader_type parameter ... modparam("lost", "geoheader_type", 1) ... -3.7. geoheader_order (int) +3.8. geoheader_order (int) A Geolocation header may include a list of locationValues. This - parameter sets the order of the URI used to retrieve location + parameter sets the order of the URI used to retrieve the location information, either the first element of a certain type or the last. Values are 0 (first) or 1 (last). Default: 0 (first) - Example 1.7. Set geoheader_order parameter + Example 1.8. Set geoheader_order parameter ... modparam("lost", "geoheader_order", 0) ... -3.8. recursion (int) +3.9. recursion (int) A Geolocation header may include a list of locationValues. This - parameter sets the order of the URI used to retrieve location + parameter sets the order of the URI used to retrieve the location information, either the first element of a certain type or the last. Values are 0 (first) or 1 (last). Default: 1 (allowed) - Example 1.8. Set recursion parameter + Example 1.9. Set recursion parameter ... modparam("lost", "recursion", 0) ... -3.9. verbose (int) +3.10. verbose (int) Detailed output of LoST findService, redirect or error response as shown below. Values are 0 (disabled) or 1 (enabled). @@ -314,7 +338,7 @@ Chapter 1. Admin Guide Default: 0 - Example 1.9. Set verbose parameter + Example 1.10. Set verbose parameter ... modparam("lost", "verbose", 1) ... @@ -340,14 +364,14 @@ Chapter 1. Admin Guide include "locationURI" in the location_type parameter. * error - any error code returned in the HELD response - The return value is 200 on success, 400 if an internal error occured, + The return value is 200 on success, 400 if an internal error occurred, or 500 if an error code is returned in the HELD locationRequest response. This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, and BRANCH_ROUTE. - Example 1.10. lost_held_query() usage + Example 1.11. lost_held_query() usage ... modparam("http_client", "httpcon", "heldsrv=>http://service.org/api/held"); ... @@ -366,7 +390,7 @@ r(pidf)\n"); 4.2. lost_held_dereference(url, rtime, rtype, pidf-lo, error) Sends a HELD POST locationRequest to a given URL. Attributes are - responseTime and resposeType. The locationType property "exact" is set + responseTime and responseType. The locationType property "exact" is set to "false". * url - a URL received via Geolocation header to dereference location * rtime - the response time as defined in Section 3.2, “response_time @@ -377,7 +401,7 @@ r(pidf)\n"); * error - any error code returned in the HELD response The return value is 200..203 on success, 400 if an internal error - occured, or 500 if an error code is returned in the HELD response. + occurred, or 500 if an error code is returned in the HELD response. Success codes in detail are as follows: * 200 - received 200 OK, but neither location-info nor locationURI element found @@ -389,7 +413,7 @@ r(pidf)\n"); This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, and BRANCH_ROUTE. - Example 1.11. lost_held_dereference() usage + Example 1.12. lost_held_dereference() usage ... # HELD location dereference if ($hdr(Geolocation)=~"^http://service.org/api/held"); modparam("http_client", "httpcon", "lostsrv=>http://service.org/api/lost"); @@ -464,9 +488,9 @@ var(name)\n"); 6. Remarks Note: libcurl leak in CentOS 6 - this module uses libcurl library (via - http_client) and in case if you are using CentOS 6, be aware that - standard libcurl-7.19.7-52 has a memory leak. To fix this memory, - install libcurl from city-fan repository. More details at: + http_client) and in case you are using CentOS 6, be aware that standard + libcurl-7.19.7-52 has a memory leak. To fix this memory, install + libcurl from city-fan repository. More details at: https://www.digitalocean.com/community/questions/how-to-upgrade-curl-in -centos6. @@ -484,4 +508,4 @@ var(name)\n"); https://gridgears.at/. Note: in case modparam "geoheader_type" is set to 2 (http), the module - may use 3 (https) as fallback and vice versa. + may use 3 (https) as a fallback and vice versa. diff --git a/src/modules/lost/doc/lost_admin.xml b/src/modules/lost/doc/lost_admin.xml index 7e1fea6c5..926e97615 100644 --- a/src/modules/lost/doc/lost_admin.xml +++ b/src/modules/lost/doc/lost_admin.xml @@ -10,19 +10,19 @@ - &adminguide; -
+ &adminguide; +
Overview - SIP requests may be forwarded based on a location provided with the + SIP requests may be forwarded based on a location provided by the request or retrieved from a specific location server using an identity (HELD). This module implements the basic functionality to get or parse location information (civic and geodetic) and to query a mapping service - (LOST) in order to get next hop based on location and service urn either - specified or provided with the request. + (LOST) to get the next hop based on location and service urn either + specified or provided with the request. - This module implements protocol functions that use the http_client api + This module implements protocol functions that use the http_client API to fetch data from external LOST and HELD servers. The module is using the http_client concept of "connections" to define properties of HTTP sessions. A connection has one or multiple servers and a set of settings @@ -48,38 +48,38 @@ The function lost_query allows &kamailio; to assemble a LOST findService request as defined in RFC5222 - () to query + () to query routing information for a given (geodetic or civic) location and a service - URN. Both, PIDF-LO and service URN may be provided as function parameter, + URN. Both, PIDF-LO and service URN may be provided as function parameters, or are taken from the request message if applicable. The findServiceResponse - is parsed and represented as display name and SIP URI typically used as next + is parsed and represented as display name and SIP URI typically used as the next hop in a Route header. - The http_client module use the CURL library setting up connections. - The CURL library by default use the system configured DNS resolver, + The http_client module uses the CURL library to set up connections. + The CURL library by default uses the system-configured DNS resolver, not the Kamailio resolver. The module is limited to using HTTP and HTTPS protocols. -
-
- Dependencies -
- &kamailio; Modules - - The following modules must be loaded before this module: +
+
+ Dependencies +
+ &kamailio; Modules + + The following modules must be loaded before this module: HTTP_CLIENT - the http_client module should be - loaded first in order to initialize connections properly. + loaded first to initialize connections properly. - TLS - if you use TLS connections (https) the tls module + TLS - if you use TLS connections (https) the TLS module should be loaded first in order to initialize &openssl; properly. - +
@@ -101,12 +101,12 @@
-
-
- Parameters +
+
+ Parameters Besides parameters listed, this module uses http_client - therefore according parameters may apply. + therefore appropriate module parameters may apply.
<varname>exact_type</varname> (int) @@ -129,13 +129,13 @@
<varname>response_time</varname> (int) - A time value indicating to the location server how long the client is + A time value informs the location server how long the client is prepared to wait for a response. - The value is expressed as integer, either -1 'emergencyDispatch', 0 'emergencyRouting', + The value is expressed as an integer, either -1 'emergencyDispatch', 0 'emergencyRouting', a non-negative integer (>0) in units of milliseconds. - Note: The time value is indicative only. + Note: The time value is indicative only. Default: 0 ('emergencyRouting') @@ -155,7 +155,7 @@ The "locationType" element contains a list of types that are requested. Values are "any", "geodetic", "civic" or "locationURI" and combinations. - + any - returns location information in all forms available @@ -206,7 +206,7 @@ profile or combinations. A LoST findService contains only one location, which is selected via this parameter as follows: - + 0 - takes the first location of any type @@ -228,6 +228,38 @@ ... modparam("lost", "location_profile, 2) + ... + + +
+
+ <varname>location_3d</varname> (int) + + A Presence Information Data Format Location Object (PIDF-LO) may + contain one of the shape types as listed in RFC5491 + (). + A LoST findService request currently contains only + a profile for two-dimensional geodetic location information, which + is the default setting for this parameter. The parameter can be set + to 1 if a LoST server supports 3d, otherwise a 3d location is reduced + to 2d by the module. + + + + 0 - two-dimensional (2d) shape representations only + + + 1 - three-dimensional (3d) volume representations allowed + + + + Default: 0 (2d representations). + + + Set <varname>location_3d</varname> parameter + + ... + modparam("lost", "location_3d, 1) ... @@ -242,7 +274,7 @@ or an http(s) URI pointing to an external source. This parameter supports filtering of the following types: - + 0 (any) - any URI (first or last) @@ -272,7 +304,7 @@ <varname>geoheader_order</varname> (int) A Geolocation header may include a list of locationValues. This - parameter sets the order of the URI used to retrieve location + parameter sets the order of the URI used to retrieve the location information, either the first element of a certain type or the last. Values are 0 (first) or 1 (last). @@ -292,7 +324,7 @@ <varname>recursion</varname> (int) A Geolocation header may include a list of locationValues. This - parameter sets the order of the URI used to retrieve location + parameter sets the order of the URI used to retrieve the location information, either the first element of a certain type or the last. Values are 0 (first) or 1 (last). @@ -337,53 +369,53 @@
-
-
- Functions -
- - <function moreinfo="none">lost_held_query(con, [id,] pidf-lo, url, error)</function> - - - Sends a HELD locationRequest to a given connection. The device identity is either +
+
+ Functions +
+ + <function moreinfo="none">lost_held_query(con, [id,] pidf-lo, url, error)</function> + + + Sends a HELD locationRequest to a given connection. The device identity is either specified, or the P-A-I header value, or the From header value. - - - - con - the name of an existing - HTTP connection, defined by a httpcon modparam - + + - id - the device id used in the HELD + con - the name of an existing + HTTP connection, defined by a httpcon modparam + + + id - the device id used in the HELD locationRequest - pidf-lo - the PIDF-LO returned in the + pidf-lo - the PIDF-LO returned in the HELD locationRequest response - url - the location reference returned + url - the location reference returned in the HELD locationRequest response - this reference may be added as Geolocation header value and forwarded downstream. Note: to work properly, it is required to include "locationURI" in the location_type parameter. - error - any error code returned in the + error - any error code returned in the HELD response - - - The return value is 200 on success, 400 if an internal error occured, or 500 if an + + + The return value is 200 on success, 400 if an internal error occurred, or 500 if an error code is returned in the HELD locationRequest response. - - - This function can be used from REQUEST_ROUTE, - ONREPLY_ROUTE, FAILURE_ROUTE, and BRANCH_ROUTE. - - - <function>lost_held_query()</function> usage - + + + This function can be used from REQUEST_ROUTE, + ONREPLY_ROUTE, FAILURE_ROUTE, and BRANCH_ROUTE. + + + <function>lost_held_query()</function> usage + ... modparam("http_client", "httpcon", "heldsrv=>http://service.org/api/held"); ... @@ -395,44 +427,44 @@ xlog("L_INFO", "HELD locationRequest: Result code $var(res)\nUrl: $var(url)\n$va $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"); ... - - -
-
- - <function moreinfo="none">lost_held_dereference(url, rtime, rtype, pidf-lo, error)</function> - - - Sends a HELD POST locationRequest to a given URL. Attributes are responseTime and resposeType. + + +
+
+ + <function moreinfo="none">lost_held_dereference(url, rtime, rtype, pidf-lo, error)</function> + + + Sends a HELD POST locationRequest to a given URL. Attributes are responseTime and responseType. The locationType property "exact" is set to "false". - - + + - url - a URL received via Geolocation header to dereference + url - a URL received via Geolocation header to dereference location - - rtime - the response time as defined + + rtime - the response time as defined in - + - rtype - the response type (location) as defined + rtype - the response type (location) as defined in - pidf-lo - the PIDF-LO returned in the + pidf-lo - the PIDF-LO returned in the HELD locationRequest response - error - any error code returned in the + error - any error code returned in the HELD response - - - The return value is 200..203 on success, 400 if an internal error occured, or 500 if an + + + The return value is 200..203 on success, 400 if an internal error occurred, or 500 if an error code is returned in the HELD response. Success codes in detail are as follows: - - + + 200 - received 200 OK, but neither location-info nor locationURI element found @@ -445,14 +477,14 @@ xlog("L_INFO", "HELD locationRequest: Result code $var(res)\nUrl: $var(url)\n$va 203 - received 200 OK with location-info and locationURI element - - - This function can be used from REQUEST_ROUTE, - ONREPLY_ROUTE, FAILURE_ROUTE, and BRANCH_ROUTE. - - - <function>lost_held_dereference()</function> usage - + + + This function can be used from REQUEST_ROUTE, + ONREPLY_ROUTE, FAILURE_ROUTE, and BRANCH_ROUTE. + + + <function>lost_held_dereference()</function> usage + ... # HELD location dereference if ($hdr(Geolocation)=~"^<http.*$") { @@ -461,19 +493,19 @@ if ($hdr(Geolocation)=~"^<http.*$") { xlog("L_INFO", "HELD location dereference: Result code $var(res)\n$var(pidf)"); ... } - - -
-
- - <function moreinfo="none">lost_query(con, [pidf-lo, urn,] uri, name, error)</function> - - - Sends a LOST findService request to a given connection. PIDF-LO and URN are either specified, + + +
+
+ + <function moreinfo="none">lost_query(con, [pidf-lo, urn,] uri, name, error)</function> + + + Sends a LOST findService request to a given connection. PIDF-LO and URN are either specified, or, if omitted, parsed from the message body (PIDF-LO) and request line (URN). Either "pidf-lo" - or "urn" can be set to an empty string in order to be ignored. - - + or "urn" can be set to an empty string to be ignored. + + con - the name of an existing HTTP connection defined by a httpcon modparam @@ -498,18 +530,18 @@ if ($hdr(Geolocation)=~"^<http.*$") { error - any error code returned in the LOST findServiceResponse - - - The return value is 200 on success, 400 if an internal error occured, or 500 if an + + + The return value is 200 on success, 400 if an internal error occurred, or 500 if an error code is returned in the LOST findServiceResponse. - - - This function can be used from REQUEST_ROUTE, - ONREPLY_ROUTE, FAILURE_ROUTE, and BRANCH_ROUTE. - - - <function>lost()</function> usage - + + + This function can be used from REQUEST_ROUTE, + ONREPLY_ROUTE, FAILURE_ROUTE, and BRANCH_ROUTE. + + + <function>lost()</function> usage + ... modparam("http_client", "httpcon", "heldsrv=>http://service.org/api/held"); modparam("http_client", "httpcon", "lostsrv=>http://service.org/api/lost"); @@ -535,24 +567,24 @@ xlog("L_INFO", "LOST findService: Result code $var(res)\nUri: $var(uri)\nName: $ $var(res) = lost_query("lostsrv", "$var(uri)", "$var(name)", "$var(err)"); xlog("L_INFO", "LOST findService: Result code $var(res)\nUri: $var(uri)\nName: $var(name)\n"); ... - - -
+ + +
- Counters + Counters This module has no specific counters but uses http_client therefore according counters may apply. -
+
Remarks Note: libcurl leak in CentOS 6 - this module uses libcurl library - (via http_client) and in case if you are using CentOS 6, be aware that + (via http_client) and in case you are using CentOS 6, be aware that standard libcurl-7.19.7-52 has a memory leak. To fix this memory, install libcurl from city-fan repository. More details at: . @@ -573,7 +605,7 @@ xlog("L_INFO", "LOST findService: Result code $var(res)\nUri: $var(uri)\nName: $ Note: in case modparam "geoheader_type" is set to 2 (http), the module may - use 3 (https) as fallback and vice versa. + use 3 (https) as a fallback and vice versa.
diff --git a/src/modules/lost/functions.c b/src/modules/lost/functions.c index 6545c3cfb..9495a6943 100644 --- a/src/modules/lost/functions.c +++ b/src/modules/lost/functions.c @@ -1,7 +1,7 @@ /* * lost module functions * - * Copyright (C) 2022 Wolfgang Kampichler + * Copyright (C) 2023 Wolfgang Kampichler * DEC112, FREQUENTIS AG * * This file is part of Kamailio, a free SIP server. @@ -67,6 +67,7 @@ extern httpc_api_t httpapi; extern int lost_geoloc_type; extern int lost_geoloc_order; +extern int lost_geoloc_3d; extern int lost_verbose; extern int held_resp_time; extern int held_exact_type; @@ -296,7 +297,7 @@ int lost_held_function(struct sip_msg *_m, char *_con, char *_pidf, char *_url, /* we have no connection ... do a NAPTR lookup */ if(lost_parse_host(did.s, &host, &flag) > 0) { - LM_DBG("no conn. trying NATPR lookup [%.*s]\n", host.len, host.s); + LM_DBG("no conn. trying NAPTR lookup [%.*s]\n", host.len, host.s); /* remove '[' and ']' from string (IPv6) */ if(flag == AF_INET6) { @@ -338,7 +339,7 @@ int lost_held_function(struct sip_msg *_m, char *_con, char *_pidf, char *_url, goto err; } - LM_DBG("NATPR lookup returned [%.*s]\n", url.len, url.s); + LM_DBG("NAPTR lookup returned [%.*s]\n", url.len, url.s); /* curl doesn't like str */ len = 0; @@ -380,7 +381,9 @@ int lost_held_function(struct sip_msg *_m, char *_con, char *_pidf, char *_url, XML_PARSE_NOBLANKS | XML_PARSE_NONET | XML_PARSE_NOCDATA); if(doc == NULL) { LM_WARN("invalid xml document: [%.*s]\n", res.len, res.s); - doc = xmlRecoverMemory(res.s, res.len); + doc = xmlReadMemory(res.s, res.len, 0, NULL, + XML_PARSE_NOBLANKS | XML_PARSE_NONET | + XML_PARSE_NOCDATA | XML_PARSE_RECOVER); if(doc == NULL) { LM_ERR("xml document recovery failed on: [%.*s]\n", res.len, res.s); goto err; @@ -701,7 +704,9 @@ int lost_held_dereference(struct sip_msg *_m, char *_url, char *_pidf, XML_PARSE_NOBLANKS | XML_PARSE_NONET | XML_PARSE_NOCDATA); if(doc == NULL) { LM_WARN("invalid xml document: [%.*s]\n", res.len, res.s); - doc = xmlRecoverMemory(res.s, res.len); + doc = xmlReadMemory(res.s, res.len, 0, NULL, + XML_PARSE_NOBLANKS | XML_PARSE_NONET | + XML_PARSE_NOCDATA | XML_PARSE_RECOVER); if(doc == NULL) { LM_ERR("xml document recovery failed on: [%.*s]\n", res.len, res.s); goto err; diff --git a/src/modules/lost/lost.c b/src/modules/lost/lost.c index 05eebec49..13091d9ff 100644 --- a/src/modules/lost/lost.c +++ b/src/modules/lost/lost.c @@ -53,6 +53,8 @@ httpc_api_t httpapi; int lost_geoloc_type = 0; /* lost: Geolocation header value order: first (0) or last (1) (default: 0) */ int lost_geoloc_order = 0; +/* lost: Geolocation header 3d representation: yes (1) or no (0) (default: 0) */ +int lost_geoloc_3d = 0; /* lost: Recursion allowed: yes (1) or no (0) (default: 1 = allowed) */ int lost_recursion = 1; /* lost geo profile: first (0), last (1), geo (2) or civic (3) (default: 0) */ @@ -124,6 +126,7 @@ static param_export_t params[] = {{"exact_type", PARAM_INT, &held_exact_type}, {"location_type", PARAM_STR, &held_loc_type}, {"recursion", PARAM_INT, &lost_recursion}, {"location_profile", PARAM_INT, &lost_profile}, + {"location_3d", PARAM_INT, &lost_geoloc_3d}, {"verbose", PARAM_INT, &lost_verbose}, {"geoheader_type", PARAM_INT, &lost_geoloc_type}, {"geoheader_order", PARAM_INT, &lost_geoloc_order}, {0, 0, 0}}; diff --git a/src/modules/lost/response.c b/src/modules/lost/response.c index 5c615899a..bce9539e3 100644 --- a/src/modules/lost/response.c +++ b/src/modules/lost/response.c @@ -1,7 +1,7 @@ /* * lost module LoST response parsing functions * - * Copyright (C) 2022 Wolfgang Kampichler + * Copyright (C) 2023 Wolfgang Kampichler * DEC112, FREQUENTIS AG * * This file is part of Kamailio, a free SIP server. @@ -54,7 +54,7 @@ #include "utilities.h" #include "response.h" -/* +/* * is_http_laquot(search) * return 1 if true else 0 */ @@ -77,7 +77,7 @@ int is_http_laquot(char *search) return 0; } -/* +/* * is_https_laquot(search) * return 1 if true else 0 */ @@ -101,7 +101,7 @@ int is_https_laquot(char *search) return 0; } -/* +/* * is_http(search) * return 1 if true else 0 */ @@ -123,7 +123,7 @@ int is_http(char *search) return 0; } -/* +/* * is_https(search) * return 1 if true else 0 */ @@ -146,7 +146,7 @@ int is_https(char *search) return 0; } -/* +/* * is_cid_laquot(search) * return 1 if true else 0 */ @@ -168,7 +168,7 @@ int is_cid_laquot(char *search) return 0; } -/* +/* * is_cid(search) * return 1 if true else 0 */ @@ -189,7 +189,7 @@ int is_cid(char *search) return 0; } -/* +/* * is_urn(search) * return 1 if true else 0 */ @@ -529,7 +529,7 @@ void lost_delete_response_issues(p_lost_issue_t *list) /* * lost_delete_response_issue(mapping) - * removes respone data object from private memory + * removes response data object from private memory */ void lost_delete_response_data(p_lost_data_t *m) { @@ -612,7 +612,7 @@ void lost_free_findServiceResponse(p_lost_fsr_t *res) /* * lost_get_response_issue(node) - * parses response issue (errors, warnings) and writes + * parses response issue (errors, warnings) and writes * results to issue object */ p_lost_issue_t lost_get_response_issues(xmlNodePtr node) @@ -963,7 +963,9 @@ p_lost_fsr_t lost_parse_findServiceResponse(str ret) if(doc == NULL) { LM_ERR("invalid xml document: [%.*s]\n", ret.len, ret.s); - doc = xmlRecoverMemory(ret.s, ret.len); + doc = xmlReadMemory(ret.s, ret.len, 0, NULL, + XML_PARSE_NOBLANKS | XML_PARSE_NONET | + XML_PARSE_NOCDATA | XML_PARSE_RECOVER); if(doc == NULL) { LM_ERR("xml document recovery failed on: [%.*s]\n", ret.len, ret.s); return NULL; @@ -1072,7 +1074,7 @@ p_lost_fsr_t lost_parse_findServiceResponse(str ret) * 1: location reference found * 2: location value found * 3: location value and reference found - * multiple occurences are ignored + * multiple occurrences are ignored */ int lost_check_HeldResponse(xmlNodePtr node) { diff --git a/src/modules/lost/response.h b/src/modules/lost/response.h index 9400f37a3..c4a6e18b4 100644 --- a/src/modules/lost/response.h +++ b/src/modules/lost/response.h @@ -120,7 +120,7 @@ typedef struct lost_fsr /* read and parse response data */ p_lost_fsr_t lost_parse_findServiceResponse(str); -/* check response to dereferece request */ +/* check response to dereference request */ int lost_check_HeldResponse(xmlNodePtr); /* appends value to list objects */ int lost_append_response_list(p_lost_list_t *, str); diff --git a/src/modules/lost/utilities.c b/src/modules/lost/utilities.c index 045340639..6e3d9c43f 100644 --- a/src/modules/lost/utilities.c +++ b/src/modules/lost/utilities.c @@ -1,7 +1,7 @@ /* * lost module utility functions * - * Copyright (C) 2021 Wolfgang Kampichler + * Copyright (C) 2023 Wolfgang Kampichler * DEC112, FREQUENTIS AG * * This file is part of Kamailio, a free SIP server. @@ -52,6 +52,7 @@ extern int lost_recursion; extern int lost_profile; +extern int lost_geoloc_3d; /* * lost_trim_content(dest, lgth) @@ -140,6 +141,7 @@ p_lost_loc_t lost_new_loc(str rurn) ptr->urn = urn; ptr->longitude = NULL; ptr->latitude = NULL; + ptr->altitude = NULL; ptr->geodetic = NULL; ptr->xpath = NULL; ptr->profile = NULL; @@ -228,6 +230,8 @@ void lost_free_loc(p_lost_loc_t *loc) pkg_free(ptr->longitude); if(ptr->latitude) pkg_free(ptr->latitude); + if(ptr->altitude) + pkg_free(ptr->altitude); if(ptr->profile) pkg_free(ptr->profile); @@ -902,7 +906,9 @@ p_lost_loc_t lost_parse_pidf(str pidf, str urn) if(doc == NULL) { LM_WARN("invalid xml (pidf-lo): [%.*s]\n", pidf.len, pidf.s); - doc = xmlRecoverMemory(pidf.s, pidf.len); + doc = xmlReadMemory(pidf.s, pidf.len, 0, NULL, + XML_PARSE_NOBLANKS | XML_PARSE_NONET | + XML_PARSE_NOCDATA | XML_PARSE_RECOVER); if(doc == NULL) { LM_ERR("xml (pidf-lo) recovery failed on: [%.*s]\n", pidf.len, pidf.s); @@ -953,9 +959,55 @@ err: return NULL; } +/* + * lost_check_3d(node) + * checks if pos is 3D and returns 1 if true + * -34.407 150.883 24.8 + */ +int lost_check_3d(xmlNodePtr node) +{ + xmlNodePtr cur = NULL; + + char *content = NULL; + int ret = 0; + + cur = node; + /* find element */ + content = xmlNodeGetNodeContentByName(cur, "pos", NULL); + + if(content == NULL) { + LM_WARN("could not find pos element\n"); + return -1; + } + + int len = 0; + char *tmp = lost_trim_content(content, &len); + + if(len == 0) { + LM_WARN("could not find pos element\n"); + xmlFree(content); /* clean up */ + return -1; + } + + int i = 0; + while(*tmp) { + if(isspace(*tmp)) + i++; + tmp++; + } + + if(i > 1) { + ret = 1; + } + /* clean up */ + xmlFree(content); + + return ret; +} + /* * lost_parse_geo(node, loc) - * parses locationResponse (pos|circle) and writes + * parses locationResponse (pos|circle) and writes * results to location object */ int lost_parse_geo(xmlNodePtr node, p_lost_loc_t loc) @@ -964,12 +1016,14 @@ int lost_parse_geo(xmlNodePtr node, p_lost_loc_t loc) char bufLat[BUFSIZE]; char bufLon[BUFSIZE]; + char bufAlt[BUFSIZE]; char *content = NULL; - char s_profile[] = LOST_PRO_GEO2D; + char *s_profile = LOST_PRO_GEO2D; int iRadius = 0; int len = 0; + int scan = 0; cur = node; /* find element */ @@ -980,9 +1034,14 @@ int lost_parse_geo(xmlNodePtr node, p_lost_loc_t loc) return -1; } - sscanf(content, "%s %s", bufLat, bufLon); + scan = sscanf(content, "%s %s %s", bufLat, bufLon, bufAlt); xmlFree(content); + if(scan < 2) { + LM_WARN("invalid pos element\n"); + return -1; + } + /* latitude */ len = strlen((char *)bufLat); loc->latitude = (char *)pkg_malloc(len + 1); if(loc->latitude == NULL) @@ -990,6 +1049,7 @@ int lost_parse_geo(xmlNodePtr node, p_lost_loc_t loc) snprintf(loc->latitude, len, "%s", (char *)bufLat); + /* logitude */ len = strlen((char *)bufLon); loc->longitude = (char *)pkg_malloc(len + 1); if(loc->longitude == NULL) { @@ -999,15 +1059,40 @@ int lost_parse_geo(xmlNodePtr node, p_lost_loc_t loc) snprintf(loc->longitude, len, "%s", (char *)bufLon); + /* altitude */ + if(scan == 3) { + LM_INFO("3d geolocation in pos element\n"); + + len = strlen((char *)bufAlt); + loc->altitude = (char *)pkg_malloc(len + 1); + if(loc->altitude == NULL) { + pkg_free(loc->latitude); + pkg_free(loc->longitude); + goto err; + } + + snprintf(loc->altitude, len, "%s", (char *)bufAlt); + } + + /* geolocation */ len = strlen((char *)bufLat) + strlen((char *)bufLon) + 1; + if((scan == 3) && (lost_geoloc_3d == 1)) { + len += strlen((char *)bufAlt); + } loc->geodetic = (char *)pkg_malloc(len + 1); - if(loc->longitude == NULL) { + if(loc->geodetic == NULL) { pkg_free(loc->latitude); pkg_free(loc->longitude); + if(loc->altitude) + pkg_free(loc->altitude); goto err; } - - snprintf(loc->geodetic, len, "%s %s", (char *)bufLat, (char *)bufLon); + if((scan == 3) && (lost_geoloc_3d == 1)) { + s_profile = LOST_PRO_GEO3D; + snprintf(loc->geodetic, len, "%s %s %s", (char *)bufLat, (char *)bufLon, (char *)bufAlt); + } else { + snprintf(loc->geodetic, len, "%s %s", (char *)bufLat, (char *)bufLon); + } /* find element */ content = xmlNodeGetNodeContentByName(cur, "radius", NULL); @@ -1030,7 +1115,7 @@ err: /* * lost_xpath_location(doc, path, loc) - * performs xpath expression on locationResponse and writes + * performs xpath expression on locationResponse and writes * results (location-info child element) to location object */ int lost_xpath_location(xmlDocPtr doc, char *path, p_lost_loc_t loc) @@ -1044,8 +1129,15 @@ int lost_xpath_location(xmlDocPtr doc, char *path, p_lost_loc_t loc) xmlChar *xmlbuff = NULL; xmlChar *cname = NULL; + /* shape representation RFC 5491 */ const unsigned char s_point[] = LOST_PNT; + const unsigned char s_polygon[] = LOST_POL; const unsigned char s_circle[] = LOST_CIR; + const unsigned char s_ellipse[] = LOST_ELL; + const unsigned char s_arcband[] = LOST_ARC; + const unsigned char s_sphere[] = LOST_SPH; + const unsigned char s_ellipsoid[] = LOST_OID; + const unsigned char s_prism[] = LOST_PSM; const unsigned char s_civic[] = LOST_CIV; char *ptr = NULL; @@ -1082,7 +1174,7 @@ int lost_xpath_location(xmlDocPtr doc, char *path, p_lost_loc_t loc) } if(nodes->nodeTab[i]->type == XML_ELEMENT_NODE) { cur = nodes->nodeTab[i]; - /* check if child element is point, circle or civic */ + /* check if child element is point, circle, ... or civic */ while(nok < LOST_XPATH_DPTH) { if(cur->children == NULL) { /* no additional DOM level */ @@ -1092,15 +1184,39 @@ int lost_xpath_location(xmlDocPtr doc, char *path, p_lost_loc_t loc) nok++; cname = BAD_CAST cur->name; if(xmlStrcasecmp(cname, s_point) == 0) { + if((lost_check_3d(cur) == 1) + && (lost_geoloc_3d == 1)) { + s_profile = LOST_PRO_GEO3D; + selgeo = i; + break; + } + if(lost_check_3d(cur) == 0) { + s_profile = LOST_PRO_GEO2D; + selgeo = i; + break; + } + } + if(xmlStrcasecmp(cname, s_circle) == 0) { s_profile = LOST_PRO_GEO2D; selgeo = i; break; } - if(xmlStrcasecmp(cname, s_circle) == 0) { + if((xmlStrcasecmp(cname, s_polygon) == 0) + || (xmlStrcasecmp(cname, s_ellipse) == 0) + || (xmlStrcasecmp(cname, s_arcband) == 0)) { s_profile = LOST_PRO_GEO2D; selgeo = i; break; } + if((xmlStrcasecmp(cname, s_sphere) == 0) + || (xmlStrcasecmp(cname, s_ellipsoid) == 0) + || (xmlStrcasecmp(cname, s_prism) == 0)) { + if(lost_geoloc_3d == 1) { + s_profile = LOST_PRO_GEO3D; + selgeo = i; + break; + } + } if(xmlStrcasecmp(cname, s_civic) == 0) { s_profile = LOST_PRO_CIVIC; selciv = i; @@ -1115,8 +1231,8 @@ int lost_xpath_location(xmlDocPtr doc, char *path, p_lost_loc_t loc) LM_DBG("xpath '%s' returned valid element (level %d/%d)\n", xpath, nok, LOST_XPATH_DPTH); } else if(nok < LOST_XPATH_DPTH) { - /* malformed pidf-lo but still ok */ - LM_WARN("xpath '%s' returned malformed pidf-lo (level " + /* no matching location ... pidf-lo still ok */ + LM_WARN("xpath '%s' shape representation not found (level " "%d/%d)\n", xpath, nok, LOST_XPATH_DPTH); } else { @@ -1205,8 +1321,9 @@ int lost_xpath_location(xmlDocPtr doc, char *path, p_lost_loc_t loc) } else { xmlFree(xmlbuff); /* clean up */ xmlFreeDoc(new); + LM_DBG("xpath '%s' no valid profile found\n", xpath); xmlXPathFreeObject(result); - goto err; + return -1; } /* remove xml header from location element */ remove = strlen("\n"); @@ -1241,7 +1358,7 @@ int lost_xpath_location(xmlDocPtr doc, char *path, p_lost_loc_t loc) pkg_free(ptr); /* clean up */ ptr = NULL; } else { - LM_WARN("xpath location-info element(%d) ignored\n", i + 1); + LM_WARN("location-info element[%d] dropped!\n", i + 1); } /* clean up */ xmlFree(xmlbuff); @@ -1251,7 +1368,7 @@ int lost_xpath_location(xmlDocPtr doc, char *path, p_lost_loc_t loc) } } } else { - LM_WARN("xpath '%s' failed\n", xpath); + LM_WARN("xpath '%s' error\n", xpath); xmlXPathFreeObject(result); return -1; } diff --git a/src/modules/lost/utilities.h b/src/modules/lost/utilities.h index fc13599a8..c7f43cdf6 100644 --- a/src/modules/lost/utilities.h +++ b/src/modules/lost/utilities.h @@ -1,7 +1,7 @@ /* * lost module utility functions * - * Copyright (C) 2021 Wolfgang Kampichler + * Copyright (C) 2023 Wolfgang Kampichler * DEC112, FREQUENTIS AG * * This file is part of Kamailio, a free SIP server. @@ -57,10 +57,18 @@ "gm=http://www.opengis.net/gml" #define LOST_PRO_GEO2D "geodetic-2d" +#define LOST_PRO_GEO3D "geodetic-3d" #define LOST_PRO_CIVIC "civic" +/* shape representation RFC 5491 */ #define LOST_PNT "Point" +#define LOST_POL "Polygon" #define LOST_CIR "Circle" +#define LOST_ELL "Ellipse" +#define LOST_ARC "ArcBand" +#define LOST_SPH "Sphere" +#define LOST_OID "Ellipsoid" +#define LOST_PSM "Prism" #define LOST_CIV "civicAddress" #define HELD_TYPE_ANY "any" @@ -89,6 +97,7 @@ typedef struct lost_loc char *geodetic; /* geodetic location (findServiceRequest) */ char *longitude; /* geo longitude */ char *latitude; /* geo latitude */ + char *altitude; /* geo altitude */ char *profile; /* location profile (findServiceRequest) */ int radius; /* geo radius (findServiceRequest) */ int recursive; /* recursion true|false (findServiceRequest)*/ diff --git a/src/modules/lrkproxy/README b/src/modules/lrkproxy/README index f5cb80173..3c30e5665 100644 --- a/src/modules/lrkproxy/README +++ b/src/modules/lrkproxy/README @@ -198,7 +198,7 @@ Chapter 1. Admin Guide ock", "udp:192.168.122.108:8080") # multiple lrkproxies for LB in -diffenrent machine +different machine modparam("lrkproxy", "lrkproxy_s ock", "udp:192.168.122.108:8080") modparam("lrkproxy", "lrkproxy_s @@ -274,7 +274,7 @@ etr", 2) the insert/remove/lookup path. NOTE: When configuring this parameter, one should consider maximum call - time VS share memory for unfinished calls. + time VS shared memory for unfinished calls. Default value is “3600”. @@ -299,8 +299,8 @@ _size", 256) 4.3.8. custom_sdp_ip_avp (string) This option useful for solving STUN and help UDP packets make it across - NAT devices safe and sound. In this way, it should be set by clients's - ip public manually. + NAT devices safe and sound. In this way, it should be set by clients' + IP public manually. Default value is “NULL”. diff --git a/src/modules/lrkproxy/doc/lrkproxy_admin.xml b/src/modules/lrkproxy/doc/lrkproxy_admin.xml index 06cbed3a6..174dfede3 100644 --- a/src/modules/lrkproxy/doc/lrkproxy_admin.xml +++ b/src/modules/lrkproxy/doc/lrkproxy_admin.xml @@ -133,7 +133,7 @@ # single lrkproxy modparam("lrkproxy", "lrkproxy_sock", "udp:192.168.122.108:8080") - # multiple lrkproxies for LB in diffenrent machine + # multiple lrkproxies for LB in different machine modparam("lrkproxy", "lrkproxy_sock", "udp:192.168.122.108:8080") modparam("lrkproxy", "lrkproxy_sock", "udp:192.168.122.109:8080") @@ -243,7 +243,7 @@ NOTE: When configuring this parameter, one should consider maximum call - time VS share memory for unfinished calls. + time VS shared memory for unfinished calls. @@ -286,7 +286,7 @@ <varname>custom_sdp_ip_avp</varname> (string) This option useful for solving STUN and help UDP packets make it across NAT devices safe and sound. - In this way, it should be set by clients's ip public manually. + In this way, it should be set by clients' IP public manually. diff --git a/src/modules/lrkproxy/lrkproxy.c b/src/modules/lrkproxy/lrkproxy.c index 5508d2dce..0ffbfbe54 100644 --- a/src/modules/lrkproxy/lrkproxy.c +++ b/src/modules/lrkproxy/lrkproxy.c @@ -446,8 +446,8 @@ static int add_lrkproxy_socks(struct lrkp_set *lrkp_list, char *lrkproxy) return 0; } -/* 0-succes - * -1 - erorr +/* 0-success + * -1 - error * */ static int lrkproxy_add_lrkproxy_set(char *lrk_proxies) { @@ -812,8 +812,8 @@ static int lrkp_test(struct lrkp_node *node) char *resp = buf + v[0].iov_len + v[1].iov_len + 1; if(memcmp(resp, "PONG", 4) == 0) - // LM_DBG("Recieve PONG response from lrk proxy server %s, Enable it right now.\n", node->ln_url.s); - LM_INFO("Recieve PONG response from lrk proxy server %s, Enable it " + // LM_DBG("Receive PONG response from lrk proxy server %s, Enable it right now.\n", node->ln_url.s); + LM_INFO("Receive PONG response from lrk proxy server %s, Enable it " "right now.\n", node->ln_url.s); @@ -1028,10 +1028,10 @@ static int lrkp_set_conntrack_rule(struct lrkproxy_hash_entry *e) // char *resp = buf + v[0].iov_len + v[1].iov_len + v[2].iov_len; char *resp = buf + v_len; if(memcmp(resp, "OK", 2) == 0) { - LM_INFO("Recieve OK response from lrk proxy server %s, Rule set " + LM_INFO("Receive OK response from lrk proxy server %s, Rule set " "successfully.\n", e->node->ln_url.s); - LM_DBG("Recieve OK response from lrk proxy server %s, Rule set " + LM_DBG("Receive OK response from lrk proxy server %s, Rule set " "successfully.\n", e->node->ln_url.s); } @@ -1150,9 +1150,9 @@ static int lrkp_remove_conntrack_rule(struct lrkproxy_hash_entry *e) // char *resp = buf + v[0].iov_len + v[1].iov_len + v[2].iov_len; char *resp = buf + v_len; if(memcmp(resp, "OK", 2) == 0) { - LM_INFO("Recieve OK response from lrk proxy server, Rule remove " + LM_INFO("Receive OK response from lrk proxy server, Rule remove " "successfully.\n"); - LM_DBG("Recieve OK response from lrk proxy server, Rule remove " + LM_DBG("Receive OK response from lrk proxy server, Rule remove " "successfully.\n"); } return 1; @@ -1574,7 +1574,7 @@ static int change_media_sdp(sip_msg_t *msg, struct lrkproxy_hash_entry *e, if((int)(start_sdp_m - off) == 0) { memset(sdp_new_m, 0, 128); char *avp_flags = off; - // int occure = 0; + // int occur = 0; for(; *avp_flags && !isspace(*avp_flags); avp_flags++) ; for(avp_flags++; *avp_flags && !isspace(*avp_flags); avp_flags++) @@ -1809,7 +1809,7 @@ static int lrkproxy_force( // fill the entry if(call_id.s && call_id.len > 0) { if(shm_str_dup(&entry->callid, &call_id) < 0) { - LM_ERR("lrkproxy hash table fail to instert call_id, " + LM_ERR("lrkproxy hash table failed to insert call_id, " "calllen=%d callid=%.*s\n", call_id.len, call_id.len, call_id.s); lrkproxy_hash_table_free_entry(entry); diff --git a/src/modules/lrkproxy/lrkproxy_funcs.c b/src/modules/lrkproxy/lrkproxy_funcs.c index 06b74a2a0..596739117 100644 --- a/src/modules/lrkproxy/lrkproxy_funcs.c +++ b/src/modules/lrkproxy/lrkproxy_funcs.c @@ -177,8 +177,8 @@ int extract_body(struct sip_msg *msg, str *body) /* * Better use the content-len value - no need of any explicit - * parcing as get_body() parsed all headers and Conten-Length - * body header is automaticaly parsed when found. + * parsing as get_body() parsed all headers and Content-Length + * body header is automatically parsed when found. */ if(msg->content_length == 0) { LM_ERR("failed to get the content length in message\n"); diff --git a/src/modules/lrkproxy/lrkproxy_hash.h b/src/modules/lrkproxy/lrkproxy_hash.h index 0ee5be93d..cbe89021e 100644 --- a/src/modules/lrkproxy/lrkproxy_hash.h +++ b/src/modules/lrkproxy/lrkproxy_hash.h @@ -34,11 +34,11 @@ struct lrkproxy_hash_entry str src_ipv4; //media ip address of initiator call in INVITE SIP message. str dst_ipv4; //media ip address of selected node in 200Ok SIP message. str snat_ipv4; //change media ip address to selected node. - str dnat_ipv4; //change media ip address to orgin destination party. + str dnat_ipv4; //change media ip address to origin destination party. str src_port; //media port of initiator call in INVITE SIP message str dst_port; //media port of selected node in 200Ok SIP message. str snat_port; //change media port to selected node. - str dnat_port; //change media port to orgin destination party. + str dnat_port; //change media port to origin destination party. str callid; // call callid str viabranch; // call viabranch diff --git a/src/modules/lwsc/api.h b/src/modules/lwsc/api.h index 55dfac8e7..2e1cef995 100644 --- a/src/modules/lwsc/api.h +++ b/src/modules/lwsc/api.h @@ -39,7 +39,7 @@ typedef int (*lwsc_api_request_f)( typedef struct lwsc_api { int loaded; - lwsc_api_request_f request; /* send and receice data */ + lwsc_api_request_f request; /* send and receive data */ } lwsc_api_t; typedef int (*bind_lwsc_f)(lwsc_api_t *api); diff --git a/src/modules/lwsc/lwsc_mod.c b/src/modules/lwsc/lwsc_mod.c index 508c60cd2..358f53e72 100644 --- a/src/modules/lwsc/lwsc_mod.c +++ b/src/modules/lwsc/lwsc_mod.c @@ -545,7 +545,7 @@ static lwsc_endpoint_t *lwsc_get_endpoint(str *wsurl, str *wsproto) ep->wsctx = lws_create_context(&ep->crtinfo); if(!ep->wsctx) { - LM_ERR("failed to intialize context for ws url [%.*s]\n", wsurl->len, + LM_ERR("failed to initialize context for ws url [%.*s]\n", wsurl->len, wsurl->s); goto error; } diff --git a/src/modules/mangler/contact_ops.c b/src/modules/mangler/contact_ops.c index 57aad1d6f..fc026e61c 100644 --- a/src/modules/mangler/contact_ops.c +++ b/src/modules/mangler/contact_ops.c @@ -316,7 +316,7 @@ int encode2format(struct sip_msg *msg, str *uri, struct uri_format *format) format->first = start - string + scheme_len + 1 /* ':' */; format->second = end - string; /* --------------------------testing ------------------------------- */ - /* sip:gva@pass@10.0.0.1;;transport=udp>;expires=2 INCORECT BEHAVIOR OF parse_uri,myfunction works good */ + /* sip:gva@pass@10.0.0.1;;transport=udp>;expires=2 INCORRECT BEHAVIOR OF parse_uri,myfunction works good */ foo = parse_uri(start, end - start, &sipUri); if(foo != 0) { LOG(L_ERR, diff --git a/src/modules/mangler/mangler.c b/src/modules/mangler/mangler.c index 702f7ec04..0ce768999 100644 --- a/src/modules/mangler/mangler.c +++ b/src/modules/mangler/mangler.c @@ -156,7 +156,7 @@ int prepare() { /* using pre-compiled expressions to speed things up*/ - compile_expresions(PORT_REGEX, IP_REGEX); + compile_expressions(PORT_REGEX, IP_REGEX); #ifdef DEMO load_tm_f load_tm; @@ -195,7 +195,7 @@ static int mod_init(void) static void destroy(void) { /*free some compiled regex expressions */ - free_compiled_expresions(); + free_compiled_expressions(); #ifdef DEMO fprintf(stdout, "Freeing pre-compiled expressions\n"); #endif diff --git a/src/modules/mangler/mangler.cfg b/src/modules/mangler/mangler.cfg index 1bc9a5a6b..affd6d6d8 100644 --- a/src/modules/mangler/mangler.cfg +++ b/src/modules/mangler/mangler.cfg @@ -42,7 +42,7 @@ loadmodule "modules/mangler/mangler.so" #loadmodule "/usr/lib/ser/modules/auth.so" # ----------------- setting module-specific parameters --------------- -# seting separator for encoded contact +# setting separator for encoded contact modparam("mangler","contact_flds_separator","*") @@ -78,7 +78,7 @@ route{ * message */ if (method == "INVITE"){ sdp_mangle_ip("0.0.0.0/0","PUBLIC_IP"); - /* diferent mangling based on what phone we use */ + /* different mangling based on what phone we use */ if (src_ip==10.0.0.1) sdp_mangle_port("+1000"); if (src_ip==10.0.0.2) sdp_mangle_port("-1000"); }; diff --git a/src/modules/mangler/sdp_mangler.c b/src/modules/mangler/sdp_mangler.c index 6341e0be2..8479e67db 100644 --- a/src/modules/mangler/sdp_mangler.c +++ b/src/modules/mangler/sdp_mangler.c @@ -46,7 +46,7 @@ regex_t *ipExpression = NULL; int sdp_mangle_port(struct sip_msg *msg, char *offset, char *unused) { int oldContentLength, newContentLength, oldlen, err, oldPort, newPort, diff, - offsetValue, len, off, ret, needToDealocate; + offsetValue, len, off, ret, needToDeallocate; struct lump *l; regmatch_t pmatch; regex_t *re; @@ -101,7 +101,7 @@ int sdp_mangle_port(struct sip_msg *msg, char *offset, char *unused) ret = -1; /* try to use pre-compiled expressions */ - needToDealocate = 0; + needToDeallocate = 0; if(portExpression != NULL) { re = portExpression; #ifdef EXTRA_DEBUG @@ -114,7 +114,7 @@ int sdp_mangle_port(struct sip_msg *msg, char *offset, char *unused) LOG(L_ERR, "ERROR: sdp_mangle_port: Unable to allocate re\n"); return -4; } - needToDealocate = 1; + needToDeallocate = 1; if((regcomp(re, key, REG_EXTENDED)) != 0) { LOG(L_ERR, "ERROR: sdp_mangle_port: Unable to compile %s \n", key); pkg_free(re); @@ -131,7 +131,7 @@ int sdp_mangle_port(struct sip_msg *msg, char *offset, char *unused) off = begin - msg->buf; if(pmatch.rm_so == -1) { LOG(L_ERR, "ERROR: sdp_mangle_port: offset unknown\n"); - if(needToDealocate) { + if(needToDeallocate) { regfree(re); pkg_free(re); } @@ -170,7 +170,7 @@ int sdp_mangle_port(struct sip_msg *msg, char *offset, char *unused) "ERROR: sdp_mangle_port: Error converting [%.*s] to int\n", oldlen, pos); #ifdef STRICT_CHECK - if(needToDealocate) { + if(needToDeallocate) { regfree(re); pkg_free(re); } @@ -194,7 +194,7 @@ int sdp_mangle_port(struct sip_msg *msg, char *offset, char *unused) "matching old port %d\n", oldPort); #ifdef STRICT_CHECK - if(needToDealocate) { + if(needToDeallocate) { regfree(re); pkg_free(re); } @@ -223,7 +223,7 @@ int sdp_mangle_port(struct sip_msg *msg, char *offset, char *unused) "matching new port %d\n", newPort); #ifdef STRICT_CHECK - if(needToDealocate) { + if(needToDeallocate) { regfree(re); pkg_free(re); } @@ -262,7 +262,7 @@ int sdp_mangle_port(struct sip_msg *msg, char *offset, char *unused) 0)) == 0) { LOG(L_ERR, "ERROR: sdp_mangle_port: del_lump failed\n"); - if(needToDealocate) { + if(needToDeallocate) { regfree(re); pkg_free(re); } @@ -271,7 +271,7 @@ int sdp_mangle_port(struct sip_msg *msg, char *offset, char *unused) s = pkg_malloc(len); if(s == 0) { LOG(L_ERR, "ERROR: sdp_mangle_port : memory allocation failure\n"); - if(needToDealocate) { + if(needToDeallocate) { regfree(re); pkg_free(re); } @@ -283,7 +283,7 @@ int sdp_mangle_port(struct sip_msg *msg, char *offset, char *unused) if(insert_new_lump_after(l, s, len, 0) == 0) { LOG(L_ERR, "ERROR: sdp_mangle_port: could not insert new lump\n"); pkg_free(s); - if(needToDealocate) { + if(needToDeallocate) { regfree(re); pkg_free(re); } @@ -298,7 +298,7 @@ int sdp_mangle_port(struct sip_msg *msg, char *offset, char *unused) begin = begin + pmatch.rm_eo; } /* while */ - if(needToDealocate) { + if(needToDeallocate) { regfree(re); pkg_free(re); #ifdef EXTRA_DEBUG @@ -322,7 +322,7 @@ int sdp_mangle_port(struct sip_msg *msg, char *offset, char *unused) int sdp_mangle_ip(struct sip_msg *msg, char *oldip, char *newip) { int i, oldContentLength, newContentLength, diff, oldlen, len, off, ret, - needToDealocate; + needToDeallocate; unsigned int mask, address, locatedIp; struct lump *l; regmatch_t pmatch; @@ -395,7 +395,7 @@ int sdp_mangle_ip(struct sip_msg *msg, char *oldip, char *newip) len = strlen(newip); /* try to use pre-compiled expressions */ - needToDealocate = 0; + needToDeallocate = 0; if(ipExpression != NULL) { re = ipExpression; #ifdef EXTRA_DEBUG @@ -409,7 +409,7 @@ int sdp_mangle_ip(struct sip_msg *msg, char *oldip, char *newip) LOG(L_ERR, "ERROR: sdp_mangle_ip: Unable to allocate re\n"); return -7; } - needToDealocate = 1; + needToDeallocate = 1; if((regcomp(re, key, REG_EXTENDED)) != 0) { LOG(L_ERR, "ERROR: sdp_mangle_ip: Unable to compile %s \n", key); pkg_free(re); @@ -517,7 +517,7 @@ int sdp_mangle_ip(struct sip_msg *msg, char *oldip, char *newip) begin = begin + pmatch.rm_eo; } /* while */ - if(needToDealocate) { + if(needToDeallocate) { regfree(re); /* if I am going to use pre-compiled expressions to be removed */ pkg_free(re); #ifdef EXTRA_DEBUG @@ -537,22 +537,22 @@ int sdp_mangle_ip(struct sip_msg *msg, char *oldip, char *newip) return ret + 2; } -int compile_expresions(char *port, char *ip) +int compile_expressions(char *port, char *ip) { portExpression = NULL; portExpression = pkg_malloc(sizeof(regex_t)); if(portExpression != NULL) { if((regcomp(portExpression, port, REG_EXTENDED)) != 0) { LOG(L_ERR, - "ERROR: compile_expresions: Unable to compile " + "ERROR: compile_expressions: Unable to compile " "portExpression [%s]\n", port); pkg_free(portExpression); portExpression = NULL; } } else { - LOG(L_ERR, - "ERROR: compile_expresions: Unable to alloc portExpression \n"); + LOG(L_ERR, "ERROR: compile_expressions: Unable to alloc portExpression " + "\n"); } ipExpression = NULL; @@ -560,21 +560,21 @@ int compile_expresions(char *port, char *ip) if(ipExpression != NULL) { if((regcomp(ipExpression, ip, REG_EXTENDED)) != 0) { LOG(L_ERR, - "ERROR: compile_expresions: Unable to compile ipExpression " - "[%s]\n", + "ERROR: compile_expressions: Unable to compile " + "ipExpression [%s]\n", ip); pkg_free(ipExpression); ipExpression = NULL; } } else { LOG(L_ERR, - "ERROR: compile_expresions: Unable to alloc ipExpression \n"); + "ERROR: compile_expressions: Unable to alloc ipExpression \n"); } return 0; } -int free_compiled_expresions() +int free_compiled_expressions() { if(portExpression != NULL) { regfree(portExpression); diff --git a/src/modules/mangler/sdp_mangler.h b/src/modules/mangler/sdp_mangler.h index db0b26d1d..fb0e64fca 100644 --- a/src/modules/mangler/sdp_mangler.h +++ b/src/modules/mangler/sdp_mangler.h @@ -20,7 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -/* TO DO: precompiled expresions */ +/* TO DO: precompiled expressions */ #ifndef SDP_MANGLER_H #define SDP_MANGLER_H @@ -83,7 +83,7 @@ int sdp_mangle_port(struct sip_msg *msg, char *offset, char *unused); int sdp_mangle_ip(struct sip_msg *msg, char *oldip, char *newip); -int compile_expresions(char *port, char *ip); -int free_compiled_expresions(); +int compile_expressions(char *port, char *ip); +int free_compiled_expressions(); #endif diff --git a/src/modules/matrix/README b/src/modules/matrix/README index ffd0bbd6d..74888790b 100644 --- a/src/modules/matrix/README +++ b/src/modules/matrix/README @@ -117,8 +117,8 @@ Chapter 1. Admin Guide 2.1. Kamailio Modules - The module depends on the following modules (in the other words the - listed modules must be loaded before this module): + The module depends on the following modules (in other words the listed + modules must be loaded before this module): * none 2.2. External Libraries or Applications diff --git a/src/modules/matrix/doc/matrix_admin.xml b/src/modules/matrix/doc/matrix_admin.xml index 8761558a0..f8746dae5 100644 --- a/src/modules/matrix/doc/matrix_admin.xml +++ b/src/modules/matrix/doc/matrix_admin.xml @@ -36,7 +36,7 @@
&kamailio; Modules - The module depends on the following modules (in the other words + The module depends on the following modules (in other words the listed modules must be loaded before this module): diff --git a/src/modules/maxfwd/README b/src/modules/maxfwd/README index 9bbf8a4e4..69602da67 100644 --- a/src/modules/maxfwd/README +++ b/src/modules/maxfwd/README @@ -172,7 +172,7 @@ if (!maxfwd_process("10") && $retcode==-1) { parameter value. It considers also the value of the new inserted header (if locally added). The parameter can be a variable. - Retuning codes: + Return codes: * 1 (true) - header was found or set and its value is strictly less than “max_value”. * -1 (false) - the header was found or set and its value is greater diff --git a/src/modules/maxfwd/doc/maxfwd_admin.xml b/src/modules/maxfwd/doc/maxfwd_admin.xml index 3a846121f..b9c31b725 100644 --- a/src/modules/maxfwd/doc/maxfwd_admin.xml +++ b/src/modules/maxfwd/doc/maxfwd_admin.xml @@ -186,7 +186,7 @@ if (!maxfwd_process("10") && $retcode==-1) { of the new inserted header (if locally added). The parameter can be a variable. - Retuning codes: + Return codes: 1 (true) - header was found or set and diff --git a/src/modules/mediaproxy/mediaproxy.c b/src/modules/mediaproxy/mediaproxy.c index 3ca59b6c9..782bc2028 100644 --- a/src/modules/mediaproxy/mediaproxy.c +++ b/src/modules/mediaproxy/mediaproxy.c @@ -123,7 +123,7 @@ typedef struct MediaproxySocket { char *name; // name int sock; // socket - int timeout; // how many miliseconds to wait for an answer + int timeout; // how many milliseconds to wait for an answer time_t last_failure; // time of the last failure char data[BUFFER_SIZE]; // buffer for the answer data } MediaproxySocket; @@ -199,7 +199,7 @@ static str ice_candidate = str_init("none"); static MediaproxySocket mediaproxy_socket = { "/run/mediaproxy/dispatcher.sock", // name -1, // sock - 500, // timeout in 500 miliseconds if there is no answer + 500, // timeout in 500 milliseconds if there is no answer 0, // time of the last failure "" // data }; @@ -754,7 +754,7 @@ err: } -// Get the SDP message from SIP message and check it's Content-Type +// Get the SDP message from SIP message and check its Content-Type // Return values: // 1 - success // -1 - error in getting body or invalid content type @@ -1614,7 +1614,7 @@ static int use_media_proxy( if(session.supported_count == 0) return 1; // there are no supported media streams. we have nothing to do. - len = sprintf(media_str, "%s", "media: "); + len = snprintf(media_str, sizeof(media_str), "%s", "media: "); for(i = 0, str_buf.len = sizeof(media_str) - len - 2, str_buf.s = media_str + len; i < session.stream_count; i++) { @@ -1628,15 +1628,15 @@ static int use_media_proxy( (unsigned long)sizeof(media_str)); return -1; } - len = sprintf(str_buf.s, "%.*s:%.*s:%.*s:%.*s:%s,", stream.type.len, - stream.type.s, stream.ip.len, stream.ip.s, stream.port.len, - stream.port.s, stream.direction.len, stream.direction.s, - stream.has_ice ? "ice=yes" : "ice=no"); + len = snprintf(str_buf.s, str_buf.len, "%.*s:%.*s:%.*s:%.*s:%s,", + stream.type.len, stream.type.s, stream.ip.len, stream.ip.s, + stream.port.len, stream.port.s, stream.direction.len, + stream.direction.s, stream.has_ice ? "ice=yes" : "ice=no"); str_buf.s += len; str_buf.len -= len; } *(str_buf.s - 1) = 0; // remove the last comma - sprintf(str_buf.s - 1, "%s", "\r\n"); + snprintf(str_buf.s - 1, str_buf.len + 1, "%s", "\r\n"); } else { media_str[0] = 0; } @@ -1819,7 +1819,7 @@ static int use_media_proxy( : ice_data->priority; port = strtoint(&tokens[j]); candidate.s = buf; - candidate.len = sprintf(candidate.s, + candidate.len = snprintf(candidate.s, sizeof(buf), "a=candidate:R%x 1 UDP %u %.*s %i typ relay%.*s", hexip.s_addr, priority, tokens[0].len, tokens[0].s, port, session.separator.len, session.separator.s); @@ -1833,7 +1833,7 @@ static int use_media_proxy( if(stream.has_rtcp_ice) { candidate.s = buf; - candidate.len = sprintf(candidate.s, + candidate.len = snprintf(candidate.s, sizeof(buf), "a=candidate:R%x 2 UDP %u %.*s %i typ relay%.*s", hexip.s_addr, priority - 1, tokens[0].len, tokens[0].s, port + 1, session.separator.len, session.separator.s); @@ -2199,4 +2199,4 @@ int mod_register(char *path, int *dlflags, void *p1, void *p2) { sr_kemi_modules_add(sr_kemi_mediaproxy_exports); return 0; -} \ No newline at end of file +} diff --git a/src/modules/memcached/doc/memcached_admin.xml b/src/modules/memcached/doc/memcached_admin.xml index 272ce7db1..05f5f5419 100644 --- a/src/modules/memcached/doc/memcached_admin.xml +++ b/src/modules/memcached/doc/memcached_admin.xml @@ -150,7 +150,7 @@ xlog("stored value is $mct(test)"); # will return <null> <varname>servers</varname> (str) The servers to connect to. At the moment only one server is supported. - diff --git a/src/modules/memcached/mcd_var.c b/src/modules/memcached/mcd_var.c index 04b2f9261..387113e6b 100644 --- a/src/modules/memcached/mcd_var.c +++ b/src/modules/memcached/mcd_var.c @@ -93,7 +93,7 @@ static inline int pv_mcd_key_expiry_split_str( } /*! - * \brief Checks if the key is avaiable and not too long, hashing it with MD5 if necessary. + * \brief Checks if the key is available and not too long, hashing it with MD5 if necessary. * \param msg SIP message * \param param pseudo-variable input parameter * \param key output string name diff --git a/src/modules/microhttpd/Makefile b/src/modules/microhttpd/Makefile new file mode 100644 index 000000000..87f2d629f --- /dev/null +++ b/src/modules/microhttpd/Makefile @@ -0,0 +1,23 @@ +# +# WARNING: do not run this directly, it should be run by the main Makefile + +include ../../Makefile.defs +auto_gen= +NAME=microhttpd.so + +ifeq ($(CROSS_COMPILE),) +BUILDER = $(shell \ + if pkg-config --exists microhttpd; then \ + echo 'pkg-config microhttpd'; \ + fi) +endif + +ifneq ($(BUILDER),) + DEFS += $(shell $(BUILDER) --cflags) + LIBS += $(shell $(BUILDER) --libs) +else + DEFS +=-I$(LOCALBASE)/include -I$(SYSBASE)/include + LIBS +=-L$(LOCALBASE)/lib -L$(SYSBASE)/lib -lmicrohttpd +endif + +include ../../Makefile.modules diff --git a/src/modules/microhttpd/README b/src/modules/microhttpd/README new file mode 100644 index 000000000..cb6fc84fd --- /dev/null +++ b/src/modules/microhttpd/README @@ -0,0 +1,176 @@ +MicroHTTPd Module + +Daniel-Constantin Mierla + + + +Edited by + +Daniel-Constantin Mierla + + + + Copyright © 2023 asipto.com + __________________________________________________________________ + + Table of Contents + + 1. Admin Guide + + 1. Overview + 2. Dependencies + + 2.1. Kamailio Modules + 2.2. External Libraries or Applications + + 3. Parameters + + 3.1. listen_addr (int) + 3.2. listen_port (int) + 3.3. event_callback (str) + + 4. Functions + + 4.1. mhttpd_reply(code, reason, ctype, body) + + 5. Event Routes + + 5.1. microhttpd:request + + List of Examples + + 1.1. Set listen_addr parameter + 1.2. Set listen_port parameter + 1.3. Set event_callback parameter + 1.4. mhttpd_reply usage + +Chapter 1. Admin Guide + + Table of Contents + + 1. Overview + 2. Dependencies + + 2.1. Kamailio Modules + 2.2. External Libraries or Applications + + 3. Parameters + + 3.1. listen_addr (int) + 3.2. listen_port (int) + 3.3. event_callback (str) + + 4. Functions + + 4.1. mhttpd_reply(code, reason, ctype, body) + + 5. Event Routes + + 5.1. microhttpd:request + +1. Overview + + This module implements an embedded HTTP server using libmicrohttpd. + +2. Dependencies + + 2.1. Kamailio Modules + 2.2. External Libraries or Applications + +2.1. Kamailio Modules + + The following modules must be loaded before this module: + * none. + +2.2. External Libraries or Applications + + The following libraries or applications must be installed before + running Kamailio with this module loaded: + * libmicrohhtpd - libmicrohttpd library + +3. Parameters + + 3.1. listen_addr (int) + 3.2. listen_port (int) + 3.3. event_callback (str) + +3.1. listen_addr (int) + + IPv4 address to listen for HTTP connection. If not set, then it listens + on all local addresses (port has to be specified by listen_port + parameter). + + Default value is "" (empty - not set). + + Example 1.1. Set listen_addr parameter +... +modparam("microhttpd", "listen_addr", "127.0.0.1") +... + +3.2. listen_port (int) + + Port to listen for HTTP connection. + + Default value is 8280. + + Example 1.2. Set listen_port parameter +... +modparam("microhttpd", "listen_port", 8284) +... + +3.3. event_callback (str) + + The name of the function in the kemi configuration file (embedded + scripting language such as Lua, Python, ...) to be executed instead of + event_route[microhttpd:request] block. + + The function has one string parameter with the value + "microhttpd:request". + + Default value is 'empty' (no function is executed for events). + + Example 1.3. Set event_callback parameter +... +modparam("microhttpd", "event_callback", "ksr_microhttpd_event") +... +-- event callback function implemented in Lua +function ksr_microhttpd_event(evname) + KSR.info("===== microhttpd module triggered event: " .. evname .. "\n"); + return 1; +end +... + +4. Functions + + 4.1. mhttpd_reply(code, reason, ctype, body) + +4.1. mhttpd_reply(code, reason, ctype, body) + + Send back a reply with content-type and body. + + Example 1.4. mhttpd_reply usage +... +event_route[microhttpd:request] { + mhttpd_reply("200", "OK", "text/html", + "OK"); +} +... + +5. Event Routes + + 5.1. microhttpd:request + +5.1. microhttpd:request + + The event route is executed when a new HTTP request is received. +... +... +loadmodule "microhttpd.so +... +event_route[microhttpd:request] { + xinfo("request: $mhttpd(method) - url: $mhttpd(url) - data: [$mhttpd(data)]\ +n"); + mhttpd_reply("200", "OK", "text/html", + "OK"); +} +... diff --git a/src/modules/microhttpd/doc/Makefile b/src/modules/microhttpd/doc/Makefile new file mode 100644 index 000000000..a876bc0e3 --- /dev/null +++ b/src/modules/microhttpd/doc/Makefile @@ -0,0 +1,4 @@ +docs = microhttpd.xml + +docbook_dir = ../../../../doc/docbook +include $(docbook_dir)/Makefile.module diff --git a/src/modules/microhttpd/doc/microhttpd.xml b/src/modules/microhttpd/doc/microhttpd.xml new file mode 100644 index 000000000..c3fecf387 --- /dev/null +++ b/src/modules/microhttpd/doc/microhttpd.xml @@ -0,0 +1,36 @@ + + + +%docentities; + +]> + + + + MicroHTTPd Module + kamailio.org + + + Daniel-Constantin + Mierla + miconda@gmail.com + + + Daniel-Constantin + Mierla + miconda@gmail.com + + + + 2023 + asipto.com + + + + + + + diff --git a/src/modules/microhttpd/doc/microhttpd_admin.xml b/src/modules/microhttpd/doc/microhttpd_admin.xml new file mode 100644 index 000000000..c548d0dfc --- /dev/null +++ b/src/modules/microhttpd/doc/microhttpd_admin.xml @@ -0,0 +1,181 @@ + + + +%docentities; + +]> + + + + + &adminguide; + +
+ Overview + + This module implements an embedded HTTP server using libmicrohttpd. + +
+ +
+ Dependencies +
+ &kamailio; Modules + + The following modules must be loaded before this module: + + + + none. + + + + +
+
+ External Libraries or Applications + + The following libraries or applications must be installed before running + &kamailio; with this module loaded: + + + + libmicrohttpd - libmicrohttpd library + + + + +
+
+ +
+ Parameters +
+ <varname>listen_addr</varname> (int) + + IPv4 address to listen for HTTP connection. If not set, then it + listens on all local addresses (port has to be specified by + listen_port parameter). + + + + Default value is "" (empty - not set). + + + + Set <varname>listen_addr</varname> parameter + +... +modparam("microhttpd", "listen_addr", "127.0.0.1") +... + + +
+
+ <varname>listen_port</varname> (int) + + Port to listen for HTTP connection. + + + + Default value is 8280. + + + + Set <varname>listen_port</varname> parameter + +... +modparam("microhttpd", "listen_port", 8284) +... + + +
+
+ <varname>event_callback</varname> (str) + + The name of the function in the kemi configuration file (embedded + scripting language such as Lua, Python, ...) to be executed instead + of event_route[microhttpd:request] block. + + + The function has one string parameter with the value "microhttpd:request". + + + + Default value is 'empty' (no function is executed for events). + + + + Set <varname>event_callback</varname> parameter + +... +modparam("microhttpd", "event_callback", "ksr_microhttpd_event") +... +-- event callback function implemented in Lua +function ksr_microhttpd_event(evname) + KSR.info("===== microhttpd module triggered event: " .. evname .. "\n"); + return 1; +end +... + + +
+
+ +
+ Functions +
+ + <function moreinfo="none">mhttpd_reply(code, reason, ctype, body)</function> + + + Send back a reply with content-type and body. + + + <function>mhttpd_reply</function> usage + +... +event_route[microhttpd:request] { + mhttpd_reply("200", "OK", "text/html", + "<html><body>OK</body></html>"); +} +... + + +
+
+ +
+ Event Routes +
+ + <function moreinfo="none">microhttpd:request</function> + + + The event route is executed when a new HTTP request is received. + + + Inside it, the $mhttpd(...) group of variables is available, giving + access to several attributes of the HTTP request, such as method, + URL, data (body) or headers. + + +... +... +loadmodule "microhttpd.so +... +event_route[microhttpd:request] { + xinfo("request: $mhttpd(method) - url: $mhttpd(url) - data: [$mhttpd(data)]\n"); + mhttpd_reply("200", "OK", "text/html", + "<html><body>OK</body></html>"); +} +... + +
+
+ +
+ diff --git a/src/modules/microhttpd/microhttpd_mod.c b/src/modules/microhttpd/microhttpd_mod.c new file mode 100644 index 000000000..f1ee8334b --- /dev/null +++ b/src/modules/microhttpd/microhttpd_mod.c @@ -0,0 +1,569 @@ +/** + * Copyright (C) 2023 Daniel-Constantin Mierla (asipto.com) + * + * This file is part of Kamailio, a free SIP server. + * + * This file 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 + * + * + * This file 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 + * + */ + +#include +#include +#include +#include +#include + +#include + +#include "../../core/sr_module.h" +#include "../../core/dprint.h" +#include "../../core/ut.h" +#include "../../core/mod_fix.h" +#include "../../core/pvar.h" +#include "../../core/kemi.h" +#include "../../core/fmsg.h" +#include "../../core/cfg/cfg_struct.h" + +MODULE_VERSION + +static int _microhttpd_listen_port = 8280; +static int _microhttpd_server_pid = -1; +static str _microhttpd_listen_addr = str_init(""); + +static int microhttpd_route_no = -1; +static str microhttpd_event_callback = STR_NULL; + +static int microhttpd_server_run(void); + +static int w_mhttpd_send_reply( + sip_msg_t *msg, char *pcode, char *preason, char *pctype, char *pbody); + +static int fixup_mhttpd_send_reply(void **param, int param_no); + + +static int mod_init(void); +static int child_init(int); +static void mod_destroy(void); + +int pv_get_mhttpd(sip_msg_t *msg, pv_param_t *param, pv_value_t *res); +int pv_parse_mhttpd_name(pv_spec_p sp, str *in); + +/* clang-format off */ +static pv_export_t mod_pvs[] = { + {{"mhttpd", (sizeof("mhttpd") - 1)}, PVT_OTHER, pv_get_mhttpd, 0, + pv_parse_mhttpd_name, 0, 0, 0}, + + {{0, 0}, 0, 0, 0, 0, 0, 0, 0} +}; + +static cmd_export_t cmds[] = { + {"mhttpd_reply", (cmd_function)w_mhttpd_send_reply, + 4, fixup_mhttpd_send_reply, 0, REQUEST_ROUTE|EVENT_ROUTE}, + + {0, 0, 0, 0, 0, 0} +}; + +static param_export_t params[] = { + {"listen_port", PARAM_INT, &_microhttpd_listen_port}, + {"listen_addr", PARAM_STR, &_microhttpd_listen_addr}, + {"event_callback", PARAM_STR, µhttpd_event_callback}, + {0, 0, 0} +}; + +struct module_exports exports = { + "microhttpd", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* exported functions */ + params, /* exported parameters */ + 0, /* exported rpc functions */ + mod_pvs, /* exported pseudo-variables */ + 0, /* response handling function */ + mod_init, /* module init function */ + child_init, /* per child init function */ + mod_destroy /* destroy function */ +}; +/* clang-format on */ + + +/** + * init module function + */ +static int mod_init(void) +{ + sr_kemi_eng_t *keng = NULL; + int route_no = -1; + + if(microhttpd_event_callback.s != NULL + && microhttpd_event_callback.len > 0) { + keng = sr_kemi_eng_get(); + if(keng == NULL) { + LM_ERR("failed to find kemi engine\n"); + return -1; + } + microhttpd_route_no = -1; + } else { + route_no = route_lookup(&event_rt, "microhttpd:request"); + if(route_no == -1) { + LM_ERR("failed to find event_route[microhttpd:request]\n"); + return -1; + } + if(event_rt.rlist[route_no] == 0) { + LM_WARN("event_route[microhttpd:request] is empty\n"); + } + microhttpd_route_no = route_no; + } + + /* add space for one extra process */ + register_procs(1); + + /* add child to update local config framework structures */ + cfg_register_child(1); + + return 0; +} + +/** + * @brief Initialize async module children + */ +static int child_init(int rank) +{ + int pid; + + if(rank != PROC_MAIN) + return 0; + + pid = fork_process(PROC_NOCHLDINIT, "MicroHTTPd Server Process", 1); + if(pid < 0) + return -1; /* error */ + if(pid == 0) { + /* child */ + _microhttpd_server_pid = getpid(); + + /* do child init to allow execution of rpc like functions */ + if(init_child(PROC_RPC) < 0) { + LM_DBG("failed to do RPC child init for dispatcher\n"); + return -1; + } + /* initialize the config framework */ + if(cfg_child_init()) + return -1; + if(microhttpd_server_run() < 0) { + LM_ERR("failed to initialize microhttpd server process\n"); + return -1; + } + } + + return 0; +} + +/** + * destroy module function + */ +static void mod_destroy(void) +{ +} + +typedef struct ksr_mhttpd_ctx +{ + struct MHD_Connection *connection; + str method; + str url; + str httpversion; + str data; + const union MHD_ConnectionInfo *cinfo; + char srcipbuf[IP_ADDR_MAX_STR_SIZE]; + str srcip; +} ksr_mhttpd_ctx_t; + +static ksr_mhttpd_ctx_t _ksr_mhttpd_ctx = {0}; + +/** + * parse the name of the $mhttpd(name) + */ +int pv_parse_mhttpd_name(pv_spec_p sp, str *in) +{ + if(sp == NULL || in == NULL || in->len <= 0) + return -1; + switch(in->len) { + case 3: + if(strncasecmp(in->s, "url", 3) == 0) { + sp->pvp.pvn.u.isname.name.n = 0; + } else { + goto error; + } + break; + case 4: + if(strncasecmp(in->s, "data", 4) == 0) { + sp->pvp.pvn.u.isname.name.n = 1; + } else if(strncasecmp(in->s, "size", 4) == 0) { + sp->pvp.pvn.u.isname.name.n = 2; + } else { + goto error; + } + break; + case 5: + if(strncasecmp(in->s, "srcip", 5) == 0) { + sp->pvp.pvn.u.isname.name.n = 5; + } else { + goto error; + } + break; + case 6: + if(strncasecmp(in->s, "method", 6) == 0) { + sp->pvp.pvn.u.isname.name.n = 3; + } else { + goto error; + } + break; + case 7: + if(strncasecmp(in->s, "version", 7) == 0) { + sp->pvp.pvn.u.isname.name.n = 4; + } else { + goto error; + } + break; + default: + if(in->len > 2 && in->s[1] == ':' + && (in->s[0] == 'h' || in->s[0] == 'H')) { + sp->pvp.pvn.type = PV_NAME_INTSTR; + sp->pvp.pvn.u.isname.type = PVT_HDR; + sp->pvp.pvn.u.isname.name.s = *in; + return 0; + } + goto error; + } + sp->pvp.pvn.type = PV_NAME_INTSTR; + sp->pvp.pvn.u.isname.type = 0; + + return 0; + +error: + LM_ERR("invalid variable name [%.*s]\n", in->len, in->s); + return -1; +} + +/** + * return the value of $mhttpd(name) + */ +int pv_get_mhttpd(sip_msg_t *msg, pv_param_t *param, pv_value_t *res) +{ + struct sockaddr *srcaddr = NULL; + const char *hdrval = NULL; + + if(param == NULL) { + return -1; + } + if(_ksr_mhttpd_ctx.connection == NULL) { + return pv_get_null(msg, param, res); + } + if(param->pvn.u.isname.type == PVT_HDR) { + hdrval = MHD_lookup_connection_value(_ksr_mhttpd_ctx.connection, + MHD_HEADER_KIND, param->pvn.u.isname.name.s.s + 2); + if(hdrval == NULL) { + return pv_get_null(msg, param, res); + } + return pv_get_strzval(msg, param, res, (char *)hdrval); + } + + switch(param->pvn.u.isname.name.n) { + case 0: /* url */ + return pv_get_strval(msg, param, res, &_ksr_mhttpd_ctx.url); + case 1: /* data */ + return pv_get_strval(msg, param, res, &_ksr_mhttpd_ctx.data); + case 2: /* size */ + return pv_get_sintval(msg, param, res, _ksr_mhttpd_ctx.data.len); + case 3: /* method */ + return pv_get_strval(msg, param, res, &_ksr_mhttpd_ctx.method); + case 4: /* version */ + return pv_get_strval(msg, param, res, &_ksr_mhttpd_ctx.httpversion); + case 5: /* srcip */ + if(_ksr_mhttpd_ctx.srcip.len > 0) { + return pv_get_strval(msg, param, res, &_ksr_mhttpd_ctx.srcip); + } + srcaddr = + (_ksr_mhttpd_ctx.cinfo ? _ksr_mhttpd_ctx.cinfo->client_addr + : NULL); + if(srcaddr == NULL) { + return pv_get_null(msg, param, res); + } + switch(srcaddr->sa_family) { + case AF_INET: + if(!inet_ntop(AF_INET, + &(((struct sockaddr_in *)srcaddr)->sin_addr), + _ksr_mhttpd_ctx.srcipbuf, + IP_ADDR_MAX_STR_SIZE)) { + return pv_get_null(msg, param, res); + } + break; + case AF_INET6: + if(!inet_ntop(AF_INET6, + &(((struct sockaddr_in6 *)srcaddr)->sin6_addr), + _ksr_mhttpd_ctx.srcipbuf, + IP_ADDR_MAX_STR_SIZE)) { + return pv_get_null(msg, param, res); + } + break; + default: + return pv_get_null(msg, param, res); + } + _ksr_mhttpd_ctx.srcip.s = _ksr_mhttpd_ctx.srcipbuf; + _ksr_mhttpd_ctx.srcip.len = strlen(_ksr_mhttpd_ctx.srcipbuf); + return pv_get_strval(msg, param, res, &_ksr_mhttpd_ctx.srcip); + default: + return pv_get_null(msg, param, res); + } +} + +/** + * + */ +static int ksr_mhttpd_send_reply( + sip_msg_t *msg, int rcode, str *sreason, str *sctype, str *sbody) +{ + struct MHD_Response *response; + int ret; + + if(_ksr_mhttpd_ctx.connection == NULL) { + LM_ERR("no connection available\n"); + return -1; + } + + if(rcode < 100 || rcode >= 700) { + LM_ERR("invalid code parameter\n"); + return -1; + } + if(sreason->s == NULL || sreason->len == 0) { + LM_ERR("invalid reason parameter\n"); + return -1; + } + if(sctype->s == NULL) { + LM_ERR("invalid content-type parameter\n"); + return -1; + } + if(sbody->s == NULL) { + LM_ERR("invalid body parameter\n"); + return -1; + } + + response = MHD_create_response_from_buffer( + sbody->len, sbody->s, MHD_RESPMEM_PERSISTENT); + if(response == NULL) { + LM_ERR("failed to create the response\n"); + return -1; + } + if(sctype->len > 0) { + MHD_add_response_header(response, "Content-Type", sctype->s); + } + ret = MHD_queue_response( + _ksr_mhttpd_ctx.connection, (unsigned int)rcode, response); + MHD_destroy_response(response); + + return (ret == MHD_YES) ? 1 : -1; +} + +/** + * + */ +static int w_mhttpd_send_reply( + sip_msg_t *msg, char *pcode, char *preason, char *pctype, char *pbody) +{ + str body = str_init(""); + str reason = str_init("OK"); + str ctype = str_init("text/plain"); + int code = 200; + + if(_ksr_mhttpd_ctx.connection == NULL) { + LM_ERR("no connection available\n"); + return -1; + } + + 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) { + LM_ERR("no reply code value\n"); + return -1; + } + + if(fixup_get_svalue(msg, (gparam_p)preason, &reason) != 0) { + LM_ERR("unable to get reason\n"); + return -1; + } + + if(fixup_get_svalue(msg, (gparam_p)pctype, &ctype) != 0) { + LM_ERR("unable to get content type\n"); + return -1; + } + + if(fixup_get_svalue(msg, (gparam_p)pbody, &body) != 0) { + LM_ERR("unable to get body\n"); + return -1; + } + + return ksr_mhttpd_send_reply(msg, code, &reason, &ctype, &body); +} + +static int fixup_mhttpd_send_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); + } + return 0; +} + + +static enum MHD_Result ksr_microhttpd_request(void *cls, + struct MHD_Connection *connection, const char *url, const char *method, + const char *version, const char *upload_data, size_t *upload_data_size, + void **ptr) +{ + static int _first_callback; + sr_kemi_eng_t *keng = NULL; + str evname = str_init("microhttpd:request"); + sip_msg_t *fmsg = NULL; + run_act_ctx_t ctx; + int rtb; + + if(&_first_callback != *ptr) { + /* the first time only the headers are valid, + do not respond in the first round... */ + *ptr = &_first_callback; + return MHD_YES; + } + *ptr = NULL; /* clear context pointer */ + + _ksr_mhttpd_ctx.connection = connection; + _ksr_mhttpd_ctx.method.s = (char *)method; + _ksr_mhttpd_ctx.method.len = strlen(_ksr_mhttpd_ctx.method.s); + _ksr_mhttpd_ctx.url.s = (char *)url; + _ksr_mhttpd_ctx.url.len = strlen(_ksr_mhttpd_ctx.url.s); + _ksr_mhttpd_ctx.httpversion.s = (char *)version; + _ksr_mhttpd_ctx.httpversion.len = strlen(_ksr_mhttpd_ctx.httpversion.s); + if(*upload_data_size > 0) { + _ksr_mhttpd_ctx.data.s = (char *)upload_data; + _ksr_mhttpd_ctx.data.len = (int)(*upload_data_size); + } else { + _ksr_mhttpd_ctx.data.s = NULL; + _ksr_mhttpd_ctx.data.len = 0; + } + _ksr_mhttpd_ctx.cinfo = MHD_get_connection_info( + connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS); + _ksr_mhttpd_ctx.srcip.s = NULL; + _ksr_mhttpd_ctx.srcip.len = 0; + + LM_DBG("executing event_route[%s] (%d)\n", evname.s, microhttpd_route_no); + if(faked_msg_init() < 0) { + return MHD_NO; + } + fmsg = faked_msg_next(); + rtb = get_route_type(); + set_route_type(REQUEST_ROUTE); + init_run_actions_ctx(&ctx); + if(microhttpd_route_no >= 0) { + run_top_route(event_rt.rlist[microhttpd_route_no], fmsg, &ctx); + } else { + keng = sr_kemi_eng_get(); + if(keng != NULL) { + if(sr_kemi_ctx_route(keng, &ctx, fmsg, EVENT_ROUTE, + µhttpd_event_callback, &evname) + < 0) { + LM_ERR("error running event route kemi callback\n"); + return MHD_NO; + } + } + } + set_route_type(rtb); + if(ctx.run_flags & DROP_R_F) { + LM_ERR("exit due to 'drop' in event route\n"); + return MHD_NO; + } + + return MHD_YES; +} + +#define KSR_MICROHTTPD_PAGE \ + "Kamailio" \ + "Thanks for flying Kamailio!" +/** + * + */ +static int microhttpd_server_run(void) +{ + + struct MHD_Daemon *d; + struct sockaddr_in address; + + if(_microhttpd_listen_addr.len > 0) { + address.sin_family = AF_INET; + address.sin_port = htons(_microhttpd_listen_port); + if(inet_pton(AF_INET, _microhttpd_listen_addr.s, &address.sin_addr) + <= 0) { + LM_ERR("failed to convert listen address\n"); + return -1; + } + LM_DBG("preparing to listen on %s :%d\n", _microhttpd_listen_addr.s, + _microhttpd_listen_port); + d = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, _microhttpd_listen_port, + NULL, NULL, &ksr_microhttpd_request, KSR_MICROHTTPD_PAGE, + MHD_OPTION_SOCK_ADDR, &address, MHD_OPTION_END); + } else { + LM_DBG("preparing to listen on port: %d\n", _microhttpd_listen_port); + d = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, _microhttpd_listen_port, + NULL, NULL, &ksr_microhttpd_request, KSR_MICROHTTPD_PAGE, + MHD_OPTION_END); + } + + if(d == NULL) { + return -1; + } + while(1) { + sleep(10); + } + return 0; +} + +/** + * + */ +/* clang-format off */ +static sr_kemi_t sr_kemi_mhttpd_exports[] = { + { str_init("microhttpd"), str_init("mhttpd_reply"), + SR_KEMIP_INT, ksr_mhttpd_send_reply, + { SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_STR, + SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + + { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } } +}; +/* clang-format on */ + + +/** + * + */ +int mod_register(char *path, int *dlflags, void *p1, void *p2) +{ + sr_kemi_modules_add(sr_kemi_mhttpd_exports); + return 0; +} diff --git a/src/modules/misc_radius/README b/src/modules/misc_radius/README index ec165d9cd..da8229966 100644 --- a/src/modules/misc_radius/README +++ b/src/modules/misc_radius/README @@ -142,8 +142,8 @@ Chapter 1. Admin Guide 2.1. Kamailio Modules - The module depends on the following modules (in the other words the - listed modules must be loaded before this module): + The module depends on the following modules (in other words the listed + modules must be loaded before this module): * none 2.2. External Libraries or Applications diff --git a/src/modules/misc_radius/doc/misc_radius_admin.xml b/src/modules/misc_radius/doc/misc_radius_admin.xml index 831a4b6cb..62094707a 100644 --- a/src/modules/misc_radius/doc/misc_radius_admin.xml +++ b/src/modules/misc_radius/doc/misc_radius_admin.xml @@ -77,7 +77,7 @@
&kamailio; Modules - The module depends on the following modules (in the other words + The module depends on the following modules (in other words the listed modules must be loaded before this module): diff --git a/src/modules/misc_radius/functions.c b/src/modules/misc_radius/functions.c index 8d338975c..bf6b86819 100644 --- a/src/modules/misc_radius/functions.c +++ b/src/modules/misc_radius/functions.c @@ -406,7 +406,7 @@ int radius_load_callee_avps(struct sip_msg *_m, char *_callee, char *_s2) /* * Check from Radius if a user belongs to a group. User-Name is given in - * first string argment that may contain pseudo variables. SIP-Group is + * first string argument that may contain pseudo variables. SIP-Group is * given in second string variable that may not contain pseudo variables. * Service-Type is Group-Check. */ diff --git a/src/modules/misctest/misctest_mod.c b/src/modules/misctest/misctest_mod.c index f3d3279d2..f7d09e77e 100644 --- a/src/modules/misctest/misctest_mod.c +++ b/src/modules/misctest/misctest_mod.c @@ -681,7 +681,7 @@ static int mem_rnd_realloc(unsigned long size, long *diff) /* * Randomly alloc. total_size bytes, in chunks of size between - * min & max. max - min should be smaller then 4G. + * min & max. max - min should be smaller than 4G. * @return < 0 if there were some alloc errors, 0 on success. */ static int mem_rnd_leak( @@ -1020,7 +1020,7 @@ static const char *rpc_mt_free_doc[2] = { " other misctest functions (e.g. mt.mem_alloc or the script " "mt_mem_alloc). Use b|k|m|g to specify the desired size unit." "Returns the number of bytes freed (can be higher or" - " smaller then the requested size)", + " smaller than the requested size)", 0}; diff --git a/src/modules/mohqueue/mohq_funcs.c b/src/modules/mohqueue/mohq_funcs.c index 530137a2a..599e5eb8a 100644 --- a/src/modules/mohqueue/mohq_funcs.c +++ b/src/modules/mohqueue/mohq_funcs.c @@ -183,7 +183,7 @@ void ack_msg(sip_msg_t *pmsg, call_lst *pcall) **********/ pcall->call_hash = pcall->call_label = 0; - sprintf(pcall->call_addr, "%s %s", + snprintf(pcall->call_addr, IP_ADDR_MAX_STR_SIZE + 4, "%s %s", pmsg->rcv.dst_ip.af == AF_INET ? "IP4" : "IP6", ip_addr2a(&pmsg->rcv.dst_ip)); pcall->call_state = CLSTA_INQUEUE; @@ -412,12 +412,12 @@ void close_call(sip_msg_t *pmsg, call_lst *pcall) + strlen(pcall->call_via) // Via + strlen(pcall->call_route) // Route + strlen(pquri); // Contact - phdr = pkg_malloc(npos1); + phdr = pkg_malloc(npos1 + 1); if(!phdr) { LM_ERR("%sNo more memory!\n", pfncname); goto bye_err; } - sprintf(phdr, pbyemsg, + snprintf(phdr, npos1 + 1, pbyemsg, pcall->call_via, // Via pcall->call_route, // Route pquri); // Contact @@ -1097,15 +1097,16 @@ void first_invite_msg(sip_msg_t *pmsg, call_lst *pcall) str pcontact[1]; char *pcontacthdr = "Contact: <%s>" SIPEOL; - pcontact->s = - pkg_malloc(strlen(pcall->pmohq->mohq_uri) + strlen(pcontacthdr)); + int tblen; + tblen = strlen(pcall->pmohq->mohq_uri) + strlen(pcontacthdr); + pcontact->s = pkg_malloc(tblen + 1); if(!pcontact->s) { LM_ERR("%sNo more memory!\n", pfncname); end_RTP(pmsg, pcall); delete_call(pcall); return; } - sprintf(pcontact->s, pcontacthdr, pcall->pmohq->mohq_uri); + snprintf(pcontact->s, tblen + 1, pcontacthdr, pcall->pmohq->mohq_uri); pcontact->len = strlen(pcontact->s); if(!add_lump_rpl2(pmsg, pcontact->s, pcontact->len, LUMP_RPL_HDR)) { LM_ERR("%sUnable to add contact (%s) to call (%s)!\n", pfncname, @@ -1277,17 +1278,17 @@ int form_rtp_SDP(str *pstr, call_lst *pcall, char *pSDP) **********/ char *pfncname = "form_rtp_SDP: "; - rtpmap **pmohfiles = + rtpmap **lpmohfiles = find_MOH(pcall->pmohq->mohq_mohdir, pcall->pmohq->mohq_mohfile); - if(!pmohfiles[0]) { + if(!lpmohfiles[0]) { LM_ERR("%sUnable to find any MOH files for queue (%s)!\n", pfncname, pcall->pmohq->mohq_name); return 0; } int nsize = strlen(pSDP) + 2; int nidx; - for(nidx = 0; pmohfiles[nidx]; nidx++) { - nsize += strlen(pmohfiles[nidx]->pencode) // encode length + for(nidx = 0; lpmohfiles[nidx]; nidx++) { + nsize += strlen(lpmohfiles[nidx]->pencode) // encode length + 19; // space, type number, "a=rtpmap:%d ", EOL } @@ -1557,12 +1558,12 @@ int refer_call(call_lst *pcall, mohq_lock *plock) + strlen(pcall->pmohq->mohq_uri) // Contact + puri->len // Refer-To + strlen(pcall->pmohq->mohq_uri); // Referred-By - char *pbuf = pkg_malloc(npos1); + char *pbuf = pkg_malloc(npos1 + 1); if(!pbuf) { LM_ERR("%sNo more memory!\n", pfncname); goto refererr; } - sprintf(pbuf, prefermsg, + snprintf(pbuf, npos1 + 1, prefermsg, pcall->call_via, // Via pcall->call_route, // Route pcall->pmohq->mohq_uri, // Contact @@ -1706,7 +1707,7 @@ void reinvite_msg(sip_msg_t *pmsg, call_lst *pcall) * o look for hold condition and matching payload type **********/ - rtpmap **pmohfiles = + rtpmap **lpmohfiles = find_MOH(pcall->pmohq->mohq_mohdir, pcall->pmohq->mohq_mohfile); int bhold = 0; int bmatch = 0; @@ -1748,8 +1749,8 @@ void reinvite_msg(sip_msg_t *pmsg, call_lst *pcall) ppayload = ppayload->next) { int ntype = atoi(ppayload->rtp_payload.s); int nidx; - for(nidx = 0; pmohfiles[nidx]; nidx++) { - if(pmohfiles[nidx]->ntype == ntype) { + for(nidx = 0; lpmohfiles[nidx]; nidx++) { + if(lpmohfiles[nidx]->ntype == ntype) { bmatch = 1; break; } @@ -1863,7 +1864,7 @@ int send_prov_rsp(sip_msg_t *pmsg, call_lst *pcall) char phdrtmp[200]; char *phdrtmplt = "Accept-Language: en" SIPEOL "Require: 100rel" SIPEOL "RSeq: %d" SIPEOL; - sprintf(phdrtmp, phdrtmplt, pcall->call_cseq); + snprintf(phdrtmp, 200, phdrtmplt, pcall->call_cseq); struct lump_rpl **phdrlump = add_lump_rpl2(pmsg, phdrtmp, strlen(phdrtmp), LUMP_RPL_HDR); if(!phdrlump) { @@ -2006,7 +2007,7 @@ int send_rtp_answer(sip_msg_t *pmsg, call_lst *pcall) npos1 += pparse[npos2].len; } char pbodylen[30]; - sprintf(pbodylen, "%s: %d\r\n\r\n", pclenhdr, pSDP->len); + snprintf(pbodylen, 30, "%s: %d\r\n\r\n", pclenhdr, pSDP->len); npos1 += pextrahdr->len + strlen(pbodylen) + pSDP->len + 1; char *pnewbuf = pkg_malloc(npos1); if(!pnewbuf) { @@ -2858,4 +2859,4 @@ int mohq_send(sip_msg_t *pmsg, char *pqueue) return -1; } return 1; -} \ No newline at end of file +} diff --git a/src/modules/mqtt/mqtt_dispatch.c b/src/modules/mqtt/mqtt_dispatch.c index f3abeffc4..2cfdf28d2 100644 --- a/src/modules/mqtt/mqtt_dispatch.c +++ b/src/modules/mqtt/mqtt_dispatch.c @@ -509,7 +509,7 @@ int pv_get_mqtt(sip_msg_t *msg, pv_param_t *param, pv_value_t *res) qos = message->qos; } - // populate value depeding on the param name + // populate value depending on the param name // see pv_parse_mqtt_name() switch(param->pvn.u.isname.name.n) { case 0: diff --git a/src/modules/mqueue/mqueue_mod.c b/src/modules/mqueue/mqueue_mod.c index 303b2dca9..d51b65f5d 100644 --- a/src/modules/mqueue/mqueue_mod.c +++ b/src/modules/mqueue/mqueue_mod.c @@ -112,10 +112,10 @@ static int mod_init(void) } while(mh != NULL) { - if(mh->dbmode == 1 || mh->dbmode == 2) { + if (mh->dbmode == 1 || mh->dbmode == 2) { if(mqueue_db_load_queue(&(mh->name)) < 0) { - LM_ERR("error loading mqueue: %.*s from DB\n", mh->name.len, - mh->name.s); + LM_ERR("error loading mqueue: %.*s from DB\n", + mh->name.len, mh->name.s); return 1; } } diff --git a/src/modules/msilo/README b/src/modules/msilo/README index 6c6eb9b6b..649f0c714 100644 --- a/src/modules/msilo/README +++ b/src/modules/msilo/README @@ -48,29 +48,33 @@ Juha Heinanen 3.11. sc_inc_time (string) 3.12. sc_snd_time (string) 3.13. sc_stored_hdrs (string) - 3.14. from_address (string) - 3.15. contact_hdr (string) - 3.16. extra_hdrs (string) - 3.17. offline_message (string) - 3.18. content_type_hdr (string) - 3.19. reminder (string) - 3.20. outbound_proxy (string) - 3.21. expire_time (int) - 3.22. check_time (int) - 3.23. send_time (int) - 3.24. clean_period (int) - 3.25. use_contact (int) - 3.26. snd_time_avp (str) - 3.27. add_date (int) - 3.28. max_messages (int) - 3.29. add_contact (int) - 3.30. extra_hdrs_avp (str) - 3.31. skip_notification_flag (int) + 3.14. sc_callid (string) + 3.15. sc_callid (string) + 3.16. from_address (string) + 3.17. contact_hdr (string) + 3.18. extra_hdrs (string) + 3.19. offline_message (string) + 3.20. content_type_hdr (string) + 3.21. reminder (string) + 3.22. outbound_proxy (string) + 3.23. expire_time (int) + 3.24. check_time (int) + 3.25. send_time (int) + 3.26. clean_period (int) + 3.27. use_contact (int) + 3.28. snd_time_avp (str) + 3.29. add_date (int) + 3.30. max_messages (int) + 3.31. add_contact (int) + 3.32. extra_hdrs_avp (str) + 3.33. skip_notification_flag (int) + 3.34. use_mode (int) 4. Functions 4.1. m_store([owner]) - 4.2. m_dump([owner]) + 4.2. m_store_addrs(owner, srcaddr, dstaddr) + 4.3. m_dump([owner]) 5. Statistics @@ -99,27 +103,31 @@ Juha Heinanen 1.11. Set the “sc_inc_time” parameter 1.12. Set the “sc_snd_time” parameter 1.13. Set the “sc_stored_hdrs” parameter - 1.14. Set the “from_address” parameter - 1.15. Set the “contact_hdr” parameter - 1.16. Set the “extra_hdrs” parameter - 1.17. Set the “offline_message” parameter - 1.18. Set the “content_type_hdr” parameter - 1.19. Set the “reminder” parameter - 1.20. Set the “outbound_proxy” parameter - 1.21. Set the “expire_time” parameter - 1.22. Set the “check_time” parameter - 1.23. Set the “send_time” parameter - 1.24. Set the “clean_period” parameter - 1.25. Set the “use_contact” parameter - 1.26. Set the “snd_time_avp” parameter - 1.27. Set the “add_date” parameter - 1.28. Set the “max_messages” parameter - 1.29. Set the “add_contact” parameter - 1.30. Set the “extra_hdrs_avp” parameter - 1.31. Set the “skip_notification_flag” parameter - 1.32. m_store usage - 1.33. m_dump usage - 1.34. Kamailio config script - sample msilo usage + 1.14. Set the “sc_callid” parameter + 1.15. Set the “sc_status” parameter + 1.16. Set the “from_address” parameter + 1.17. Set the “contact_hdr” parameter + 1.18. Set the “extra_hdrs” parameter + 1.19. Set the “offline_message” parameter + 1.20. Set the “content_type_hdr” parameter + 1.21. Set the “reminder” parameter + 1.22. Set the “outbound_proxy” parameter + 1.23. Set the “expire_time” parameter + 1.24. Set the “check_time” parameter + 1.25. Set the “send_time” parameter + 1.26. Set the “clean_period” parameter + 1.27. Set the “use_contact” parameter + 1.28. Set the “snd_time_avp” parameter + 1.29. Set the “add_date” parameter + 1.30. Set the “max_messages” parameter + 1.31. Set the “add_contact” parameter + 1.32. Set the “extra_hdrs_avp” parameter + 1.33. Set the “skip_notification_flag” parameter + 1.34. Set the “use_mode” parameter + 1.35. m_store usage + 1.36. m_store_addrs usage + 1.37. m_dump usage + 1.38. Kamailio config script - sample msilo usage Chapter 1. Admin Guide @@ -146,29 +154,33 @@ Chapter 1. Admin Guide 3.11. sc_inc_time (string) 3.12. sc_snd_time (string) 3.13. sc_stored_hdrs (string) - 3.14. from_address (string) - 3.15. contact_hdr (string) - 3.16. extra_hdrs (string) - 3.17. offline_message (string) - 3.18. content_type_hdr (string) - 3.19. reminder (string) - 3.20. outbound_proxy (string) - 3.21. expire_time (int) - 3.22. check_time (int) - 3.23. send_time (int) - 3.24. clean_period (int) - 3.25. use_contact (int) - 3.26. snd_time_avp (str) - 3.27. add_date (int) - 3.28. max_messages (int) - 3.29. add_contact (int) - 3.30. extra_hdrs_avp (str) - 3.31. skip_notification_flag (int) + 3.14. sc_callid (string) + 3.15. sc_callid (string) + 3.16. from_address (string) + 3.17. contact_hdr (string) + 3.18. extra_hdrs (string) + 3.19. offline_message (string) + 3.20. content_type_hdr (string) + 3.21. reminder (string) + 3.22. outbound_proxy (string) + 3.23. expire_time (int) + 3.24. check_time (int) + 3.25. send_time (int) + 3.26. clean_period (int) + 3.27. use_contact (int) + 3.28. snd_time_avp (str) + 3.29. add_date (int) + 3.30. max_messages (int) + 3.31. add_contact (int) + 3.32. extra_hdrs_avp (str) + 3.33. skip_notification_flag (int) + 3.34. use_mode (int) 4. Functions 4.1. m_store([owner]) - 4.2. m_dump([owner]) + 4.2. m_store_addrs(owner, srcaddr, dstaddr) + 4.3. m_dump([owner]) 5. Statistics @@ -248,24 +260,27 @@ Chapter 1. Admin Guide 3.11. sc_inc_time (string) 3.12. sc_snd_time (string) 3.13. sc_stored_hdrs (string) - 3.14. from_address (string) - 3.15. contact_hdr (string) - 3.16. extra_hdrs (string) - 3.17. offline_message (string) - 3.18. content_type_hdr (string) - 3.19. reminder (string) - 3.20. outbound_proxy (string) - 3.21. expire_time (int) - 3.22. check_time (int) - 3.23. send_time (int) - 3.24. clean_period (int) - 3.25. use_contact (int) - 3.26. snd_time_avp (str) - 3.27. add_date (int) - 3.28. max_messages (int) - 3.29. add_contact (int) - 3.30. extra_hdrs_avp (str) - 3.31. skip_notification_flag (int) + 3.14. sc_callid (string) + 3.15. sc_callid (string) + 3.16. from_address (string) + 3.17. contact_hdr (string) + 3.18. extra_hdrs (string) + 3.19. offline_message (string) + 3.20. content_type_hdr (string) + 3.21. reminder (string) + 3.22. outbound_proxy (string) + 3.23. expire_time (int) + 3.24. check_time (int) + 3.25. send_time (int) + 3.26. clean_period (int) + 3.27. use_contact (int) + 3.28. snd_time_avp (str) + 3.29. add_date (int) + 3.30. max_messages (int) + 3.31. add_contact (int) + 3.32. extra_hdrs_avp (str) + 3.33. skip_notification_flag (int) + 3.34. use_mode (int) 3.1. db_url (string) @@ -413,7 +428,29 @@ modparam("msilo", "sc_snd_time", "send_reminder_time") modparam("msilo", "sc_stored_hdrs", "extra_headers") ... -3.14. from_address (string) +3.14. sc_callid (string) + + The name of the column in silo table, storing callid. + + Default value is “callid”. + + Example 1.14. Set the “sc_callid” parameter +... +modparam("msilo", "sc_callid", "call_id") +... + +3.15. sc_callid (string) + + The name of the column in silo table, storing status. + + Default value is “status”. + + Example 1.15. Set the “sc_status” parameter +... +modparam("msilo", "sc_status", "st") +... + +3.16. from_address (string) The SIP address used to inform users that destination of their message is not online and the message will be delivered next time when that @@ -422,13 +459,13 @@ modparam("msilo", "sc_stored_hdrs", "extra_headers") Default value is “NULL”. - Example 1.14. Set the “from_address” parameter + Example 1.16. Set the “from_address” parameter ... modparam("msilo", "from_address", "sip:registrar@example.org") modparam("msilo", "from_address", "sip:$rU@example.org") ... -3.15. contact_hdr (string) +3.17. contact_hdr (string) The value of the “Contact” header (including header name and ending \r\n) to be added in notification messages. It can contain @@ -436,36 +473,36 @@ modparam("msilo", "from_address", "sip:$rU@example.org") Default value is “NULL”. - Example 1.15. Set the “contact_hdr” parameter + Example 1.17. Set the “contact_hdr” parameter ... modparam("msilo", "contact_hdr", "Contact: \r\n") ... -3.16. extra_hdrs (string) +3.18. extra_hdrs (string) Extra headers (each ending with \r\n) to be added in messages sent from silo by m_dump. It can contain pseudo-variables. Default value is “NULL”. - Example 1.16. Set the “extra_hdrs” parameter + Example 1.18. Set the “extra_hdrs” parameter ... modparam("msilo", "extra_hdrs", "X-Extra: $tu\r\nY-Extra: foo\r\n") ... -3.17. offline_message (string) +3.19. offline_message (string) The body of the notification message. It can contain pseudo-variables. Default value is “NULL”. - Example 1.17. Set the “offline_message” parameter + Example 1.19. Set the “offline_message” parameter ... modparam("msilo", "offline_message", "*** User $rU is offline!") modparam("msilo", "offline_message", "I am offline!") ... -3.18. content_type_hdr (string) +3.20. content_type_hdr (string) The value of the Content-Type header (including header name and ending \r\n) to be added in notification messages. It must reflect what the @@ -473,25 +510,25 @@ modparam("msilo", "offline_message", "I am offline!") Default value is “NULL”. - Example 1.18. Set the “content_type_hdr” parameter + Example 1.20. Set the “content_type_hdr” parameter ... modparam("msilo", "content_type_hdr", "Content-Type: text/plain\r\n") modparam("msilo", "content_type_hdr", "Content-Type: text/html\r\n") ... -3.19. reminder (string) +3.21. reminder (string) The SIP address used to send reminder messages. If this value is not set, the reminder feature is disabled. Default value is “NULL”. - Example 1.19. Set the “reminder” parameter + Example 1.21. Set the “reminder” parameter ... modparam("msilo", "reminder", "sip:registrar@example.org") ... -3.20. outbound_proxy (string) +3.22. outbound_proxy (string) The SIP address used as next hop when sending the message. Very useful when using Kamailio with a domain name not in DNS, or when using a @@ -500,24 +537,24 @@ modparam("msilo", "reminder", "sip:registrar@example.org") Default value is “NULL”. - Example 1.20. Set the “outbound_proxy” parameter + Example 1.22. Set the “outbound_proxy” parameter ... modparam("msilo", "outbound_proxy", "sip:kamailio.org;transport=tcp") ... -3.21. expire_time (int) +3.23. expire_time (int) Expire time of stored messages - seconds. When this time passed, the message is silently discarded from database. Default value is “259200 (72 hours = 3 days)”. - Example 1.21. Set the “expire_time” parameter + Example 1.23. Set the “expire_time” parameter ... modparam("msilo", "expire_time", 36000) ... -3.22. check_time (int) +3.24. check_time (int) Timer interval to check if dumped messages are sent OK - seconds. The module keeps each request send by itself for a new online user and if @@ -525,12 +562,12 @@ modparam("msilo", "expire_time", 36000) Default value is “60”. - Example 1.22. Set the “check_time” parameter + Example 1.24. Set the “check_time” parameter ... modparam("msilo", "check_time", 10) ... -3.23. send_time (int) +3.25. send_time (int) Timer interval in seconds to check if there are reminder messages. The module takes all reminder messages that must be sent at that moment or @@ -540,39 +577,39 @@ modparam("msilo", "check_time", 10) Default value is “0”. - Example 1.23. Set the “send_time” parameter + Example 1.25. Set the “send_time” parameter ... modparam("msilo", "send_time", 60) ... -3.24. clean_period (int) +3.26. clean_period (int) Number of “check_time” cycles when to check if there are expired messages in database. Default value is “10”. - Example 1.24. Set the “clean_period” parameter + Example 1.26. Set the “clean_period” parameter ... modparam("msilo", "clean_period", 3) ... -3.25. use_contact (int) +3.27. use_contact (int) Turns on/off the usage of the “Contact” address to send notification back to sender whose message is stored by MSILO. Default value is “1 (0 = off, 1 = on)”. - Example 1.25. Set the “use_contact” parameter + Example 1.27. Set the “use_contact” parameter ... modparam("msilo", "use_contact", 0) ... -3.26. snd_time_avp (str) +3.28. snd_time_avp (str) - The name of an AVP which may contain the time when to sent the received - message as reminder. The AVP is used ony by m_store(). + The name of an AVP which may contain the time when to send the received + message as reminder. The AVP is used only by m_store(). If the parameter is not set, the module does not look for this AVP. If the value is set to a valid AVP name, then the module expects in the @@ -581,47 +618,47 @@ modparam("msilo", "use_contact", 0) Default value is “null”. - Example 1.26. Set the “snd_time_avp” parameter + Example 1.28. Set the “snd_time_avp” parameter ... modparam("msilo", "snd_time_avp", "$avp(i:123)") ... -3.27. add_date (int) +3.29. add_date (int) Whether to add as prefix the date when the message was stored. Default value is “1” (1==on/0==off). - Example 1.27. Set the “add_date” parameter + Example 1.29. Set the “add_date” parameter ... modparam("msilo", "add_date", 0) ... -3.28. max_messages (int) +3.30. max_messages (int) Maximum number of stored message for an AoR. Value 0 equals to no limit. Default value is 0. - Example 1.28. Set the “max_messages” parameter + Example 1.30. Set the “max_messages” parameter ... modparam("msilo", "max_messages", 0) ... -3.29. add_contact (int) +3.31. add_contact (int) Whether to add contact header to generated messages. The contact address is the From URI. Default value is “0” (1==on; 0==off as per RFC3428). - Example 1.29. Set the “add_contact” parameter + Example 1.31. Set the “add_contact” parameter ... modparam("msilo", "add_contact", 1) ... -3.30. extra_hdrs_avp (str) +3.32. extra_hdrs_avp (str) Name of an AVP which may contain extra headers that are stored with the message when m_store() is called. These extra headers (if any) are then @@ -632,19 +669,19 @@ modparam("msilo", "add_contact", 1) Default value is “null”. - Example 1.30. Set the “extra_hdrs_avp” parameter + Example 1.32. Set the “extra_hdrs_avp” parameter ... modparam("msilo", "extra_hdrs_avp", "$avp(msilo_extra_hdrs)") ... -3.31. skip_notification_flag (int) +3.33. skip_notification_flag (int) Flag to mark the message for which no notification should be sent back to sender when storing in msilo. Valid value is in between 0 and 31. Default value is “-1” (feature disabled). - Example 1.31. Set the “skip_notification_flag” parameter + Example 1.33. Set the “skip_notification_flag” parameter ... modparam("msilo", "skip_notification_flag", 18) ... @@ -652,10 +689,23 @@ setflag(18); m_store(...); ... +3.34. use_mode (int) + + If set to 1, the call-id header of incoming MESSAGE is stored and + reused later for delivery MESSAGE. + + Default value is “0”. + + Example 1.34. Set the “use_mode” parameter +... +modparam("msilo", "use_mode", 1) +... + 4. Functions 4.1. m_store([owner]) - 4.2. m_dump([owner]) + 4.2. m_store_addrs(owner, srcaddr, dstaddr) + 4.3. m_dump([owner]) 4.1. m_store([owner]) @@ -673,13 +723,34 @@ m_store(...); This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. - Example 1.32. m_store usage + Example 1.35. m_store usage ... m_store(); m_store("$tu"); ... -4.2. m_dump([owner]) +4.2. m_store_addrs(owner, srcaddr, dstaddr) + + Similar to m_store(), but instead of getting source user address from + From-URI and destination user address from To_URI, this function allows + to give them via parameters. + + Meaning of the parameters is as follows: + * owner - is a string that must contain a SIP URI in whose inbox the + message will be stored. It can have any pseudo variable. + * srcaddr - is a string that must contain a SIP URI corresponding to + From user. It can have any pseudo variable. + * dstaddr - is a string that must contain a SIP URI correspinding to + To user. It can have any pseudo variable. + + This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. + + Example 1.36. m_store_addrs usage +... +m_store_addrs("sip:$rU@a.com", "sip:$fU@a.com", "sip:$tU@a.com"); +... + +4.3. m_dump([owner]) The method sends stored messages for the SIP user that has registered to the contact address in the registration. The method should be called @@ -693,7 +764,7 @@ m_store("$tu"); This function can be used from REQUEST_ROUTE. - Example 1.33. m_dump usage + Example 1.37. m_dump usage ... m_dump(); m_dump("$fu"); @@ -735,7 +806,7 @@ m_dump("$fu"); Next picture displays a sample usage of msilo. - Example 1.34. Kamailio config script - sample msilo usage + Example 1.38. Kamailio config script - sample msilo usage ... # # MSILO usage example diff --git a/src/modules/msilo/doc/msilo_admin.xml b/src/modules/msilo/doc/msilo_admin.xml index e89edc315..f96238914 100644 --- a/src/modules/msilo/doc/msilo_admin.xml +++ b/src/modules/msilo/doc/msilo_admin.xml @@ -297,6 +297,36 @@ modparam("msilo", "sc_snd_time", "send_reminder_time") ... modparam("msilo", "sc_stored_hdrs", "extra_headers") ... + + +
+
+ <varname>sc_callid</varname> (string) + + The name of the column in silo table, storing callid. + + Default value is callid. + + Set the <quote>sc_callid</quote> parameter + +... +modparam("msilo", "sc_callid", "call_id") +... + + +
+
+ <varname>sc_callid</varname> (string) + + The name of the column in silo table, storing status. + + Default value is status. + + Set the <quote>sc_status</quote> parameter + +... +modparam("msilo", "sc_status", "st") +...
@@ -560,8 +590,8 @@ modparam("msilo", "use_contact", 0)
<varname>snd_time_avp</varname> (str) - The name of an AVP which may contain the time when to sent - the received message as reminder. The AVP is used ony by m_store(). + The name of an AVP which may contain the time when to send + the received message as reminder. The AVP is used only by m_store(). If the parameter is not set, the module does not look for this AVP. If @@ -696,6 +726,27 @@ m_store(...);
+
+ <varname>use_mode</varname> (int) + + If set to 1, the call-id header of incoming MESSAGE is stored and reused + later for delivery MESSAGE. + + + + Default value is 0. + + + + Set the <quote>use_mode</quote> parameter + +... +modparam("msilo", "use_mode", 1) +... + + +
+
@@ -731,6 +782,49 @@ m_store(...); m_store(); m_store("$tu"); ... + + +
+
+ <function moreinfo="none">m_store_addrs(owner, srcaddr, dstaddr)</function> + + Similar to m_store(), but instead of getting source user address from + From-URI and destination user address from To_URI, this function allows + to give them via parameters. + + Meaning of the parameters is as follows: + + + + owner - is a string that must contain + a SIP URI in whose inbox the message will be stored. It can have + any pseudo variable. + + + + + srcaddr - is a string that must contain + a SIP URI corresponding to From user. It can have + any pseudo variable. + + + + + dstaddr - is a string that must contain + a SIP URI correspinding to To user. It can have + any pseudo variable. + + + + + This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. + + + <function>m_store_addrs</function> usage + +... +m_store_addrs("sip:$rU@a.com", "sip:$fU@a.com", "sip:$tU@a.com"); +...
diff --git a/src/modules/msilo/msilo.c b/src/modules/msilo/msilo.c index c00176cc8..6cfa48b67 100644 --- a/src/modules/msilo/msilo.c +++ b/src/modules/msilo/msilo.c @@ -53,7 +53,7 @@ #include "api.h" #define MAX_DEL_KEYS 1 -#define NR_KEYS 11 +#define NR_KEYS 13 static str sc_mid = str_init("id"); /* 0 */ static str sc_from = str_init("src_addr"); /* 1 */ @@ -66,6 +66,8 @@ static str sc_exp_time = str_init("exp_time"); /* 7 */ static str sc_inc_time = str_init("inc_time"); /* 8 */ static str sc_snd_time = str_init("snd_time"); /* 9 */ static str sc_stored_hdrs = str_init("extra_hdrs"); /* 10 */ +static str sc_callid = str_init("callid"); /* 11 */ +static str sc_status = str_init("status"); /* 12 */ #define SET_STR_VAL(_str, _res, _r, _c) \ if(RES_ROWS(_res)[_r].values[_c].nul == 0) { \ @@ -95,15 +97,17 @@ MODULE_VERSION #define S_TABLE_VERSION 8 +#define MS_USEMODE_CALLID 1 + /** database connection */ static db1_con_t *db_con = NULL; static db_func_t msilo_dbf; -/** precessed msg list - used for dumping the messages */ -msg_list ml = NULL; +/** processed msg list - used for dumping the messages */ +static msg_list _msilo_ml = NULL; /** TM bind */ -struct tm_binds tmb; +static struct tm_binds _msilo_tmb; /** parameters */ @@ -131,6 +135,7 @@ int ms_use_contact = 1; int ms_add_date = 1; int ms_add_contact = 0; int ms_max_messages = 0; +int ms_use_mode = 0; static str ms_snd_time_avp_param = {NULL, 0}; int_str ms_snd_time_avp_name; @@ -147,11 +152,14 @@ static int ms_skip_notification_flag = -1; static int mod_init(void); static int child_init(int); -static int m_store(sip_msg_t *masg, str *owner_s); +static int m_store_addrs( + sip_msg_t *msg, str *owner, str *srcaddr, str *dstaddr); +static int m_store_uri(sip_msg_t *msg, str *owner); static int m_dump(sip_msg_t *msg, str *owner_s); -static int m_store_2(struct sip_msg *, char *, char *); -static int m_dump_2(struct sip_msg *, char *, char *); +static int m_store1(sip_msg_t *, char *, char *); +static int m_store3(sip_msg_t *, char *, char *, char *); +static int m_dump_2(sip_msg_t *, char *, char *); static void destroy(void); @@ -168,46 +176,60 @@ int check_message_support(struct sip_msg *msg); /** TM callback function */ static void m_tm_callback(struct cell *t, int type, struct tmcb_params *ps); -static cmd_export_t cmds[] = {{"m_store", (cmd_function)m_store_2, 0, 0, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, - {"m_store", (cmd_function)m_store_2, 1, fixup_spve_null, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, - {"m_dump", (cmd_function)m_dump_2, 0, 0, 0, REQUEST_ROUTE}, - {"m_dump", (cmd_function)m_dump_2, 1, fixup_spve_null, 0, - REQUEST_ROUTE}, - {"bind_msilo", (cmd_function)bind_msilo, 1, 0, 0, ANY_ROUTE}, - {0, 0, 0, 0, 0, 0}}; - - -static param_export_t params[] = {{"db_url", PARAM_STR, &ms_db_url}, - {"db_table", PARAM_STR, &ms_db_table}, - {"from_address", PARAM_STRING, &ms_from}, - {"contact_hdr", PARAM_STRING, &ms_contact}, - {"extra_hdrs", PARAM_STRING, &ms_extra_hdrs}, - {"content_type_hdr", PARAM_STRING, &ms_content_type}, - {"offline_message", PARAM_STRING, &ms_offline_message}, - {"reminder", PARAM_STR, &ms_reminder}, - {"outbound_proxy", PARAM_STR, &ms_outbound_proxy}, - {"expire_time", INT_PARAM, &ms_expire_time}, - {"check_time", INT_PARAM, &ms_check_time}, - {"send_time", INT_PARAM, &ms_send_time}, - {"clean_period", INT_PARAM, &ms_clean_period}, - {"use_contact", INT_PARAM, &ms_use_contact}, - {"sc_mid", PARAM_STR, &sc_mid}, {"sc_from", PARAM_STR, &sc_from}, - {"sc_to", PARAM_STR, &sc_to}, {"sc_uri_user", PARAM_STR, &sc_uri_user}, - {"sc_uri_host", PARAM_STR, &sc_uri_host}, - {"sc_body", PARAM_STR, &sc_body}, {"sc_ctype", PARAM_STR, &sc_ctype}, - {"sc_exp_time", PARAM_STR, &sc_exp_time}, - {"sc_inc_time", PARAM_STR, &sc_inc_time}, - {"sc_snd_time", PARAM_STR, &sc_snd_time}, - {"sc_stored_hdrs", PARAM_STR, &sc_stored_hdrs}, - {"snd_time_avp", PARAM_STR, &ms_snd_time_avp_param}, - {"extra_hdrs_avp", PARAM_STR, &ms_extra_hdrs_avp_param}, - {"add_date", INT_PARAM, &ms_add_date}, - {"max_messages", INT_PARAM, &ms_max_messages}, - {"add_contact", INT_PARAM, &ms_add_contact}, - {"skip_notification_flag", PARAM_INT, &ms_skip_notification_flag}, - {0, 0, 0}}; +/* clang-format off */ +static cmd_export_t cmds[] = { + {"m_store", (cmd_function)m_store1, 0, 0, + 0, REQUEST_ROUTE | FAILURE_ROUTE}, + {"m_store", (cmd_function)m_store1, 1, fixup_spve_null, + 0, REQUEST_ROUTE | FAILURE_ROUTE}, + {"m_store_addrs", (cmd_function)m_store3, 3, fixup_spve_all, + fixup_free_spve_all, REQUEST_ROUTE | FAILURE_ROUTE}, + {"m_dump", (cmd_function)m_dump_2, 0, 0, 0, REQUEST_ROUTE}, + {"m_dump", (cmd_function)m_dump_2, 0, 0, 0, REQUEST_ROUTE}, + {"m_dump", (cmd_function)m_dump_2, 1, fixup_spve_null, + 0, REQUEST_ROUTE}, + {"bind_msilo", (cmd_function)bind_msilo, 1, 0, 0, ANY_ROUTE}, + {0, 0, 0, 0, 0, 0} +}; + + +static param_export_t params[] = { + {"db_url", PARAM_STR, &ms_db_url}, + {"db_table", PARAM_STR, &ms_db_table}, + {"from_address", PARAM_STRING, &ms_from}, + {"contact_hdr", PARAM_STRING, &ms_contact}, + {"extra_hdrs", PARAM_STRING, &ms_extra_hdrs}, + {"content_type_hdr", PARAM_STRING, &ms_content_type}, + {"offline_message", PARAM_STRING, &ms_offline_message}, + {"reminder", PARAM_STR, &ms_reminder}, + {"outbound_proxy", PARAM_STR, &ms_outbound_proxy}, + {"expire_time", INT_PARAM, &ms_expire_time}, + {"check_time", INT_PARAM, &ms_check_time}, + {"send_time", INT_PARAM, &ms_send_time}, + {"clean_period", INT_PARAM, &ms_clean_period}, + {"use_contact", INT_PARAM, &ms_use_contact}, + {"sc_mid", PARAM_STR, &sc_mid}, + {"sc_from", PARAM_STR, &sc_from}, + {"sc_to", PARAM_STR, &sc_to}, + {"sc_uri_user", PARAM_STR, &sc_uri_user}, + {"sc_uri_host", PARAM_STR, &sc_uri_host}, + {"sc_body", PARAM_STR, &sc_body}, + {"sc_ctype", PARAM_STR, &sc_ctype}, + {"sc_exp_time", PARAM_STR, &sc_exp_time}, + {"sc_inc_time", PARAM_STR, &sc_inc_time}, + {"sc_snd_time", PARAM_STR, &sc_snd_time}, + {"sc_stored_hdrs", PARAM_STR, &sc_stored_hdrs}, + {"sc_callid", PARAM_STR, &sc_callid}, + {"sc_status", PARAM_STR, &sc_status}, + {"snd_time_avp", PARAM_STR, &ms_snd_time_avp_param}, + {"extra_hdrs_avp", PARAM_STR, &ms_extra_hdrs_avp_param}, + {"add_date", INT_PARAM, &ms_add_date}, + {"max_messages", INT_PARAM, &ms_max_messages}, + {"add_contact", INT_PARAM, &ms_add_contact}, + {"skip_notification_flag", PARAM_INT, &ms_skip_notification_flag}, + {"use_mode", PARAM_INT, &ms_use_mode}, + {0, 0, 0} +}; #ifdef STATISTICS #include "../../core/counters.h" @@ -218,33 +240,37 @@ stat_var *ms_failed_msgs; stat_var *ms_dumped_rmds; stat_var *ms_failed_rmds; -stat_export_t msilo_stats[] = {{"stored_messages", 0, &ms_stored_msgs}, - {"dumped_messages", 0, &ms_dumped_msgs}, - {"failed_messages", 0, &ms_failed_msgs}, - {"dumped_reminders", 0, &ms_dumped_rmds}, - {"failed_reminders", 0, &ms_failed_rmds}, {0, 0, 0}}; +stat_export_t msilo_stats[] = { + {"stored_messages", 0, &ms_stored_msgs}, + {"dumped_messages", 0, &ms_dumped_msgs}, + {"failed_messages", 0, &ms_failed_msgs}, + {"dumped_reminders", 0, &ms_dumped_rmds}, + {"failed_reminders", 0, &ms_failed_rmds}, + {0, 0, 0} +}; #endif /** module exports */ struct module_exports exports = { - "msilo", /* module id */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* module's exported functions */ - params, /* module's exported parameters */ - 0, /* exported RPC methods */ - 0, /* exported pseudo-variables */ - 0, /* response handler */ - mod_init, /* module initialization function */ - child_init, /* per-child init function */ - destroy /* module destroy function */ + "msilo", /* module id */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* module's exported functions */ + params, /* module's exported parameters */ + 0, /* exported RPC methods */ + 0, /* exported pseudo-variables */ + 0, /* response handler */ + mod_init, /* module initialization function */ + child_init, /* per-child init function */ + destroy /* module destroy function */ }; +/* clang-format on */ static int bind_msilo(msilo_api_t *api) { if(!api) { return -1; } - api->m_store = m_store; + api->m_store = m_store_uri; api->m_dump = m_dump; return 0; } @@ -337,7 +363,7 @@ static int mod_init(void) db_con = NULL; /* load the TM API */ - if(load_tm_api(&tmb) != 0) { + if(load_tm_api(&_msilo_tmb) != 0) { LM_ERR("can't load TM API\n"); return -1; } @@ -407,8 +433,8 @@ static int mod_init(void) return -1; } - ml = msg_list_init(); - if(ml == NULL) { + _msilo_ml = msg_list_init(); + if(_msilo_ml == NULL) { LM_ERR("can't initialize msg list\n"); return -1; } @@ -504,12 +530,9 @@ static int get_non_mandatory_headers( /** * store message - * mode = "0" -- look for outgoing URI starting with new_uri - * = "1" -- look for outgoing URI starting with r-uri - * = "2" -- look for outgoing URI only at to header */ -static int m_store(sip_msg_t *msg, str *owner_s) +static int m_store_addrs(sip_msg_t *msg, str *owner, str *srcaddr, str *dstaddr) { str body, str_hdr, ctaddr; struct to_body *pto, *pfrom; @@ -569,12 +592,12 @@ static int m_store(sip_msg_t *msg, str *owner_s) /* get the owner */ memset(&puri, 0, sizeof(struct sip_uri)); - if(owner_s != NULL) { - if(parse_uri(owner_s->s, owner_s->len, &puri) != 0) { + if(owner != NULL) { + if(parse_uri(owner->s, owner->len, &puri) != 0) { LM_ERR("bad owner SIP address!\n"); goto error; } else { - LM_DBG("using user id [%.*s]\n", owner_s->len, owner_s->s); + LM_DBG("using user id [%.*s]\n", owner->len, owner->s); } } else { /* get it from R-URI */ if(msg->new_uri.len <= 0) { @@ -586,7 +609,7 @@ static int m_store(sip_msg_t *msg, str *owner_s) } else { duri = msg->new_uri; } - LM_DBG("NEW R-URI found - check if is AoR!\n"); + LM_DBG("NEW R-URI found - check if it is AoR!\n"); if(parse_uri(duri.s, duri.len, &puri) != 0) { LM_ERR("bad dst R-URI!!\n"); goto error; @@ -641,8 +664,13 @@ static int m_store(sip_msg_t *msg, str *owner_s) db_vals[nr_keys].type = DB1_STR; db_vals[nr_keys].nul = 0; - db_vals[nr_keys].val.str_val.s = pto->uri.s; - db_vals[nr_keys].val.str_val.len = pto->uri.len; + if(dstaddr == NULL || dstaddr->len <= 0) { + db_vals[nr_keys].val.str_val.s = pto->uri.s; + db_vals[nr_keys].val.str_val.len = pto->uri.len; + } else { + db_vals[nr_keys].val.str_val.s = dstaddr->s; + db_vals[nr_keys].val.str_val.len = dstaddr->len; + } nr_keys++; @@ -658,8 +686,13 @@ static int m_store(sip_msg_t *msg, str *owner_s) db_vals[nr_keys].type = DB1_STR; db_vals[nr_keys].nul = 0; - db_vals[nr_keys].val.str_val.s = pfrom->uri.s; - db_vals[nr_keys].val.str_val.len = pfrom->uri.len; + if(srcaddr == NULL || srcaddr->len <= 0) { + db_vals[nr_keys].val.str_val.s = pfrom->uri.s; + db_vals[nr_keys].val.str_val.len = pfrom->uri.len; + } else { + db_vals[nr_keys].val.str_val.s = srcaddr->s; + db_vals[nr_keys].val.str_val.len = srcaddr->len; + } nr_keys++; @@ -759,6 +792,19 @@ static int m_store(sip_msg_t *msg, str *owner_s) nr_keys++; + if(ms_use_mode & MS_USEMODE_CALLID) { + if(parse_headers(msg, HDR_CALLID_F, 0) < 0) { + LM_ERR("failed to parse call-id header\n"); + goto error; + } + db_keys[nr_keys] = &sc_callid; + db_vals[nr_keys].type = DB1_STR; + db_vals[nr_keys].nul = 0; + db_vals[nr_keys].val.str_val.s = msg->callid->body.s; + db_vals[nr_keys].val.str_val.len = msg->callid->body.len; + nr_keys++; + } + if(msilo_dbf.insert(db_con, db_keys, db_vals, nr_keys) < 0) { LM_ERR("failed to store message\n"); goto error; @@ -835,11 +881,11 @@ static int m_store(sip_msg_t *msg, str *owner_s) } } - memset(&uac_r, '\0', sizeof(uac_r)); + memset(&uac_r, 0, sizeof(uac_r)); uac_r.method = &msg_type; uac_r.headers = &str_hdr; uac_r.body = ¬ify_body; - tmb.t_request(&uac_r, /* UAC Req */ + _msilo_tmb.t_request(&uac_r, /* UAC Req */ (ctaddr.s) ? &ctaddr : &pfrom->uri, /* Request-URI */ &pfrom->uri, /* To */ ¬ify_from, /* From */ @@ -852,10 +898,15 @@ error: return -1; } +static int m_store_uri(sip_msg_t *msg, str *owner) +{ + return m_store_addrs(msg, owner, NULL, NULL); +} + /** * store message */ -static int m_store_2(struct sip_msg *msg, char *owner, char *s2) +static int m_store1(struct sip_msg *msg, char *owner, char *s2) { str owner_s; if(owner != NULL) { @@ -863,9 +914,35 @@ static int m_store_2(struct sip_msg *msg, char *owner, char *s2) LM_ERR("invalid owner uri parameter"); return -1; } - return m_store(msg, &owner_s); + return m_store_addrs(msg, &owner_s, NULL, NULL); } - return m_store(msg, NULL); + return m_store_addrs(msg, NULL, NULL, NULL); +} + + +/** + * store message + */ +static int m_store3(sip_msg_t *msg, char *owner, char *srcaddr, char *dstaddr) +{ + str owner_s; + str srcaddr_s; + str dstaddr_s; + + if(fixup_get_svalue(msg, (gparam_t *)owner, &owner_s) != 0) { + LM_ERR("invalid owner uri parameter"); + return -1; + } + if(fixup_get_svalue(msg, (gparam_t *)srcaddr, &srcaddr_s) != 0) { + LM_ERR("invalid srcaddr uri parameter"); + return -1; + } + if(fixup_get_svalue(msg, (gparam_t *)dstaddr, &dstaddr_s) != 0) { + LM_ERR("invalid dstaddr uri parameter"); + return -1; + } + + return m_store_addrs(msg, &owner_s, &srcaddr_s, &dstaddr_s); } /** @@ -873,7 +950,7 @@ static int m_store_2(struct sip_msg *msg, char *owner, char *s2) */ static int ki_m_store(sip_msg_t *msg) { - return m_store(msg, NULL); + return m_store_addrs(msg, NULL, NULL, NULL); } /** @@ -886,14 +963,14 @@ static int m_dump(sip_msg_t *msg, str *owner_s) db_key_t ob_key; db_op_t db_ops[3]; db_val_t db_vals[3]; - db_key_t db_cols[7]; + db_key_t db_cols[8]; db1_res_t *db_res = NULL; - int i, db_no_cols = 7, db_no_keys = 3, mid, n; + int i, db_no_cols = 8, db_no_keys = 3, mid, n; static char hdr_buf[1024]; static char body_buf[1024]; struct sip_uri puri; uac_req_t uac_r; - str str_vals[5], hdr_str, body_str, extra_hdrs_str, tmp_extra_hdrs; + str str_vals[6], hdr_str, body_str, extra_hdrs_str, tmp_extra_hdrs; time_t rtime; /* init */ @@ -913,6 +990,7 @@ static int m_dump(sip_msg_t *msg, str *owner_s) db_cols[4] = &sc_ctype; db_cols[5] = &sc_inc_time; db_cols[6] = &sc_stored_hdrs; + db_cols[7] = &sc_callid; LM_DBG("------------ start ------------\n"); hdr_str.s = hdr_buf; @@ -1004,17 +1082,18 @@ static int m_dump(sip_msg_t *msg, str *owner_s) for(i = 0; i < RES_ROW_N(db_res); i++) { mid = RES_ROWS(db_res)[i].values[0].val.int_val; - if(msg_list_check_msg(ml, mid)) { + if(msg_list_check_msg(_msilo_ml, mid)) { LM_DBG("message[%d] mid=%d already sent.\n", i, mid); continue; } - memset(str_vals, 0, 5 * sizeof(str)); + memset(str_vals, 0, 6 * sizeof(str)); SET_STR_VAL(str_vals[0], db_res, i, 1); /* from */ SET_STR_VAL(str_vals[1], db_res, i, 2); /* to */ SET_STR_VAL(str_vals[2], db_res, i, 3); /* body */ SET_STR_VAL(str_vals[3], db_res, i, 4); /* ctype */ SET_STR_VAL(str_vals[4], db_res, i, 6); /* stored hdrs */ + SET_STR_VAL(str_vals[5], db_res, i, 7); /* callid */ rtime = (time_t)RES_ROWS(db_res)[i].values[5 /*inc time*/].val.int_val; if(ms_extra_hdrs != NULL) { @@ -1036,7 +1115,7 @@ static int m_dump(sip_msg_t *msg, str *owner_s) LM_ERR("Out of pkg memory"); if(msilo_dbf.free_result(db_con, db_res) < 0) LM_ERR("failed to free the query result\n"); - msg_list_set_flag(ml, mid, MS_MSG_ERRO); + msg_list_set_flag(_msilo_ml, mid, MS_MSG_ERRO); goto error; } if(extra_hdrs_str.len > 0) @@ -1057,7 +1136,7 @@ static int m_dump(sip_msg_t *msg, str *owner_s) pkg_free(tmp_extra_hdrs.s); if(msilo_dbf.free_result(db_con, db_res) < 0) LM_ERR("failed to free the query result\n"); - msg_list_set_flag(ml, mid, MS_MSG_ERRO); + msg_list_set_flag(_msilo_ml, mid, MS_MSG_ERRO); goto error; } if(tmp_extra_hdrs.len > 0) @@ -1079,15 +1158,20 @@ static int m_dump(sip_msg_t *msg, str *owner_s) else LM_DBG("sending composed body\n"); - memset(&uac_r, '\0', sizeof(uac_r)); + memset(&uac_r, 0, sizeof(uac_r)); uac_r.method = &msg_type; uac_r.headers = &hdr_str; uac_r.body = (n < 0) ? &str_vals[2] : &body_str; uac_r.cb_flags = TMCB_LOCAL_COMPLETED; uac_r.cb = m_tm_callback; uac_r.cbp = (void *)(long)mid; + if(ms_use_mode & MS_USEMODE_CALLID) { + if(str_vals[5].s != NULL && str_vals[5].len > 0) { + uac_r.callid = &str_vals[5]; + } + } - tmb.t_request(&uac_r, /* UAC Req */ + _msilo_tmb.t_request(&uac_r, /* UAC Req */ &str_vals[1], /* Request-URI */ &str_vals[1], /* To */ &str_vals[0], /* From */ @@ -1146,8 +1230,8 @@ void m_clean_silo(unsigned int ticks, void *param) LM_DBG("cleaning stored messages - %d\n", ticks); - msg_list_check(ml); - mle = p = msg_list_reset(ml); + msg_list_check(_msilo_ml); + mle = p = msg_list_reset(_msilo_ml); n = 0; if(msilo_dbf.use_table(db_con, &ms_db_table) < 0) { LM_ERR("failed to use_table\n"); @@ -1213,7 +1297,7 @@ void m_clean_silo(unsigned int ticks, void *param) */ static void destroy(void) { - msg_list_free(ml); + msg_list_free(_msilo_ml); if(db_con && msilo_dbf.close) msilo_dbf.close(db_con); @@ -1237,12 +1321,12 @@ void m_tm_callback(struct cell *t, int type, struct tmcb_params *ps) } if(ps->code >= 300) { LM_DBG("message <%d> was not sent successfully\n", *((int *)ps->param)); - msg_list_set_flag(ml, *((int *)ps->param), MS_MSG_ERRO); + msg_list_set_flag(_msilo_ml, *((int *)ps->param), MS_MSG_ERRO); goto done; } LM_DBG("message <%d> was sent successfully\n", *((int *)ps->param)); - msg_list_set_flag(ml, *((int *)ps->param), MS_MSG_DONE); + msg_list_set_flag(_msilo_ml, *((int *)ps->param), MS_MSG_DONE); done: return; @@ -1322,7 +1406,7 @@ void m_send_ontimer(unsigned int ticks, void *param) for(i = 0; i < RES_ROW_N(db_res); i++) { mid = RES_ROWS(db_res)[i].values[0].val.int_val; - if(msg_list_check_msg(ml, mid)) { + if(msg_list_check_msg(_msilo_ml, mid)) { LM_DBG("message[%d] mid=%d already sent.\n", i, mid); continue; } @@ -1346,7 +1430,7 @@ void m_send_ontimer(unsigned int ticks, void *param) LM_ERR("headers building failed [%d]\n", mid); if(msilo_dbf.free_result(db_con, db_res) < 0) LM_DBG("failed to free result of query\n"); - msg_list_set_flag(ml, mid, MS_MSG_ERRO); + msg_list_set_flag(_msilo_ml, mid, MS_MSG_ERRO); return; } @@ -1369,17 +1453,17 @@ void m_send_ontimer(unsigned int ticks, void *param) else LM_DBG("sending composed body\n"); - msg_list_set_flag(ml, mid, MS_MSG_TSND); + msg_list_set_flag(_msilo_ml, mid, MS_MSG_TSND); - memset(&uac_r, '\0', sizeof(uac_r)); + memset(&uac_r, 0, sizeof(uac_r)); uac_r.method = &msg_type; uac_r.headers = &hdr_str; uac_r.body = (n < 0) ? &str_vals[2] : &body_str; uac_r.cb_flags = TMCB_LOCAL_COMPLETED; uac_r.cb = m_tm_callback; uac_r.cbp = (void *)(long)mid; - tmb.t_request(&uac_r, /* UAC Req */ + _msilo_tmb.t_request(&uac_r, /* UAC Req */ &puri, /* Request-URI */ &puri, /* To */ &ms_reminder, /* From */ @@ -1537,10 +1621,15 @@ static sr_kemi_t sr_kemi_msilo_exports[] = { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, { str_init("msilo"), str_init("mstore_uri"), - SR_KEMIP_INT, m_store, + SR_KEMIP_INT, m_store_uri, { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, + { str_init("msilo"), str_init("mstore_addrs"), + SR_KEMIP_INT, m_store_addrs, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, { str_init("msilo"), str_init("mdump"), SR_KEMIP_INT, ki_m_dump, { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, diff --git a/src/modules/nat_traversal/nat_traversal.c b/src/modules/nat_traversal/nat_traversal.c index b07534ec9..4a27945a3 100644 --- a/src/modules/nat_traversal/nat_traversal.c +++ b/src/modules/nat_traversal/nat_traversal.c @@ -1168,7 +1168,7 @@ static void __dialog_destroy( lock_get(¶m->lock); - // remove all keepalives on unanswered branches. this is neded because + // remove all keepalives on unanswered branches. This is needed because // we may transit from early to ended without going through confirmed for(i = 0; i < param->callee_candidates.count; i++) { h = HASH(nat_table, param->callee_candidates.uri[i]); @@ -1724,10 +1724,12 @@ static void restore_keepalive_state(void) res = fscanf(f, STATE_FILE_HEADER); // skip header while(true) { + ll_1 = 0; + ll_2 = 0; + uri[0] = '\0'; + socket[0] = '\0'; res = fscanf(f, "%63s %63s %" TIME_T_FMT " %" TIME_T_FMT, uri, socket, &ll_1, &ll_2); - rtime = ll_1; - stime = ll_2; if(res == EOF) { if(ferror(f)) LM_ERR("error while reading keepalive state file: %s\n", @@ -1738,6 +1740,8 @@ static void restore_keepalive_state(void) "entries.\n"); break; } else { + rtime = ll_1; + stime = ll_2; if(now > rtime && now > stime) continue; // expired entry diff --git a/src/modules/nathelper/README b/src/modules/nathelper/README index b1edb5d45..43938459b 100644 --- a/src/modules/nathelper/README +++ b/src/modules/nathelper/README @@ -861,9 +861,11 @@ Chapter 2. Frequently Asked Questions First at all check if your question was already answered on one of our mailing lists: * User Mailing List - - https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users + https://lists.kamailio.org/mailman3/postorius/lists/sr-users.lists. + kamailio.org/ * Developer Mailing List - - https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-dev + https://lists.kamailio.org/mailman3/postorius/lists/sr-dev.lists.ka + mailio.org/ E-mails regarding any stable Kamailio release should be sent to and e-mails regarding development diff --git a/src/modules/nathelper/sip_pinger.h b/src/modules/nathelper/sip_pinger.h index 733e38f21..b3ee4d39f 100644 --- a/src/modules/nathelper/sip_pinger.h +++ b/src/modules/nathelper/sip_pinger.h @@ -151,7 +151,7 @@ static inline char *build_sipping(str *curi, struct socket_info *s, str *path, + ruid->len + 1 + 8 + 1 + 8 + s_len(CRLF "To: ") + curi->len + s_len(CRLF "Call-ID: ") + sipping_callid.len + 1 + 8 + 1 + 8 + 1 + s->address_str.len + s_len(CRLF "CSeq: 1 ") - + sipping_method.len + + sipping_method.len + s_len(CRLF "Max-Forwards: 70") + s_len(CRLF "Content-Length: 0" CRLF CRLF) > MAX_SIPPING_SIZE) { LM_ERR("len exceeds %d\n", MAX_SIPPING_SIZE); @@ -205,6 +205,7 @@ static inline char *build_sipping(str *curi, struct socket_info *s, str *path, append_str(p, s->address_str.s, s->address_str.len); append_fix(p, CRLF "CSeq: 1 "); append_str(p, sipping_method.s, sipping_method.len); + append_fix(p, CRLF "Max-Forwards: 70"); append_fix(p, CRLF "Content-Length: 0" CRLF CRLF); *len_p = p - buf; diff --git a/src/modules/nats/nats_mod.c b/src/modules/nats/nats_mod.c index 697372406..94c975a32 100644 --- a/src/modules/nats/nats_mod.c +++ b/src/modules/nats/nats_mod.c @@ -59,7 +59,9 @@ static param_export_t params[] = { static cmd_export_t cmds[] = { {"nats_publish", (cmd_function)w_nats_publish_f, - 3, fixup_publish_get_value, fixup_publish_get_value_free, ANY_ROUTE}, + 2, fixup_publish_get_value, fixup_publish_get_value_free, ANY_ROUTE}, + {"nats_publish", (cmd_function)w_nats_publish_reply_f, + 3, fixup_publish_reply_get_value, fixup_publish_reply_get_value_free, ANY_ROUTE}, {0, 0, 0, 0, 0, 0} }; diff --git a/src/modules/nats/nats_mod.h b/src/modules/nats/nats_mod.h index ef543e7fa..e43395699 100644 --- a/src/modules/nats/nats_mod.h +++ b/src/modules/nats/nats_mod.h @@ -35,10 +35,13 @@ static int mod_init(void); static int mod_child_init(int); static void mod_destroy(void); -extern int w_nats_publish_f( +extern int w_nats_publish_f(sip_msg_t *msg, char *subj, char *payload); +extern int w_nats_publish_reply_f( sip_msg_t *msg, char *subj, char *payload, char *reply); extern int fixup_publish_get_value(void **param, int param_no); extern int fixup_publish_get_value_free(void **param, int param_no); +extern int fixup_publish_reply_get_value(void **param, int param_no); +extern int fixup_publish_reply_get_value_free(void **param, int param_no); extern void _nats_pub_worker_cb(uv_poll_t *handle, int status, int events); int nats_run_cfg_route(int rt, str *evname); diff --git a/src/modules/nats/nats_pub.c b/src/modules/nats/nats_pub.c index a2c38a75e..d80525009 100644 --- a/src/modules/nats/nats_pub.c +++ b/src/modules/nats/nats_pub.c @@ -32,7 +32,7 @@ int pub_worker = 0; int fixup_publish_get_value(void **param, int param_no) { - if(param_no == 1 || param_no == 2 || param_no == 3) { + if(param_no == 1 || param_no == 2) { return fixup_spve_null(param, 1); } LM_ERR("invalid parameter number <%d>\n", param_no); @@ -40,6 +40,25 @@ int fixup_publish_get_value(void **param, int param_no) } int fixup_publish_get_value_free(void **param, int param_no) +{ + if(param_no == 1 || param_no == 2) { + fixup_free_spve_null(param, 1); + return 0; + } + LM_ERR("invalid parameter number <%d>\n", param_no); + return -1; +} + +int fixup_publish_reply_get_value(void **param, int param_no) +{ + if(param_no == 1 || param_no == 2 || param_no == 3) { + return fixup_spve_null(param, 1); + } + LM_ERR("invalid parameter number <%d>\n", param_no); + return -1; +} + +int fixup_publish_reply_get_value_free(void **param, int param_no) { if(param_no == 1 || param_no == 2 || param_no == 3) { fixup_free_spve_null(param, 1); @@ -84,7 +103,24 @@ static int _w_nats_publish_f(str subj, str payload, str reply, int worker) return 1; } -int w_nats_publish_f(sip_msg_t *msg, char *subj, char *payload, char *reply) +int w_nats_publish_f(sip_msg_t *msg, char *subj, char *payload) +{ + str subj_s = STR_NULL; + str payload_s = STR_NULL; + str reply_s = STR_NULL; + if(fixup_get_svalue(msg, (gparam_t *)subj, &subj_s) < 0) { + LM_ERR("failed to get subj value\n"); + return -1; + } + if(fixup_get_svalue(msg, (gparam_t *)payload, &payload_s) < 0) { + LM_ERR("failed to get subj value\n"); + return -1; + } + return w_nats_publish(msg, subj_s, payload_s, reply_s); +} + +int w_nats_publish_reply_f( + sip_msg_t *msg, char *subj, char *payload, char *reply) { str subj_s = STR_NULL; str payload_s = STR_NULL; diff --git a/src/modules/nats/nats_pub.h b/src/modules/nats/nats_pub.h index cf0c11da1..099571ac4 100644 --- a/src/modules/nats/nats_pub.h +++ b/src/modules/nats/nats_pub.h @@ -39,9 +39,13 @@ typedef struct _nats_pub_delivery nats_pub_delivery_ptr _nats_pub_delivery_new( str subject, str payload, str reply); void nats_pub_free_delivery_ptr(nats_pub_delivery_ptr ptr); -int w_nats_publish_f(sip_msg_t *msg, char *subj, char *payload, char *reply); +int w_nats_publish_f(sip_msg_t *msg, char *subj, char *payload); +int w_nats_publish_reply_f( + sip_msg_t *msg, char *subj, char *payload, char *reply); int w_nats_publish(sip_msg_t *msg, str subj_s, str payload_s, str reply_s); int fixup_publish_get_value(void **param, int param_no); int fixup_publish_get_value_free(void **param, int param_no); +int fixup_publish_reply_get_value(void **param, int param_no); +int fixup_publish_reply_get_value_free(void **param, int param_no); #endif diff --git a/src/modules/ndb_cassandra/README b/src/modules/ndb_cassandra/README index b9a5577e4..80287f323 100644 --- a/src/modules/ndb_cassandra/README +++ b/src/modules/ndb_cassandra/README @@ -145,8 +145,8 @@ modparam("ndb_cassandra", "port", 9160) $var(val_write) = "TestMyName"; # To be written if (cass_insert("$var(keyspace)", "$var(column_family)", "$ru", "$var(column )", "$var(val_write)") > 0) { - xlog("L_DBG", "ndb_cassandra. Sucess while inserting to Cassandra. val_wr -ite: \"$var(val_write)\""); + xlog("L_DBG", "ndb_cassandra. Success while inserting to Cassandra. val_w +rite: \"$var(val_write)\""); } else { xlog("L_DBG", "ndb_cassandra. Error while inserting to Cassandra"); } @@ -160,8 +160,8 @@ ite: \"$var(val_write)\""); $var(val_read) = ""; # To be read if (cass_retrieve("$var(keyspace)", "$var(column_family)", "$var(key)", "$va r(column)", "$var(val_read)") > 0) { - xlog("L_DBG", "ndb_cassandra. Sucess while reading from Cassandra. val_re -ad: \"$var(val_read)\""); + xlog("L_DBG", "ndb_cassandra. Success while reading from Cassandra. val_r +ead: \"$var(val_read)\""); } else { xlog("L_DBG", "ndb_cassandra. Error while reading from Cassandra"); } diff --git a/src/modules/ndb_cassandra/doc/ndb_cassandra_admin.xml b/src/modules/ndb_cassandra/doc/ndb_cassandra_admin.xml index d1fa9df73..c5359ac66 100644 --- a/src/modules/ndb_cassandra/doc/ndb_cassandra_admin.xml +++ b/src/modules/ndb_cassandra/doc/ndb_cassandra_admin.xml @@ -148,7 +148,7 @@ modparam("ndb_cassandra", "port", 9160) $var(column) = "name"; $var(val_write) = "TestMyName"; # To be written if (cass_insert("$var(keyspace)", "$var(column_family)", "$ru", "$var(column)", "$var(val_write)") > 0) { - xlog("L_DBG", "ndb_cassandra. Sucess while inserting to Cassandra. val_write: \"$var(val_write)\""); + xlog("L_DBG", "ndb_cassandra. Success while inserting to Cassandra. val_write: \"$var(val_write)\""); } else { xlog("L_DBG", "ndb_cassandra. Error while inserting to Cassandra"); } @@ -160,7 +160,7 @@ modparam("ndb_cassandra", "port", 9160) $var(column) = "name"; $var(val_read) = ""; # To be read if (cass_retrieve("$var(keyspace)", "$var(column_family)", "$var(key)", "$var(column)", "$var(val_read)") > 0) { - xlog("L_DBG", "ndb_cassandra. Sucess while reading from Cassandra. val_read: \"$var(val_read)\""); + xlog("L_DBG", "ndb_cassandra. Success while reading from Cassandra. val_read: \"$var(val_read)\""); } else { xlog("L_DBG", "ndb_cassandra. Error while reading from Cassandra"); } diff --git a/src/modules/ndb_mongodb/README b/src/modules/ndb_mongodb/README index 24299696f..ae306022a 100644 --- a/src/modules/ndb_mongodb/README +++ b/src/modules/ndb_mongodb/README @@ -159,7 +159,7 @@ modparam("ndb_mongodb", "server", "name=mgs2;uri='mongodb://127.0.0.2/kamailio'" Meaning of the parameters: * srvname - MongoDB server name as given via 'server' parameter. * dbname - MongoDB database name. - * cname - MongodDB collection (table) name. + * cname - MongoDB collection (table) name. * command - valid MongoDB command given as JSON string. * replyid - the name of the container to store the response. diff --git a/src/modules/ndb_mongodb/doc/ndb_mongodb_admin.xml b/src/modules/ndb_mongodb/doc/ndb_mongodb_admin.xml index b16a92c93..e7a33463d 100644 --- a/src/modules/ndb_mongodb/doc/ndb_mongodb_admin.xml +++ b/src/modules/ndb_mongodb/doc/ndb_mongodb_admin.xml @@ -137,7 +137,7 @@ modparam("ndb_mongodb", "server", "name=mgs2;uri='mongodb://127.0.0.2/kamailio'" - cname - MongodDB collection (table) name. + cname - MongoDB collection (table) name. diff --git a/src/modules/ndb_redis/Makefile b/src/modules/ndb_redis/Makefile index 66c34617f..429b69d6e 100644 --- a/src/modules/ndb_redis/Makefile +++ b/src/modules/ndb_redis/Makefile @@ -14,10 +14,27 @@ endif ifeq ($(HIREDIS_BUILDER),) HIREDISDEFS=-I$(LOCALBASE)/include -I$(LOCALBASE)/include/hiredis -I/usr/include/hiredis - HIREDISLIBS=-L$(LOCALBASE)/lib -lhiredis + HIREDISLIBS=-L$(LOCALBASE)/lib + ifneq ($(shell ls $(LOCALBASE) | grep libhiredis_ssl.so),) + HIREDISDEFS += -DWITH_SSL + HIREDISLIBS += -lhiredis_ssl + endif else HIREDISDEFS = $(shell $(HIREDIS_BUILDER) --cflags) HIREDISLIBS = $(shell $(HIREDIS_BUILDER) --libs) + HIREDISLIBSPATH = $(shell $(HIREDIS_BUILDER) --libs-only-L | cut -c 3-) + ifeq ($(HIREDISLIBSPATH),) + GCCSEARCHDIRS = $(shell $(CC) -print-search-dirs | grep -Eo '^.*libraries: =.*' | cut -d "=" -f2- | tr : ' ') + ifneq ($(shell find $(GCCSEARCHDIRS) -name libhiredis_ssl.so 2>/dev/null),) + HIREDISDEFS += -DWITH_SSL + HIREDISLIBS += -lhiredis_ssl + endif + else + ifneq ($(shell ls $(HIREDISLIBSPATH) | grep libhiredis_ssl.so),) + HIREDISDEFS += -DWITH_SSL + HIREDISLIBS += -lhiredis_ssl + endif + endif ifeq (,$(findstring hiredis,$(HIREDISDEFS))) DEFS+=-DWITH_HIREDIS_PATH @@ -26,6 +43,10 @@ endif ifeq ($(HIREDISLIBS),-L -lhiredis) HIREDISDEFS = $(shell $(HIREDIS_BUILDER) --cflags) /opt/local/include HIREDISLIBS = -L/opt/local/lib -lhiredis + ifneq ($(shell ls /opt/local/lib | grep libhiredis_ssl.so),) + HIREDISDEFS += -DWITH_SSL + HIREDISLIBS += -lhiredis_ssl + endif endif endif diff --git a/src/modules/ndb_redis/README b/src/modules/ndb_redis/README index 46081b7ec..1cdfc842d 100644 --- a/src/modules/ndb_redis/README +++ b/src/modules/ndb_redis/README @@ -22,6 +22,10 @@ Carsten Bock +Joel Centelles Martin + + + Copyright © 2011 asipto.com Copyright © 2012 www.systemonenoc.com @@ -51,6 +55,7 @@ Carsten Bock 3.8. flush_on_reconnect (integer) 3.9. allow_dynamic_nodes (integer) 3.10. debug (integer) + 3.11. ac_path (string) 4. Functions @@ -71,9 +76,10 @@ Carsten Bock 1.8. Set flush_on_reconnect parameter 1.9. Set allow_dynamic_nodes parameter 1.10. Set debug parameter - 1.11. redis_cmd usage - 1.12. redis_execute usage - 1.13. redis_free usage + 1.11. Setting CA path + 1.12. redis_cmd usage + 1.13. redis_execute usage + 1.14. redis_free usage Chapter 1. Admin Guide @@ -97,6 +103,7 @@ Chapter 1. Admin Guide 3.8. flush_on_reconnect (integer) 3.9. allow_dynamic_nodes (integer) 3.10. debug (integer) + 3.11. ac_path (string) 4. Functions @@ -142,18 +149,20 @@ Chapter 1. Admin Guide 3.8. flush_on_reconnect (integer) 3.9. allow_dynamic_nodes (integer) 3.10. debug (integer) + 3.11. ac_path (string) 3.1. server (str) Specify the details to connect to REDIS server. It takes a list of attribute=value separated by semicolon, the attributes can be name, - unix, addr, port, db and pass. Name is a generic identifier to be used - with module functions. unix is the path to the unix domain socket + unix, addr, port, db, pass and tls. Name is a generic identifier to be + used with module functions. unix is the path to the unix domain socket provided by redis server. addr and port are the IP address and the port - to connect to REDIS server. pass is the server password. unix and - (addr, port) are mutually exclusive. If both appear in same server - settings unix domain socket is configured. db is the DB number to use - (defaults to 0 if not specified). + to connect to REDIS server. pass is the server password. tls is to + enable TLS connectivity. unix and (addr, port) are mutually exclusive. + If both appear in same server settings unix domain socket is + configured. db is the DB number to use (defaults to 0 if not + specified). You can set this parameter many times, in case you want to connect to many REDIS servers, just give different attributes and use the specific @@ -166,6 +175,8 @@ Chapter 1. Admin Guide modparam("ndb_redis", "server", "name=srvN;addr=127.0.0.1;port=6379;db=1") modparam("ndb_redis", "server", "name=srvX;addr=127.0.0.2;port=6379;db=4;pass=my password") +modparam("ndb_redis", "server", "name=srvY;addr=127.0.0.3;port=6379;db=5;pass=my +password;tls=1") # Unix domain socket modparam("ndb_redis", "server", "name=srvY;unix=/tmp/redis.sock;db=3") @@ -335,6 +346,17 @@ modparam("ndb_redis", "allow_dynamic_nodes", 1) modparam("ndb_redis", "debug", 1) ... +3.11. ac_path (string) + + Sets the path where Certificates Authorities certs are stored. + + Default value: "" (empty). + + Example 1.11. Setting CA path +... +modparam("db_redis", "ca_path", "/etc/ssl/certs") +... + 4. Functions 4.1. redis_cmd(srvname, command, ..., replyid) @@ -375,7 +397,7 @@ modparam("ndb_redis", "debug", 1) value. The key can be: rpl_str, rpl_arr, rpl_int, rpl_err, rpl_sts, rpl_nil. - Example 1.11. redis_cmd usage + Example 1.12. redis_cmd usage ... if(redis_cmd("srvN", "INCR cnt", "r")) { # success - the incremented value is in $redis(r=>value) @@ -454,7 +476,7 @@ if (redis_cmd("srvN", "EXEC", "r")) { If cluster parameter is set to 1, this function will log an error and do nothing. - Example 1.12. redis_execute usage + Example 1.13. redis_execute usage ... After several redis command calls: redis_pipe_cmd("srvA", "SET foo bar", "r1"); @@ -502,7 +524,7 @@ d commands. The call is not necessary function. When ndb_redis module closes, all pending replies are freed automatically. - Example 1.13. redis_free usage + Example 1.14. redis_free usage ... After a redis command call: redis_cmd("srvN", "INCR cnt", "r"); diff --git a/src/modules/ndb_redis/doc/ndb_redis.xml b/src/modules/ndb_redis/doc/ndb_redis.xml index e33a8a787..7adefadc0 100644 --- a/src/modules/ndb_redis/doc/ndb_redis.xml +++ b/src/modules/ndb_redis/doc/ndb_redis.xml @@ -38,6 +38,11 @@ Bock carsten@ng-voice.com + + Joel + Centelles Martin + joel_centellesmartin@baxter.com + 2011 diff --git a/src/modules/ndb_redis/doc/ndb_redis_admin.xml b/src/modules/ndb_redis/doc/ndb_redis_admin.xml index 1c8391c20..74d35c75c 100644 --- a/src/modules/ndb_redis/doc/ndb_redis_admin.xml +++ b/src/modules/ndb_redis/doc/ndb_redis_admin.xml @@ -63,12 +63,12 @@ <varname>server</varname> (str) Specify the details to connect to REDIS server. It takes a list of attribute=value - separated by semicolon, the attributes can be name, unix, addr, port, db and pass. Name + separated by semicolon, the attributes can be name, unix, addr, port, db, pass and tls. Name is a generic identifier to be used with module functions. unix is the path to the unix domain socket provided by redis server. addr and port are the IP address and the port to - connect to REDIS server. pass is the server password. unix and (addr, port) are mutually - exclusive. If both appear in same server settings unix domain socket is configured. db - is the DB number to use (defaults to 0 if not specified). + connect to REDIS server. pass is the server password. tls is to enable TLS connectivity. + unix and (addr, port) are mutually exclusive. If both appear in same server settings unix + domain socket is configured. db is the DB number to use (defaults to 0 if not specified). You can set this parameter many times, in case you want to connect to @@ -86,6 +86,7 @@ ... modparam("ndb_redis", "server", "name=srvN;addr=127.0.0.1;port=6379;db=1") modparam("ndb_redis", "server", "name=srvX;addr=127.0.0.2;port=6379;db=4;pass=mypassword") +modparam("ndb_redis", "server", "name=srvY;addr=127.0.0.3;port=6379;db=5;pass=mypassword;tls=1") # Unix domain socket modparam("ndb_redis", "server", "name=srvY;unix=/tmp/redis.sock;db=3") @@ -324,6 +325,23 @@ modparam("ndb_redis", "allow_dynamic_nodes", 1) ... modparam("ndb_redis", "debug", 1) +... + + +
+
+ <varname>ac_path</varname> (string) + + Sets the path where Certificates Authorities certs are stored. + + + Default value: "" (empty). + + + Setting CA path + +... +modparam("db_redis", "ca_path", "/etc/ssl/certs") ... diff --git a/src/modules/ndb_redis/ndb_redis_mod.c b/src/modules/ndb_redis/ndb_redis_mod.c index 3db07703a..8256c0a61 100644 --- a/src/modules/ndb_redis/ndb_redis_mod.c +++ b/src/modules/ndb_redis/ndb_redis_mod.c @@ -54,6 +54,9 @@ int redis_allowed_timeouts_param = -1; int redis_flush_on_reconnect_param = 0; int redis_allow_dynamic_nodes_param = 0; int ndb_redis_debug = L_DBG; +#ifdef WITH_SSL +char *ndb_redis_ca_path = 0; +#endif static int w_redis_cmd3( struct sip_msg *msg, char *ssrv, char *scmd, char *sres); @@ -76,8 +79,9 @@ static int w_redis_execute(struct sip_msg *msg, char *ssrv); static int w_redis_free_reply(struct sip_msg *msg, char *res); -static void mod_destroy(void); +static int mod_init(void); static int child_init(int rank); +static void mod_destroy(void); int bind_ndb_redis(ndb_redis_api_t *api); @@ -88,67 +92,92 @@ static int pv_get_rediscd( struct sip_msg *msg, pv_param_t *param, pv_value_t *res); static int pv_parse_rediscd_name(pv_spec_p sp, str *in); +/* clang-format off */ static pv_export_t mod_pvs[] = { - {{"redis", sizeof("redis") - 1}, PVT_OTHER, pv_get_redisc, 0, - pv_parse_redisc_name, 0, 0, 0}, - {{"redisd", sizeof("redisd") - 1}, PVT_OTHER, pv_get_rediscd, 0, - pv_parse_rediscd_name, 0, 0, 0}, - {{0, 0}, 0, 0, 0, 0, 0, 0, 0}}; - - -static cmd_export_t cmds[] = {{"redis_cmd", (cmd_function)w_redis_cmd3, 3, - fixup_redis_cmd6, 0, ANY_ROUTE}, - {"redis_cmd", (cmd_function)w_redis_cmd4, 4, fixup_redis_cmd6, 0, - ANY_ROUTE}, - {"redis_cmd", (cmd_function)w_redis_cmd5, 5, fixup_redis_cmd6, 0, - ANY_ROUTE}, - {"redis_cmd", (cmd_function)w_redis_cmd6, 6, fixup_redis_cmd6, 0, - ANY_ROUTE}, - {"redis_pipe_cmd", (cmd_function)w_redis_pipe_cmd3, 3, fixup_redis_cmd6, - 0, ANY_ROUTE}, - {"redis_pipe_cmd", (cmd_function)w_redis_pipe_cmd4, 4, fixup_redis_cmd6, - 0, ANY_ROUTE}, - {"redis_pipe_cmd", (cmd_function)w_redis_pipe_cmd5, 5, fixup_redis_cmd6, - 0, ANY_ROUTE}, - {"redis_pipe_cmd", (cmd_function)w_redis_pipe_cmd6, 6, fixup_redis_cmd6, - 0, ANY_ROUTE}, - {"redis_execute", (cmd_function)w_redis_execute, 1, fixup_redis_cmd6, 0, - ANY_ROUTE}, - {"redis_free", (cmd_function)w_redis_free_reply, 1, fixup_spve_null, 0, - ANY_ROUTE}, - - {"bind_ndb_redis", (cmd_function)bind_ndb_redis, 0, 0, 0, 0}, - - {0, 0, 0, 0, 0, 0}}; + {{"redis", sizeof("redis") - 1}, PVT_OTHER, pv_get_redisc, 0, + pv_parse_redisc_name, 0, 0, 0}, + {{"redisd", sizeof("redisd") - 1}, PVT_OTHER, pv_get_rediscd, 0, + pv_parse_rediscd_name, 0, 0, 0}, + {{0, 0}, 0, 0, 0, 0, 0, 0, 0} +}; + + +static cmd_export_t cmds[] = { + {"redis_cmd", (cmd_function)w_redis_cmd3, 3, + fixup_redis_cmd6, 0, ANY_ROUTE}, + {"redis_cmd", (cmd_function)w_redis_cmd4, 4, fixup_redis_cmd6, 0, + ANY_ROUTE}, + {"redis_cmd", (cmd_function)w_redis_cmd5, 5, fixup_redis_cmd6, 0, + ANY_ROUTE}, + {"redis_cmd", (cmd_function)w_redis_cmd6, 6, fixup_redis_cmd6, 0, + ANY_ROUTE}, + {"redis_pipe_cmd", (cmd_function)w_redis_pipe_cmd3, 3, fixup_redis_cmd6, + 0, ANY_ROUTE}, + {"redis_pipe_cmd", (cmd_function)w_redis_pipe_cmd4, 4, fixup_redis_cmd6, + 0, ANY_ROUTE}, + {"redis_pipe_cmd", (cmd_function)w_redis_pipe_cmd5, 5, fixup_redis_cmd6, + 0, ANY_ROUTE}, + {"redis_pipe_cmd", (cmd_function)w_redis_pipe_cmd6, 6, fixup_redis_cmd6, + 0, ANY_ROUTE}, + {"redis_execute", (cmd_function)w_redis_execute, 1, fixup_redis_cmd6, 0, + ANY_ROUTE}, + {"redis_free", (cmd_function)w_redis_free_reply, 1, fixup_spve_null, 0, + ANY_ROUTE}, + + {"bind_ndb_redis", (cmd_function)bind_ndb_redis, 0, 0, 0, 0}, + + {0, 0, 0, 0, 0, 0} +}; static param_export_t params[] = { - {"server", PARAM_STRING | USE_FUNC_PARAM, (void *)redis_srv_param}, - {"init_without_redis", INT_PARAM, &init_without_redis}, - {"connect_timeout", INT_PARAM, &redis_connect_timeout_param}, - {"cmd_timeout", INT_PARAM, &redis_cmd_timeout_param}, - {"cluster", INT_PARAM, &redis_cluster_param}, - {"disable_time", INT_PARAM, &redis_disable_time_param}, - {"allowed_timeouts", INT_PARAM, &redis_allowed_timeouts_param}, - {"flush_on_reconnect", INT_PARAM, &redis_flush_on_reconnect_param}, - {"allow_dynamic_nodes", INT_PARAM, &redis_allow_dynamic_nodes_param}, - {"debug", PARAM_INT, &ndb_redis_debug}, {0, 0, 0}}; + {"server", PARAM_STRING | USE_FUNC_PARAM, (void *)redis_srv_param}, + {"init_without_redis", INT_PARAM, &init_without_redis}, + {"connect_timeout", INT_PARAM, &redis_connect_timeout_param}, + {"cmd_timeout", INT_PARAM, &redis_cmd_timeout_param}, + {"cluster", INT_PARAM, &redis_cluster_param}, + {"disable_time", INT_PARAM, &redis_disable_time_param}, + {"allowed_timeouts", INT_PARAM, &redis_allowed_timeouts_param}, + {"flush_on_reconnect", INT_PARAM, &redis_flush_on_reconnect_param}, + {"allow_dynamic_nodes", INT_PARAM, &redis_allow_dynamic_nodes_param}, + {"debug", PARAM_INT, &ndb_redis_debug}, +#ifdef WITH_SSL + {"ca_path", PARAM_STRING, &ndb_redis_ca_path}, +#endif + {0, 0, 0} +}; struct module_exports exports = { - "ndb_redis", DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, params, 0, /* exported RPC methods */ - mod_pvs, /* exported pseudo-variables */ - 0, /* response function */ - 0, /* module initialization function */ - child_init, /* per child init function */ - mod_destroy /* destroy function */ + "ndb_redis", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* exported functions */ + params, /* exported parameters */ + 0, /* exported RPC methods */ + mod_pvs, /* exported pseudo-variables */ + 0, /* response function */ + mod_init, /* module initialization function */ + child_init, /* per child init function */ + mod_destroy /* destroy function */ }; +/* clang-format on */ +/** + * + */ +static int mod_init(void) +{ + /* + * register the need to be called post-fork of all children + * with the special rank PROC_POSTCHILDINIT by main attendant + */ + ksr_module_set_flag(KSRMOD_FLAG_POSTCHILDINIT); + return 0; +} /* each child get a new connection to the database */ static int child_init(int rank) { - /* skip child init for non-worker process ranks */ - if(rank == PROC_INIT || rank == PROC_MAIN || rank == PROC_TCP_MAIN) + /* skip child init for special process ranks */ + if(rank == PROC_INIT || rank == PROC_MAIN) return 0; if(redisc_init() < 0) { diff --git a/src/modules/ndb_redis/redis_client.c b/src/modules/ndb_redis/redis_client.c index a0865dc61..c9280991f 100644 --- a/src/modules/ndb_redis/redis_client.c +++ b/src/modules/ndb_redis/redis_client.c @@ -62,6 +62,9 @@ extern int redis_allowed_timeouts_param; extern int redis_flush_on_reconnect_param; extern int redis_allow_dynamic_nodes_param; extern int ndb_redis_debug; +#ifdef WITH_SSL +extern char *ndb_redis_ca_path; +#endif /* backwards compatibility with hiredis < 0.12 */ #if(HIREDIS_MAJOR == 0) && (HIREDIS_MINOR < 12) @@ -81,6 +84,9 @@ int redisc_init(void) char addr[256], pass[256], unix_sock_path[256], sentinel_group[256]; unsigned int port, db, sock = 0, haspass = 0, sentinel_master = 1; +#ifdef WITH_SSL + unsigned int enable_ssl = 0; +#endif int i, row; redisc_server_t *rsrv = NULL; param_t *pit = NULL; @@ -133,6 +139,14 @@ int redisc_init(void) snprintf(pass, sizeof(pass) - 1, "%.*s", pit->body.len, pit->body.s); haspass = 1; +#ifdef WITH_SSL + } else if(pit->name.len == 3 + && strncmp(pit->name.s, "tls", 3) == 0) { + snprintf(pass, sizeof(pass) - 1, "%.*s", pit->body.len, + pit->body.s); + if(str2int(&pit->body, &enable_ssl) < 0) + enable_ssl = 0; +#endif } else if(pit->name.len == 14 && strncmp(pit->name.s, "sentinel_group", 14) == 0) { snprintf(sentinel_group, sizeof(sentinel_group) - 1, "%.*s", @@ -218,16 +232,40 @@ int redisc_init(void) } } +#ifdef WITH_SSL + if(enable_ssl) { + /* Create SSL context*/ + redisInitOpenSSL(); + rsrv->sslCtxRedis = redisCreateSSLContext( + NULL, ndb_redis_ca_path, NULL, NULL, NULL, NULL); + if(rsrv->sslCtxRedis == NULL) { + LM_ERR("Unable to create Redis TLS Context.\n"); + } + } +#endif + if(sock != 0) { LOG(ndb_redis_debug, "Connecting to unix socket: %s\n", unix_sock_path); rsrv->ctxRedis = redisConnectUnixWithTimeout(unix_sock_path, tv_conn); } else { +#ifdef WITH_SSL + LOG(ndb_redis_debug, "Connecting to %s %s:%d\n", + (enable_ssl) ? "TLS" : "UDP", addr, port); +#else LOG(ndb_redis_debug, "Connecting to %s:%d\n", addr, port); +#endif rsrv->ctxRedis = redisConnectWithTimeout(addr, port, tv_conn); } +#ifdef WITH_SSL + if(enable_ssl) { + /* Negotiate SSL/TLS handshake*/ + redisInitiateSSLWithContext(rsrv->ctxRedis, rsrv->sslCtxRedis); + } +#endif + LOG(ndb_redis_debug, "rsrv->ctxRedis = %p\n", rsrv->ctxRedis); if(!rsrv->ctxRedis) { @@ -420,6 +458,9 @@ int redisc_reconnect_server(redisc_server_t *rsrv) { char addr[256], pass[256], unix_sock_path[256], sentinel_group[256]; unsigned int port, db, sock = 0, haspass = 0, sentinel_master = 1; +#ifdef WITH_SSL + unsigned int enable_ssl = 0; +#endif char sentinels[MAXIMUM_SENTINELS][256]; uint8_t sentinels_count = 0; int i, row; @@ -456,6 +497,13 @@ int redisc_reconnect_server(redisc_server_t *rsrv) snprintf( pass, sizeof(pass) - 1, "%.*s", pit->body.len, pit->body.s); haspass = 1; +#ifdef WITH_SSL + } else if(pit->name.len == 3 && strncmp(pit->name.s, "tls", 3) == 0) { + snprintf( + pass, sizeof(pass) - 1, "%.*s", pit->body.len, pit->body.s); + if(str2int(&pit->body, &enable_ssl) < 0) + enable_ssl = 0; +#endif } else if(pit->name.len == 14 && strncmp(pit->name.s, "sentinel_group", 14) == 0) { snprintf(sentinel_group, sizeof(sentinel_group) - 1, "%.*s", @@ -485,13 +533,14 @@ int redisc_reconnect_server(redisc_server_t *rsrv) for(i = 0; i < sentinels_count; i++) { char *sentinelAddr = sentinels[i]; char *pos; + int srvfound = 0; redisContext *redis; redisReply *res, *res2; port = 6379; if((pos = strchr(sentinelAddr, ':')) != NULL) { port = atoi(pos + 1); - pos[i] = '\0'; + pos[0] = '\0'; } redis = redisConnectWithTimeout(sentinelAddr, port, tv_conn); @@ -507,6 +556,7 @@ int redisc_reconnect_server(redisc_server_t *rsrv) port = atoi(res->element[1]->str); LOG(ndb_redis_debug, "sentinel replied: %s:%d\n", addr, port); + srvfound = 1; } } else { res = redisCommand( @@ -530,9 +580,13 @@ int redisc_reconnect_server(redisc_server_t *rsrv) } LOG(ndb_redis_debug, "slave for %s: %s:%d\n", sentinel_group, addr, port); + srvfound = 1; } } } + if(srvfound == 1) { + break; + } } } @@ -541,12 +595,34 @@ int redisc_reconnect_server(redisc_server_t *rsrv) redisFree(rsrv->ctxRedis); rsrv->ctxRedis = NULL; } +#ifdef WITH_SSL + if(rsrv->sslCtxRedis != NULL) { + redisFreeSSLContext(rsrv->sslCtxRedis); + rsrv->sslCtxRedis = NULL; + } + + if(enable_ssl) { + /* Create SSL context*/ + redisInitOpenSSL(); + rsrv->sslCtxRedis = redisCreateSSLContext( + NULL, ndb_redis_ca_path, NULL, NULL, NULL, NULL); + if(rsrv->sslCtxRedis == NULL) { + LM_ERR("Unable to create Redis TLS Context.\n"); + } + } +#endif if(sock != 0) { rsrv->ctxRedis = redisConnectUnixWithTimeout(unix_sock_path, tv_conn); } else { rsrv->ctxRedis = redisConnectWithTimeout(addr, port, tv_conn); } +#ifdef WITH_SSL + if(enable_ssl) { + /* Negotiate SSL/TLS handshake*/ + redisInitiateSSLWithContext(rsrv->ctxRedis, rsrv->sslCtxRedis); + } +#endif LM_DBG("rsrv->ctxRedis = %p\n", rsrv->ctxRedis); if(!rsrv->ctxRedis) goto err; diff --git a/src/modules/ndb_redis/redis_client.h b/src/modules/ndb_redis/redis_client.h index 5b1ca593e..fd13d7129 100644 --- a/src/modules/ndb_redis/redis_client.h +++ b/src/modules/ndb_redis/redis_client.h @@ -30,8 +30,14 @@ #ifdef WITH_HIREDIS_PATH #include +#ifdef WITH_SSL +#include +#endif #else #include +#ifdef WITH_SSL +#include +#endif #endif #include "../../core/str.h" @@ -76,6 +82,9 @@ typedef struct redisc_server param_t *attrs; char *spec; redisContext *ctxRedis; +#ifdef WITH_SSL + redisSSLContext *sslCtxRedis; +#endif struct redisc_server *next; redisc_piped_cmds_t piped; redisc_srv_disable_t disable; diff --git a/src/modules/osp/README b/src/modules/osp/README index 761982829..076bfbf4a 100644 --- a/src/modules/osp/README +++ b/src/modules/osp/README @@ -221,7 +221,7 @@ modparam("osp","device_ip","[1.1.1.1]") The device_port (string) parameter is an optional field which includes the SIP port being used by Kamailio in the peering request (as - SourceAlternate type=network) to the peering server. If is not + SourceAlternate type=network) to the peering server. If it is not configured, this information is not included in the peering request. This field is useful if multiple Kamailio are running on the same Linux computer since it enables the peering server to administer different @@ -393,7 +393,7 @@ modparam("osp","redirection_uri_format",1) value is "$avp(s:_osp_source_networkid_)". Then the source network ID can be set by "$avp(s:_osp_source_networkid_) = pseudo-variables". All pseudo variables are described in - http://kamailio.org/dokuwiki/doku.php/pseudovariables:1.3.x. + https://www.kamailio.org/wikidocs/cookbooks/devel/pseudovariables/. Example 1.17. Setting the source network ID AVP modparam("osp","source_networkid_avp","$avp(s:snid)") diff --git a/src/modules/osp/destination.c b/src/modules/osp/destination.c index 008221d7a..2a34875c5 100644 --- a/src/modules/osp/destination.c +++ b/src/modules/osp/destination.c @@ -239,7 +239,7 @@ osp_dest *ospGetLastOrigDestination(void) if(dest->used == 1) { if(dest->supported == 1) { lastdest = dest; - LM_DBG("curent destination '%s'\n", lastdest->host); + LM_DBG("current destination '%s'\n", lastdest->host); } } else { break; diff --git a/src/modules/osp/doc/osp_admin.xml b/src/modules/osp/doc/osp_admin.xml index dd1f77e0e..990ddf128 100644 --- a/src/modules/osp/doc/osp_admin.xml +++ b/src/modules/osp/doc/osp_admin.xml @@ -98,7 +98,7 @@ modparam("osp","device_ip","[1.1.1.1]")
<varname>device_port</varname> - The device_port (string) parameter is an optional field which includes the SIP port being used by &kamailio; in the peering request (as SourceAlternate type=network) to the peering server. If is not configured, this information is not included in the peering request. This field is useful if multiple &kamailio; are running on the same Linux computer since it enables the peering server to administer different peering policies based on different SIP proxies. This parameter has not been implemented yet. + The device_port (string) parameter is an optional field which includes the SIP port being used by &kamailio; in the peering request (as SourceAlternate type=network) to the peering server. If it is not configured, this information is not included in the peering request. This field is useful if multiple &kamailio; are running on the same Linux computer since it enables the peering server to administer different peering policies based on different SIP proxies. This parameter has not been implemented yet. Setting the device port @@ -234,7 +234,7 @@ modparam("osp","redirection_uri_format",1)
<varname>source_networkid_avp</varname> - The source_networkid_avp (string) parameter instructs the OSP module to use the defined AVP to pass the source network ID value. The default value is "$avp(s:_osp_source_networkid_)". Then the source network ID can be set by "$avp(s:_osp_source_networkid_) = pseudo-variables". All pseudo variables are described in http://kamailio.org/dokuwiki/doku.php/pseudovariables:1.3.x. + The source_networkid_avp (string) parameter instructs the OSP module to use the defined AVP to pass the source network ID value. The default value is "$avp(s:_osp_source_networkid_)". Then the source network ID can be set by "$avp(s:_osp_source_networkid_) = pseudo-variables". All pseudo variables are described in https://www.kamailio.org/wikidocs/cookbooks/devel/pseudovariables/. Setting the source network ID AVP diff --git a/src/modules/osp/orig_transaction.c b/src/modules/osp/orig_transaction.c index 10126770d..4220483ea 100644 --- a/src/modules/osp/orig_transaction.c +++ b/src/modules/osp/orig_transaction.c @@ -410,7 +410,7 @@ int ospCheckTranslation(struct sip_msg *msg, char *ignore1, char *ignore2) if(search_first_avp(AVP_NAME_STR, (int_str)OSP_CALLING_NAME, &callingval, 0) != NULL) { if(callingval.n == 0) { - LM_DBG("the calling number does not been translated\n"); + LM_DBG("the calling number has not been translated\n"); } else { LM_DBG("the calling number is translated\n"); result = MODULE_RETURNCODE_TRUE; diff --git a/src/modules/osp/osp_mod.c b/src/modules/osp/osp_mod.c index 61a8f026f..1c5f5d905 100644 --- a/src/modules/osp/osp_mod.c +++ b/src/modules/osp/osp_mod.c @@ -202,7 +202,7 @@ static int ospInitMod(void) } /* - * Destrroy OSP module + * Destroy OSP module */ static void ospDestMod(void) { diff --git a/src/modules/osp/osptoolkit.h b/src/modules/osp/osptoolkit.h index 3ed1b2d1d..7862421fb 100644 --- a/src/modules/osp/osptoolkit.h +++ b/src/modules/osp/osptoolkit.h @@ -35,7 +35,7 @@ /* * This module implements help functions for the OSP toolkit. - * Some of the functions maybe impemented by the toolkit in the future. + * Some of the functions may be implemented by the toolkit in the future. */ /* diff --git a/src/modules/outbound/outbound_mod.c b/src/modules/outbound/outbound_mod.c index e2e3a86a7..e5ed17126 100644 --- a/src/modules/outbound/outbound_mod.c +++ b/src/modules/outbound/outbound_mod.c @@ -40,6 +40,10 @@ #include "../../core/parser/parse_uri.h" #include "../../core/parser/parse_supported.h" +#define KSR_RTHREAD_SKIP_P +#define KSR_RTHREAD_NEED_V +#include "../../core/rthreads.h" + #include "api.h" #include "config.h" @@ -75,26 +79,25 @@ struct module_exports exports = { destroy /* destroy function */ }; -static void *mod_init_openssl(void *arg) { - if(flow_token_secret.s) { - assert(ob_key.len == SHA_DIGEST_LENGTH); - LM_DBG("flow_token_secret mod param set. use persistent ob_key"); +static void mod_init_openssl(void) +{ + if(flow_token_secret.s) { + assert(ob_key.len == SHA_DIGEST_LENGTH); + LM_DBG("flow_token_secret mod param set. use persistent ob_key"); #if OPENSSL_VERSION_NUMBER < 0x030000000L - SHA1((const unsigned char *)flow_token_secret.s, flow_token_secret.len, - (unsigned char *)ob_key.s); + SHA1((const unsigned char *)flow_token_secret.s, flow_token_secret.len, + (unsigned char *)ob_key.s); #else - EVP_Q_digest(NULL, "SHA1", NULL, flow_token_secret.s, - flow_token_secret.len, (unsigned char *)ob_key.s, NULL); + EVP_Q_digest(NULL, "SHA1", NULL, flow_token_secret.s, + flow_token_secret.len, (unsigned char *)ob_key.s, NULL); #endif - } else { - if(RAND_bytes((unsigned char *)ob_key.s, ob_key.len) == 0) { - LM_ERR("unable to get %d cryptographically strong pseudo-" - "random bytes\n", - ob_key.len); - } - } - - return NULL; + } else { + if(RAND_bytes((unsigned char *)ob_key.s, ob_key.len) == 0) { + LM_ERR("unable to get %d cryptographically strong pseudo-" + "random bytes\n", + ob_key.len); + } + } } static int mod_init(void) @@ -116,12 +119,9 @@ static int mod_init(void) ob_key.len = OB_KEY_LEN; #if OPENSSL_VERSION_NUMBER < 0x010101000L - mod_init_openssl(NULL); + mod_init_openssl(); #else - pthread_t tid; - void *retval; - pthread_create(&tid, NULL, mod_init_openssl, NULL); - pthread_join(tid, &retval); + run_threadV(mod_init_openssl); #endif if(cfg_declare("outbound", outbound_cfg_def, &default_outbound_cfg, diff --git a/src/modules/p_usrloc/README b/src/modules/p_usrloc/README index 351aedd76..ae0702db5 100644 --- a/src/modules/p_usrloc/README +++ b/src/modules/p_usrloc/README @@ -54,6 +54,7 @@ Patric Marschall 3.27. default_db_url(str) 3.28. matching_mode(int) 3.29. UTC_timestamps(int) + 3.30. use_domain_crc32(str) 4. Changes from usrloc module @@ -126,8 +127,9 @@ Patric Marschall 1.27. Set default_db_type parameter 1.28. Set matching_mode parameter 1.29. Set UTC_timestamps parameter - 1.30. Set db_mode parameter - 1.31. Example database content - reg_table (locdb) table + 1.30. Set use_domain_crc32 parameter + 1.31. Set db_mode parameter + 1.32. Example database content - reg_table (locdb) table Chapter 1. User's Guide @@ -170,6 +172,7 @@ Chapter 1. User's Guide 3.27. default_db_url(str) 3.28. matching_mode(int) 3.29. UTC_timestamps(int) + 3.30. use_domain_crc32(str) 4. Changes from usrloc module @@ -289,6 +292,7 @@ Warning 3.27. default_db_url(str) 3.28. matching_mode(int) 3.29. UTC_timestamps(int) + 3.30. use_domain_crc32(str) 3.1. write_db_url (string) @@ -696,6 +700,18 @@ kamcmd cfg.get p_usrloc matching_mode modparam("p_usrloc", "UTC_timestamps", 1) ... +3.30. use_domain_crc32(str) + + Enables or disables the crc32 of domain part for user@domain. If + disabled, will calculate crc32 only for user part. + + Default value is “1” (enabled). + + Example 1.30. Set use_domain_crc32 parameter +... +modparam("p_usrloc", "use_domain_crc32", "0") +... + 4. Changes from usrloc module 4.1. db_mode (integer) @@ -718,7 +734,7 @@ modparam("p_usrloc", "UTC_timestamps", 1) Default value is 3. - Example 1.30. Set db_mode parameter + Example 1.31. Set db_mode parameter ... modparam("p_usrloc", "db_mode", 2) ... @@ -752,7 +768,7 @@ modparam("p_usrloc", "db_mode", 2) complete database documentation on the project webpage, https://www.kamailio.org/docs/db-tables/kamailio-db-devel.html. - Example 1.31. Example database content - reg_table (locdb) table + Example 1.32. Example database content - reg_table (locdb) table ... +----+----+------+--------+--------+---------------------+-------+----+ | id | no | url | status | errors | failover | spare | rg | diff --git a/src/modules/p_usrloc/dlist.c b/src/modules/p_usrloc/dlist.c index fa66b20b9..0a7080e2c 100644 --- a/src/modules/p_usrloc/dlist.c +++ b/src/modules/p_usrloc/dlist.c @@ -171,3 +171,42 @@ int synchronize_all_udomains(void) LM_INFO("not available with partitioned interface\n"); return res; } + +/*! + * \brief Registers a new domain with usrloc + * + * Find and return a usrloc domain (location table) + * \param _n domain name + * \param _d usrloc domain + * \return 0 on success, -1 on failure + */ +int get_udomain(const char *_n, udomain_t **_d) +{ + struct domain_list_item *item; + str s; + + if(_n == NULL) { + LM_ERR("null location table name\n"); + goto notfound; + } + + s.s = (char *)_n; + s.len = strlen(_n); + if(s.len <= 0) { + LM_ERR("empty location table name\n"); + goto notfound; + } + + item = find_dlist(&s); + if(item == NULL) { + LM_ERR("domain %s not found.\n", _n); + goto notfound; + } + + *_d = &item->domain; + return 0; + +notfound: + *_d = NULL; + return -1; +} diff --git a/src/modules/p_usrloc/dlist.h b/src/modules/p_usrloc/dlist.h index 20152694f..662847fb1 100644 --- a/src/modules/p_usrloc/dlist.h +++ b/src/modules/p_usrloc/dlist.h @@ -118,5 +118,13 @@ int get_all_ucontacts(void *, int, unsigned int, unsigned int part_idx, */ int find_domain(str *_d, udomain_t **_p); +/*! + * \brief Find and return usrloc domain + * + * \param _n domain name + * \param _d usrloc domain (location table) + * \return 0 on success, -1 on failure + */ +int get_udomain(const char *_n, udomain_t **_d); #endif diff --git a/src/modules/p_usrloc/doc/p_usrloc_admin.xml b/src/modules/p_usrloc/doc/p_usrloc_admin.xml index 983229df3..0c59d9e6d 100644 --- a/src/modules/p_usrloc/doc/p_usrloc_admin.xml +++ b/src/modules/p_usrloc/doc/p_usrloc_admin.xml @@ -779,6 +779,27 @@ modparam("p_usrloc", "UTC_timestamps", 1)
+
+ <varname>use_domain_crc32</varname>(str) + + Enables or disables the crc32 of domain part for user@domain. + If disabled, will calculate crc32 only for user part. + + + + Default value is 1 (enabled). + + + + Set <varname>use_domain_crc32</varname> parameter + +... +modparam("p_usrloc", "use_domain_crc32", "0") +... + + +
+
diff --git a/src/modules/p_usrloc/p_usrloc_mod.c b/src/modules/p_usrloc/p_usrloc_mod.c index ccbe07e5f..539ad31b0 100644 --- a/src/modules/p_usrloc/p_usrloc_mod.c +++ b/src/modules/p_usrloc/p_usrloc_mod.c @@ -88,6 +88,11 @@ static int child_init(int rank); /*!< Per-child init function */ extern int bind_usrloc(usrloc_api_t *api); extern int ul_locks_no; +#define UL_PRELOAD_SIZE 8 +static char *ul_preload_list[UL_PRELOAD_SIZE]; +static int ul_preload_index = 0; +static int ul_preload_param(modparam_t type, void *val); + /* * Module parameters and their default values */ @@ -161,7 +166,9 @@ str uniq_col = str_init(UNIQ_COL); /*!< Name of column containing the uniq value*/ int db_mode = 3; /*!< Database sync scheme: 1-write through, 2-write back, 3-only db */ -int use_domain = 0; /*!< Whether usrloc should use domain part of aor */ +int use_domain = 0; /*!< Whether usrloc should use domain part of aor */ +int use_domain_crc32 = + 1; /*!< Whether usrloc should use domain part of aor when calculating crc32 */ int desc_time_order = 0; /*!< By default do not enable timestamp ordering */ int ul_fetch_rows = 2000; /*!< number of rows to fetch from result */ @@ -225,6 +232,7 @@ static param_export_t params[] = {{"ruid_column", PARAM_STR, &ruid_col}, {"cflags_column", PARAM_STR, &cflags_col}, {"db_mode", INT_PARAM, &db_mode}, {"use_domain", INT_PARAM, &use_domain}, + {"use_domain_crc32", INT_PARAM, &use_domain_crc32}, {"desc_time_order", INT_PARAM, &desc_time_order}, {"user_agent_column", PARAM_STR, &user_agent_col}, {"received_column", PARAM_STR, &received_col}, @@ -266,6 +274,7 @@ static param_export_t params[] = {{"ruid_column", PARAM_STR, &ruid_col}, {"db_update_as_insert", INT_PARAM, &default_p_usrloc_cfg.db_update_as_insert}, {"mdb_availability_control", INT_PARAM, &mdb_availability_control}, + {"preload", PARAM_STRING | USE_FUNC_PARAM, (void *)ul_preload_param}, {0, 0, 0}}; @@ -307,6 +316,8 @@ struct module_exports exports = { */ static int mod_init(void) { + int i = 0; + udomain_t *d; int matching_mode_cfg = cfg_get(p_usrloc, p_usrloc_cfg, matching_mode); #ifdef STATISTICS @@ -349,6 +360,14 @@ static int mod_init(void) return -1; } + /* preload tables */ + for(i = 0; i < ul_preload_index; i++) { + if(register_udomain((const char *)ul_preload_list[i], &d) < 0) { + LM_ERR("cannot register preloaded table %s\n", ul_preload_list[i]); + return -1; + } + } + if(db_mode != DB_ONLY) { LM_ERR("DB_ONLY is the only mode possible for partitioned usrloc. " "Please set db_mode to 3\n"); @@ -510,3 +529,23 @@ time_t ul_db_datetime_get(time_t v) return v; } } + +/*! \brief + * preload module parameter handler + */ +static int ul_preload_param(modparam_t type, void *val) +{ + if(val == NULL) { + LM_ERR("invalid parameter\n"); + goto error; + } + if(ul_preload_index >= UL_PRELOAD_SIZE) { + LM_ERR("too many preloaded tables\n"); + goto error; + } + ul_preload_list[ul_preload_index] = (char *)val; + ul_preload_index++; + return 0; +error: + return -1; +} diff --git a/src/modules/p_usrloc/p_usrloc_mod.h b/src/modules/p_usrloc/p_usrloc_mod.h index b2ff0fb86..fb85603d2 100644 --- a/src/modules/p_usrloc/p_usrloc_mod.h +++ b/src/modules/p_usrloc/p_usrloc_mod.h @@ -88,6 +88,7 @@ extern str uniq_col; extern int db_mode; extern int use_domain; +extern int use_domain_crc32; extern int desc_time_order; extern int cseq_delay; extern int ul_fetch_rows; diff --git a/src/modules/p_usrloc/udomain.c b/src/modules/p_usrloc/udomain.c index 2c00f3954..68182a22a 100644 --- a/src/modules/p_usrloc/udomain.c +++ b/src/modules/p_usrloc/udomain.c @@ -215,7 +215,7 @@ void print_udomain(FILE *_f, udomain_t *_d) * \brief Convert database values into ucontact_info * * Convert database values into ucontact_info, - * expects 12 rows (contact, expirs, q, callid, cseq, flags, + * expects 12 rows (contact, expires, q, callid, cseq, flags, * ua, received, path, socket, methods, last_modified) * \param vals database values * \param contact contact diff --git a/src/modules/p_usrloc/ul_db.c b/src/modules/p_usrloc/ul_db.c index f0ce33726..6d0897749 100644 --- a/src/modules/p_usrloc/ul_db.c +++ b/src/modules/p_usrloc/ul_db.c @@ -35,7 +35,7 @@ ul_db_handle_t dbh_tmp; -ul_master_db_set_t mdb; +ul_master_db_set_t _pusrl_mdb; int required_caps = DB_CAP_QUERY | DB_CAP_RAW_QUERY | DB_CAP_INSERT | DB_CAP_DELETE | DB_CAP_UPDATE | DB_CAP_INSERT_UPDATE; @@ -58,28 +58,28 @@ static db_func_t *get_and_remove_dbf(db1_res_t *res); int ul_db_init(void) { - mdb.read.url = &read_db_url; - mdb.write.url = &write_db_url; + _pusrl_mdb.read.url = &read_db_url; + _pusrl_mdb.write.url = &write_db_url; memset(results, 0, sizeof(results)); if(db_master_write) { - if(db_bind_mod(mdb.write.url, &mdb.write.dbf) < 0) { + if(db_bind_mod(_pusrl_mdb.write.url, &_pusrl_mdb.write.dbf) < 0) { LM_ERR("could not bind api for write db.\n"); return -1; } - if(!(mdb.write.dbf.cap & required_caps)) { + if(!(_pusrl_mdb.write.dbf.cap & required_caps)) { LM_ERR("db api of write db doesn't support required operation.\n"); return -1; } LM_INFO("write db initialized\n"); } - if(db_bind_mod(mdb.read.url, &mdb.read.dbf) < 0) { + if(db_bind_mod(_pusrl_mdb.read.url, &_pusrl_mdb.read.dbf) < 0) { LM_ERR("could not bind db api for read db.\n"); return -1; } - if(!(mdb.read.dbf.cap & required_caps)) { + if(!(_pusrl_mdb.read.dbf.cap & required_caps)) { LM_ERR("db api of read db doesn't support required operation.\n"); return -1; } @@ -89,15 +89,16 @@ int ul_db_init(void) int ul_db_child_init(void) { - if(mdb.read.dbh) { - mdb.read.dbf.close(mdb.read.dbh); - mdb.read.dbh = NULL; + if(_pusrl_mdb.read.dbh) { + _pusrl_mdb.read.dbf.close(_pusrl_mdb.read.dbh); + _pusrl_mdb.read.dbh = NULL; } - if(mdb.write.dbh) { - mdb.write.dbf.close(mdb.write.dbh); - mdb.write.dbh = NULL; + if(_pusrl_mdb.write.dbh) { + _pusrl_mdb.write.dbf.close(_pusrl_mdb.write.dbh); + _pusrl_mdb.write.dbh = NULL; } - if((mdb.read.dbh = mdb.read.dbf.init(mdb.read.url)) == NULL) { + if((_pusrl_mdb.read.dbh = _pusrl_mdb.read.dbf.init(_pusrl_mdb.read.url)) + == NULL) { LM_ERR("could not connect to sip master db (read).\n"); return -1; } @@ -108,7 +109,9 @@ int ul_db_child_init(void) LM_INFO("location number is %d\n", max_loc_nr); if(db_master_write) { - if((mdb.write.dbh = mdb.write.dbf.init(mdb.write.url)) == NULL) { + if((_pusrl_mdb.write.dbh = + _pusrl_mdb.write.dbf.init(_pusrl_mdb.write.url)) + == NULL) { if(mdb_availability_control) { LM_INFO("starting with no connection to sip master db write\n"); return 0; @@ -124,11 +127,13 @@ int ul_db_child_init(void) int ul_db_child_locnr_init(void) { - if(!mdb.read.dbh) { + if(!_pusrl_mdb.read.dbh) { LM_ERR("Sip master DB connection(read) is down\n"); return -1; } - if(load_location_number(&mdb.read.dbf, mdb.read.dbh, &max_loc_nr) != 0) { + if(load_location_number( + &_pusrl_mdb.read.dbf, _pusrl_mdb.read.dbh, &max_loc_nr) + != 0) { LM_ERR("could not load location number\n"); return -1; } @@ -138,11 +143,11 @@ int ul_db_child_locnr_init(void) void ul_db_shutdown(void) { destroy_handles(); - if(mdb.read.dbh) { - mdb.read.dbf.close(mdb.read.dbh); + if(_pusrl_mdb.read.dbh) { + _pusrl_mdb.read.dbf.close(_pusrl_mdb.read.dbh); } - if(mdb.write.dbh) { - mdb.write.dbf.close(mdb.write.dbh); + if(_pusrl_mdb.write.dbh) { + _pusrl_mdb.write.dbf.close(_pusrl_mdb.write.dbh); } return; } @@ -209,10 +214,10 @@ int db_handle_error(ul_db_handle_t *handle, int no) tmp.s = query; tmp.len = strlen(query); - if(init_w_dbh(&mdb.write) < 0) + if(init_w_dbh(&_pusrl_mdb.write) < 0) return -1; - if(mdb.write.dbf.raw_query(mdb.write.dbh, &tmp, NULL)) { + if(_pusrl_mdb.write.dbf.raw_query(_pusrl_mdb.write.dbh, &tmp, NULL)) { LM_ERR("error in database update.\n"); return -1; } @@ -225,7 +230,9 @@ int db_handle_error(ul_db_handle_t *handle, int no) } } - if(load_data(&mdb.read.dbf, mdb.read.dbh, &dbh_tmp, handle->id) < 0) { + if(load_data( + &_pusrl_mdb.read.dbf, _pusrl_mdb.read.dbh, &dbh_tmp, handle->id) + < 0) { LM_ERR("could not load id %i\n", handle->id); return -1; } @@ -236,13 +243,17 @@ int db_handle_error(ul_db_handle_t *handle, int no) cfg_get(p_usrloc, p_usrloc_cfg, db_err_threshold)); if(db->errors >= cfg_get(p_usrloc, p_usrloc_cfg, db_err_threshold)) { LM_DBG("db_handle_error: now doing failover\n"); - if(init_w_dbh(&mdb.write) < 0) + if(init_w_dbh(&_pusrl_mdb.write) < 0) return -1; - if((db_failover(&mdb.write.dbf, mdb.write.dbh, handle, no)) < 0) { + if((db_failover( + &_pusrl_mdb.write.dbf, _pusrl_mdb.write.dbh, handle, no)) + < 0) { LM_ERR("error in doing failover.\n"); return -1; } - if(load_data(&mdb.read.dbf, mdb.read.dbh, &dbh_tmp, handle->id) < 0) { + if(load_data(&_pusrl_mdb.read.dbf, _pusrl_mdb.read.dbh, &dbh_tmp, + handle->id) + < 0) { return -1; } refresh_handle(handle, &dbh_tmp, 0); @@ -347,7 +358,8 @@ int ul_db_insert( LM_ERR("not allowed in read only mode, abort.\n"); return -1; } - if((handle = get_handle(&mdb.read.dbf, mdb.read.dbh, first, second)) + if((handle = get_handle( + &_pusrl_mdb.read.dbf, _pusrl_mdb.read.dbh, first, second)) == NULL) { LM_ERR("could not retrieve db handle.\n"); return -1; @@ -363,7 +375,8 @@ int ul_db_replace(str *table, str *first, str *second, db_key_t *_k, LM_ERR("not allowed in read only mode, abort.\n"); return -1; } - if((handle = get_handle(&mdb.read.dbf, mdb.read.dbh, first, second)) + if((handle = get_handle( + &_pusrl_mdb.read.dbf, _pusrl_mdb.read.dbh, first, second)) == NULL) { LM_ERR("could not retrieve db handle.\n"); return -1; @@ -380,7 +393,8 @@ int ul_db_update(str *table, str *first, str *second, db_key_t *_k, LM_ERR("not allowed in read only mode, abort.\n"); return -1; } - if((handle = get_handle(&mdb.read.dbf, mdb.read.dbh, first, second)) + if((handle = get_handle( + &_pusrl_mdb.read.dbf, _pusrl_mdb.read.dbh, first, second)) == NULL) { LM_ERR("could not retrieve db handle.\n"); return -1; @@ -396,7 +410,8 @@ int ul_db_insert_update( LM_ERR("not allowed in read only mode, abort.\n"); return -1; } - if((handle = get_handle(&mdb.read.dbf, mdb.read.dbh, first, second)) + if((handle = get_handle( + &_pusrl_mdb.read.dbf, _pusrl_mdb.read.dbh, first, second)) == NULL) { LM_ERR("could not retrieve db handle.\n"); return -1; @@ -412,7 +427,8 @@ int ul_db_delete(str *table, str *first, str *second, db_key_t *_k, db_op_t *_o, LM_ERR("not allowed in read only mode, abort.\n"); return -1; } - if((handle = get_handle(&mdb.read.dbf, mdb.read.dbh, first, second)) + if((handle = get_handle( + &_pusrl_mdb.read.dbf, _pusrl_mdb.read.dbh, first, second)) == NULL) { LM_ERR("could not retrieve db handle.\n"); return -1; @@ -427,7 +443,8 @@ int ul_db_query(str *table, str *first, str *second, db1_con_t ***_r_h, ul_db_handle_t *handle; db_func_t *f; int ret; - if((handle = get_handle(&mdb.read.dbf, mdb.read.dbh, first, second)) + if((handle = get_handle( + &_pusrl_mdb.read.dbf, _pusrl_mdb.read.dbh, first, second)) == NULL) { LM_ERR("could not retrieve db handle.\n"); return -1; @@ -460,9 +477,10 @@ int db_reactivate(ul_db_handle_t *handle, int no) LM_ERR("running in read only mode, abort.\n"); return -1; } - if(init_w_dbh(&mdb.write) < 0) + if(init_w_dbh(&_pusrl_mdb.write) < 0) return -1; - return db_failover_reactivate(&mdb.write.dbf, mdb.write.dbh, handle, no); + return db_failover_reactivate( + &_pusrl_mdb.write.dbf, _pusrl_mdb.write.dbh, handle, no); } int db_reset_failover_time(ul_db_handle_t *handle, int no) @@ -471,17 +489,19 @@ int db_reset_failover_time(ul_db_handle_t *handle, int no) LM_ERR("running in read only mode, abort.\n"); return -1; } - if(init_w_dbh(&mdb.write) < 0) + if(init_w_dbh(&_pusrl_mdb.write) < 0) return -1; - return db_failover_reset(&mdb.write.dbf, mdb.write.dbh, handle->id, no); + return db_failover_reset( + &_pusrl_mdb.write.dbf, _pusrl_mdb.write.dbh, handle->id, no); } int ul_db_check(ul_db_handle_t *handle) { if(db_master_write) { - if(init_w_dbh(&mdb.write) < 0) + if(init_w_dbh(&_pusrl_mdb.write) < 0) return -1; - return check_handle(&mdb.write.dbf, mdb.write.dbh, handle); + return check_handle( + &_pusrl_mdb.write.dbf, _pusrl_mdb.write.dbh, handle); } else { LM_ERR("checking is useless in read-only mode\n"); return 0; diff --git a/src/modules/p_usrloc/ul_db.h b/src/modules/p_usrloc/ul_db.h index 080e144c0..16c1be248 100644 --- a/src/modules/p_usrloc/ul_db.h +++ b/src/modules/p_usrloc/ul_db.h @@ -58,7 +58,7 @@ typedef struct ul_master_db_set } ul_master_db_set_t; extern int required_caps; -extern ul_master_db_set_t mdb; +extern ul_master_db_set_t _pusrl_mdb; int ul_db_init(); diff --git a/src/modules/p_usrloc/ul_db_handle.c b/src/modules/p_usrloc/ul_db_handle.c index d3f607349..df5793c8f 100644 --- a/src/modules/p_usrloc/ul_db_handle.c +++ b/src/modules/p_usrloc/ul_db_handle.c @@ -28,7 +28,7 @@ static ul_db_handle_list_t *db_handles = NULL; -static ul_db_handle_t tmp; +static ul_db_handle_t _pusrl_db_tmp; static ul_db_handle_t *allocate_handle(void); @@ -76,7 +76,7 @@ ul_db_handle_t *get_handle( */ } - if(load_data(dbf, dbh, &tmp, id) < 0) { + if(load_data(dbf, dbh, &_pusrl_db_tmp, id) < 0) { // load_data should explain this return NULL; } @@ -84,10 +84,10 @@ ul_db_handle_t *get_handle( element = db_handles; db_ok = 0; while(element && element->handle) { - if(element->handle->id == tmp.id) { + if(element->handle->id == _pusrl_db_tmp.id) { LM_DBG("found handle with id %i\n", element->handle->id); element->handle->expires = time(NULL) + connection_expires; - if(check_status(element->handle, &tmp) == 0) { + if(check_status(element->handle, &_pusrl_db_tmp) == 0) { db_ok = 1; } ret = element->handle; @@ -104,18 +104,18 @@ ul_db_handle_t *get_handle( element = NULL; if(ret == NULL) { - LM_DBG("didn't find handle with id %i\n", tmp.id); + LM_DBG("didn't find handle with id %i\n", _pusrl_db_tmp.id); if((element = allocate_handle_list()) == NULL) { LM_ERR("could not allocate handle.\n"); return NULL; } ret = element->handle; - ret->id = tmp.id; + ret->id = _pusrl_db_tmp.id; activate_handle(ret); element->next = db_handles; db_handles = element; } - if(refresh_handle(ret, &tmp, db_write) < 0) { + if(refresh_handle(ret, &_pusrl_db_tmp, db_write) < 0) { ret = NULL; } ret: @@ -266,7 +266,7 @@ int load_location_number(db_func_t *dbf, db1_con_t *dbh, int *loc_nr) db1_res_t *res; db_row_t *row; int query_len; - str tmp; + str stmp; if(!loc_nr || !dbf || !dbh) { LM_ERR("NULL parameter passed \n"); @@ -294,10 +294,10 @@ int load_location_number(db_func_t *dbf, db1_con_t *dbh, int *loc_nr) } LM_DBG("%s\n", query); - tmp.s = query; - tmp.len = strlen(query); + stmp.s = query; + stmp.len = strlen(query); - if(dbf->raw_query(dbh, &tmp, &res) < 0) { + if(dbf->raw_query(dbh, &stmp, &res) < 0) { LM_ERR("in database query.\n"); return -1; } @@ -337,11 +337,11 @@ int refresh_handles(db_func_t *dbf, db1_con_t *dbh) element->handle->db[i].dbh = NULL; } } - if(load_data(dbf, dbh, &tmp, element->handle->id) < 0) { + if(load_data(dbf, dbh, &_pusrl_db_tmp, element->handle->id) < 0) { LM_ERR("couldn't load handle data.\n"); return -1; } - if(refresh_handle(element->handle, &tmp, db_write) < 0) { + if(refresh_handle(element->handle, &_pusrl_db_tmp, db_write) < 0) { LM_ERR("couldn't refresh handle data.\n"); return -1; } @@ -384,10 +384,10 @@ int check_handle(db_func_t *dbf, db1_con_t *dbh, ul_db_handle_t *handle) int i; str tmpurl; LM_INFO("checking id %i\n", handle->id); - if(load_data(dbf, dbh, &tmp, handle->id) < 0) { + if(load_data(dbf, dbh, &_pusrl_db_tmp, handle->id) < 0) { return -1; } - refresh_handle(handle, &tmp, 1); + refresh_handle(handle, &_pusrl_db_tmp, 1); for(i = 0; i < DB_NUM; i++) { if(handle->db[i].url.len > 0) { LM_INFO("checking id %i no %i, url %.*s, status %s\n", handle->id, @@ -503,13 +503,13 @@ static int compute_id(str *first, str *second) unsigned int crc32_val; #define BUF_MAXSIZE 1024 char aux[BUF_MAXSIZE]; - str tmp; + str stmp; if(!first) { LM_ERR("Null first parameter received\n"); return -1; } - if(use_domain) { + if(use_domain && use_domain_crc32) { //compute crc32(user@domain) LM_DBG("XDBGX: compute_id HAS second key : %.*s", first->len, first->s); if(!second) { @@ -518,17 +518,17 @@ static int compute_id(str *first, str *second) return -1; } - tmp.len = first->len + second->len + 1; - if(tmp.len > BUF_MAXSIZE - 1) { + stmp.len = first->len + second->len + 1; + if(stmp.len > BUF_MAXSIZE - 1) { LM_ERR("Very long user or domain\n"); return -1; } memcpy(aux, first->s, first->len); aux[first->len] = '@'; memcpy(aux + first->len + 1, second->s, second->len); - tmp.s = aux; + stmp.s = aux; - crc32_uint(&tmp, &crc32_val); + crc32_uint(&stmp, &crc32_val); return crc32_val % max_loc_nr + 1; } else { crc32_uint(first, &crc32_val); diff --git a/src/modules/p_usrloc/ul_db_watch.c b/src/modules/p_usrloc/ul_db_watch.c index 141c79d45..0b468493a 100644 --- a/src/modules/p_usrloc/ul_db_watch.c +++ b/src/modules/p_usrloc/ul_db_watch.c @@ -163,12 +163,13 @@ void check_dbs(unsigned int ticks, void *param) void check_master_db() { - if(mdb.write.dbh) { - mdb.write.dbf.close(mdb.write.dbh); - mdb.write.dbh = NULL; + if(_pusrl_mdb.write.dbh) { + _pusrl_mdb.write.dbf.close(_pusrl_mdb.write.dbh); + _pusrl_mdb.write.dbh = NULL; } - if((mdb.write.dbh = mdb.write.dbf.init(mdb.write.url)) == NULL) { + if((_pusrl_mdb.write.dbh = _pusrl_mdb.write.dbf.init(_pusrl_mdb.write.url)) + == NULL) { LM_INFO("Master db is unavailable.\n"); *mdb_w_available = 0; } else { diff --git a/src/modules/p_usrloc/usrloc.c b/src/modules/p_usrloc/usrloc.c index 6de32f2ee..221f2d682 100644 --- a/src/modules/p_usrloc/usrloc.c +++ b/src/modules/p_usrloc/usrloc.c @@ -79,5 +79,6 @@ int bind_usrloc(usrloc_api_t *api) api->db_mode = db_mode; api->nat_flag = nat_bflag; + api->get_udomain = get_udomain; return 0; } diff --git a/src/modules/path/path.c b/src/modules/path/path.c index 23309c33f..8fde99126 100644 --- a/src/modules/path/path.c +++ b/src/modules/path/path.c @@ -105,7 +105,8 @@ static int prepend_path( sip_msg_t *_m, str *user, path_param_t param, str *add_params) { struct lump *l; - char *prefix, *suffix, *cp, *dp; + char *prefix, *suffix, *dp; + str cp = STR_NULL; const char *proto_str; int prefix_len, suffix_len; struct hdr_field *hf; @@ -115,13 +116,13 @@ static int prepend_path( + IP_ADDR_MAX_STR_SIZE + 2 + (add_params ? add_params->len : 0) + path_received_name.len + 1; - cp = suffix = pkg_malloc(suffix_len); + cp.s = suffix = pkg_malloc(suffix_len); if(!suffix) { PKG_MEM_ERROR_FMT("for suffix\n"); goto out1; } - cp += sprintf(cp, ";lr"); + cp.len = sprintf(cp.s, ";lr"); if(param & PATH_PARAM_RECEIVED) { if(path_received_format == 0) { @@ -132,21 +133,25 @@ static int prepend_path( proto_str = NULL; } if(_m->rcv.src_ip.af == AF_INET6) { - cp += sprintf(cp, ";%s=sip:[%s]:%hu%s", path_received_name.s, + cp.len += snprintf(cp.s + cp.len, suffix_len - cp.len, + ";%s=sip:[%s]:%hu%s", path_received_name.s, ip_addr2a(&_m->rcv.src_ip), _m->rcv.src_port, proto_str ?: ""); } else { - cp += sprintf(cp, ";%s=sip:%s:%hu%s", path_received_name.s, + cp.len += snprintf(cp.s + cp.len, suffix_len - cp.len, + ";%s=sip:%s:%hu%s", path_received_name.s, ip_addr2a(&_m->rcv.src_ip), _m->rcv.src_port, proto_str ?: ""); } } else { if(_m->rcv.src_ip.af == AF_INET6) { - cp += sprintf(cp, ";%s=[%s]~%hu~%d", path_received_name.s, + cp.len += snprintf(cp.s + cp.len, suffix_len - cp.len, + ";%s=[%s]~%hu~%d", path_received_name.s, ip_addr2a(&_m->rcv.src_ip), _m->rcv.src_port, (int)_m->rcv.proto); } else { - cp += sprintf(cp, ";%s=%s~%hu~%d", path_received_name.s, + cp.len += snprintf(cp.s + cp.len, suffix_len - cp.len, + ";%s=%s~%hu~%d", path_received_name.s, ip_addr2a(&_m->rcv.src_ip), _m->rcv.src_port, (int)_m->rcv.proto); } @@ -154,17 +159,18 @@ static int prepend_path( } if(param & PATH_PARAM_OB) { - cp += sprintf(cp, ";ob"); + cp.len += sprintf(cp.s + cp.len, ";ob"); } if(add_params && add_params->len) { - cp += sprintf(cp, ";%.*s", add_params->len, add_params->s); + cp.len += snprintf(cp.s + cp.len, suffix_len - cp.len, ";%.*s", + add_params->len, add_params->s); } if(path_enable_r2 == 0) { - cp += sprintf(cp, ">\r\n"); + cp.len += sprintf(cp.s + cp.len, ">\r\n"); } else { - cp += sprintf(cp, ";r2=on>\r\n"); + cp.len += sprintf(cp.s + cp.len, ";r2=on>\r\n"); } prefix_len = PATH_PREFIX_LEN + (user ? user->len : 0) + 2; @@ -174,9 +180,10 @@ static int prepend_path( goto out2; } if(user && user->len) - prefix_len = sprintf(prefix, PATH_PREFIX "%.*s@", user->len, user->s); + prefix_len = snprintf( + prefix, prefix_len, PATH_PREFIX "%.*s@", user->len, user->s); else - prefix_len = sprintf(prefix, PATH_PREFIX); + prefix_len = snprintf(prefix, prefix_len, PATH_PREFIX); if(parse_headers(_m, HDR_PATH_F, 0) < 0) { LM_ERR("failed to parse message for Path header\n"); @@ -201,7 +208,7 @@ static int prepend_path( l, (path_sockname_mode) ? SUBST_SND_ALL_EX : SUBST_SND_ALL, 0); if(!l) goto out2; - l = insert_new_lump_before(l, suffix, cp - suffix, 0); + l = insert_new_lump_before(l, suffix, cp.len, 0); if(!l) goto out2; @@ -216,10 +223,10 @@ static int prepend_path( l, (path_sockname_mode) ? SUBST_RCV_ALL_EX : SUBST_RCV_ALL, 0); if(!l) goto out1; - dp = path_strzdup(suffix, cp - suffix); + dp = path_strzdup(suffix, cp.len); if(dp == NULL) goto out1; - l = insert_new_lump_before(l, dp, cp - suffix, 0); + l = insert_new_lump_before(l, dp, cp.len, 0); if(!l) goto out1; } diff --git a/src/modules/pdb/README b/src/modules/pdb/README index 60b329d84..52ebab2e8 100644 --- a/src/modules/pdb/README +++ b/src/modules/pdb/README @@ -29,6 +29,7 @@ Pawel Kuzak 3.1. timeout (integer) 3.2. server (string) + 3.3. ll_info (int) 4. Functions @@ -44,10 +45,11 @@ Pawel Kuzak 1.1. Set timeout parameter 1.2. Set server parameter - 1.3. pdb_query usage - 1.4. pdb.status usage - 1.5. pdb.activate usage - 1.6. pdb.deactivate usage + 1.3. Set ll_info parameter + 1.4. pdb_query usage + 1.5. pdb.status usage + 1.6. pdb.activate usage + 1.7. pdb.deactivate usage Chapter 1. Admin Guide @@ -63,6 +65,7 @@ Chapter 1. Admin Guide 3.1. timeout (integer) 3.2. server (string) + 3.3. ll_info (int) 4. Functions @@ -113,6 +116,7 @@ Chapter 1. Admin Guide 3.1. timeout (integer) 3.2. server (string) + 3.3. ll_info (int) 3.1. timeout (integer) @@ -136,6 +140,19 @@ modparam("pdb", "timeout", 10) modparam("pdb", "server", "localhost:10001,host.name:10001,192.168.1.7:10002") ... +3.3. ll_info (int) + + Local log level (per module) for specific INFO messages. It has to be a + valid log level value (see xlog() function from xlog module for more + details). + + Default value is “2”. + + Example 1.3. Set ll_info parameter +... +modparam("pdb", "ll_info", 3) +... + 4. Functions 4.1. pdb_query (string query, string dstavp) @@ -149,7 +166,7 @@ modparam("pdb", "server", "localhost:10001,host.name:10001,192.168.1.7:10002") a two byte integer value in network byte order. The integer value will be stored in the given AVP. - Example 1.3. pdb_query usage + Example 1.4. pdb_query usage ... # query external service for routing information if (!pdb_query("$rU", "$avp(i:82)")) @@ -169,7 +186,7 @@ cr_route("$avp(i:82)", "$rd", "$rU", "$rU", "call_id"); Prints the status of the module. This can either be "active" or "deactivated". - Example 1.4. pdb.status usage + Example 1.5. pdb.status usage ... kamcmd pdb.status ... @@ -178,7 +195,7 @@ kamcmd pdb.status Activates the module. This is the default after loading the module. - Example 1.5. pdb.activate usage + Example 1.6. pdb.activate usage ... kamcmd pdb.activate ... @@ -189,7 +206,7 @@ kamcmd pdb.activate activated again. As long as the module is deactivated, the pdb_query function will return -1. - Example 1.6. pdb.deactivate usage + Example 1.7. pdb.deactivate usage ... kamcmd pdb.deactivate ... diff --git a/src/modules/pdb/doc/pdb_admin.xml b/src/modules/pdb/doc/pdb_admin.xml index da2ecb3a0..19b00bd99 100644 --- a/src/modules/pdb/doc/pdb_admin.xml +++ b/src/modules/pdb/doc/pdb_admin.xml @@ -94,6 +94,27 @@ modparam("pdb", "timeout", 10) ... modparam("pdb", "server", "localhost:10001,host.name:10001,192.168.1.7:10002") +... + + +
+
+ <varname>ll_info</varname> (int) + + Local log level (per module) for specific INFO messages. It has to + be a valid log level value (see xlog() function from xlog module for + more details). + + + + Default value is 2. + + + + Set <varname>ll_info</varname> parameter + +... +modparam("pdb", "ll_info", 3) ... diff --git a/src/modules/pdb/pdb.c b/src/modules/pdb/pdb.c index 75013cccb..1398f7574 100644 --- a/src/modules/pdb/pdb.c +++ b/src/modules/pdb/pdb.c @@ -48,6 +48,7 @@ static int timeoutlogs = -10; /*!< for aggregating timeout logs */ static int *active = NULL; static uint16_t *global_id = NULL; +ksr_loglevels_t _ksr_loglevels_pdb = KSR_LOGLEVELS_DEFAULTS; /*! * Generic parameter that holds a string, an int or a pseudo-variable @@ -90,7 +91,7 @@ static int rpc_child_init(void); static void mod_destroy(); /* debug function for the new client <-> server protocol */ -static void pdb_msg_dbg(struct pdb_msg msg, char *dbg_msg); +static void pdb_msg_dbg(struct pdb_msg *msg, char *dbg_msg); /* build the new protocol message before transmission */ static int pdb_msg_format_send(struct pdb_msg *msg, uint8_t version, @@ -103,9 +104,15 @@ static cmd_export_t cmds[] = { {0, 0, 0, 0, 0, 0}}; -static param_export_t params[] = {{"server", PARAM_STRING, &modp_server}, - {"timeout", INT_PARAM, &timeout}, {0, 0, 0}}; +/* clang-format off */ +static param_export_t params[] = { + {"server", PARAM_STRING, &modp_server}, + {"timeout", PARAM_INT, &timeout}, + {"ll_info", PARAM_INT, &_ksr_loglevels_pdb.ll_info}, + {0, 0, 0} +}; +/* clang-format on */ struct module_exports exports = { "pdb", /* module name */ @@ -145,15 +152,15 @@ static struct server_list_t *server_list; /* debug function for the new client <-> server protocol */ -static void pdb_msg_dbg(struct pdb_msg msg, char *dbg_msg) +static void pdb_msg_dbg(struct pdb_msg *msg, char *dbg_msg) { int i; char buf[PAYLOADSIZE * 3 + 1]; char *ptr = buf; - if(msg.hdr.length > sizeof(msg.hdr)) { - for(i = 0; i < msg.hdr.length - sizeof(msg.hdr); i++) { - ptr += sprintf(ptr, "%02X ", msg.bdy.payload[i]); + if(msg->hdr.length > sizeof(msg->hdr)) { + for(i = 0; i < msg->hdr.length - sizeof(msg->hdr); i++) { + ptr += sprintf(ptr, "%02X ", msg->bdy.payload[i]); } } else { *ptr = '\0'; @@ -162,8 +169,8 @@ static void pdb_msg_dbg(struct pdb_msg msg, char *dbg_msg) LM_DBG("%s\n" "version = %d\ntype = %d\ncode = %d\nid = %d\nlen = %d\n" "payload = %s\n", - dbg_msg, msg.hdr.version, msg.hdr.type, msg.hdr.code, msg.hdr.id, - msg.hdr.length, buf); + dbg_msg, msg->hdr.version, msg->hdr.type, msg->hdr.code, + msg->hdr.id, msg->hdr.length, buf); } /* build the message before send */ @@ -297,7 +304,7 @@ static int pdb_query(struct sip_msg *_msg, struct multiparam_t *_number, case PDB_VERSION_1: pdb_msg_format_send(&msg, PDB_VERSION, PDB_TYPE_REQUEST_ID, PDB_CODE_DEFAULT, htons(*global_id), buf, reqlen); - pdb_msg_dbg(msg, "Kamailio pdb client sends:"); + pdb_msg_dbg(&msg, "Kamailio pdb client sends:"); /* increment msg id for the next request */ *global_id = *global_id + 1; @@ -369,7 +376,7 @@ static int pdb_query(struct sip_msg *_msg, struct multiparam_t *_number, switch(PDB_VERSION) { case PDB_VERSION_1: memcpy(&msg, buf, bytes_received); - pdb_msg_dbg(msg, "Kamailio pdb client receives:"); + pdb_msg_dbg(&msg, "Kamailio pdb client receives:"); _idv = msg.hdr.id; /* make gcc happy */ msg.hdr.id = ntohs(_idv); @@ -386,20 +393,20 @@ static int pdb_query(struct sip_msg *_msg, struct multiparam_t *_number, goto found; } break; - case PDB_CODE_NOT_NUMBER: - LM_NOTICE("Number %s has letters in it\n", - number.s); - carrierid = 0; - goto found; case PDB_CODE_NOT_FOUND: LM_NOTICE("Number %s pdb_id not found\n", number.s); - carrierid = 0; + carrierid = -1; + goto found; + case PDB_CODE_NOT_NUMBER: + LM_NOTICE("Number %s has letters in it\n", + number.s); + carrierid = -2; goto found; default: LM_NOTICE("Invalid code %d received\n", msg.hdr.code); - carrierid = 0; + carrierid = -3; goto found; } @@ -429,7 +436,7 @@ found: timeoutlogs = -10; } if(gettimeofday(&tnow, NULL) == 0) { - LM_INFO("got an answer in %f ms\n", + LLM_INFO("got an answer in %f ms\n", ((double)(tnow.tv_usec - tstart.tv_usec + (tnow.tv_sec - tstart.tv_sec) * 1000000)) / 1000); diff --git a/src/modules/pdt/README b/src/modules/pdt/README index 569ababf5..8404139d3 100644 --- a/src/modules/pdt/README +++ b/src/modules/pdt/README @@ -39,6 +39,7 @@ Elena-Ramona Modroiu 3.7. fetch_rows (integer) 3.8. char_list (string) 3.9. check_domain (integer) + 3.10. mode (integer) 4. Functions @@ -64,8 +65,9 @@ Elena-Ramona Modroiu 1.8. Set fetch_rows parameter 1.9. Set char_list parameter 1.10. Set check_domain parameter - 1.11. prefix2domain usage - 1.12. pd_translate usage + 1.11. Set mode parameter + 1.12. prefix2domain usage + 1.13. pd_translate usage Chapter 1. Admin Guide @@ -88,6 +90,7 @@ Chapter 1. Admin Guide 3.7. fetch_rows (integer) 3.8. char_list (string) 3.9. check_domain (integer) + 3.10. mode (integer) 4. Functions @@ -172,6 +175,7 @@ sip:12391001@mydomain.com => sip:91001@alpha.org 3.7. fetch_rows (integer) 3.8. char_list (string) 3.9. check_domain (integer) + 3.10. mode (integer) 3.1. db_url (string) @@ -277,6 +281,18 @@ modparam("pdt", "char_list", "0123456789*+") modparam("pdt", "check_domain", 0) ... +3.10. mode (integer) + + If set to 1, duplicated prefixes are ingnored and starting continues, + if 0, then starting or loading fails. + + Default value is 0. + + Example 1.11. Set mode parameter +... +modparam("pdt", "mode", 1) +... + 4. Functions 4.1. prefix2domain(rewrite_mode, multidomain_mode) @@ -320,7 +336,7 @@ modparam("pdt", "check_domain", 0) This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. - Example 1.11. prefix2domain usage + Example 1.12. prefix2domain usage ... prefix2domain("2", "2"); ... @@ -367,7 +383,7 @@ prefix2domain(); This function can be used from REQUEST_ROUTE, FAILURE_ROUTE or BRANCH_ROUTE. - Example 1.12. pd_translate usage + Example 1.13. pd_translate usage ... pd_translate("$fd", "2"); ... diff --git a/src/modules/pdt/doc/pdt_admin.xml b/src/modules/pdt/doc/pdt_admin.xml index f49f95157..47aefffcf 100644 --- a/src/modules/pdt/doc/pdt_admin.xml +++ b/src/modules/pdt/doc/pdt_admin.xml @@ -299,6 +299,27 @@ modparam("pdt", "char_list", "0123456789*+") ... modparam("pdt", "check_domain", 0) ... + + +
+ +
+ <varname>mode</varname> (integer) + + If set to 1, duplicated prefixes are ingnored and starting continues, + if 0, then starting or loading fails. + + + + Default value is 0. + + + + Set <varname>mode</varname> parameter + +... +modparam("pdt", "mode", 1) +...
diff --git a/src/modules/pdt/pdt.c b/src/modules/pdt/pdt.c index 4d6f66b95..d68cd8a33 100644 --- a/src/modules/pdt/pdt.c +++ b/src/modules/pdt/pdt.c @@ -57,6 +57,7 @@ int pdt_fetch_rows = 1000; /** structures containing prefix-domain pairs */ pdt_tree_t **_ptree = NULL; +int _pdt_mode = 0; /** database connection */ static db1_con_t *db_con = NULL; @@ -95,40 +96,47 @@ static int fixup_translate(void **param, int param_no); static int update_new_uri(struct sip_msg *msg, int plen, str *d, int mode); static int pdt_init_rpc(void); -static cmd_export_t cmds[] = {{"prefix2domain", (cmd_function)w_prefix2domain, - 0, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE}, - {"prefix2domain", (cmd_function)w_prefix2domain_1, 1, fixup_igp_null, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, - {"prefix2domain", (cmd_function)w_prefix2domain_2, 2, fixup_igp_igp, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, - {"pd_translate", (cmd_function)w_pd_translate, 2, fixup_translate, 0, - REQUEST_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, - {0, 0, 0, 0, 0, 0}}; - -static param_export_t params[] = {{"db_url", PARAM_STR, &db_url}, - {"db_table", PARAM_STR, &db_table}, - {"sdomain_column", PARAM_STR, &sdomain_column}, - {"prefix_column", PARAM_STR, &prefix_column}, - {"domain_column", PARAM_STR, &domain_column}, - {"prefix", PARAM_STR, &pdt_prefix}, - {"char_list", PARAM_STR, &pdt_char_list}, - {"fetch_rows", INT_PARAM, &pdt_fetch_rows}, - {"check_domain", INT_PARAM, &pdt_check_domain}, {0, 0, 0}}; +/* clang-format off */ +static cmd_export_t cmds[] = { + {"prefix2domain", (cmd_function)w_prefix2domain, + 0, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE}, + {"prefix2domain", (cmd_function)w_prefix2domain_1, 1, fixup_igp_null, 0, + REQUEST_ROUTE | FAILURE_ROUTE}, + {"prefix2domain", (cmd_function)w_prefix2domain_2, 2, fixup_igp_igp, 0, + REQUEST_ROUTE | FAILURE_ROUTE}, + {"pd_translate", (cmd_function)w_pd_translate, 2, fixup_translate, 0, + REQUEST_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, + {0, 0, 0, 0, 0, 0} +}; + +static param_export_t params[] = { + {"db_url", PARAM_STR, &db_url}, + {"db_table", PARAM_STR, &db_table}, + {"sdomain_column", PARAM_STR, &sdomain_column}, + {"prefix_column", PARAM_STR, &prefix_column}, + {"domain_column", PARAM_STR, &domain_column}, + {"prefix", PARAM_STR, &pdt_prefix}, + {"char_list", PARAM_STR, &pdt_char_list}, + {"fetch_rows", INT_PARAM, &pdt_fetch_rows}, + {"check_domain", INT_PARAM, &pdt_check_domain}, + {"mode", PARAM_INT, &_pdt_mode}, + {0, 0, 0} +}; struct module_exports exports = { - "pdt", /* module name */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* cmd exports */ - params, /* param exports */ - 0, /* RPC method exports */ - 0, /* exported pseudo-variables */ - 0, /* response function */ - mod_init, /* module initialization function */ - child_init, /* per child init function */ - mod_destroy /* destroy function */ + "pdt", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* cmd exports */ + params, /* param exports */ + 0, /* RPC method exports */ + 0, /* exported pseudo-variables */ + 0, /* response function */ + mod_init, /* module initialization function */ + child_init, /* per child init function */ + mod_destroy /* destroy function */ }; - +/* clang-format on */ /** * init module function @@ -846,9 +854,13 @@ error: } +/* clang-format off */ rpc_export_t pdt_rpc_cmds[] = { - {"pdt.reload", pdt_rpc_reload, pdt_rpc_reload_doc, 0}, - {"pdt.list", pdt_rpc_list, pdt_rpc_list_doc, 0}, {0, 0, 0, 0}}; + {"pdt.reload", pdt_rpc_reload, pdt_rpc_reload_doc, 0}, + {"pdt.list", pdt_rpc_list, pdt_rpc_list_doc, 0}, + {0, 0, 0, 0} +}; +/* clang-format on */ /** diff --git a/src/modules/pdt/pdtree.c b/src/modules/pdt/pdtree.c index 3e71b8702..0d47b6496 100644 --- a/src/modules/pdt/pdtree.c +++ b/src/modules/pdt/pdtree.c @@ -35,6 +35,7 @@ //extern str pdt_char_list = {"1234567890*",11}; extern str pdt_char_list; +extern int _pdt_mode; /** * */ @@ -117,9 +118,15 @@ int add_to_tree(pdt_tree_t *pt, str *sp, str *sd) if(itn0[strpos(pdt_char_list.s, sp->s[l]) % PDT_NODE_SIZE].domain.s != NULL) { - LM_ERR("prefix already allocated [%.*s/[%.*s]\n", sp->len, sp->s, - sd->len, sd->s); - return -1; + if(_pdt_mode & 1) { + LM_DBG("prefix already allocated [%.*s/[%.*s] - ignoring\n", + sp->len, sp->s, sd->len, sd->s); + return 0; + } else { + LM_ERR("prefix already allocated [%.*s/[%.*s]\n", sp->len, sp->s, + sd->len, sd->s); + return -1; + } } itn0[strpos(pdt_char_list.s, sp->s[l]) % PDT_NODE_SIZE].domain.s = diff --git a/src/modules/permissions/parse_config.c b/src/modules/permissions/parse_config.c index 20fdf8b6c..7bf0c95a4 100644 --- a/src/modules/permissions/parse_config.c +++ b/src/modules/permissions/parse_config.c @@ -1,7 +1,7 @@ /* * PERMISSIONS module * - * Copyright (C) 2003 Mikls Tirpk (mtirpak@sztaki.hu) + * Copyright (C) 2003 Miklós Tirpák (mtirpak@sztaki.hu) * * This file is part of Kamailio, a free SIP server. * @@ -137,7 +137,7 @@ static int parse_expression(char *sv, expression **e, expression **e_exceptions) } } else { /* no exception */ - strcpy(str2, sv); + strncpy(str2, sv, LINE_LENGTH); *e_exceptions = NULL; } diff --git a/src/modules/permissions/rule.c b/src/modules/permissions/rule.c index 3140acfe0..f315d10d7 100644 --- a/src/modules/permissions/rule.c +++ b/src/modules/permissions/rule.c @@ -1,7 +1,7 @@ /* * PERMISSIONS module * - * Copyright (C) 2003 Mikls Tirpk (mtirpak@sztaki.hu) + * Copyright (C) 2003 Miklós Tirpák (mtirpak@sztaki.hu) * * This file is part of Kamailio, a free SIP server. * @@ -148,7 +148,7 @@ expression *new_expression(char *sv) return 0; } - strcpy(e->value, sv); + strncpy(e->value, sv, EXPRESSION_LENGTH); e->reg_value = (regex_t *)pkg_malloc(sizeof(regex_t)); if(!e->reg_value) { diff --git a/src/modules/permissions/trusted.c b/src/modules/permissions/trusted.c index 5775da87a..9bef104c9 100644 --- a/src/modules/permissions/trusted.c +++ b/src/modules/permissions/trusted.c @@ -655,7 +655,7 @@ error: /* * Checks based on source address and protocol given in pvar arguments and - * and requests's From URI, if request can be trusted without authentication. + * requests' From URI, if request can be trusted without authentication. */ int allow_trusted_2(struct sip_msg *_msg, char *_src_ip_sp, char *_proto_sp) { @@ -680,7 +680,7 @@ int allow_trusted_2(struct sip_msg *_msg, char *_src_ip_sp, char *_proto_sp) /* * Checks based on source address and protocol given in pvar arguments and - * and requests's From URI, if request can be trusted without authentication. + * requests' From URI, if request can be trusted without authentication. */ int allow_trusted_3(struct sip_msg *_msg, char *_src_ip_sp, char *_proto_sp, char *_from_uri) diff --git a/src/modules/permissions/trusted.h b/src/modules/permissions/trusted.h index c9c71b947..09f2185fe 100644 --- a/src/modules/permissions/trusted.h +++ b/src/modules/permissions/trusted.h @@ -78,7 +78,7 @@ int allow_trusted_0(struct sip_msg *_msg, char *str1, char *str2); /* * Checks based on source address and protocol given in pvar arguments and - * and requests's From URI, if request can be trusted without authentication. + * requests' From URI, if request can be trusted without authentication. */ int allow_trusted_2(struct sip_msg *_msg, char *_src_ip_sp, char *_proto_sp); diff --git a/src/modules/phonenum/Makefile b/src/modules/phonenum/Makefile index f465226a9..477808692 100644 --- a/src/modules/phonenum/Makefile +++ b/src/modules/phonenum/Makefile @@ -7,6 +7,7 @@ NAME=phonenum.so CXX?=g++ LD?=g++ +CSTDVER?="c++17" LIBS+=-L$(LOCALBASE)/lib cphonenumber.o -lphonenumber -lgeocoding DEFS+=-I$(LOCALBASE)/include @@ -18,7 +19,7 @@ include ../../Makefile.modules cphonenumber.o: cphonenumber.cpp cphonenumber.h @echo "Compiling $<" - $(CXX) -std=c++11 $(CXXFLAGS) $(CFLAGS) $(C_DEFS) $(DEFS) -c $< -o $@ + $(CXX) -std=$(CSTDVER) $(CXXFLAGS) $(CFLAGS) $(C_DEFS) $(DEFS) -c $< -o $@ phonenum.so: cphonenumber.o diff --git a/src/modules/pike/README b/src/modules/pike/README index de5ee1a38..39654d5bd 100644 --- a/src/modules/pike/README +++ b/src/modules/pike/README @@ -307,7 +307,7 @@ tree root / \ - 142 necessary to block an IP. The maximum number of hits to turn an address red are (n is the - address's number of bytes): + address' number of bytes): 1 (first byte) + x (second byte) + (x / 2) * (n - 2) (for the rest of the bytes) + (n - 1) (to turn the node to red). diff --git a/src/modules/pike/doc/pike_devel.xml b/src/modules/pike/doc/pike_devel.xml index 0742d2a57..19558f7cf 100644 --- a/src/modules/pike/doc/pike_devel.xml +++ b/src/modules/pike/doc/pike_devel.xml @@ -69,7 +69,7 @@ tree root / \ - 142 variable number of hits necessary to block an &ip;. - The maximum number of hits to turn an address red are (n is the address's number of bytes): + The maximum number of hits to turn an address red are (n is the address' number of bytes): 1 (first byte) + x (second byte) + (x / 2) * (n - 2) (for the rest of the bytes) + (n - 1) diff --git a/src/modules/pike/pike_top.c b/src/modules/pike/pike_top.c index 0d9a5218e..bf450ee55 100644 --- a/src/modules/pike/pike_top.c +++ b/src/modules/pike/pike_top.c @@ -33,7 +33,7 @@ static struct TopListItem_t *top_list_root = 0; static struct TopListItem_t *top_list_iter = 0; -static char buff[PIKE_BUFF_SIZE]; +static char _pike_top_buff[PIKE_BUFF_SIZE]; struct TopListItem_t *pike_top_get_root() { @@ -41,39 +41,39 @@ struct TopListItem_t *pike_top_get_root() } char *pike_top_print_addr( - unsigned char *ip, int iplen, char *buff, int buffsize) + unsigned char *ip, int iplen, char *obuff, int obuffsize) { unsigned short *ipv6_ptr = (unsigned short *)ip; - int bsize; int blen; - bsize = PIKE_BUFF_SIZE * sizeof(char); - memset(buff, 0, bsize); + memset(obuff, 0, obuffsize); - DBG("pike:top:print_addr(iplen: %d, buffsize: %d)", iplen, buffsize); + DBG("address iplen: %d, buffsize: %d", iplen, obuffsize); if(iplen == 4) { - inet_ntop(AF_INET, ip, buff, buffsize); + inet_ntop(AF_INET, ip, obuff, obuffsize); } else if(iplen == 16) { - inet_ntop(AF_INET6, ip, buff, buffsize); + inet_ntop(AF_INET6, ip, obuff, obuffsize); } else { - blen = snprintf(buff, bsize, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", - htons(ipv6_ptr[0]), htons(ipv6_ptr[1]), htons(ipv6_ptr[2]), - htons(ipv6_ptr[3]), htons(ipv6_ptr[4]), htons(ipv6_ptr[5]), - htons(ipv6_ptr[6]), htons(ipv6_ptr[7])); - if(blen < 0 || blen >= bsize) { + blen = snprintf(obuff, obuffsize, + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", htons(ipv6_ptr[0]), + htons(ipv6_ptr[1]), htons(ipv6_ptr[2]), htons(ipv6_ptr[3]), + htons(ipv6_ptr[4]), htons(ipv6_ptr[5]), htons(ipv6_ptr[6]), + htons(ipv6_ptr[7])); + if(blen < 0 || blen >= obuffsize) { LM_ERR("failed to print the address - reset it\n"); - memset(buff, 0, bsize); + memset(obuff, 0, obuffsize); } } - return buff; + return obuff; } /* if you do not need global buffer, you can use this simpler call */ static char *print_addr(unsigned char *ip, int iplen) { - return pike_top_print_addr(ip, iplen, buff, sizeof(buff)); + return pike_top_print_addr( + ip, iplen, _pike_top_buff, sizeof(_pike_top_buff)); } int pike_top_add_entry(unsigned char *ip_addr, int addr_len, @@ -89,8 +89,8 @@ int pike_top_add_entry(unsigned char *ip_addr, int addr_len, print_addr(ip_addr, addr_len); DBG("pike_top_add_enrty(ip: %s, leaf_hits[%d,%d], hits[%d,%d]," " expires: %d, status: %d)", - buff, leaf_hits[0], leaf_hits[1], hits[0], hits[1], expires, - status); + _pike_top_buff, leaf_hits[0], leaf_hits[1], hits[0], hits[1], + expires, status); assert(new_item != 0); memset((void *)new_item, 0, sizeof(struct TopListItem_t)); @@ -124,5 +124,5 @@ void pike_top_list_clear() top_list_iter = ptr; } top_list_root = 0; - memset(buff, 0, sizeof(buff)); + memset(_pike_top_buff, 0, sizeof(_pike_top_buff)); } diff --git a/src/modules/pipelimit/README b/src/modules/pipelimit/README index 18f5ff482..717f28f6c 100644 --- a/src/modules/pipelimit/README +++ b/src/modules/pipelimit/README @@ -273,7 +273,7 @@ modparam("pipelimit", "plp_pipeid_column", "name") Name of 'limit' column. - Default value is “limit”. + Default value is “plimit”. Example 1.5. Set plp_limit_column parameter ... diff --git a/src/modules/pipelimit/doc/pipelimit_admin.xml b/src/modules/pipelimit/doc/pipelimit_admin.xml index 42fbbc0a0..20658412e 100644 --- a/src/modules/pipelimit/doc/pipelimit_admin.xml +++ b/src/modules/pipelimit/doc/pipelimit_admin.xml @@ -218,7 +218,7 @@ modparam("pipelimit", "plp_pipeid_column", "name") - Default value is limit. + Default value is plimit. diff --git a/src/modules/pipelimit/pipelimit.c b/src/modules/pipelimit/pipelimit.c index e9fc83b79..8ecf9c7dd 100644 --- a/src/modules/pipelimit/pipelimit.c +++ b/src/modules/pipelimit/pipelimit.c @@ -68,31 +68,31 @@ MODULE_VERSION #define PL_TIMER_INTERVAL_DEFAULT 10 /** SL API structure */ -sl_api_t slb; +static sl_api_t _pl_slb; -enum -{ +/* clang-format off */ +enum { LOAD_SOURCE_CPU, LOAD_SOURCE_EXTERNAL }; str_map_t source_names[] = { - {str_init("cpu"), LOAD_SOURCE_CPU}, - {str_init("external"), LOAD_SOURCE_EXTERNAL}, - {{0, 0}, 0}, + {str_init("cpu"), LOAD_SOURCE_CPU}, + {str_init("external"), LOAD_SOURCE_EXTERNAL}, + {{0, 0}, 0}, }; -static int pl_drop_code = 503; -static str pl_drop_reason = str_init("Server Unavailable"); -static int pl_hash_size = 6; - -typedef struct pl_queue -{ +typedef struct pl_queue { int *pipe; int pipe_mp; str *method; str method_mp; } pl_queue_t; +/* clang-format on */ + +static int pl_drop_code = 503; +static str pl_drop_reason = str_init("Server Unavailable"); +static int pl_hash_size = 6; static struct timer_ln *pl_timer = NULL; @@ -133,50 +133,53 @@ static int w_pl_drop(struct sip_msg *, char *, char *); static void destroy(void); static int fixup_pl_check3(void **param, int param_no); -static cmd_export_t cmds[] = {{"pl_check", (cmd_function)w_pl_check, 1, - fixup_spve_null, 0, ANY_ROUTE}, - {"pl_check", (cmd_function)w_pl_check3, 3, fixup_pl_check3, 0, - ANY_ROUTE}, - {"pl_active", (cmd_function)w_pl_active, 1, fixup_spve_null, 0, - ANY_ROUTE}, - {"pl_drop", (cmd_function)w_pl_drop_default, 0, 0, 0, - REQUEST_ROUTE | BRANCH_ROUTE | FAILURE_ROUTE | ONSEND_ROUTE}, - {"pl_drop", (cmd_function)w_pl_drop_forced, 1, fixup_uint_null, 0, - REQUEST_ROUTE | BRANCH_ROUTE | FAILURE_ROUTE | ONSEND_ROUTE}, - {"pl_drop", (cmd_function)w_pl_drop, 2, fixup_uint_uint, 0, - REQUEST_ROUTE | BRANCH_ROUTE | FAILURE_ROUTE | ONSEND_ROUTE}, - {0, 0, 0, 0, 0, 0}}; +/* clang-format off */ +static cmd_export_t cmds[] = { + {"pl_check", (cmd_function)w_pl_check, 1, fixup_spve_null, 0, ANY_ROUTE}, + {"pl_check", (cmd_function)w_pl_check3, 3, fixup_pl_check3, 0, ANY_ROUTE}, + {"pl_active", (cmd_function)w_pl_active, 1, fixup_spve_null, 0, ANY_ROUTE}, + {"pl_drop", (cmd_function)w_pl_drop_default, 0, 0, 0, + REQUEST_ROUTE | BRANCH_ROUTE | FAILURE_ROUTE | ONSEND_ROUTE}, + {"pl_drop", (cmd_function)w_pl_drop_forced, 1, fixup_uint_null, 0, + REQUEST_ROUTE | BRANCH_ROUTE | FAILURE_ROUTE | ONSEND_ROUTE}, + {"pl_drop", (cmd_function)w_pl_drop, 2, fixup_uint_uint, 0, + REQUEST_ROUTE | BRANCH_ROUTE | FAILURE_ROUTE | ONSEND_ROUTE}, + {0, 0, 0, 0, 0, 0} +}; + static param_export_t params[] = { - {"timer_interval", INT_PARAM, &pl_timer_interval}, - {"timer_mode", INT_PARAM, &pl_timer_mode}, - {"reply_code", INT_PARAM, &pl_drop_code}, - {"reply_reason", PARAM_STR, &pl_drop_reason}, - {"db_url", PARAM_STR, &pl_db_url}, - {"plp_table_name", PARAM_STR, &rlp_table_name}, - {"plp_pipeid_column", PARAM_STR, &rlp_pipeid_col}, - {"plp_limit_column", PARAM_STR, &rlp_limit_col}, - {"plp_algorithm_column", PARAM_STR, &rlp_algorithm_col}, - {"hash_size", INT_PARAM, &pl_hash_size}, - {"load_fetch", INT_PARAM, &pl_load_fetch}, - {"clean_unused", INT_PARAM, &pl_clean_unused}, - - {0, 0, 0}}; + {"timer_interval", INT_PARAM, &pl_timer_interval}, + {"timer_mode", INT_PARAM, &pl_timer_mode}, + {"reply_code", INT_PARAM, &pl_drop_code}, + {"reply_reason", PARAM_STR, &pl_drop_reason}, + {"db_url", PARAM_STR, &pl_db_url}, + {"plp_table_name", PARAM_STR, &rlp_table_name}, + {"plp_pipeid_column", PARAM_STR, &rlp_pipeid_col}, + {"plp_limit_column", PARAM_STR, &rlp_limit_col}, + {"plp_algorithm_column", PARAM_STR, &rlp_algorithm_col}, + {"hash_size", INT_PARAM, &pl_hash_size}, + {"load_fetch", INT_PARAM, &pl_load_fetch}, + {"clean_unused", INT_PARAM, &pl_clean_unused}, + + {0, 0, 0} +}; static rpc_export_t rpc_methods[]; /** module exports */ struct module_exports exports = { - "pipelimit", /* module name */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* cmd exports */ - params, /* param exports */ - 0, /* RPC method exports */ - 0, /* exported pseudo-variables */ - 0, /* response handling function */ - mod_init, /* module initialization function */ - 0, /* per-child init function */ - destroy /* module exit function */ + "pipelimit", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* cmd exports */ + params, /* param exports */ + 0, /* RPC method exports */ + 0, /* exported pseudo-variables */ + 0, /* response handling function */ + mod_init, /* module initialization function */ + 0, /* per-child init function */ + destroy /* module exit function */ }; +/* clang-format on */ #ifdef __OS_darwin #include @@ -214,13 +217,16 @@ int get_num_cpus() /* not using /proc/loadavg because it only works when our_timer_interval == theirs */ static int get_cpuload(double *load) { - static long long o_user, o_nice, o_sys, o_idle, o_iow, o_irq, o_sirq, o_stl; - long long n_user, n_nice, n_sys, n_idle, n_iow, n_irq, n_sirq, n_stl; + static long long o_user = 0, o_nice = 0, o_sys = 0, o_idle = 0, o_iow = 0, + o_irq = 0, o_sirq = 0, o_stl = 0; + long long n_user = 0, n_nice = 0, n_sys = 0, n_idle = 0, n_iow = 0, + n_irq = 0, n_sirq = 0, n_stl = 0; static int first_time = 1; FILE *f = fopen("/proc/stat", "r"); - double vload; - int ncpu; + double vload = 0.0; + int ncpu = 0; static int errormsg = 0; + int n = 0; if(!f) { /* Only write this error message five times. Otherwise you will annoy @@ -231,9 +237,9 @@ static int get_cpuload(double *load) } return -1; } - if(fscanf(f, "cpu %lld%lld%lld%lld%lld%lld%lld%lld", &n_user, &n_nice, - &n_sys, &n_idle, &n_iow, &n_irq, &n_sirq, &n_stl) - < 0) { + n = fscanf(f, "cpu %lld%lld%lld%lld%lld%lld%lld%lld", &n_user, &n_nice, + &n_sys, &n_idle, &n_iow, &n_irq, &n_sirq, &n_stl); + if(n < 8) { LM_ERR("could not parse load information\n"); fclose(f); return -1; @@ -365,7 +371,7 @@ static int mod_init(void) } /* bind the SL API */ - if(sl_load_api(&slb) != 0) { + if(sl_load_api(&_pl_slb) != 0) { LM_ERR("cannot bind to SL API\n"); return -1; } @@ -476,7 +482,7 @@ static int pl_drop(struct sip_msg *msg, unsigned int low, unsigned int high) LM_DBG("(%d, %d)\n", low, high); - if(slb.freply != 0) { + if(_pl_slb.freply != 0) { if(low != 0 && high != 0) { hdr.s = (char *)pkg_malloc(64); if(hdr.s == 0) { @@ -502,11 +508,11 @@ static int pl_drop(struct sip_msg *msg, unsigned int low, unsigned int high) return 0; } - ret = slb.freply(msg, pl_drop_code, &pl_drop_reason); + ret = _pl_slb.freply(msg, pl_drop_code, &pl_drop_reason); pkg_free(hdr.s); } else { - ret = slb.freply(msg, pl_drop_code, &pl_drop_reason); + ret = _pl_slb.freply(msg, pl_drop_code, &pl_drop_reason); } } else { LM_ERR("Can't send reply\n"); diff --git a/src/modules/pipelimit/pl_ht.c b/src/modules/pipelimit/pl_ht.c index 5f9b52dfc..c4e30de61 100644 --- a/src/modules/pipelimit/pl_ht.c +++ b/src/modules/pipelimit/pl_ht.c @@ -56,6 +56,7 @@ str_map_t algo_names[] = { int pl_init_htable(unsigned int hsize) { int i; + int j; if(_pl_pipes_ht != NULL) return -1; @@ -80,10 +81,10 @@ int pl_init_htable(unsigned int hsize) for(i = 0; i < _pl_pipes_ht->htsize; i++) { if(lock_init(&_pl_pipes_ht->slots[i].lock) == 0) { LM_ERR("cannot initialize lock[%d]\n", i); - i--; - while(i >= 0) { - lock_destroy(&_pl_pipes_ht->slots[i].lock); - i--; + j = i - 1; + while(j >= 0) { + lock_destroy(&_pl_pipes_ht->slots[j].lock); + j--; } shm_free(_pl_pipes_ht->slots); shm_free(_pl_pipes_ht); diff --git a/src/modules/pipelimit/pl_statistics.c b/src/modules/pipelimit/pl_statistics.c index c350acb0f..40d48b0a7 100644 --- a/src/modules/pipelimit/pl_statistics.c +++ b/src/modules/pipelimit/pl_statistics.c @@ -184,7 +184,7 @@ int get_socket_list_from_proto_and_family( return 0; } - *ipList = pkg_malloc(numberOfSockets * (num_ip_octets + 1) * sizeof(int)); + *ipList = pkg_malloc(sizeof(int) * numberOfSockets * (num_ip_octets + 1)); /* We couldn't allocate memory for the IP List. So all we can do is * fail. */ diff --git a/src/modules/presence/README b/src/modules/presence/README index 8d6172584..8b1378917 100644 --- a/src/modules/presence/README +++ b/src/modules/presence/README @@ -1,1589 +1 @@ -Presence Module -Anca-Maria Vamanu - - Voice Sistem SRL - -Juha Heinanen - - TutPro Inc. - -Edited by - -Anca-Maria Vamanu - -Juha Heinanen - - Copyright © 2006 Voice Sistem SRL - - Copyright © 2009 Juha Heinanen - __________________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1. Overview - 2. Dependencies - - 2.1. Kamailio Modules - 2.2. External Libraries or Applications - - 3. Parameters - - 3.1. db_url(str) - 3.2. presentity_table(str) - 3.3. active_watchers_table(str) - 3.4. watchers_table(str) - 3.5. clean_period (int) - 3.6. cseq_offset (int) - 3.7. db_update_period (int) - 3.8. waitn_time (int) - 3.9. notifier_poll_rate (int) - 3.10. notifier_processes (int) - 3.11. force_delete (int) - 3.12. startup_mode (int) - 3.13. expires_offset (int) - 3.14. max_expires (int) - 3.15. min_expires (int) - 3.16. min_expires_action (int) - 3.17. server_address (str) - 3.18. subs_db_mode (int) - 3.19. publ_cache (int) - 3.20. subs_htable_size (int) - 3.21. pres_htable_size (int) - 3.22. send_fast_notify (int) - 3.23. enable_sphere_check (int) - 3.24. timeout_rm_subs (int) - 3.25. fetch_rows (integer) - 3.26. db_table_lock_type (integer) - 3.27. local_log_level (int) - 3.28. local_log_facility (int) - 3.29. subs_remove_match (int) - 3.30. xavp_cfg (str) - 3.31. retrieve_order (int) - 3.32. retrieve_order_by (str) - 3.33. sip_uri_match (int) - 3.34. enable_dmq (integer) - 3.35. pres_subs_mode (integer) - 3.36. delete_same_subs (integer) - 3.37. timer_mode (integer) - 3.38. subs_respond_200 (integer) - - 4. Functions - - 4.1. handle_publish([sender_uri]) - 4.2. handle_subscribe([watcher_uri]) - 4.3. pres_auth_status(watcher_uri, presentity_uri) - 4.4. pres_has_subscribers(presentity_uri, event) - 4.5. pres_refresh_watchers(uri, event, type[, file_uri, - filename]) - - 4.6. pres_update_watchers(uri, event) - - 5. RPC Commands - - 5.1. presence.cleanup - 5.2. presence.refreshWatchers - 5.3. presence.updateWatchers - 5.4. presence.presentity_list - 5.5. presence.presentity_show - 5.6. presence.watcher_list - - 6. Exported Variables - - 6.1. $subs(attr) - 6.2. $notify_reply(attr) - - 7. Events - - 7.1. presence:notify-reply - - 8. Installation - - 2. Developer Guide - - 1. bind_presence(presence_api_t* api) - 2. add_event - 3. get_rules_doc - 4. get_auth_status - 5. apply_auth_nbody - 6. agg_nbody - 7. free_body - 8. aux_body_processing - 9. aux_free_body - 10. evs_publ_handl - 11. evs_subs_handl - 12. contains_event - 13. get_event_list - 14. update_watchers_status - 15. get_sphere - 16. get_presentity - 17. free_presentity - - List of Examples - - 1.1. Set db_url parameter - 1.2. Set presentity_table parameter - 1.3. Set active_watchers_table parameter - 1.4. Set watchers_table parameter - 1.5. Set clean_period parameter - 1.6. Set cseq_offset parameter - 1.7. Set db_update_period parameter - 1.8. Set waitn_time parameter - 1.9. Set notifier_poll_rate parameter - 1.10. Set notifier_processes parameter - 1.11. Set force_delete parameter - 1.12. Set startup_mode parameter - 1.13. Set expires_offset parameter - 1.14. Set max_expires parameter - 1.15. Set min_expires parameter - 1.16. Set min_expires parameter - 1.17. Set server_address parameter - 1.18. Set subs_db_mode parameter - 1.19. Set publ_cache parameter - 1.20. Set subs_htable_size parameter - 1.21. Set pres_htable_size parameter - 1.22. Set send_fast_notify parameter - 1.23. Set enable_sphere_check parameter - 1.24. Set timeout_rm_subs parameter - 1.25. Set fetch_rows parameter - 1.26. Set db_table_lock_type parameter - 1.27. Set local_log_level parameter - 1.28. Set local_log_facility parameter - 1.29. Set subs_remove_match parameter - 1.30. Set xavp_cfg parameter - 1.31. Set retrieve_order parameter - 1.32. Set retrieve_order_by parameter - 1.33. Set sip_uri_match parameter - 1.34. Set enable_dmq parameter - 1.35. Set pres_subs_mode parameter - 1.36. Set delete_same_subs parameter - 1.37. Set timer_mode parameter - 1.38. Set subs_respond_200 parameter - 1.39. handle_publish usage - 1.40. handle_subscribe usage - 1.41. pres_auth_status usage - 1.42. pres_has_subscribers usage - 1.43. pres_refresh_watchers usage - 1.44. pres_update_watchers usage - 1.45. $subs(name) usage - 1.46. $notify_reply(name) usage - 1.47. $notify_reply(name) usage - 2.1. presence_api_t structure - -Chapter 1. Admin Guide - - Table of Contents - - 1. Overview - 2. Dependencies - - 2.1. Kamailio Modules - 2.2. External Libraries or Applications - - 3. Parameters - - 3.1. db_url(str) - 3.2. presentity_table(str) - 3.3. active_watchers_table(str) - 3.4. watchers_table(str) - 3.5. clean_period (int) - 3.6. cseq_offset (int) - 3.7. db_update_period (int) - 3.8. waitn_time (int) - 3.9. notifier_poll_rate (int) - 3.10. notifier_processes (int) - 3.11. force_delete (int) - 3.12. startup_mode (int) - 3.13. expires_offset (int) - 3.14. max_expires (int) - 3.15. min_expires (int) - 3.16. min_expires_action (int) - 3.17. server_address (str) - 3.18. subs_db_mode (int) - 3.19. publ_cache (int) - 3.20. subs_htable_size (int) - 3.21. pres_htable_size (int) - 3.22. send_fast_notify (int) - 3.23. enable_sphere_check (int) - 3.24. timeout_rm_subs (int) - 3.25. fetch_rows (integer) - 3.26. db_table_lock_type (integer) - 3.27. local_log_level (int) - 3.28. local_log_facility (int) - 3.29. subs_remove_match (int) - 3.30. xavp_cfg (str) - 3.31. retrieve_order (int) - 3.32. retrieve_order_by (str) - 3.33. sip_uri_match (int) - 3.34. enable_dmq (integer) - 3.35. pres_subs_mode (integer) - 3.36. delete_same_subs (integer) - 3.37. timer_mode (integer) - 3.38. subs_respond_200 (integer) - - 4. Functions - - 4.1. handle_publish([sender_uri]) - 4.2. handle_subscribe([watcher_uri]) - 4.3. pres_auth_status(watcher_uri, presentity_uri) - 4.4. pres_has_subscribers(presentity_uri, event) - 4.5. pres_refresh_watchers(uri, event, type[, file_uri, filename]) - - 4.6. pres_update_watchers(uri, event) - - 5. RPC Commands - - 5.1. presence.cleanup - 5.2. presence.refreshWatchers - 5.3. presence.updateWatchers - 5.4. presence.presentity_list - 5.5. presence.presentity_show - 5.6. presence.watcher_list - - 6. Exported Variables - - 6.1. $subs(attr) - 6.2. $notify_reply(attr) - - 7. Events - - 7.1. presence:notify-reply - - 8. Installation - -1. Overview - - The Presence module implements the core functionality of SIP event - notification. It handles PUBLISH and SUBSCRIBE messages and generates - NOTIFY messages in a general, event independent way. It is extensible - and allows registering events to it from other Kamailio modules. - Supported SIP event packages are presence, presence.winfo, dialog;sla - from the presence_xml module and message-summary from the presence_mwi - module. - - The module can use database and memory storage (to improve - performance). For subscriptions it supports the 4 storage modes: Memory - Only, Write Back, Write Through and DB Only. For publishes, it stores - the state documents in database only (because of the large size) and it - can store a publish cache in memory to avoid unnecessary database - queries. Read the subs_db_mode and publ_cache parameter sections to - decide which is the best storage configuration for you. - - The module implements several API functions, that can be used by other - modules. In fact, it can be used only as a resource module, or - "library". This mode of operation is enabled if the db_url parameter is - not set to any value. - - The Kamailio Presence module implements the specifications in: RFC3265, - RFC3856, RFC3857, RFC3858. - -2. Dependencies - - 2.1. Kamailio Modules - 2.2. External Libraries or Applications - -2.1. Kamailio Modules - - The following modules must be loaded before this module: - * a database module. - * sl. - * tm. - * dmq (only if replication is enabled). - -2.2. External Libraries or Applications - - * libxml. - -3. Parameters - - 3.1. db_url(str) - 3.2. presentity_table(str) - 3.3. active_watchers_table(str) - 3.4. watchers_table(str) - 3.5. clean_period (int) - 3.6. cseq_offset (int) - 3.7. db_update_period (int) - 3.8. waitn_time (int) - 3.9. notifier_poll_rate (int) - 3.10. notifier_processes (int) - 3.11. force_delete (int) - 3.12. startup_mode (int) - 3.13. expires_offset (int) - 3.14. max_expires (int) - 3.15. min_expires (int) - 3.16. min_expires_action (int) - 3.17. server_address (str) - 3.18. subs_db_mode (int) - 3.19. publ_cache (int) - 3.20. subs_htable_size (int) - 3.21. pres_htable_size (int) - 3.22. send_fast_notify (int) - 3.23. enable_sphere_check (int) - 3.24. timeout_rm_subs (int) - 3.25. fetch_rows (integer) - 3.26. db_table_lock_type (integer) - 3.27. local_log_level (int) - 3.28. local_log_facility (int) - 3.29. subs_remove_match (int) - 3.30. xavp_cfg (str) - 3.31. retrieve_order (int) - 3.32. retrieve_order_by (str) - 3.33. sip_uri_match (int) - 3.34. enable_dmq (integer) - 3.35. pres_subs_mode (integer) - 3.36. delete_same_subs (integer) - 3.37. timer_mode (integer) - 3.38. subs_respond_200 (integer) - -3.1. db_url(str) - - The database url. - - If set, the module is a fully operational presence server. Otherwise, - it is used as a 'library', for its exported functions. - - Default value is “NULL”. - - Example 1.1. Set db_url parameter -... -modparam("presence", "db_url", - "mysql://kamailio:kamailiorw@localhost/kamailio") -... - -3.2. presentity_table(str) - - The name of the db table where PUBLISH presence information is stored. - - Default value is “presentity”. - - Example 1.2. Set presentity_table parameter -... -modparam("presence", "presentity_table", "presentity") -... - -3.3. active_watchers_table(str) - - The name of the db table where active subscription information is - stored. - - Default value is “active_watchers”. - - Example 1.3. Set active_watchers_table parameter -... -modparam("presence", "active_watchers_table", "active_watchers") -... - -3.4. watchers_table(str) - - The name of the db table where subscription states are stored. - - Default value is “watchers”. - - Example 1.4. Set watchers_table parameter -... -modparam("presence", "watchers_table", "watchers") -... - -3.5. clean_period (int) - - The period in seconds between checks if there are expired messages - stored in the database. - - Default value is “100”. A zero or negative value disables this - activity. - - Example 1.5. Set clean_period parameter -... -modparam("presence", "clean_period", 100) -... - -3.6. cseq_offset (int) - - The allowed offset between server and client cseq. - - Default value is “0”. - - Example 1.6. Set cseq_offset parameter -... -modparam("presence", "cseq_offset", 1) -... - -3.7. db_update_period (int) - - The period at which to synchronize cached subscriber info with the - database. - - Default value is “100”. A zero or negative value disables - synchronization. - - Example 1.7. Set db_update_period parameter -... -modparam("presence", "db_update_period", 100) -... - -3.8. waitn_time (int) - - The maximum time period that NOTIFY requests will be buffered for. The - server will attempt to send NOTIFY requests within many seconds of a - change occurring. - - Note: this parameter is only used when notifier_processes is greater - than 0. When notifier_processes is less than or equal to 0 NOTIFY - requests are sent immediately. - - Default value is “5”. - - Example 1.8. Set waitn_time parameter -... -modparam("presence", "waitn_time", 10) -... - -3.9. notifier_poll_rate (int) - - The number of times per second that the notifier processes should check - for work. Approximately 1/(waitn_time * notifier_poll_rate * - notifier_processes) of the pending updates will be sent each time a - notifier process runs. - - Separate notifier processes are only run when subs_db_mode is 3 (DB - only mode). - - Default value is “10”. - - Example 1.9. Set notifier_poll_rate parameter -... -modparam("presence", "notifier_poll_rate", 20) -... - -3.10. notifier_processes (int) - - The number of notifier processes that should be started. - - Separate notifier processes are only run when subs_db_mode is 3 (DB - only mode). - - Note: setting this parameter to 0 when subs_db_mode is 3 keeps the old - behaviour (sending NOTIFY requests immediately). This (old) behaviour - is disabled by default in DB only mode because under load, when lots of - NOTIFY requests can be sent on a dialog at the same time, there are - race conditions which result in CSeq re-use. - - Default value is “1”. - - Example 1.10. Set notifier_processes parameter -... -modparam("presence", "notifier_processes", 2) -... - -3.11. force_delete (int) - - Enabling this parameter will delete expired presentity records without - updating watchers. - - Set this parameter to “1” to enable. - - Default value is “0”. - - Example 1.11. Set force_delete parameter -... -modparam("presence", "force_delete", 1) -... - -3.12. startup_mode (int) - - Setting this parameter to 0 will provide startup related backward - compatibility for some modules. Setting to 0 fixes presentity requests - with low expires (e.g. time() + 1) - - Set this parameter to “0” to enable backward compatibility. - - Default value is “1”. - - Example 1.12. Set startup_mode parameter -... -modparam("presence", "startup_mode", 0) -... - -3.13. expires_offset (int) - - The value in seconds that should be subtracted from the expires value - when sending a 200OK for a publish. It is used for forcing the client - to send an update before the old publish expires. - - Default value is “0”. - - Example 1.13. Set expires_offset parameter -... -modparam("presence", "expires_offset", 10) -... - -3.14. max_expires (int) - - The maximum admissible expires value for PUBLISH/SUBSCRIBE message (in - seconds). - - Default value is “3600”. - - Example 1.14. Set max_expires parameter -... -modparam("presence", "max_expires", 3600) -... - -3.15. min_expires (int) - - The minimum admissible expires value for PUBLISH/SUBSCRIBE message (in - seconds). - - If > 0 then min_expires_action parameter determines the response. - - Default value is “0”. - - Example 1.15. Set min_expires parameter -... -modparam("presence", "min_expires", 1800) -... - -3.16. min_expires_action (int) - - The action to take when UA sends an expires value less than - min_expires. - - Possible Values - * 1 : RFC Compliant, returns “423 Interval Too Brief” - * 2 : forces the min_expires value in the subscription - - If > 0 then min_expires_action parameter determines the response. - - Default value is “1”. - - Example 1.16. Set min_expires parameter - ... - modparam("presence", "min_expires", 1800) - ... - -3.17. server_address (str) - - The presence server address which will become the value of Contact - header filed for 200 OK replies to SUBSCRIBE and PUBLISH and in NOTIFY - messages. - - Example 1.17. Set server_address parameter -... -modparam("presence", "server_address", "sip:10.10.10.10:5060") -... - -3.18. subs_db_mode (int) - - The presence module can utilize database for persistent subscription - storage. If you use database, your subscriptions will survive machine - restarts or SW crashes. The disadvantage is that accessing the database - can be time consuming. Therefore, presence module implements four - database accessing modes: - * 0 - This disables database completely. Only memory will be used. - Subscriptions will not survive restart. Use this value if you need - a really fast presence module and subscription persistence is not - necessary or is provided by other means. - * 1 - Write-Through scheme. Subscriptions are updated synchronously - in database and in memory(used for read operations). Use this - scheme if speed is not top priority, but it's important that no - subscriptions will be lost during crash or reboot or if you have an - external application that reads the state of the subscriptions from - database and they need to be updated synchronously. - * 2 - Write-Back scheme. This is a combination of previous two - schemes. All changes are made to memory and database - synchronization is done in the timer. The timer deletes all expired - contacts and flushes all modified or new subscriptions to database. - Use this scheme if you encounter high-load peaks and want them to - process as fast as possible. Latency of this mode is much lower - than latency of mode 1, but slightly higher than latency of mode 0. - To control the interval at which data is flushed to database, set - the db_update_period parameter. - * 3 - DB-Only scheme. No memory cache is kept, all operations being - directly performed with the database. The timer deletes all expired - subscriptions from database. The mode is useful if you configure - more servers sharing the same DB without any replication at SIP - level. The mode may be slower due the high number of DB operation. - - Default value is 2 (Write-Back scheme). - - Example 1.18. Set subs_db_mode parameter -... -modparam("presence", "subs_db_mode", 1) -... - -3.19. publ_cache (int) - - To improve performance, the presence module can operate in a couple of - modes related to how PUBLISH data is stored. If publ_cache is 0, then - no information is stored in memory. - - If publ_cache is 1, then the module keeps in memory an index of the - records stored in database, In this mode it keeps only the list of URIs - and events, so it does not use much memory. The cache is used when a - Subscription is received to check if there is any published state in - database. This way unnecessary queries in presentity table are avoided. - - If publ_cache is 2, then the module keeps everything related to PUBLISH - requests in memory, not storing anything in the database. - - Setting this parameter to 0 will disable the usage of the publish - cache. This is desirable when you have more servers sharing the same - database or there are other external entities inserting data into the - presentity table. - - Default value is “1”. - - Example 1.19. Set publ_cache parameter -... -modparam("presence", "publ_cache", 0) -... - -3.20. subs_htable_size (int) - - The size of the in-memory hash table to store subscription dialogs. - This parameter will be used as the power of 2 when computing table - size. - - Default value is “9 (512)”. - - Example 1.20. Set subs_htable_size parameter -... -modparam("presence", "subs_htable_size", 11) -... - -3.21. pres_htable_size (int) - - The size of the in-memory hash table to store publish records. This - parameter will be used as the power of 2 when computing table size. - - Default value is “9 (512)”. - - Example 1.21. Set pres_htable_size parameter -... -modparam("presence", "pres_htable_size", 11) -... - -3.22. send_fast_notify (int) - - This parameter enables or disables the sending of an initial empty - NOTIFY after a SUBSCRIBE/reSUBSCRIBE. This caused problems for MWI - application, because some CPEs (like Samsung) fail to understand an - empty NOTIFY to a message-summary event. This parameter is enabled by - default, thus adhering to the standard. - - Default value is “1 ”. - - Example 1.22. Set send_fast_notify parameter -... -modparam("presence", "send_fast_notify", 0) -... - -3.23. enable_sphere_check (int) - - This parameter is a flag that should be set if permission rules include - sphere checking. The sphere information is expected to be present in - the RPID body published by the presentity. The flag is introduced as - this check requires extra processing that should be avoided if this - feature is not supported by the clients. - - Default value is “0 ”. - - Example 1.23. Set enable_sphere_check parameter -... -modparam("presence", "enable_sphere_check", 1) -... - -3.24. timeout_rm_subs (int) - - This parameter is a flag that should be set if subscriptions should be - removed from the active_watchers when a NOTIFY times out. RFC3265 - section 3.2.2 defines this behaviour as a SHOULD, so by default it is - on. Disabling this will keep subscriptions active on unreliable - networks. - - Default value is “1”. - - Example 1.24. Set timeout_rm_subs parameter -... -modparam("presence", "timeout_rm_subs", 0) -... - -3.25. fetch_rows (integer) - - Number of rows to be loaded in one step from database. - - Default value is 500. - - Example 1.25. Set fetch_rows parameter -... -modparam("presence", "fetch_rows", 1000) -... - -3.26. db_table_lock_type (integer) - - Enable (=1) or disable (=0) the Locks for table during a transaction. - Locking only the "current" table causes problems with a MySQL-Databases - in "DB-Only" mode. - - In order to use the Presence-Module in "DB_ONLY"-mode with a - MySQL-Backend, set this parameter to "0", otherwise the - MySQL-Operations will fail. The Presence-Module will generate a "500 - Server error" due to the failed MySQL-queries. - - Default value is 1 (Write Lock for the Tables). - - Example 1.26. Set db_table_lock_type parameter -... -modparam("presence", "db_table_lock_type", 0) -... - -3.27. local_log_level (int) - - Control log level for some debug messages inside the module. - - Default value is 2 (L_INFO). - - Example 1.27. Set local_log_level parameter -... -modparam("presence", "local_log_level", 3) -... - -3.28. local_log_facility (int) - - Control syslog facility for some debug messages inside the module. - - Default value is taken from the core log_facility configuration - parameter. - - Example 1.28. Set local_log_facility parameter -... -modparam("presence", "local_log_facility", "LOG_LOCAL3") -... - -3.29. subs_remove_match (int) - - Control how to match the subscriptions to remove from memory. If set to - 0, then the match is done on To-Tag (local generated), if set to 1, - then the match is done on all dialog attributes (Call-Id, From-Tag, - To-Tag). - - Default value is 0. - - Example 1.29. Set subs_remove_match parameter -... -modparam("presence", "subs_remove_match", 1) -... - -3.30. xavp_cfg (str) - - The name of the xavp to be used to specify attributes for internal - processing of presence module. - - Inner attributes inside xavp can be: - * priority - integer value to set the priority of the presence - document (higher value, higher priority). It can set the order of - the aggregated presence documents sent by NOTIFY (first the - document with higher priority). If xavp_cfg parameter is set but - this attribute is not in the avp, the priority of the presence - document is based on timestamp, so newer documents have higher - priority. - * delete_subscription - integer value to give extra control of - deleting the subscription after processing of - event_route[presence:notify-reply]. If value = 1, it deletes the - subscription. If xavp_cfg parameter is set but this attribute is - not in the avp, the subscription is not deleted. this does not - apply for codes 404, 481 and 408 (when timeout_rm_subs = 1) where - subscription is deleted. - - Default value is empty (not set). - - Example 1.30. Set xavp_cfg parameter -... -modparam("presence", "xavp_cfg", "pres") -... -if(is_method("PUBLISH")) { - $xavp(pres=>priority) = 100; -} -... - -3.31. retrieve_order (int) - - If set to 0, presentity records are retrieved by received_time order. - If set to 1, presentity records are retrieved by the value of - retrieve_order_by parameter. - - Default value is 0. - - Example 1.31. Set retrieve_order parameter -... -modparam("presence", "retrieve_order", 1) -... - -3.32. retrieve_order_by (str) - - Used to set the order-by of the db query for fetching the presence - records when retrieve_order is set to 1. - - Default value is “priority”. - - Example 1.32. Set retrieve_order_by parameter -... -modparam("presence", "retrieve_order_by", "priority, received_time") -... - -3.33. sip_uri_match (int) - - The mode used when comparing uris. - - Possible Values - * 0 : case sensitive - * 1 : case insensitive - - Default value is “0”. - - Example 1.33. Set sip_uri_match parameter -... -modparam("presence", "sip_uri_match", 1) -... - -3.34. enable_dmq (integer) - - If set to 1, will enable DMQ replication of presentities between nodes. - Use this instead of a shared DB to share state across a cluster and - update local watchers in realtime (subs_db_mode < 3) or on next - notifier run (subs_db_mode = 3). - - If this parameter is enabled, the DMQ module must be loaded first - - otherwise, startup will fail. - - Default value is 0. - - Example 1.34. Set enable_dmq parameter -... -modparam("presence", "enable_dmq", 1) -... - -3.35. pres_subs_mode (integer) - - Allow disabling cloning subscription structure for pv $subs(...), - saving the pkg memory and copy operations for all its fields. If 1 the - cloning is done; if 0, no cloning and $subs(...) returns $null. - - Default value is 1. - - Example 1.35. Set pres_subs_mode parameter -... -modparam("presence", "pres_subs_mode", 0) -... - -3.36. delete_same_subs (integer) - - Enable deleting of subscriptions with the same presence uri and callid. - - Default value is 0 (disabled behavior). - - Example 1.36. Set delete_same_subs parameter -... -modparam("presence", "delete_same_subs", 1) -... - -3.37. timer_mode (integer) - - Specify what timer process to be used. If set to 0, the core main timer - is used. If set to 1, the core secondary timer is used. - - Default value is 1. - - Example 1.37. Set timer_mode parameter -... -modparam("presence", "timer_mode", 0) -... - -3.38. subs_respond_200 (integer) - - Specify the response code for accepted SUBSCRIBE requests. If set to 0, - "202 Accepted" will be returned (default behaviour till version 5.5). - If set to 1, "200 OK" will be returned instead, in conformance to - RFC6665, which prohibits 202 responses. - - Default value is 1. - - Example 1.38. Set subs_respond_200 parameter -... -modparam("presence", "subs_respond_200", 0) -... - -4. Functions - - 4.1. handle_publish([sender_uri]) - 4.2. handle_subscribe([watcher_uri]) - 4.3. pres_auth_status(watcher_uri, presentity_uri) - 4.4. pres_has_subscribers(presentity_uri, event) - 4.5. pres_refresh_watchers(uri, event, type[, file_uri, filename]) - 4.6. pres_update_watchers(uri, event) - -4.1. handle_publish([sender_uri]) - - Handles PUBLISH requests by storing and updating published information - in memory cache and database, then calls functions to send NOTIFY - messages when changes in the published information occur. It takes one - argument -> sender_uri. The parameter was added for enabling BLA - implementation. If present, notification of a change in published state - is not sent to the respective uri even though a subscription exists. It - should be taken from the Sender header. It was left at the decision of - the administrator whether or not to transmit the content of this header - as parameter for handle_publish, to prevent security problems. - - This function can be used from REQUEST_ROUTE. - - Return code: - * 1 - if success. - * -1 - if error. - - The module sends an appropriate stateless reply in all cases. - - Example 1.39. handle_publish usage -... - if(is_method("PUBLISH")) - { - if($hdr(Sender)!= NULL) - handle_publish("$hdr(Sender)"); - else - handle_publish(); - t_release(); - } -... - -4.2. handle_subscribe([watcher_uri]) - - The function which handles SUBSCRIBE requests. It stores or updates - information in memory and database and calls functions to send NOTIFY - messages when a SUBSCRIBE which initiate a dialog is received. - - By default this function uses the From: URI from the SUBSCRIBE request - as the Watcher URI. The optional watcher_uri parameter can be used to - specify a different Watcher URI, possibly taken from a SIP header like - P-Asserted-Identity:. - - This function can be used from REQUEST_ROUTE. - - Return code: - * 1 - if success. - * -1 - if error. - - The module sends an appropriate stateless reply in all cases. - - Example 1.40. handle_subscribe usage -... -if(method=="SUBSCRIBE") - handle_subscribe(); -... - -4.3. pres_auth_status(watcher_uri, presentity_uri) - - The function checks if watcher URI is authorized to subscribe event - 'presence' of presentity URI. Both watcher_uri and presentity_uri can - be static strings or contain pseudo variables. - - The function returns ACTIVE_STATUS, if subscription is allowed, and - PENDING_STATUS, TERMINATED_STATUS, or WAITING_STATUS otherwise. See - presence/subscribe.h for the corresponding integer codes. In case of - error, function returns -1. - - This function can be used from REQUEST_ROUTE. - - Example 1.41. pres_auth_status usage -... -if (method=="MESSAGE") { - pres_auth_status("$fu", $ru"); - if ($retcode == 1) { - t_relay(); - } else { - send_reply("403", "Forbidden"); - } -} -... - -4.4. pres_has_subscribers(presentity_uri, event) - - Allows to check if presentity has any subscribers of event. - - This function can be used from ANY_ROUTE. - - Example 1.42. pres_has_subscribers usage -... -if(pres_has_subscribers($var(uri), "message-summary")) - # do something...; -... - -4.5. pres_refresh_watchers(uri, event, type[, file_uri, filename]) - - The function can be used in configuration to trigger notifies to - watchers if a change in watchers authorization or in published state - occurred (i.e., updates of xcap documents). - - Parameters: - * uri - the uri of the user who made the change and whose watchers - should be informed. - * event - the event package. - * type - it distinguishes between the three different types of events - that can trigger the refresh, depending on its value: - + 0 - a change in watchers authentication. - + 1 - a statical update in published state through direct update - in db table. - + 2 - a statical update in published state by modifying the pidf - manipulation document. - * file_uri - the uri of the pidf-manipulation file on the XCAP server - (only used for type 2). - * filename - the name of the pidf-manipulation file on the XCAP - server (only used for type 2). - - This function can be used from ANY_ROUTE. - - Example 1.43. pres_refresh_watchers usage -... -pres_refresh_watchers("sip:test@kamailio.org", "presence", 1); -... - -4.6. pres_update_watchers(uri, event) - - The function can be used in configuration to trigger updates to - watchers status if a change in watchers authorization state occurred - (i.e., updates of xcap documents change state from pending to active). - - Parameters: - * uri - the uri of the user who made the change and whose watchers - should be informed. Can be PV. - * event - the event package (e.g., presence). - - This function can be used from ANY_ROUTE. - - Example 1.44. pres_update_watchers usage -... -pres_update_watchers("sip:test@kamailio.org", "presence"); -... - -5. RPC Commands - - 5.1. presence.cleanup - 5.2. presence.refreshWatchers - 5.3. presence.updateWatchers - 5.4. presence.presentity_list - 5.5. presence.presentity_show - 5.6. presence.watcher_list - -5.1. presence.cleanup - - Manually triggers the cleanup functions for the active_watchers, - presentity, and watchers tables. Useful if you have set clean_period - and/or db_update_period to zero or less. - - Name: presence.cleanup - - Parameters: none - - RPC Command Format: -... -kamcmd presence.cleanup -... - -5.2. presence.refreshWatchers - - Triggers sending Notify messages to watchers if a change in watchers - authorization or in published state occurred. - - Name: presence.refreshWatchers - - Parameters: - * uri - the uri of the user who made the change and whose watchers - should be informed - * event - the event package. - * type - it distinguishes between the three different types of events - that can trigger the refresh, depending on its value: - + 0 - a change in watchers authentication. - + 1 - a statical update in published state through direct update - in db table. - + 2 - a statical update in published state by modifying the pidf - manipulation document. - * file_uri - the uri of the pidf-manipulation file on the XCAP server - (only used for type 2). - * filename - the name of the pidf-manipulation file on the XCAP - server (only used for type 2). - - RPC Command Format: -... -kamcmd presence.refreshWatchers sip:test@kamailio.org presence 1 -... - -5.3. presence.updateWatchers - - Manually triggers updates to watchers (for example, after the contents - of XCAP docs has been updated). - - Name: presence.updateWatchers - - Parameters: - * uri - the uri of the user who made the changes and whose watchers - should be updated. - * event - the event package (e.g. presence). - - RPC Command Format: -... -kamcmd presence.updateWatchers sip:alice@domain.com presence -... - -5.4. presence.presentity_list - - List the presentity records stored in memory. - - Name: presence.presentity_list - - Parameters: - * mode - (optional) it can be 'full' to print all the fields of - presentity record. If missing, only a selected set of fields are - printed in the response. - - RPC Command Format: -... -kamctl rpc presence.presentity_list -kamctl rpc presence.presentity_list full -... - -5.5. presence.presentity_show - - Return the presentity records stored in memory by filtering with - username and/or domain. - - Name: presence.presentity_show - - Parameters: - * mode - it can be 'basic' or 'full' to print a selection or all the - fields of presentity record. - * user - username to match presentity records, use '*' to match any - username. - * domain - the value to match the domain of the presentity records, - use '*' to match any domain. - - RPC Command Format: -... -kamctl rpc presence.presentity_show basic alice sipserver.com -kamctl rpc presence.presentity_show full * sipserver.com -... - -5.6. presence.watcher_list - - Return the watcher records for a specific presentity uri. - - Name: presence.watcher_list - - Parameters: - * mode - it can be 'basic' or 'full' to print a selection or all the - fields of watcher record. - * uri - the presentity uri. - - RPC Command Format: -... -kamctl rpc presence.watcher_list basic sip:alice@sipserver.com -... - -6. Exported Variables - - 6.1. $subs(attr) - 6.2. $notify_reply(attr) - -6.1. $subs(attr) - - Access the attributes of handled subscription. It must be used after a - successful call of “handle_subscription()” or in the following events. - * tm:local-request - before notify is sent - * presence:notify-reply - after notify is sent - - The “attr” can be: - * uri - subscription presentity uri - * pres_uri - alias for presentity uri - * to_user - * to_domain - * from_user - * from_domain - * watcher_username - * watcher_domain - * event - * event_id - * to_tag - * from_tag - * callid - * remote_cseq - * local_cseq - * contact - * local_contact - * record_route - * expires - * status - * reason - * version - * flags - * user_agent - - Example 1.45. $subs(name) usage -... -if(handle_subscription()) -{ - xlog("presentity=$subs(uri)\n"); -} -... - -6.2. $notify_reply(attr) - - Access the reply message received when notifying subscriber. It must be - used in the following events. - * presence:notify-reply - after notify is sent - - The “attr” can be any pseudo var that accesses attributes of msg - - Example 1.46. $notify_reply(name) usage -... -event_route[presence:notify-reply] -{ - xlog("received message = $notify_reply($mb)\n"); -} -... - -7. Events - - 7.1. presence:notify-reply - -7.1. presence:notify-reply - - Fired after notify reply is received or timeout. - - Example 1.47. $notify_reply(name) usage -... -event_route[presence:notify-reply] -{ - xlog("received message = $notify_reply($mb)\n"); -} -... - -8. Installation - - The module requires 3 tables in the Kamailio database: "presentity", - "active_watchers" and "watchers". The SQL syntax to create them can be - found in presence-create.sql script in the database directories in the - kamailio/scripts folder. You can also find the complete database - documentation on the project webpage, - https://www.kamailio.org/docs/db-tables/kamailio-db-devel.html. - -Chapter 2. Developer Guide - - Table of Contents - - 1. bind_presence(presence_api_t* api) - 2. add_event - 3. get_rules_doc - 4. get_auth_status - 5. apply_auth_nbody - 6. agg_nbody - 7. free_body - 8. aux_body_processing - 9. aux_free_body - 10. evs_publ_handl - 11. evs_subs_handl - 12. contains_event - 13. get_event_list - 14. update_watchers_status - 15. get_sphere - 16. get_presentity - 17. free_presentity - - The module provides the following functions that can be used in other - Kamailio modules. - -1. bind_presence(presence_api_t* api) - - This function binds the presence modules and fills the structure with - one exported function -> add_event, which when called adds a new event - to be handled by presence. - - Example 2.1. presence_api_t structure -... -typedef struct presence_api { - add_event_t add_event; - contains_event_t contains_event; - search_event_t search_event; - get_event_list_t get_event_list; - - update_watchers_t update_watchers_status; - - /* subs hash table handling functions */ - new_shtable_t new_shtable; - destroy_shtable_t destroy_shtable; - insert_shtable_t insert_shtable; - search_shtable_t search_shtable; - delete_shtable_t delete_shtable; - update_shtable_t update_shtable; - /* function to duplicate a subs structure*/ - mem_copy_subs_t mem_copy_subs; - /* function used for update in database*/ - update_db_subs_t update_db_subs_timer; - /* function to extract dialog information from a - SUBSCRIBE message */ - extract_sdialog_info_t extract_sdialog_info; - /* function to request sphere definition for a presentity */ - pres_get_sphere_t get_sphere; - -}presence_api_t; -... - -2. add_event - - Field type: -... -typedef int (*add_event_t)(pres_ev_t* event); -... - - This function receives as a parameter a structure with event specific - information and adds it to presence event list. - - The structure received as a parameter: -... -typedef struct pres_ev -{ - str name; - event_t* evp; - str content_type; - int default_expires; - int type; - int etag_not_new; - /* - * 0 - the standard mechanism (allocating new etag - for each Publish) - * 1 - allocating an etag only - for an initial Publish - */ - int req_auth; - get_rules_doc_t* get_rules_doc; - apply_auth_t* apply_auth_nbody; - is_allowed_t* get_auth_status; - - /* an agg_body_t function should be registered - * if the event permits having multiple published - * states and requires an aggregation of the information - * otherwise, this field should be NULL and the last - * published state is taken when constructing Notify msg - */ - agg_nbody_t* agg_nbody; - publ_handling_t * evs_publ_handl; - subs_handling_t * evs_subs_handl; - free_body_t* free_body; - /* sometimes it is necessary that a module make changes for a body for each - * active watcher (e.g. setting the "version" parameter in an XML document. - * If a module registers the aux_body_processing callback, it gets called fo -r - * each watcher. It either gets the body received by the PUBLISH, or the bod -y - * generated by the agg_nbody function. - * The module can decide if it makes a copy of the original body, which is t -hen - * manipulated, or if it works directly in the original body. If the module -makes a - * copy of the original body, it also has to register the aux_free_body() to - * free this "per watcher" body. - */ - aux_body_processing_t* aux_body_processing; - free_body_t* aux_free_body; - struct pres_ev* wipeer; - struct pres_ev* next; - -}pres_ev_t; -... - -3. get_rules_doc - - Filed type: -... -typedef int (get_rules_doc_t)(str* user, str* domain, str** rules_doc); -... - - This function returns the authorization rules document that will be - used in obtaining the status of the subscription and processing the - notified body. A reference to the document should be put in the - auth_rules_doc of the subs_t structure given as a parameter to the - functions described below. - -4. get_auth_status - - This filed is a function to be called for a subscription request to - return the state for that subscription according to authorization - rules. In the auth_rules_doc field of the subs_t structure received as - a parameter should contain the rules document of the presentity in - case, if it exists. - - It is called only if the req_auth field is not 0. - - Filed type: -... -typedef int (is_allowed_t)(struct subscription* subs); -... - -5. apply_auth_nbody - - This parameter should be a function to be called for an event that - requires authorization, when constructing final body. The authorization - document is taken from the auth_rules_doc field of the subs_t structure - given as a parameter. It is called only if the req_auth field is not 0. - - Filed type: -... -typedef int (apply_auth_t)(str* , struct subscription*, str** ); -... - -6. agg_nbody - - If present, this field marks that the events requires aggregation of - states. This function receives a body array and should return the final - body. If not present, it is considered that the event does not require - aggregation and the most recent published information is used when - constructing Notifies. - - Filed type: -... -typedef str* (agg_nbody_t)(str* pres_user, str* pres_domain, -str** body_array, int n, int off_index); -.. - -7. free_body - - This field must be field in if subsequent processing is performed on - the info from database before being inserted in Notify message body(if - agg_nbody or apply_auth_nbody fields are filled in). It should match - the allocation function used when processing the body. - - Filed type: -... -typedef void(free_body_t)(char* body); -.. - -8. aux_body_processing - - This field must be set if the module needs to manipulate the NOTIFY - body for each watcher. E.g. if the XML body includes a 'version' - parameter which will be increased for each NOTIFY, on a "per watcher" - basis. The module can either allocate a new buffer for the new body and - return it (aux_free_body function must be set too) or it manipulates - the original body directly and returns NULL. - - Filed type: -... -typedef str* (aux_body_processing_t)(struct subscription *subs, str* body); -.. - -9. aux_free_body - - This field must be set if the module registers the aux_body_processing - function and allocates memory for the new modified body. Then, this - function will be used to free the pointer returned by the - aux_body_processing function. If the module does use the - aux_body_processing, but does not allocate new memory, but manipulates - directly the original body buffer, then the aux_body_processing must - return NULL and this field should not be set. - - Filed type: -... -typedef void(free_body_t)(char* body); -.. - -10. evs_publ_handl - - This function is called when handling Publish requests. Most contain - body correctness check. - -... -typedef int (publ_handling_t)(struct sip_msg*); -.. - -11. evs_subs_handl - - It is not compulsory. Should contain event specific handling for - Subscription requests. - - Filed type: -... -typedef int (subs_handling_t)(struct sip_msg*); -.. - -12. contains_event - - Field type: -.. -typedef pres_ev_t* (*contains_event_t)(str* name, -event_t* parsed_event); -... - - The function parses the event name received as a parameter and searches - the result in the list. It returns the found event or NULL, if not - found. If the second argument is an allocated event_t* structure it - fills it with the result of the parsing. - -13. get_event_list - - Field type: -... -typedef int (*get_event_list_t) (str** ev_list); -... - - This function returns a string representation of the events registered - in presence module (used for Allowed-Events header). - -14. update_watchers_status - - Field type: -... -typedef int (*update_watchers_t)(str pres_uri, pres_ev_t* ev, -str* rules_doc); -... - - This function is an external command that can be used to announce a - change in authorization rules for a presentity. It updates the stored - status and sends a Notify to the watchers whose status has changes. - (used by presence_xml module when notified through an RPC command of a - change in an xcap document). - -15. get_sphere - - Field type: -... -typedef char* (*pres_get_sphere_t)(str* pres_uri); -... - - This function searches for a sphere definition in the published - information if this has type RPID. If not found returns NULL. (the - return value is allocated in private memory and should be freed) - -16. get_presentity - - Field type: -... -typedef str* (*pres_get_presentity_t)(str pres_uri, pres_ev_t *ev, str *etag, st -r *contact); -... - - This function returns a pointer to a str containing an XML document - with all of the matching presentities. If no matching presentities are - found the function returns NULL. - - The etag and contact parameters are optional and may be set to NULL. - Once you are finished with the presentity document you must call - free_presentity to free the allocated memory. - -17. free_presentity - - Field type: -... -typedef void (*pres_free_presentity_t)(str *presentity, pres_ev_t *ev); -... - - This function frees memory allocated by a call to get_presentity. The - ev parameter MUST point to the same pres_ev_t data-structure that was - used in the call to get_presentity. diff --git a/src/modules/presence/doc/presence_admin.xml b/src/modules/presence/doc/presence_admin.xml index dbad0acf6..503fd6159 100644 --- a/src/modules/presence/doc/presence_admin.xml +++ b/src/modules/presence/doc/presence_admin.xml @@ -796,7 +796,7 @@ modparam("presence", "subs_remove_match", 1) give extra control of deleting the subscription after processing of event_route[presence:notify-reply]. If value = 1, it deletes the subscription. If xavp_cfg parameter is set but this attribute is not in the avp, - the subscription is not deleted. this does not apply for codes 404, 481 + the subscription is not deleted. This does not apply for codes 404, 481 and 408 (when timeout_rm_subs = 1) where subscription is deleted. @@ -1284,6 +1284,26 @@ pres_update_watchers("sip:test@kamailio.org", "presence"); ... + +
+ presence.publish_cache_sync + + Synchronize changes made to the presentity table with the publish cache. + + + Name: presence.publish_cache_sync + + Parameters: none + + RPC Command Format: + + +... +&kamcmd; presence.publish_cache_sync +... + +
+
presence.refreshWatchers diff --git a/src/modules/presence/notify.c b/src/modules/presence/notify.c index a3bba03e2..4c9dece1a 100644 --- a/src/modules/presence/notify.c +++ b/src/modules/presence/notify.c @@ -1726,12 +1726,12 @@ jump_over_body: set_uac_req(&uac_r, &met, &str_hdr, notify_body, td, TMCB_LOCAL_COMPLETED, p_tm_callback, (void *)cb_param); - result = tmb.t_request_within(&uac_r); + result = _pres_tmb.t_request_within(&uac_r); if(_pres_subs_mode == 1) { _pres_subs_last_sub = backup_subs; } if(result < 0) { - LM_ERR("in function tmb.t_request_within\n"); + LM_ERR("in function tm t_request_within()\n"); if(cb_param) shm_free(cb_param); goto error; diff --git a/src/modules/presence/presence.c b/src/modules/presence/presence.c index f2e4036d6..9315c0d6f 100644 --- a/src/modules/presence/presence.c +++ b/src/modules/presence/presence.c @@ -111,9 +111,9 @@ static int sip_uri_case_sensitive_match(str *s1, str *s2); static int sip_uri_case_insensitive_match(str *s1, str *s2); /* TM bind */ -struct tm_binds tmb; +struct tm_binds _pres_tmb; /* SL API structure */ -sl_api_t slb; +sl_api_t _pres_slb; /** module functions */ @@ -340,13 +340,13 @@ static int mod_init(void) } /* bind the SL API */ - if(sl_load_api(&slb) != 0) { + if(sl_load_api(&_pres_slb) != 0) { LM_ERR("cannot bind to SL API\n"); return -1; } /* load all TM stuff */ - if(load_tm_api(&tmb) == -1) { + if(load_tm_api(&_pres_tmb) == -1) { LM_ERR("Can't load tm functions. Module TM not loaded?\n"); return -1; } @@ -1859,6 +1859,23 @@ static const char *rpc_presence_cleanup_doc[3] = { "presentity, and watchers tables.", 0}; + +void rpc_presence_publish_cache_sync(rpc_t *rpc, void *ctx) +{ + LM_DBG("Synchronizing presentity table with the publish cache.\n"); + if(pres_htable_db_restore() == -1) { + rpc->fault(ctx, 500, + "Failed to sync presinity table with the publish cache."); + } else { + rpc->rpl_printf(ctx, "OK"); + } + return; +} + +static const char *rpc_presence_publish_cache_sync_doc[4] = { + "Syncs changes made to presentity table with the publish cache.", 0}; + + /*! \brief * Build the rpc response for listing presentity records * - imode - output attributes control @@ -2124,6 +2141,8 @@ static const char *rpc_presence_watcher_list_doc[2] = { rpc_export_t presence_rpc[] = { + {"presence.publish_cache_sync", rpc_presence_publish_cache_sync, + rpc_presence_publish_cache_sync_doc, 0}, {"presence.cleanup", rpc_presence_cleanup, rpc_presence_cleanup_doc, 0}, {"presence.refreshWatchers", rpc_presence_refresh_watchers, rpc_presence_refresh_watchers_doc, 0}, diff --git a/src/modules/presence/presence.h b/src/modules/presence/presence.h index 390aee49f..5dc6490ef 100644 --- a/src/modules/presence/presence.h +++ b/src/modules/presence/presence.h @@ -57,9 +57,9 @@ #define PS_PCACHE_RECORD 2 /** TM bind */ -extern struct tm_binds tmb; +extern struct tm_binds _pres_tmb; -extern sl_api_t slb; +extern sl_api_t _pres_slb; /* DB module bind */ extern db_func_t pa_dbf; diff --git a/src/modules/presence/presentity.c b/src/modules/presence/presentity.c index 60edf348e..1c3dac8f8 100644 --- a/src/modules/presence/presentity.c +++ b/src/modules/presence/presentity.c @@ -143,7 +143,7 @@ int publ_send200ok(struct sip_msg *msg, int lexpire, str etag) goto error; } - if(slb.freply(msg, 200, &pu_200_rpl) < 0) { + if(_pres_slb.freply(msg, 200, &pu_200_rpl) < 0) { LM_ERR("sending reply\n"); goto error; } @@ -1377,7 +1377,7 @@ send_412: } if(msg != NULL) { - if(slb.freply(msg, 412, &pu_412_rpl) < 0) { + if(_pres_slb.freply(msg, 412, &pu_412_rpl) < 0) { LM_ERR("sending '412 Conditional request failed' reply\n"); goto error; } @@ -1858,7 +1858,7 @@ send_412: } if(msg != NULL) { - if(slb.freply(msg, 412, &pu_412_rpl) < 0) { + if(_pres_slb.freply(msg, 412, &pu_412_rpl) < 0) { LM_ERR("sending '412 Conditional request failed' reply\n"); goto error; } diff --git a/src/modules/presence/publish.c b/src/modules/presence/publish.c index 2399ff43e..fa39498d9 100644 --- a/src/modules/presence/publish.c +++ b/src/modules/presence/publish.c @@ -46,8 +46,6 @@ #include "publish.h" #include "presentity.h" -extern gen_lock_set_t *set; - static str pu_400a_rpl = str_init("Bad request"); static str pu_400b_rpl = str_init("Invalid request"); static str pu_500_rpl = str_init("Server Internal Error"); @@ -713,4 +711,4 @@ done: } return ret; -} \ No newline at end of file +} diff --git a/src/modules/presence/subscribe.c b/src/modules/presence/subscribe.c index d5e09e401..eb3e865a3 100644 --- a/src/modules/presence/subscribe.c +++ b/src/modules/presence/subscribe.c @@ -124,7 +124,7 @@ static int send_2XX_reply(sip_msg_t *msg, int reply_code, unsigned int lexpire, goto error; } - if(slb.freply(msg, reply_code, &su_200_rpl) < 0) { + if(_pres_slb.freply(msg, reply_code, &su_200_rpl) < 0) { LM_ERR("sending reply\n"); goto error; } @@ -996,7 +996,7 @@ int handle_subscribe0(struct sip_msg *msg) if(parse_from_uri(msg) == NULL) { LM_ERR("failed to find From header\n"); - if(slb.freply(msg, 400, &pu_400_rpl) < 0) { + if(_pres_slb.freply(msg, 400, &pu_400_rpl) < 0) { LM_ERR("while sending 400 reply\n"); return -1; } @@ -1418,7 +1418,8 @@ int extract_sdialog_info_ex(subs_t *subs, struct sip_msg *msg, uint32_t miexp, LM_DBG("generating to_tag\n"); *to_tag_gen = 1; rtag_value.len = 0; - if(slb.get_reply_totag(msg, &rtag_value) < 0 || rtag_value.len <= 0) { + if(_pres_slb.get_reply_totag(msg, &rtag_value) < 0 + || rtag_value.len <= 0) { LM_ERR("while creating to_tag\n"); goto error; } diff --git a/src/modules/presence/utils_func.c b/src/modules/presence/utils_func.c index 00552fe31..a0f13cf22 100644 --- a/src/modules/presence/utils_func.c +++ b/src/modules/presence/utils_func.c @@ -132,7 +132,7 @@ int send_error_reply(struct sip_msg *msg, int reply_code, str reply_str) } } - if(slb.freply(msg, reply_code, &reply_str) < 0) { + if(_pres_slb.freply(msg, reply_code, &reply_str) < 0) { LM_ERR("sending %d %.*s reply\n", reply_code, reply_str.len, reply_str.s); return -1; diff --git a/src/modules/presence_dialoginfo/pidf.c b/src/modules/presence_dialoginfo/pidf.c index 958523794..382045eab 100644 --- a/src/modules/presence_dialoginfo/pidf.c +++ b/src/modules/presence_dialoginfo/pidf.c @@ -141,6 +141,7 @@ time_t xml_parse_dateTime(char *xml_time_str) char h1, h2, m1, m2; int sign = 1; signed int timezone_diff = 0; + int rv = 0; p = strptime(xml_time_str, "%F", &tm); if(p == NULL) { @@ -178,7 +179,8 @@ time_t xml_parse_dateTime(char *xml_time_str) p++; - if(sscanf(p, "%c%c:%c%c", &h1, &h2, &m1, &m2) < 0) { + rv = sscanf(p, "%c%c:%c%c", &h1, &h2, &m1, &m2); + if(rv == EOF || rv < 4) { printf("error: failed to parse time\n"); return 0; } diff --git a/src/modules/presence_xml/pidf.c b/src/modules/presence_xml/pidf.c index 09d11438a..b9c85c654 100644 --- a/src/modules/presence_xml/pidf.c +++ b/src/modules/presence_xml/pidf.c @@ -181,7 +181,7 @@ time_t xml_parse_dateTime(char *xml_time_str) p++; - if(sscanf(p, "%c%c:%c%c", &h1, &h2, &m1, &m2) < 0) { + if(sscanf(p, "%c%c:%c%c", &h1, &h2, &m1, &m2) < 4) { printf("error: failed to parse time\n"); return 0; } diff --git a/src/modules/pua/add_events.c b/src/modules/pua/add_events.c index e2fc78be3..bf4a437e4 100644 --- a/src/modules/pua/add_events.c +++ b/src/modules/pua/add_events.c @@ -82,7 +82,7 @@ int pua_add_events(void) } /* add application/reginfo+xml */ - if(dlginfo_increase_version) { + if(reginfo_increase_version) { if(add_pua_event(REGINFO_EVENT, "reg", "application/reginfo+xml", reginfo_process_body) < 0) { diff --git a/src/modules/pua_dialoginfo/pua_dialoginfo.c b/src/modules/pua_dialoginfo/pua_dialoginfo.c index 6efcdc0a8..22a2fb11d 100644 --- a/src/modules/pua_dialoginfo/pua_dialoginfo.c +++ b/src/modules/pua_dialoginfo/pua_dialoginfo.c @@ -83,6 +83,7 @@ unsigned short pubruri_callee_avp_type; int_str pubruri_callee_avp_name; sruid_t _puadi_sruid; +static char *DLG_VAR_SEP = ","; static str caller_dlg_var = {0, 0}; /* pubruri_caller */ static str callee_dlg_var = {0, 0}; /* pubruri_callee */ static str caller_entity_when_publish_disabled = {0, 0}; /* pubruri_caller */ @@ -596,7 +597,6 @@ struct str_list *get_str_list(unsigned short avp_flags, int_str avp_name) { int_str avp_value; - unsigned int len; struct str_list *list_first = 0; struct str_list *list_current = 0; struct search_state st; @@ -606,33 +606,123 @@ struct str_list *get_str_list(unsigned short avp_flags, int_str avp_name) } do { - LM_DBG("AVP found '%.*s'\n", avp_value.s.len, avp_value.s.s); - - len = sizeof(struct str_list) + avp_value.s.len; - if(list_current) { - list_current->next = (struct str_list *)shm_malloc(len); + list_current->next = + (struct str_list *)shm_malloc(sizeof(struct str_list)); list_current = list_current->next; } else { - list_current = list_first = (struct str_list *)shm_malloc(len); + list_current = list_first = + (struct str_list *)shm_malloc(sizeof(struct str_list)); } - if(list_current == 0) { + if(!list_current) { SHM_MEM_ERROR; - return 0; + free_str_list_all(list_first); + return NULL; + } + memset(list_current, 0, sizeof(struct str_list)); + list_current->s.s = shm_str2char_dup(&avp_value.s); + if(!list_current->s.s) { + free_str_list_all(list_first); + return NULL; } + list_current->s.len = avp_value.s.len; + } while(search_next_avp(&st, &avp_value)); - memset(list_current, 0, len); + return list_first; +} - list_current->s.s = (char *)list_current + sizeof(struct str_list); - list_current->s.len = avp_value.s.len; - memcpy(list_current->s.s, avp_value.s.s, avp_value.s.len); +/** + * @brief set dlg_var value from str_list as comma separated values + * + * @param dlg dialog + * @param key dlg_var keyname + * @param lst list of str values + * @return int + */ +static int set_dlg_var(struct dlg_cell *dlg, str *key, struct str_list *lst) +{ + str buf = STR_NULL; + struct str_list *it = lst; + int num = -1; + int res; + if(!lst) + return -1; - } while(search_next_avp(&st, &avp_value)); + while(it) { + buf.len += it->s.len + ++num; + it = it->next; + } + buf.s = (char *)pkg_malloc(sizeof(char) * buf.len); + + it = lst; + num = 0; + while(it) { + memcpy(buf.s + num, it->s.s, it->s.len); + if(it->next) { + num += it->s.len; + buf.s[num++] = *DLG_VAR_SEP; + } + it = it->next; + } + res = dlg_api.set_dlg_var(dlg, key, &buf); + pkg_free(buf.s); - return list_first; + return res; +} + +static int get_dlg_var(struct dlg_cell *dlg, str *key, struct str_list **lst) +{ + str dval = STR_NULL; + str val = STR_NULL; + struct str_list *it, *prev; + char *sep, *ini, *end; + + if(dlg_api.get_dlg_varval(dlg, &caller_dlg_var, &dval) != 0 + || dval.s == NULL) + return 0; + + if(*lst) { + free_str_list_all(*lst); + } + *lst = prev = NULL; + ini = dval.s; + end = dval.s + dval.len - 1; + sep = stre_search_strz(ini, end, DLG_VAR_SEP); + if(!sep) + sep = end; + do { + val.s = ini; + val.len = sep - ini + 1; + ini = sep + 1; + it = (struct str_list *)shm_malloc(sizeof(struct str_list)); + if(!it) { + SHM_MEM_ERROR; + return -1; + } + memset(it, 0, sizeof(struct str_list)); + it->s.s = shm_str2char_dup(&val); + if(!it->s.s) { + free_str_list_all(*lst); + return -1; + } + it->s.len = val.len; + LM_DBG("Found uri '%.*s' in dlg_var:'%.*s'\n", val.len, val.s, key->len, + key->s); + if(!*lst) { + *lst = prev = it; + } else { + prev->next = it; + } + if(ini < end) + sep = stre_search_strz(ini, end, DLG_VAR_SEP); + else + sep = NULL; + } while(sep); + + return 0; } struct dlginfo_cell *get_dialog_data(struct dlg_cell *dlg, int type, @@ -640,7 +730,6 @@ struct dlginfo_cell *get_dialog_data(struct dlg_cell *dlg, int type, { struct dlginfo_cell *dlginfo; int len; - str dval = {0}; // generate new random uuid if(sruid_next_safe(&_puadi_sruid) < 0) { @@ -701,59 +790,35 @@ struct dlginfo_cell *get_dialog_data(struct dlg_cell *dlg, int type, dlginfo->pubruris_callee = get_str_list( pubruri_callee_avp_type, pubruri_callee_avp_name); - if(dlginfo->pubruris_callee != NULL && callee_dlg_var.len > 0) - dlg_api.set_dlg_var( - dlg, &callee_dlg_var, &dlginfo->pubruris_callee->s); - - if(dlginfo->pubruris_caller != NULL && caller_dlg_var.len > 0) - dlg_api.set_dlg_var( - dlg, &caller_dlg_var, &dlginfo->pubruris_caller->s); - + if(dlginfo->pubruris_callee != NULL && callee_dlg_var.len > 0) { + if(set_dlg_var(dlg, &callee_dlg_var, dlginfo->pubruris_callee) + < 0) { + free_str_list_all(dlginfo->pubruris_callee); + dlginfo->pubruris_callee = NULL; + } + } + if(dlginfo->pubruris_caller != NULL && caller_dlg_var.len > 0) { + if(set_dlg_var(dlg, &caller_dlg_var, dlginfo->pubruris_caller) + < 0) { + free_str_list_all(dlginfo->pubruris_caller); + dlginfo->pubruris_caller = NULL; + } + } } else { - if(caller_dlg_var.len > 0 - && (dlg_api.get_dlg_varval(dlg, &caller_dlg_var, &dval) - == 0) - && dval.s != NULL) { - dlginfo->pubruris_caller = (struct str_list *)shm_malloc( - sizeof(struct str_list) + dval.len + 1); - if(dlginfo->pubruris_caller == 0) { - SHM_MEM_ERROR; + if(caller_dlg_var.len > 0) { + if(get_dlg_var(dlg, &caller_dlg_var, &dlginfo->pubruris_caller) + < 0) { free_dlginfo_cell(dlginfo); return NULL; } - memset(dlginfo->pubruris_caller, 0, sizeof(struct str_list)); - dlginfo->pubruris_caller->s.s = - (char *)dlginfo->pubruris_caller - + sizeof(sizeof(struct str_list)); - memcpy(dlginfo->pubruris_caller->s.s, dval.s, dval.len); - dlginfo->pubruris_caller->s.s[dval.len] = '\0'; - dlginfo->pubruris_caller->s.len = dval.len; - LM_DBG("Found pubruris_caller in dialog '%.*s'\n", - dlginfo->pubruris_caller->s.len, - dlginfo->pubruris_caller->s.s); } - if(callee_dlg_var.len > 0 - && (dlg_api.get_dlg_varval(dlg, &callee_dlg_var, &dval) - == 0) - && dval.s != NULL) { - dlginfo->pubruris_callee = (struct str_list *)shm_malloc( - sizeof(struct str_list) + dval.len + 1); - if(dlginfo->pubruris_callee == 0) { - SHM_MEM_ERROR; + if(callee_dlg_var.len > 0) { + if(get_dlg_var(dlg, &callee_dlg_var, &dlginfo->pubruris_callee) + < 0) { free_dlginfo_cell(dlginfo); return NULL; } - memset(dlginfo->pubruris_callee, 0, sizeof(struct str_list)); - dlginfo->pubruris_callee->s.s = - (char *)dlginfo->pubruris_callee - + sizeof(sizeof(struct str_list)); - memcpy(dlginfo->pubruris_callee->s.s, dval.s, dval.len); - dlginfo->pubruris_callee->s.s[dval.len] = '\0'; - dlginfo->pubruris_callee->s.len = dval.len; - LM_DBG("Found pubruris_callee in dialog '%.*s'\n", - dlginfo->pubruris_callee->s.len, - dlginfo->pubruris_callee->s.s); } } @@ -772,7 +837,11 @@ struct dlginfo_cell *get_dialog_data(struct dlg_cell *dlg, int type, return NULL; } memset(dlginfo->pubruris_caller, 0, sizeof(struct str_list)); - dlginfo->pubruris_caller->s = dlginfo->from_uri; + dlginfo->pubruris_caller->s.s = shm_str2char_dup(&dlginfo->from_uri); + if(!dlginfo->pubruris_caller->s.s) { + free_dlginfo_cell(dlginfo); + return NULL; + } dlginfo->pubruris_callee = (struct str_list *)shm_malloc(sizeof(struct str_list)); @@ -784,9 +853,11 @@ struct dlginfo_cell *get_dialog_data(struct dlg_cell *dlg, int type, memset(dlginfo->pubruris_callee, 0, sizeof(struct str_list)); if(include_req_uri) { - dlginfo->pubruris_callee->s = dlginfo->req_uri; + dlginfo->pubruris_callee->s.s = shm_str2char_dup(&dlginfo->req_uri); + dlginfo->pubruris_callee->s.len = dlginfo->req_uri.len; } else { - dlginfo->pubruris_callee->s = dlginfo->to_uri; + dlginfo->pubruris_callee->s.s = shm_str2char_dup(&dlginfo->to_uri); + dlginfo->pubruris_callee->s.len = dlginfo->to_uri.len; } } @@ -1107,8 +1178,9 @@ void free_str_list_all(struct str_list *del_current) while(del_current) { del_next = del_current->next; + if(del_current->s.s) + shm_free(del_current->s.s); shm_free(del_current); - del_current = del_next; } } diff --git a/src/modules/pv/README b/src/modules/pv/README index a8667ade6..62eb86f83 100644 --- a/src/modules/pv/README +++ b/src/modules/pv/README @@ -47,28 +47,29 @@ Daniel-Constantin Mierla 4.8. xavp_params_explode(sparams, xname) 4.9. xavp_params_implode(xname, pvname) - 4.10. xavu_params_explode(sparams, xname) - 4.11. xavu_params_implode(xname, pvname) - 4.12. xavp_slist_explode(slist, sep, mode, xname) - 4.13. xavp_child_seti(rname, cname, ival) - 4.14. xavi_child_seti(rname, cname, ival) - 4.15. xavp_child_sets(rname, cname, sval) - 4.16. xavi_child_sets(rname, cname, sval) - 4.17. xavp_rm(rname) - 4.18. xavi_rm(rname) - 4.19. xavp_child_rm(rname, cname) - 4.20. xavi_child_rm(rname, cname) - 4.21. xavp_lshift(xname, idx) - 4.22. xavp_push_dst(xname) - 4.23. sbranch_set_ruri() - 4.24. sbranch_append() - 4.25. sbranch_reset() - 4.26. pv_xavp_print() - 4.27. pv_xavu_print() - 4.28. pv_xavi_print() - 4.29. pv_var_to_xavp(varname, xname) - 4.30. pv_xavp_to_var(xname) - 4.31. pv_evalx(dst, fmt) + 4.10. xavp_params_implode_qval(xname, pvname) + 4.11. xavu_params_explode(sparams, xname) + 4.12. xavu_params_implode(xname, pvname) + 4.13. xavp_slist_explode(slist, sep, mode, xname) + 4.14. xavp_child_seti(rname, cname, ival) + 4.15. xavi_child_seti(rname, cname, ival) + 4.16. xavp_child_sets(rname, cname, sval) + 4.17. xavi_child_sets(rname, cname, sval) + 4.18. xavp_rm(rname) + 4.19. xavi_rm(rname) + 4.20. xavp_child_rm(rname, cname) + 4.21. xavi_child_rm(rname, cname) + 4.22. xavp_lshift(xname, idx) + 4.23. xavp_push_dst(xname) + 4.24. sbranch_set_ruri() + 4.25. sbranch_append() + 4.26. sbranch_reset() + 4.27. pv_xavp_print() + 4.28. pv_xavu_print() + 4.29. pv_xavi_print() + 4.30. pv_var_to_xavp(varname, xname) + 4.31. pv_xavp_to_var(xname) + 4.32. pv_evalx(dst, fmt) 5. RPC Commands @@ -89,30 +90,31 @@ Daniel-Constantin Mierla 1.10. xavp_copy usage 1.11. xavp_params_explode usage 1.12. xavp_params_implode usage - 1.13. xavu_params_explode usage - 1.14. xavu_params_implode usage - 1.15. xavp_slist_explode usage - 1.16. xavp_child_seti usage - 1.17. xavi_child_seti usage - 1.18. xavp_child_sets usage - 1.19. xavi_child_sets usage - 1.20. xavp_rm usage - 1.21. xavi_rm usage - 1.22. xavp_child_rm usage - 1.23. xavi_child_rm usage - 1.24. xavp_lshift usage - 1.25. xavp_push_dst usage - 1.26. sbranch_set_ruri() usage - 1.27. sbranch_append() usage + 1.13. xavp_params_implode_qval usage + 1.14. xavu_params_explode usage + 1.15. xavu_params_implode usage + 1.16. xavp_slist_explode usage + 1.17. xavp_child_seti usage + 1.18. xavi_child_seti usage + 1.19. xavp_child_sets usage + 1.20. xavi_child_sets usage + 1.21. xavp_rm usage + 1.22. xavi_rm usage + 1.23. xavp_child_rm usage + 1.24. xavi_child_rm usage + 1.25. xavp_lshift usage + 1.26. xavp_push_dst usage + 1.27. sbranch_set_ruri() usage 1.28. sbranch_append() usage - 1.29. pv_xavp_print() usage - 1.30. pv_xavu_print() usage - 1.31. pv_xavi_print() usage - 1.32. pv_var_to_xavp() usage - 1.33. pv_xavp_to_var() usage + 1.29. sbranch_append() usage + 1.30. pv_xavp_print() usage + 1.31. pv_xavu_print() usage + 1.32. pv_xavi_print() usage + 1.33. pv_var_to_xavp() usage 1.34. pv_xavp_to_var() usage - 1.35. pv.shvSet usage - 1.36. pv.shvGet usage + 1.35. pv_xavp_to_var() usage + 1.36. pv.shvSet usage + 1.37. pv.shvGet usage Chapter 1. Admin Guide @@ -143,28 +145,29 @@ Chapter 1. Admin Guide 4.8. xavp_params_explode(sparams, xname) 4.9. xavp_params_implode(xname, pvname) - 4.10. xavu_params_explode(sparams, xname) - 4.11. xavu_params_implode(xname, pvname) - 4.12. xavp_slist_explode(slist, sep, mode, xname) - 4.13. xavp_child_seti(rname, cname, ival) - 4.14. xavi_child_seti(rname, cname, ival) - 4.15. xavp_child_sets(rname, cname, sval) - 4.16. xavi_child_sets(rname, cname, sval) - 4.17. xavp_rm(rname) - 4.18. xavi_rm(rname) - 4.19. xavp_child_rm(rname, cname) - 4.20. xavi_child_rm(rname, cname) - 4.21. xavp_lshift(xname, idx) - 4.22. xavp_push_dst(xname) - 4.23. sbranch_set_ruri() - 4.24. sbranch_append() - 4.25. sbranch_reset() - 4.26. pv_xavp_print() - 4.27. pv_xavu_print() - 4.28. pv_xavi_print() - 4.29. pv_var_to_xavp(varname, xname) - 4.30. pv_xavp_to_var(xname) - 4.31. pv_evalx(dst, fmt) + 4.10. xavp_params_implode_qval(xname, pvname) + 4.11. xavu_params_explode(sparams, xname) + 4.12. xavu_params_implode(xname, pvname) + 4.13. xavp_slist_explode(slist, sep, mode, xname) + 4.14. xavp_child_seti(rname, cname, ival) + 4.15. xavi_child_seti(rname, cname, ival) + 4.16. xavp_child_sets(rname, cname, sval) + 4.17. xavi_child_sets(rname, cname, sval) + 4.18. xavp_rm(rname) + 4.19. xavi_rm(rname) + 4.20. xavp_child_rm(rname, cname) + 4.21. xavi_child_rm(rname, cname) + 4.22. xavp_lshift(xname, idx) + 4.23. xavp_push_dst(xname) + 4.24. sbranch_set_ruri() + 4.25. sbranch_append() + 4.26. sbranch_reset() + 4.27. pv_xavp_print() + 4.28. pv_xavu_print() + 4.29. pv_xavi_print() + 4.30. pv_var_to_xavp(varname, xname) + 4.31. pv_xavp_to_var(xname) + 4.32. pv_evalx(dst, fmt) 5. RPC Commands @@ -269,28 +272,29 @@ modparam("pv","avp_aliases","email=s:email_addr;tmp=i:100") 4.8. xavp_params_explode(sparams, xname) 4.9. xavp_params_implode(xname, pvname) - 4.10. xavu_params_explode(sparams, xname) - 4.11. xavu_params_implode(xname, pvname) - 4.12. xavp_slist_explode(slist, sep, mode, xname) - 4.13. xavp_child_seti(rname, cname, ival) - 4.14. xavi_child_seti(rname, cname, ival) - 4.15. xavp_child_sets(rname, cname, sval) - 4.16. xavi_child_sets(rname, cname, sval) - 4.17. xavp_rm(rname) - 4.18. xavi_rm(rname) - 4.19. xavp_child_rm(rname, cname) - 4.20. xavi_child_rm(rname, cname) - 4.21. xavp_lshift(xname, idx) - 4.22. xavp_push_dst(xname) - 4.23. sbranch_set_ruri() - 4.24. sbranch_append() - 4.25. sbranch_reset() - 4.26. pv_xavp_print() - 4.27. pv_xavu_print() - 4.28. pv_xavi_print() - 4.29. pv_var_to_xavp(varname, xname) - 4.30. pv_xavp_to_var(xname) - 4.31. pv_evalx(dst, fmt) + 4.10. xavp_params_implode_qval(xname, pvname) + 4.11. xavu_params_explode(sparams, xname) + 4.12. xavu_params_implode(xname, pvname) + 4.13. xavp_slist_explode(slist, sep, mode, xname) + 4.14. xavp_child_seti(rname, cname, ival) + 4.15. xavi_child_seti(rname, cname, ival) + 4.16. xavp_child_sets(rname, cname, sval) + 4.17. xavi_child_sets(rname, cname, sval) + 4.18. xavp_rm(rname) + 4.19. xavi_rm(rname) + 4.20. xavp_child_rm(rname, cname) + 4.21. xavi_child_rm(rname, cname) + 4.22. xavp_lshift(xname, idx) + 4.23. xavp_push_dst(xname) + 4.24. sbranch_set_ruri() + 4.25. sbranch_append() + 4.26. sbranch_reset() + 4.27. pv_xavp_print() + 4.28. pv_xavu_print() + 4.29. pv_xavi_print() + 4.30. pv_var_to_xavp(varname, xname) + 4.31. pv_xavp_to_var(xname) + 4.32. pv_evalx(dst, fmt) 4.1. pv_isset(pvar) @@ -483,7 +487,31 @@ xavp_params_implode("x", "$var(out)"); # results in: $var(out) is "a=b;c=d;e=f;" ... -4.10. xavu_params_explode(sparams, xname) +4.10. xavp_params_implode_qval(xname, pvname) + + Serialize the subfields in an XAVP to a parameters string format, + enclosing string values in double quotes. + + Number values are serialized as unsigned integer string format. + + The first parameter has to be the name of XAVP (only the string name, + not the in $xavp(name)). The second parameter is the name of output + variable (in full name, like $var(output)). + + The value is stored as string type. + + Function can be used from ANY ROUTE. + + Example 1.13. xavp_params_implode_qval usage +... +$xavp(x=>e) = "f"; +$xavp(x[0]=>c) = 5; +$xavp(x[0]=>a) = "b"; +xavp_params_implode("x", "$var(out)"); +# results in: $var(out) is: a="b";c=5;e="f"; +... + +4.11. xavu_params_explode(sparams, xname) Convert a parameters string in xavu attributes. @@ -495,7 +523,7 @@ xavp_params_implode("x", "$var(out)"); Function can be used from ANY ROUTE. - Example 1.13. xavu_params_explode usage + Example 1.14. xavu_params_explode usage ... xavu_params_explode("a=b;c=d;e=d", "x"); # results in: @@ -504,7 +532,7 @@ xavu_params_explode("a=b;c=d;e=d", "x"); # $xavu(x=>e) = "f"; ... -4.11. xavu_params_implode(xname, pvname) +4.12. xavu_params_implode(xname, pvname) Serialize the subfields in an XAUP to a parameters string format. @@ -518,7 +546,7 @@ xavu_params_explode("a=b;c=d;e=d", "x"); Function can be used from ANY ROUTE. - Example 1.14. xavu_params_implode usage + Example 1.15. xavu_params_implode usage ... $xavu(x=>e) = "f"; $xavu(x=>c) = "d"; @@ -527,7 +555,7 @@ xavu_params_implode("x", "$var(out)"); # results in: $var(out) is "a=b;c=d;e=f;" ... -4.12. xavp_slist_explode(slist, sep, mode, xname) +4.13. xavp_slist_explode(slist, sep, mode, xname) Breaks a string list in tokens by separators and stores them in XAVPs. Note that is not storing empty values. @@ -548,7 +576,7 @@ xavu_params_implode("x", "$var(out)"); Function can be used from ANY ROUTE. - Example 1.15. xavp_slist_explode usage + Example 1.16. xavp_slist_explode usage ... xavp_slist_explode("a=b; c=d;", "=;", "t", "x"); # results in: @@ -558,7 +586,7 @@ xavp_slist_explode("a=b; c=d;", "=;", "t", "x"); # $xavp(x[0]=>v[3]) = "d"; ... -4.13. xavp_child_seti(rname, cname, ival) +4.14. xavp_child_seti(rname, cname, ival) Set the value of $xavp(rname=>cname) to integer value ival. @@ -568,14 +596,14 @@ xavp_slist_explode("a=b; c=d;", "=;", "t", "x"); Function can be used from ANY ROUTE. - Example 1.16. xavp_child_seti usage + Example 1.17. xavp_child_seti usage ... $var(n) = 10; xavp_child_seti("x", "y", "$var(n)"); # results in: $xavp(x=>y) is 10 ... -4.14. xavi_child_seti(rname, cname, ival) +4.15. xavi_child_seti(rname, cname, ival) Set the value of $xavi(rname=>cname) to integer value ival. @@ -585,14 +613,14 @@ xavp_child_seti("x", "y", "$var(n)"); Function can be used from ANY ROUTE. - Example 1.17. xavi_child_seti usage + Example 1.18. xavi_child_seti usage ... $var(n) = 10; xavi_child_seti("WhatEver", "FoO", "$var(n)"); # results in: $xavi(whatever=>foo) is 10 ... -4.15. xavp_child_sets(rname, cname, sval) +4.16. xavp_child_sets(rname, cname, sval) Set the value of $xavp(rname=>cname) to string value sval. @@ -602,14 +630,14 @@ xavi_child_seti("WhatEver", "FoO", "$var(n)"); Function can be used from ANY ROUTE. - Example 1.18. xavp_child_sets usage + Example 1.19. xavp_child_sets usage ... $var(n) = 10; xavp_child_sets("x", "y", "Count: $var(n)"); # results in: $xavp(x=>y) is "Count: 10" ... -4.16. xavi_child_sets(rname, cname, sval) +4.17. xavi_child_sets(rname, cname, sval) Set the value of $xavi(rname=>cname) to string value sval. @@ -619,14 +647,14 @@ xavp_child_sets("x", "y", "Count: $var(n)"); Function can be used from ANY ROUTE. - Example 1.19. xavi_child_sets usage + Example 1.20. xavi_child_sets usage ... $var(n) = 10; xavi_child_sets("WhatEver", "FoO", "Count: $var(n)"); # results in: $xavi(whatever=>foo) is "Count: 10" ... -4.17. xavp_rm(rname) +4.18. xavp_rm(rname) Remove the value of $xavp(rname). @@ -635,13 +663,13 @@ xavi_child_sets("WhatEver", "FoO", "Count: $var(n)"); Function can be used from ANY ROUTE. - Example 1.20. xavp_rm usage + Example 1.21. xavp_rm usage ... xavp_rm("x"); # same result as: $xavp(x) = $null; ... -4.18. xavi_rm(rname) +4.19. xavi_rm(rname) Remove the value of $xavi(rname). @@ -650,13 +678,13 @@ xavp_rm("x"); Function can be used from ANY ROUTE. - Example 1.21. xavi_rm usage + Example 1.22. xavi_rm usage ... xavi_rm("WhatEver"); # same result as: $xavi(whatever) = $null; ... -4.19. xavp_child_rm(rname, cname) +4.20. xavp_child_rm(rname, cname) Remove the value of $xavp(rname=>cname). @@ -666,13 +694,13 @@ xavi_rm("WhatEver"); Function can be used from ANY ROUTE. - Example 1.22. xavp_child_rm usage + Example 1.23. xavp_child_rm usage ... xavp_child_rm("x", "y"); # same result as: $xavp(x=>y) = $null; ... -4.20. xavi_child_rm(rname, cname) +4.21. xavi_child_rm(rname, cname) Remove the value of $xavi(rname=>cname). @@ -682,13 +710,13 @@ xavp_child_rm("x", "y"); Function can be used from ANY ROUTE. - Example 1.23. xavi_child_rm usage + Example 1.24. xavi_child_rm usage ... xavi_child_rm("WhatEver", "FoO"); # same result as: $xavi(whatever=>foo) = $null; ... -4.21. xavp_lshift(xname, idx) +4.22. xavp_lshift(xname, idx) Left shift with rotation of the xavps with name xname so that the one at the index idx becomes the first and the ones before it are at the @@ -704,7 +732,7 @@ xavi_child_rm("WhatEver", "FoO"); Function can be used from ANY ROUTE. - Example 1.24. xavp_lshift usage + Example 1.25. xavp_lshift usage ... $xavp(n) = 10; $xavp(n) = 20; @@ -713,7 +741,7 @@ xavp_lshift("n", "1"); # results in: $xavp(n) having the list of values 20 30 10 ... -4.22. xavp_push_dst(xname) +4.23. xavp_push_dst(xname) Set destination fields from XAVP attributes. @@ -728,7 +756,7 @@ xavp_lshift("n", "1"); Function can be used from REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE. - Example 1.25. xavp_push_dst usage + Example 1.26. xavp_push_dst usage ... $xavp(dst=>uri) = "sip:alice@server.com"; $xavp(dst[0]=>dsturi) = "sip:proxy.com"; @@ -736,7 +764,7 @@ $xavp(dst[0]=>socket) = "udp:1.2.3.4:5060"; xavp_push_dst("dst"); ... -4.23. sbranch_set_ruri() +4.24. sbranch_set_ruri() Use the attributes from static branch ($sbranch(key) variable) to set request URI and the other fields of the branch associated with request @@ -747,7 +775,7 @@ xavp_push_dst("dst"); Function can be used from REQUEST_ROUTE, BRANCH_ROUTE or FAILURE_ROUTE. - Example 1.26. sbranch_set_ruri() usage + Example 1.27. sbranch_set_ruri() usage ... sbranch_reset(); $sbranch(uri) = "sip:127.0.0.1:5080"; @@ -757,7 +785,7 @@ $sbranch(send_socket) = "udp:127.0.0.1:5060"; sbranch_set_ruri(); ... -4.24. sbranch_append() +4.25. sbranch_append() Use the attributes from static branch ($sbranch(key) variable) to append a new branch to destination set. It is an alternative to @@ -769,7 +797,7 @@ sbranch_set_ruri(); Function can be used from REQUEST_ROUTE, BRANCH_ROUTE or FAILURE_ROUTE. - Example 1.27. sbranch_append() usage + Example 1.28. sbranch_append() usage ... sbranch_reset(); $sbranch(uri) = "sip:127.0.0.1:5080"; @@ -778,51 +806,51 @@ $sbranch(send_socket) = "udp:127.0.0.1:5060"; sbranch_append(); ... -4.25. sbranch_reset() +4.26. sbranch_reset() Reset the content of static branch ($sbranch(key) variable. Function can be used from REQUEST_ROUTE, BRANCH_ROUTE or FAILURE_ROUTE. - Example 1.28. sbranch_append() usage + Example 1.29. sbranch_append() usage ... sbranch_reset(); ... -4.26. pv_xavp_print() +4.27. pv_xavp_print() Print all XAVPs to the syslog using INFO log level. Function can be used from ANY_ROUTE. - Example 1.29. pv_xavp_print() usage + Example 1.30. pv_xavp_print() usage ... pv_xavp_print(); ... -4.27. pv_xavu_print() +4.28. pv_xavu_print() Print all XAVUs to the syslog using INFO log level. Function can be used from ANY_ROUTE. - Example 1.30. pv_xavu_print() usage + Example 1.31. pv_xavu_print() usage ... pv_xavu_print(); ... -4.28. pv_xavi_print() +4.29. pv_xavi_print() Print all XAVIs to the syslog using INFO log level. Function can be used from ANY_ROUTE. - Example 1.31. pv_xavi_print() usage + Example 1.32. pv_xavi_print() usage ... pv_xavi_print(); ... -4.29. pv_var_to_xavp(varname, xname) +4.30. pv_var_to_xavp(varname, xname) Copy the script variable value into an xavp. @@ -834,7 +862,7 @@ pv_xavi_print(); Function can be used from ANY_ROUTE. - Example 1.32. pv_var_to_xavp() usage + Example 1.33. pv_var_to_xavp() usage ... $var("temp") = 3; $var("foo") = "foo indeed"; @@ -848,7 +876,7 @@ $xavp("ok[0]=>temp") now is 3 $xavp("ok[0]=>foo") now is "foo indeed" ... -4.30. pv_xavp_to_var(xname) +4.31. pv_xavp_to_var(xname) Copy xavp values into vars. Reverse of pv_var_to_xavp(). @@ -856,7 +884,7 @@ $xavp("ok[0]=>foo") now is "foo indeed" Function can be used from ANY_ROUTE. - Example 1.33. pv_xavp_to_var() usage + Example 1.34. pv_xavp_to_var() usage ... $xavp("bar=>temp") = 3; $xavp("bar[0]=>foo") = "foo indeed"; @@ -866,7 +894,7 @@ $var("temp") now is 3 $var("foo") now is "foo indeed" ... -4.31. pv_evalx(dst, fmt) +4.32. pv_evalx(dst, fmt) The fmt string is evaluated twice for exiting variables, the result is stored in dst variable. The dst must be the name of a writable @@ -875,7 +903,7 @@ $var("foo") now is "foo indeed" Function can be used from ANY_ROUTE. - Example 1.34. pv_xavp_to_var() usage + Example 1.35. pv_xavp_to_var() usage ... $var(x) = "test"; $var(y) = "$var(x)" @@ -900,7 +928,7 @@ pv_evalx("$var(z)", "$var(y) one"); + “str”: string value * _value_: value to be set - Example 1.35. pv.shvSet usage + Example 1.36. pv.shvSet usage ... $ kamcmd pv.shvSet debug int 3 ... @@ -914,7 +942,7 @@ $ kamcmd pv.shvSet debug int 3 If no name is given, all shared variables are listed. - Example 1.36. pv.shvGet usage + Example 1.37. pv.shvGet usage ... $ kamcmd pv.shvGet debug ... diff --git a/src/modules/pv/doc/pv_admin.xml b/src/modules/pv/doc/pv_admin.xml index c60e74fec..1f91e633a 100644 --- a/src/modules/pv/doc/pv_admin.xml +++ b/src/modules/pv/doc/pv_admin.xml @@ -421,6 +421,41 @@ $xavp(x[0]=>c) = "d"; $xavp(x[0]=>a) = "b"; xavp_params_implode("x", "$var(out)"); # results in: $var(out) is "a=b;c=d;e=f;" +... + + +
+
+ + <function moreinfo="none">xavp_params_implode_qval(xname, pvname)</function> + + + Serialize the subfields in an XAVP to a parameters string format, + enclosing string values in double quotes. + + + Number values are serialized as unsigned integer string format. + + + The first parameter has to be the name of XAVP (only the string + name, not the in $xavp(name)). The second parameter + is the name of output variable (in full name, like $var(output)). + + + The value is stored as string type. + + + Function can be used from ANY ROUTE. + + + <function>xavp_params_implode_qval</function> usage + +... +$xavp(x=>e) = "f"; +$xavp(x[0]=>c) = 5; +$xavp(x[0]=>a) = "b"; +xavp_params_implode("x", "$var(out)"); +# results in: $var(out) is: a="b";c=5;e="f"; ... diff --git a/src/modules/pv/pv.c b/src/modules/pv/pv.c index 3a905593d..5e9da2703 100644 --- a/src/modules/pv/pv.c +++ b/src/modules/pv/pv.c @@ -47,420 +47,411 @@ MODULE_VERSION -static tr_export_t mod_trans[] = {{{"s", sizeof("s") - 1}, /* string class */ - tr_parse_string}, - {{"nameaddr", sizeof("nameaddr") - 1}, /* nameaddr class */ - tr_parse_nameaddr}, - {{"uri", sizeof("uri") - 1}, /* uri class */ - tr_parse_uri}, - {{"param", sizeof("param") - 1}, /* param class */ - tr_parse_paramlist}, - {{"tobody", sizeof("tobody") - 1}, /* param class */ - tr_parse_tobody}, - {{"line", sizeof("line") - 1}, /* line class */ - tr_parse_line}, - {{"urialias", sizeof("urialias") - 1}, /* uri alias class */ - tr_parse_urialias}, - {{"val", sizeof("val") - 1}, /* val class */ - tr_parse_val}, - - {{0, 0}, 0}}; +static int add_avp_aliases(modparam_t type, void *val); -static pv_export_t mod_pvs[] = { - {{"_s", (sizeof("_s") - 1)}, PVT_OTHER, pv_get__s, 0, pv_parse__s_name, - 0, 0, 0}, - {{"af", (sizeof("af") - 1)}, PVT_OTHER, pv_get_af, 0, pv_parse_af_name, - 0, 0, 0}, - {{"branch", sizeof("branch") - 1}, /* branch attributes */ - PVT_CONTEXT, pv_get_branchx, pv_set_branchx, - pv_parse_branchx_name, pv_parse_index, 0, 0}, - {{"sbranch", sizeof("sbranch") - 1}, /* static branch attributes */ - PVT_CONTEXT, pv_get_sbranch, pv_set_sbranch, - pv_parse_branchx_name, 0, 0, 0}, - {{"mi", (sizeof("mi") - 1)}, /* message id */ - PVT_OTHER, pv_get_msgid, 0, 0, 0, 0, 0}, - {{"stat", sizeof("stat") - 1}, /* statistics */ - PVT_OTHER, pv_get_stat, 0, pv_parse_stat_name, 0, 0, 0}, - {{"sel", sizeof("sel") - 1}, /* select */ - PVT_OTHER, pv_get_select, 0, pv_parse_select_name, 0, 0, 0}, - {{"snd", (sizeof("snd") - 1)}, PVT_OTHER, pv_get_sndto, 0, - pv_parse_snd_name, 0, 0, 0}, - {{"sndto", (sizeof("sndto") - 1)}, PVT_OTHER, pv_get_sndto, 0, - pv_parse_snd_name, 0, 0, 0}, - {{"sndfrom", (sizeof("sndfrom") - 1)}, PVT_OTHER, pv_get_sndfrom, 0, - pv_parse_snd_name, 0, 0, 0}, - {{"rcv", (sizeof("rcv") - 1)}, PVT_OTHER, pv_get_rcv, pv_set_rcv, - pv_parse_rcv_name, 0, 0, 0}, - {{"xavp", sizeof("xavp") - 1}, /* xavp */ - PVT_XAVP, pv_get_xavp, pv_set_xavp, pv_parse_xavp_name, 0, 0, - 0}, - {{"xavu", sizeof("xavu") - 1}, /* xavu */ - PVT_XAVU, pv_get_xavu, pv_set_xavu, pv_parse_xavu_name, 0, 0, - 0}, - {{"xavi", sizeof("xavi") - 1}, /* xavi */ - PVT_XAVI, pv_get_xavi, pv_set_xavi, 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, pv_parse_index, 0, 0}, - {{"hdrc", (sizeof("hdrc") - 1)}, PVT_HDRC, pv_get_hdrc, 0, - pv_parse_hdr_name, 0, 0, 0}, - {{"hfl", (sizeof("hfl") - 1)}, PVT_HDR, pv_get_hfl, 0, - pv_parse_hfl_name, pv_parse_index, 0, 0}, - {{"hflc", (sizeof("hflc") - 1)}, PVT_HDRC, pv_get_hflc, 0, - pv_parse_hfl_name, 0, 0, 0}, - {{"var", (sizeof("var") - 1)}, PVT_SCRIPTVAR, pv_get_scriptvar, - pv_set_scriptvar, pv_parse_scriptvar_name, 0, 0, 0}, - {{"vz", (sizeof("vz") - 1)}, PVT_SCRIPTVAR, pv_get_scriptvar, - pv_set_scriptvar, pv_parse_scriptvar_name, 0, 0, 0}, - {{"vn", (sizeof("vn") - 1)}, PVT_SCRIPTVAR, pv_get_scriptvar, - pv_set_scriptvar, pv_parse_scriptvarnull_name, 0, 0, 0}, - {{"ai", (sizeof("ai") - 1)}, /* */ - PVT_OTHER, pv_get_pai, 0, 0, pv_parse_index, 0, 0}, - {{"adu", (sizeof("adu") - 1)}, /* auth digest uri */ - PVT_OTHER, pv_get_authattr, 0, 0, 0, pv_init_iname, 3}, - {{"ar", (sizeof("ar") - 1)}, /* auth realm */ - PVT_OTHER, pv_get_authattr, 0, 0, 0, pv_init_iname, 2}, - {{"au", (sizeof("au") - 1)}, /* */ - PVT_OTHER, pv_get_authattr, 0, 0, 0, pv_init_iname, 1}, - {{"ad", (sizeof("ad") - 1)}, /* */ - PVT_OTHER, pv_get_authattr, 0, 0, 0, pv_init_iname, 4}, - {{"aU", (sizeof("aU") - 1)}, /* */ - PVT_OTHER, pv_get_authattr, 0, 0, 0, pv_init_iname, 5}, - {{"aa", (sizeof("aa") - 1)}, /* auth algorithm */ - PVT_OTHER, pv_get_authattr, 0, 0, 0, pv_init_iname, 6}, - {{"adn", (sizeof("adn") - 1)}, /* auth nonce */ - PVT_OTHER, pv_get_authattr, 0, 0, 0, pv_init_iname, 7}, - {{"adc", (sizeof("adc") - 1)}, /* auth cnonce */ - PVT_OTHER, pv_get_authattr, 0, 0, 0, pv_init_iname, 8}, - {{"adr", (sizeof("adr") - 1)}, /* auth response */ - PVT_OTHER, pv_get_authattr, 0, 0, 0, pv_init_iname, 9}, - {{"ado", (sizeof("ado") - 1)}, /* auth opaque */ - PVT_OTHER, pv_get_authattr, 0, 0, 0, pv_init_iname, 10}, - {{"Au", (sizeof("Au") - 1)}, /* */ - PVT_OTHER, pv_get_acc_username, 0, 0, 0, pv_init_iname, 1}, - {{"AU", (sizeof("AU") - 1)}, /* */ - PVT_OTHER, pv_get_acc_user, 0, 0, 0, pv_init_iname, 1}, - {{"bf", (sizeof("bf") - 1)}, /* */ - PVT_CONTEXT, pv_get_bflags, pv_set_bflags, 0, 0, 0, 0}, - {{"bF", (sizeof("bF") - 1)}, /* */ - PVT_CONTEXT, pv_get_hexbflags, pv_set_bflags, 0, 0, 0, 0}, - {{"Bf", (sizeof("Bf") - 1)}, /* */ - PVT_CONTEXT, pv_get_bflag, pv_set_bflag, pv_parse_flag_param, 0, - 0, 0}, - {{"br", (sizeof("br") - 1)}, /* */ - PVT_BRANCH, pv_get_branch, pv_set_branch, 0, 0, 0, 0}, - {{"bR", (sizeof("bR") - 1)}, /* */ - PVT_CONTEXT, pv_get_branches, 0, 0, 0, 0, 0}, - {{"bs", (sizeof("bs") - 1)}, /* */ - PVT_OTHER, pv_get_body_size, 0, 0, 0, 0, 0}, - {{"ci", (sizeof("ci") - 1)}, /* */ - PVT_OTHER, pv_get_callid, 0, 0, 0, 0, 0}, - {{"cl", (sizeof("cl") - 1)}, /* */ - PVT_OTHER, pv_get_content_length, 0, 0, 0, 0, 0}, - {{"cnt", sizeof("cnt") - 1}, PVT_OTHER, pv_get_cnt, 0, - pv_parse_cnt_name, 0, 0, 0}, - {{"conid", (sizeof("conid") - 1)}, /* */ - PVT_OTHER, pv_get_tcpconn_id, 0, 0, 0, 0, 0}, - {{"cs", (sizeof("cs") - 1)}, /* */ - PVT_OTHER, pv_get_cseq, 0, 0, 0, 0, 0}, - {{"csb", (sizeof("csb") - 1)}, /* */ - PVT_OTHER, pv_get_cseq_body, 0, 0, 0, 0, 0}, - {{"ct", (sizeof("ct") - 1)}, /* */ - PVT_OTHER, pv_get_contact, 0, 0, 0, 0, 0}, - {{"cT", (sizeof("cT") - 1)}, /* */ - PVT_OTHER, pv_get_content_type, 0, 0, 0, 0, 0}, - {{"dd", (sizeof("dd") - 1)}, /* */ - PVT_OTHER, pv_get_dsturi_attr, 0, 0, 0, pv_init_iname, 1}, - {{"di", (sizeof("di") - 1)}, /* */ - PVT_OTHER, pv_get_diversion, 0, 0, 0, pv_init_iname, 1}, - {{"dir", (sizeof("dir") - 1)}, /* */ - PVT_OTHER, pv_get_diversion, 0, 0, 0, pv_init_iname, 2}, - {{"dip", (sizeof("dis") - 1)}, /* */ - PVT_OTHER, pv_get_diversion, 0, 0, 0, pv_init_iname, 3}, - {{"dic", (sizeof("dic") - 1)}, /* */ - PVT_OTHER, pv_get_diversion, 0, 0, 0, pv_init_iname, 4}, - {{"dp", (sizeof("dp") - 1)}, /* */ - PVT_OTHER, pv_get_dsturi_attr, 0, 0, 0, pv_init_iname, 2}, - {{"dP", (sizeof("dP") - 1)}, /* */ - PVT_OTHER, pv_get_dsturi_attr, 0, 0, 0, pv_init_iname, 3}, - {{"ds", (sizeof("ds") - 1)}, /* */ - PVT_CONTEXT, pv_get_dset, 0, 0, 0, 0, 0}, - {{"du", (sizeof("du") - 1)}, /* */ - PVT_DSTURI, pv_get_dsturi, pv_set_dsturi, 0, 0, 0, 0}, - {{"duri", (sizeof("duri") - 1)}, /* */ - PVT_DSTURI, pv_get_dsturi, pv_set_dsturi, 0, 0, 0, 0}, - {{"err.class", (sizeof("err.class") - 1)}, /* */ - PVT_OTHER, pv_get_errinfo_attr, 0, 0, 0, 0, 0}, - {{"err.level", (sizeof("err.level") - 1)}, /* */ - PVT_OTHER, pv_get_errinfo_attr, 0, 0, 0, pv_init_iname, 1}, - {{"err.info", (sizeof("err.info") - 1)}, /* */ - PVT_OTHER, pv_get_errinfo_attr, 0, 0, 0, pv_init_iname, 2}, - {{"err.rcode", (sizeof("err.rcode") - 1)}, /* */ - PVT_OTHER, pv_get_errinfo_attr, 0, 0, 0, pv_init_iname, 3}, - {{"err.rreason", (sizeof("err.rreason") - 1)}, /* */ - PVT_OTHER, pv_get_errinfo_attr, 0, 0, 0, pv_init_iname, 4}, - {{"fd", (sizeof("fd") - 1)}, /* */ - PVT_OTHER, pv_get_from_attr, pv_set_from_domain, 0, 0, - pv_init_iname, 3}, - {{"from.domain", (sizeof("from.domain") - 1)}, /* */ - PVT_OTHER, pv_get_from_attr, pv_set_from_domain, 0, 0, - pv_init_iname, 3}, - {{"fn", (sizeof("fn") - 1)}, /* */ - PVT_OTHER, pv_get_from_attr, pv_set_from_display, 0, 0, - pv_init_iname, 5}, - {{"fs", (sizeof("fs") - 1)}, /* */ - PVT_OTHER, pv_get_force_sock, pv_set_force_sock, 0, 0, 0, 0}, - {{"fsn", (sizeof("fsn") - 1)}, /* */ - PVT_OTHER, pv_get_force_sock_name, pv_set_force_sock_name, 0, 0, - 0, 0}, - {{"fsp", (sizeof("fsp") - 1)}, /* */ - PVT_OTHER, pv_get_force_sock_port, 0, 0, 0, 0, 0}, - {{"ft", (sizeof("ft") - 1)}, /* */ - PVT_OTHER, pv_get_from_attr, 0, 0, 0, pv_init_iname, 4}, - {{"fu", (sizeof("fu") - 1)}, /* */ - PVT_FROM, pv_get_from_attr, pv_set_from_uri, 0, 0, - pv_init_iname, 1}, - {{"from", (sizeof("from") - 1)}, /* */ - PVT_FROM, pv_get_from_attr, pv_set_from_uri, 0, 0, - pv_init_iname, 1}, - {{"fU", (sizeof("fU") - 1)}, /* */ - PVT_OTHER, pv_get_from_attr, pv_set_from_username, 0, 0, - pv_init_iname, 2}, - {{"from.user", (sizeof("from.user") - 1)}, /* */ - PVT_OTHER, pv_get_from_attr, pv_set_from_username, 0, 0, - pv_init_iname, 2}, - {{"fUl", (sizeof("fUl") - 1)}, /* */ - PVT_OTHER, pv_get_from_attr, 0, 0, 0, pv_init_iname, 6}, - {{"mb", (sizeof("mb") - 1)}, /* */ - PVT_OTHER, pv_get_msg_buf, 0, 0, 0, 0, 0}, - {{"mbu", (sizeof("mbu") - 1)}, /* */ - PVT_OTHER, pv_get_msg_buf_updated, 0, 0, 0, 0, 0}, - {{"mf", (sizeof("mf") - 1)}, /* */ - PVT_OTHER, pv_get_flags, pv_set_mflags, 0, 0, 0, 0}, - {{"mF", (sizeof("mF") - 1)}, /* */ - PVT_OTHER, pv_get_hexflags, pv_set_mflags, 0, 0, 0, 0}, - {{"Mf", (sizeof("mf") - 1)}, /* */ - PVT_OTHER, pv_get_flag, pv_set_mflag, pv_parse_flag_param, 0, 0, - 0}, - {{"ml", (sizeof("ml") - 1)}, /* */ - PVT_OTHER, pv_get_msg_len, 0, 0, 0, 0, 0}, - {{"mt", (sizeof("mt") - 1)}, /* */ - PVT_OTHER, pv_get_msgtype, 0, 0, 0, 0, 0}, - {{"mts", (sizeof("mts") - 1)}, /* */ - PVT_OTHER, pv_get_msgtypes, 0, 0, 0, 0, 0}, - {{"od", (sizeof("od") - 1)}, /* */ - PVT_OTHER, pv_get_ouri_attr, 0, 0, 0, pv_init_iname, 2}, - {{"op", (sizeof("op") - 1)}, /* */ - PVT_OTHER, pv_get_ouri_attr, 0, 0, 0, pv_init_iname, 3}, - {{"oP", (sizeof("oP") - 1)}, /* */ - PVT_OTHER, pv_get_ouri_attr, 0, 0, 0, pv_init_iname, 4}, - {{"ou", (sizeof("ou") - 1)}, /* */ - PVT_OURI, pv_get_ouri, 0, 0, 0, 0, 0}, - {{"ouri", (sizeof("ouri") - 1)}, /* */ - PVT_OURI, pv_get_ouri, 0, 0, 0, 0, 0}, - {{"oU", (sizeof("oU") - 1)}, /* */ - PVT_OTHER, pv_get_ouri_attr, 0, 0, 0, pv_init_iname, 1}, - {{"oUl", (sizeof("oUl") - 1)}, /* */ - PVT_OTHER, pv_get_ouri_attr, 0, 0, 0, pv_init_iname, 6}, - {{"pd", (sizeof("pd") - 1)}, /* */ - PVT_OTHER, pv_get_ppi_attr, 0, 0, pv_parse_index, pv_init_iname, - 3}, - {{"pn", (sizeof("pn") - 1)}, /* */ - PVT_OTHER, pv_get_ppi_attr, 0, 0, pv_parse_index, pv_init_iname, - 4}, - {{"pp", (sizeof("pp") - 1)}, /* */ - PVT_OTHER, pv_get_pid, 0, 0, 0, 0, 0}, - {{"pr", (sizeof("pr") - 1)}, /* */ - PVT_OTHER, pv_get_proto, 0, 0, 0, 0, 0}, - {{"prid", (sizeof("prid") - 1)}, /* */ - PVT_OTHER, pv_get_protoid, 0, 0, 0, 0, 0}, - {{"proto", (sizeof("proto") - 1)}, /* */ - PVT_OTHER, pv_get_proto, 0, 0, 0, 0, 0}, - {{"pu", (sizeof("pu") - 1)}, /* */ - PVT_OTHER, pv_get_ppi_attr, 0, 0, pv_parse_index, pv_init_iname, - 1}, - {{"pU", (sizeof("pU") - 1)}, /* */ - PVT_OTHER, pv_get_ppi_attr, 0, 0, pv_parse_index, pv_init_iname, - 2}, - {{"rb", (sizeof("rb") - 1)}, /* */ - PVT_MSG_BODY, pv_get_msg_body, 0, 0, 0, 0, 0}, - {{"rd", (sizeof("rd") - 1)}, /* */ - PVT_RURI_DOMAIN, pv_get_ruri_attr, pv_set_ruri_host, 0, 0, - pv_init_iname, 2}, - {{"ruri.domain", (sizeof("ruri.domain") - 1)}, /* */ - PVT_RURI_DOMAIN, pv_get_ruri_attr, pv_set_ruri_host, 0, 0, - pv_init_iname, 2}, - {{"re", (sizeof("re") - 1)}, /* */ - PVT_OTHER, pv_get_rpid, 0, 0, 0, 0, 0}, - {{"rm", (sizeof("rm") - 1)}, /* */ - PVT_OTHER, pv_get_method, 0, 0, 0, 0, 0}, - {{"rmid", (sizeof("rmid") - 1)}, /* */ - PVT_OTHER, pv_get_methodid, 0, 0, 0, 0, 0}, - {{"rp", (sizeof("rp") - 1)}, /* */ - PVT_OTHER, pv_get_ruri_attr, pv_set_ruri_port, 0, 0, - pv_init_iname, 3}, - {{"rP", (sizeof("rP") - 1)}, /* */ - PVT_OTHER, pv_get_ruri_attr, 0, 0, 0, pv_init_iname, 4}, - {{"rr", (sizeof("rr") - 1)}, /* */ - PVT_OTHER, pv_get_reason, 0, 0, 0, 0, 0}, - {{"rs", (sizeof("rs") - 1)}, /* */ - PVT_OTHER, pv_get_status, 0, 0, 0, 0, 0}, - {{"rsi", (sizeof("rsi") - 1)}, /* */ - PVT_OTHER, pv_get_statusi, 0, 0, 0, 0, 0}, - {{"rt", (sizeof("rt") - 1)}, /* */ - PVT_OTHER, pv_get_refer_to, 0, 0, 0, 0, 0}, - {{"ru", (sizeof("ru") - 1)}, /* */ - PVT_RURI, pv_get_ruri, pv_set_ruri, 0, 0, 0, 0}, - {{"ruri", (sizeof("ruri") - 1)}, /* */ - PVT_RURI, pv_get_ruri, pv_set_ruri, 0, 0, 0, 0}, - {{"rU", (sizeof("rU") - 1)}, /* */ - PVT_RURI_USERNAME, pv_get_ruri_attr, pv_set_ruri_user, 0, 0, - pv_init_iname, 1}, - {{"ruri.user", (sizeof("ruri.user") - 1)}, /* */ - PVT_RURI_USERNAME, pv_get_ruri_attr, pv_set_ruri_user, 0, 0, - pv_init_iname, 1}, - {{"rUl", (sizeof("rUl") - 1)}, /* */ - PVT_RURI_USERNAME, pv_get_ruri_attr, 0, 0, 0, pv_init_iname, 6}, - {{"rv", (sizeof("rv") - 1)}, /* */ - PVT_OTHER, pv_get_version, 0, 0, 0, 0, 0}, - {{"rz", (sizeof("rz") - 1)}, /* */ - PVT_OTHER, pv_get_ruri_attr, 0, 0, 0, pv_init_iname, 5}, - {{"Ras", (sizeof("Ras") - 1)}, /* */ - PVT_OTHER, pv_get_rcvaddr_socket, 0, 0, 0, 0, 0}, - {{"Ri", (sizeof("Ri") - 1)}, /* */ - PVT_OTHER, pv_get_rcvip, 0, 0, 0, 0, 0}, - {{"Rp", (sizeof("Rp") - 1)}, /* */ - PVT_OTHER, pv_get_rcvport, 0, 0, 0, 0, 0}, - {{"Ru", (sizeof("Ru") - 1)}, /* */ - PVT_OTHER, pv_get_rcvaddr_uri, 0, 0, 0, 0, 0}, - {{"Rut", (sizeof("Rut") - 1)}, /* */ - PVT_OTHER, pv_get_rcvaddr_uri_full, 0, 0, 0, 0, 0}, - {{"Rn", (sizeof("Rn") - 1)}, /* */ - PVT_OTHER, pv_get_rcvsname, 0, 0, 0, 0, 0}, - {{"RAi", (sizeof("RAi") - 1)}, /* */ - PVT_OTHER, pv_get_rcv_advertised_ip, 0, 0, 0, 0, 0}, - {{"RAp", (sizeof("RAp") - 1)}, /* */ - PVT_OTHER, pv_get_rcv_advertised_port, 0, 0, 0, 0, 0}, - {{"RAu", (sizeof("RAu") - 1)}, /* */ - PVT_OTHER, pv_get_rcvadv_uri, 0, 0, 0, 0, 0}, - {{"RAut", (sizeof("RAut") - 1)}, /* */ - PVT_OTHER, pv_get_rcvadv_uri_full, 0, 0, 0, 0, 0}, - {{"sas", (sizeof("sas") - 1)}, /* */ - PVT_OTHER, pv_get_srcaddr_socket, 0, 0, 0, 0, 0}, - {{"sf", (sizeof("sf") - 1)}, /* */ - PVT_OTHER, pv_get_sflags, pv_set_sflags, 0, 0, 0, 0}, - {{"sF", (sizeof("sF") - 1)}, /* */ - PVT_OTHER, pv_get_hexsflags, pv_set_sflags, 0, 0, 0, 0}, - {{"Sf", (sizeof("sf") - 1)}, /* */ - PVT_OTHER, pv_get_sflag, pv_set_sflag, pv_parse_flag_param, 0, - 0, 0}, - {{"src_ip", (sizeof("src_ip") - 1)}, /* */ - PVT_OTHER, pv_get_srcip, 0, 0, 0, 0, 0}, - {{"si", (sizeof("si") - 1)}, /* */ - PVT_OTHER, pv_get_srcip, 0, 0, 0, 0, 0}, - {{"siz", (sizeof("siz") - 1)}, /* */ - PVT_OTHER, pv_get_srcipz, 0, 0, 0, 0, 0}, - {{"sid", (sizeof("sid") - 1)}, /* server id */ - PVT_OTHER, pv_get_server_id, 0, 0, 0, 0, 0}, - {{"sp", (sizeof("sp") - 1)}, /* */ - PVT_OTHER, pv_get_srcport, 0, 0, 0, 0, 0}, - {{"su", (sizeof("su") - 1)}, /* */ - PVT_OTHER, pv_get_srcaddr_uri, 0, 0, 0, 0, 0}, - {{"sut", (sizeof("sut") - 1)}, /* */ - PVT_OTHER, pv_get_srcaddr_uri_full, 0, 0, 0, 0, 0}, - {{"td", (sizeof("td") - 1)}, /* */ - PVT_OTHER, pv_get_to_attr, pv_set_to_domain, 0, 0, - pv_init_iname, 3}, - {{"to.domain", (sizeof("to.domain") - 1)}, /* */ - PVT_OTHER, pv_get_to_attr, pv_set_to_domain, 0, 0, - pv_init_iname, 3}, - {{"tn", (sizeof("tn") - 1)}, /* */ - PVT_OTHER, pv_get_to_attr, pv_set_to_display, 0, 0, - pv_init_iname, 5}, - {{"tt", (sizeof("tt") - 1)}, /* */ - PVT_OTHER, pv_get_to_attr, 0, 0, 0, pv_init_iname, 4}, - {{"tu", (sizeof("tu") - 1)}, /* */ - PVT_TO, pv_get_to_attr, pv_set_to_uri, 0, 0, pv_init_iname, 1}, - {{"to", (sizeof("to") - 1)}, /* */ - PVT_TO, pv_get_to_attr, pv_set_to_uri, 0, 0, pv_init_iname, 1}, - {{"tU", (sizeof("tU") - 1)}, /* */ - PVT_OTHER, pv_get_to_attr, pv_set_to_username, 0, 0, - pv_init_iname, 2}, - {{"to.user", (sizeof("to.user") - 1)}, /* */ - PVT_OTHER, pv_get_to_attr, pv_set_to_username, 0, 0, - pv_init_iname, 2}, - {{"tUl", (sizeof("tUl") - 1)}, /* */ - PVT_OTHER, pv_get_to_attr, pv_set_to_username, 0, 0, - pv_init_iname, 6}, - {{"true", (sizeof("true") - 1)}, /* */ - PVT_OTHER, pv_get_true, 0, 0, 0, 0, 0}, - {{"Tb", (sizeof("Tb") - 1)}, /* */ - PVT_OTHER, pv_get_timeb, 0, 0, 0, 0, 0}, - {{"Tf", (sizeof("Tf") - 1)}, /* */ - PVT_CONTEXT, pv_get_timef, 0, 0, 0, 0, 0}, - {{"TF", (sizeof("TF") - 1)}, /* */ - PVT_OTHER, pv_get_timenowf, 0, 0, 0, 0, 0}, - {{"Ts", (sizeof("Ts") - 1)}, /* */ - PVT_CONTEXT, pv_get_times, 0, 0, 0, 0, 0}, - {{"TS", (sizeof("TS") - 1)}, /* */ - PVT_OTHER, pv_get_timenows, 0, 0, 0, 0, 0}, - {{"ua", (sizeof("ua") - 1)}, /* */ - PVT_OTHER, pv_get_useragent, 0, 0, 0, 0, 0}, - {{"ruid", (sizeof("ruid") - 1)}, /* */ - PVT_OTHER, pv_get_ruid, 0, 0, 0, 0, 0}, - {{"location_ua", (sizeof("location_ua") - 1)}, /* */ - PVT_OTHER, pv_get_location_ua, 0, 0, 0, 0, 0}, - - {{"shv", (sizeof("shv") - 1)}, PVT_OTHER, pv_get_shvar, pv_set_shvar, - pv_parse_shvar_name, 0, 0, 0}, - {{"shvinc", (sizeof("shvinc") - 1)}, PVT_OTHER, pv_get_shvinc, 0, - pv_parse_shvar_name, 0, 0, 0}, - {{"time", (sizeof("time") - 1)}, PVT_CONTEXT, pv_get_local_time, 0, - pv_parse_time_name, 0, 0, 0}, - {{"timef", (sizeof("timef") - 1)}, PVT_CONTEXT, pv_get_local_strftime, - 0, pv_parse_strftime_name, 0, 0, 0}, - {{"utime", (sizeof("utime") - 1)}, PVT_CONTEXT, pv_get_utc_time, 0, - pv_parse_time_name, 0, 0, 0}, - {{"utimef", (sizeof("utimef") - 1)}, PVT_CONTEXT, pv_get_utc_strftime, - 0, pv_parse_strftime_name, 0, 0, 0}, - {{"TV", (sizeof("TV") - 1)}, PVT_OTHER, pv_get_timeval, 0, - pv_parse_timeval_name, 0, 0, 0}, - {{"nh", (sizeof("nh") - 1)}, PVT_OTHER, pv_get_nh, 0, pv_parse_nh_name, - 0, 0, 0}, - {{"version", (sizeof("version") - 1)}, PVT_OTHER, pv_get_sr_version, 0, - pv_parse_sr_version_name, 0, 0, 0}, - {{"K", (sizeof("K") - 1)}, PVT_OTHER, pv_get_K, 0, pv_parse_K_name, 0, - 0, 0}, - {{"expires", (sizeof("expires") - 1)}, PVT_OTHER, pv_get_expires, 0, - pv_parse_expires_name, 0, 0, 0}, - {{"msg", (sizeof("msg") - 1)}, PVT_OTHER, pv_get_msg_attrs, 0, - pv_parse_msg_attrs_name, 0, 0, 0}, - {{"ksr", (sizeof("ksr") - 1)}, PVT_OTHER, pv_get_ksr_attrs, 0, - pv_parse_ksr_attrs_name, 0, 0, 0}, - {{"rpl", (sizeof("rpl") - 1)}, PVT_OTHER, pv_get_rpl_attrs, 0, - pv_parse_rpl_attrs_name, 0, 0, 0}, - {{"ccp", (sizeof("ccp") - 1)}, PVT_OTHER, pv_get_ccp_attrs, - pv_set_ccp_attrs, pv_parse_ccp_attrs_name, 0, 0, 0}, - {{"via0", (sizeof("via0") - 1)}, PVT_OTHER, pv_get_via0, 0, - pv_parse_via_name, 0, 0, 0}, - {{"via1", (sizeof("via1") - 1)}, PVT_OTHER, pv_get_via1, 0, - pv_parse_via_name, 0, 0, 0}, - {{"viaZ", (sizeof("viaZ") - 1)}, PVT_OTHER, pv_get_viaZ, 0, - pv_parse_via_name, 0, 0, 0}, - {{"msgbuf", (sizeof("msgbuf") - 1)}, PVT_OTHER, pv_get_msgbuf, - pv_set_msgbuf, pv_parse_msgbuf_name, 0, 0, 0}, - - {{0, 0}, 0, 0, 0, 0, 0, 0, 0}}; +/* clang-format off */ +static tr_export_t mod_trans[] = { + {{"s", sizeof("s") - 1}, tr_parse_string}, /* string class */ + {{"nameaddr", sizeof("nameaddr") - 1}, tr_parse_nameaddr}, /* nameaddr class */ + {{"uri", sizeof("uri") - 1}, tr_parse_uri}, /* uri class */ + {{"param", sizeof("param") - 1}, tr_parse_paramlist}, /* param class */ + {{"tobody", sizeof("tobody") - 1}, tr_parse_tobody}, /* param class */ + {{"line", sizeof("line") - 1}, tr_parse_line}, /* line class */ + {{"urialias", sizeof("urialias") - 1}, tr_parse_urialias}, /* uri alias class */ + {{"val", sizeof("val") - 1}, tr_parse_val}, /* val class */ + + {{0, 0}, 0} +}; -static int add_avp_aliases(modparam_t type, void *val); +static pv_export_t mod_pvs[] = { + {{"_s", (sizeof("_s") - 1)}, PVT_OTHER, pv_get__s, 0, pv_parse__s_name, + 0, 0, 0}, + {{"af", (sizeof("af") - 1)}, PVT_OTHER, pv_get_af, 0, pv_parse_af_name, + 0, 0, 0}, + {{"branch", sizeof("branch") - 1}, /* branch attributes */ + PVT_CONTEXT, pv_get_branchx, pv_set_branchx, + pv_parse_branchx_name, pv_parse_index, 0, 0}, + {{"sbranch", sizeof("sbranch") - 1}, /* static branch attributes */ + PVT_CONTEXT, pv_get_sbranch, pv_set_sbranch, + pv_parse_branchx_name, 0, 0, 0}, + {{"mi", (sizeof("mi") - 1)}, /* message id */ + PVT_OTHER, pv_get_msgid, 0, 0, 0, 0, 0}, + {{"stat", sizeof("stat") - 1}, /* statistics */ + PVT_OTHER, pv_get_stat, 0, pv_parse_stat_name, 0, 0, 0}, + {{"sel", sizeof("sel") - 1}, /* select */ + PVT_OTHER, pv_get_select, 0, pv_parse_select_name, 0, 0, 0}, + {{"snd", (sizeof("snd") - 1)}, PVT_OTHER, pv_get_sndto, 0, + pv_parse_snd_name, 0, 0, 0}, + {{"sndto", (sizeof("sndto") - 1)}, PVT_OTHER, pv_get_sndto, 0, + pv_parse_snd_name, 0, 0, 0}, + {{"sndfrom", (sizeof("sndfrom") - 1)}, PVT_OTHER, pv_get_sndfrom, 0, + pv_parse_snd_name, 0, 0, 0}, + {{"rcv", (sizeof("rcv") - 1)}, PVT_OTHER, pv_get_rcv, pv_set_rcv, + pv_parse_rcv_name, 0, 0, 0}, + {{"xavp", sizeof("xavp") - 1}, /* xavp */ + PVT_XAVP, pv_get_xavp, pv_set_xavp, pv_parse_xavp_name, 0, 0, 0}, + {{"xavu", sizeof("xavu") - 1}, /* xavu */ + PVT_XAVU, pv_get_xavu, pv_set_xavu, pv_parse_xavu_name, 0, 0, 0}, + {{"xavi", sizeof("xavi") - 1}, /* xavi */ + PVT_XAVI, pv_get_xavi, pv_set_xavi, 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, pv_parse_index, 0, 0}, + {{"hdrc", (sizeof("hdrc") - 1)}, PVT_HDRC, pv_get_hdrc, 0, + pv_parse_hdr_name, 0, 0, 0}, + {{"hfl", (sizeof("hfl") - 1)}, PVT_HDR, pv_get_hfl, 0, + pv_parse_hfl_name, pv_parse_index, 0, 0}, + {{"hflc", (sizeof("hflc") - 1)}, PVT_HDRC, pv_get_hflc, 0, + pv_parse_hfl_name, 0, 0, 0}, + {{"var", (sizeof("var") - 1)}, PVT_SCRIPTVAR, pv_get_scriptvar, + pv_set_scriptvar, pv_parse_scriptvar_name, 0, 0, 0}, + {{"vz", (sizeof("vz") - 1)}, PVT_SCRIPTVAR, pv_get_scriptvar, + pv_set_scriptvar, pv_parse_scriptvar_name, 0, 0, 0}, + {{"vn", (sizeof("vn") - 1)}, PVT_SCRIPTVAR, pv_get_scriptvar, + pv_set_scriptvar, pv_parse_scriptvarnull_name, 0, 0, 0}, + {{"ai", (sizeof("ai") - 1)}, /* */ + PVT_OTHER, pv_get_pai, 0, 0, pv_parse_index, 0, 0}, + {{"adu", (sizeof("adu") - 1)}, /* auth digest uri */ + PVT_OTHER, pv_get_authattr, 0, 0, 0, pv_init_iname, 3}, + {{"ar", (sizeof("ar") - 1)}, /* auth realm */ + PVT_OTHER, pv_get_authattr, 0, 0, 0, pv_init_iname, 2}, + {{"au", (sizeof("au") - 1)}, /* */ + PVT_OTHER, pv_get_authattr, 0, 0, 0, pv_init_iname, 1}, + {{"ad", (sizeof("ad") - 1)}, /* */ + PVT_OTHER, pv_get_authattr, 0, 0, 0, pv_init_iname, 4}, + {{"aU", (sizeof("aU") - 1)}, /* */ + PVT_OTHER, pv_get_authattr, 0, 0, 0, pv_init_iname, 5}, + {{"aa", (sizeof("aa") - 1)}, /* auth algorithm */ + PVT_OTHER, pv_get_authattr, 0, 0, 0, pv_init_iname, 6}, + {{"adn", (sizeof("adn") - 1)}, /* auth nonce */ + PVT_OTHER, pv_get_authattr, 0, 0, 0, pv_init_iname, 7}, + {{"adc", (sizeof("adc") - 1)}, /* auth cnonce */ + PVT_OTHER, pv_get_authattr, 0, 0, 0, pv_init_iname, 8}, + {{"adr", (sizeof("adr") - 1)}, /* auth response */ + PVT_OTHER, pv_get_authattr, 0, 0, 0, pv_init_iname, 9}, + {{"ado", (sizeof("ado") - 1)}, /* auth opaque */ + PVT_OTHER, pv_get_authattr, 0, 0, 0, pv_init_iname, 10}, + {{"Au", (sizeof("Au") - 1)}, /* */ + PVT_OTHER, pv_get_acc_username, 0, 0, 0, pv_init_iname, 1}, + {{"AU", (sizeof("AU") - 1)}, /* */ + PVT_OTHER, pv_get_acc_user, 0, 0, 0, pv_init_iname, 1}, + {{"bf", (sizeof("bf") - 1)}, /* */ + PVT_CONTEXT, pv_get_bflags, pv_set_bflags, 0, 0, 0, 0}, + {{"bF", (sizeof("bF") - 1)}, /* */ + PVT_CONTEXT, pv_get_hexbflags, pv_set_bflags, 0, 0, 0, 0}, + {{"Bf", (sizeof("Bf") - 1)}, /* */ + PVT_CONTEXT, pv_get_bflag, pv_set_bflag, pv_parse_flag_param, 0, + 0, 0}, + {{"br", (sizeof("br") - 1)}, /* */ + PVT_BRANCH, pv_get_branch, pv_set_branch, 0, 0, 0, 0}, + {{"bR", (sizeof("bR") - 1)}, /* */ + PVT_CONTEXT, pv_get_branches, 0, 0, 0, 0, 0}, + {{"bs", (sizeof("bs") - 1)}, /* */ + PVT_OTHER, pv_get_body_size, 0, 0, 0, 0, 0}, + {{"ci", (sizeof("ci") - 1)}, /* */ + PVT_OTHER, pv_get_callid, 0, 0, 0, 0, 0}, + {{"cl", (sizeof("cl") - 1)}, /* */ + PVT_OTHER, pv_get_content_length, 0, 0, 0, 0, 0}, + {{"cnt", sizeof("cnt") - 1}, PVT_OTHER, pv_get_cnt, 0, + pv_parse_cnt_name, 0, 0, 0}, + {{"conid", (sizeof("conid") - 1)}, /* */ + PVT_OTHER, pv_get_tcpconn_id, 0, 0, 0, 0, 0}, + {{"cs", (sizeof("cs") - 1)}, /* */ + PVT_OTHER, pv_get_cseq, 0, 0, 0, 0, 0}, + {{"csb", (sizeof("csb") - 1)}, /* */ + PVT_OTHER, pv_get_cseq_body, 0, 0, 0, 0, 0}, + {{"ct", (sizeof("ct") - 1)}, /* */ + PVT_OTHER, pv_get_contact, 0, 0, 0, 0, 0}, + {{"cT", (sizeof("cT") - 1)}, /* */ + PVT_OTHER, pv_get_content_type, 0, 0, 0, 0, 0}, + {{"dd", (sizeof("dd") - 1)}, /* */ + PVT_OTHER, pv_get_dsturi_attr, 0, 0, 0, pv_init_iname, 1}, + {{"di", (sizeof("di") - 1)}, /* */ + PVT_OTHER, pv_get_diversion, 0, 0, 0, pv_init_iname, 1}, + {{"dir", (sizeof("dir") - 1)}, /* */ + PVT_OTHER, pv_get_diversion, 0, 0, 0, pv_init_iname, 2}, + {{"dip", (sizeof("dis") - 1)}, /* */ + PVT_OTHER, pv_get_diversion, 0, 0, 0, pv_init_iname, 3}, + {{"dic", (sizeof("dic") - 1)}, /* */ + PVT_OTHER, pv_get_diversion, 0, 0, 0, pv_init_iname, 4}, + {{"dp", (sizeof("dp") - 1)}, /* */ + PVT_OTHER, pv_get_dsturi_attr, 0, 0, 0, pv_init_iname, 2}, + {{"dP", (sizeof("dP") - 1)}, /* */ + PVT_OTHER, pv_get_dsturi_attr, 0, 0, 0, pv_init_iname, 3}, + {{"ds", (sizeof("ds") - 1)}, /* */ + PVT_CONTEXT, pv_get_dset, 0, 0, 0, 0, 0}, + {{"du", (sizeof("du") - 1)}, /* */ + PVT_DSTURI, pv_get_dsturi, pv_set_dsturi, 0, 0, 0, 0}, + {{"duri", (sizeof("duri") - 1)}, /* */ + PVT_DSTURI, pv_get_dsturi, pv_set_dsturi, 0, 0, 0, 0}, + {{"err.class", (sizeof("err.class") - 1)}, /* */ + PVT_OTHER, pv_get_errinfo_attr, 0, 0, 0, 0, 0}, + {{"err.level", (sizeof("err.level") - 1)}, /* */ + PVT_OTHER, pv_get_errinfo_attr, 0, 0, 0, pv_init_iname, 1}, + {{"err.info", (sizeof("err.info") - 1)}, /* */ + PVT_OTHER, pv_get_errinfo_attr, 0, 0, 0, pv_init_iname, 2}, + {{"err.rcode", (sizeof("err.rcode") - 1)}, /* */ + PVT_OTHER, pv_get_errinfo_attr, 0, 0, 0, pv_init_iname, 3}, + {{"err.rreason", (sizeof("err.rreason") - 1)}, /* */ + PVT_OTHER, pv_get_errinfo_attr, 0, 0, 0, pv_init_iname, 4}, + {{"fd", (sizeof("fd") - 1)}, /* */ + PVT_OTHER, pv_get_from_attr, pv_set_from_domain, 0, 0, + pv_init_iname, 3}, + {{"from.domain", (sizeof("from.domain") - 1)}, /* */ + PVT_OTHER, pv_get_from_attr, pv_set_from_domain, 0, 0, + pv_init_iname, 3}, + {{"fn", (sizeof("fn") - 1)}, /* */ + PVT_OTHER, pv_get_from_attr, pv_set_from_display, 0, 0, + pv_init_iname, 5}, + {{"fs", (sizeof("fs") - 1)}, /* */ + PVT_OTHER, pv_get_force_sock, pv_set_force_sock, 0, 0, 0, 0}, + {{"fsn", (sizeof("fsn") - 1)}, /* */ + PVT_OTHER, pv_get_force_sock_name, pv_set_force_sock_name, 0, 0, + 0, 0}, + {{"fsp", (sizeof("fsp") - 1)}, /* */ + PVT_OTHER, pv_get_force_sock_port, 0, 0, 0, 0, 0}, + {{"ft", (sizeof("ft") - 1)}, /* */ + PVT_OTHER, pv_get_from_attr, 0, 0, 0, pv_init_iname, 4}, + {{"fu", (sizeof("fu") - 1)}, /* */ + PVT_FROM, pv_get_from_attr, pv_set_from_uri, 0, 0, + pv_init_iname, 1}, + {{"from", (sizeof("from") - 1)}, /* */ + PVT_FROM, pv_get_from_attr, pv_set_from_uri, 0, 0, + pv_init_iname, 1}, + {{"fU", (sizeof("fU") - 1)}, /* */ + PVT_OTHER, pv_get_from_attr, pv_set_from_username, 0, 0, + pv_init_iname, 2}, + {{"from.user", (sizeof("from.user") - 1)}, /* */ + PVT_OTHER, pv_get_from_attr, pv_set_from_username, 0, 0, + pv_init_iname, 2}, + {{"fUl", (sizeof("fUl") - 1)}, /* */ + PVT_OTHER, pv_get_from_attr, 0, 0, 0, pv_init_iname, 6}, + {{"mb", (sizeof("mb") - 1)}, /* */ + PVT_OTHER, pv_get_msg_buf, 0, 0, 0, 0, 0}, + {{"mbu", (sizeof("mbu") - 1)}, /* */ + PVT_OTHER, pv_get_msg_buf_updated, 0, 0, 0, 0, 0}, + {{"mf", (sizeof("mf") - 1)}, /* */ + PVT_OTHER, pv_get_flags, pv_set_mflags, 0, 0, 0, 0}, + {{"mF", (sizeof("mF") - 1)}, /* */ + PVT_OTHER, pv_get_hexflags, pv_set_mflags, 0, 0, 0, 0}, + {{"Mf", (sizeof("mf") - 1)}, /* */ + PVT_OTHER, pv_get_flag, pv_set_mflag, pv_parse_flag_param, 0, 0, 0}, + {{"ml", (sizeof("ml") - 1)}, /* */ + PVT_OTHER, pv_get_msg_len, 0, 0, 0, 0, 0}, + {{"mt", (sizeof("mt") - 1)}, /* */ + PVT_OTHER, pv_get_msgtype, 0, 0, 0, 0, 0}, + {{"mts", (sizeof("mts") - 1)}, /* */ + PVT_OTHER, pv_get_msgtypes, 0, 0, 0, 0, 0}, + {{"od", (sizeof("od") - 1)}, /* */ + PVT_OTHER, pv_get_ouri_attr, 0, 0, 0, pv_init_iname, 2}, + {{"op", (sizeof("op") - 1)}, /* */ + PVT_OTHER, pv_get_ouri_attr, 0, 0, 0, pv_init_iname, 3}, + {{"oP", (sizeof("oP") - 1)}, /* */ + PVT_OTHER, pv_get_ouri_attr, 0, 0, 0, pv_init_iname, 4}, + {{"ou", (sizeof("ou") - 1)}, /* */ + PVT_OURI, pv_get_ouri, 0, 0, 0, 0, 0}, + {{"ouri", (sizeof("ouri") - 1)}, /* */ + PVT_OURI, pv_get_ouri, 0, 0, 0, 0, 0}, + {{"oU", (sizeof("oU") - 1)}, /* */ + PVT_OTHER, pv_get_ouri_attr, 0, 0, 0, pv_init_iname, 1}, + {{"oUl", (sizeof("oUl") - 1)}, /* */ + PVT_OTHER, pv_get_ouri_attr, 0, 0, 0, pv_init_iname, 6}, + {{"pd", (sizeof("pd") - 1)}, /* */ + PVT_OTHER, pv_get_ppi_attr, 0, 0, pv_parse_index, pv_init_iname, 3}, + {{"pn", (sizeof("pn") - 1)}, /* */ + PVT_OTHER, pv_get_ppi_attr, 0, 0, pv_parse_index, pv_init_iname, 4}, + {{"pp", (sizeof("pp") - 1)}, /* */ + PVT_OTHER, pv_get_pid, 0, 0, 0, 0, 0}, + {{"pr", (sizeof("pr") - 1)}, /* */ + PVT_OTHER, pv_get_proto, 0, 0, 0, 0, 0}, + {{"prid", (sizeof("prid") - 1)}, /* */ + PVT_OTHER, pv_get_protoid, 0, 0, 0, 0, 0}, + {{"proto", (sizeof("proto") - 1)}, /* */ + PVT_OTHER, pv_get_proto, 0, 0, 0, 0, 0}, + {{"pu", (sizeof("pu") - 1)}, /* */ + PVT_OTHER, pv_get_ppi_attr, 0, 0, pv_parse_index, pv_init_iname, 1}, + {{"pU", (sizeof("pU") - 1)}, /* */ + PVT_OTHER, pv_get_ppi_attr, 0, 0, pv_parse_index, pv_init_iname, 2}, + {{"rb", (sizeof("rb") - 1)}, /* */ + PVT_MSG_BODY, pv_get_msg_body, 0, 0, 0, 0, 0}, + {{"rd", (sizeof("rd") - 1)}, /* */ + PVT_RURI_DOMAIN, pv_get_ruri_attr, pv_set_ruri_host, 0, 0, + pv_init_iname, 2}, + {{"ruri.domain", (sizeof("ruri.domain") - 1)}, /* */ + PVT_RURI_DOMAIN, pv_get_ruri_attr, pv_set_ruri_host, 0, 0, + pv_init_iname, 2}, + {{"re", (sizeof("re") - 1)}, /* */ + PVT_OTHER, pv_get_rpid, 0, 0, 0, 0, 0}, + {{"rm", (sizeof("rm") - 1)}, /* */ + PVT_OTHER, pv_get_method, 0, 0, 0, 0, 0}, + {{"rmid", (sizeof("rmid") - 1)}, /* */ + PVT_OTHER, pv_get_methodid, 0, 0, 0, 0, 0}, + {{"rp", (sizeof("rp") - 1)}, /* */ + PVT_OTHER, pv_get_ruri_attr, pv_set_ruri_port, 0, 0, + pv_init_iname, 3}, + {{"rP", (sizeof("rP") - 1)}, /* */ + PVT_OTHER, pv_get_ruri_attr, 0, 0, 0, pv_init_iname, 4}, + {{"rr", (sizeof("rr") - 1)}, /* */ + PVT_OTHER, pv_get_reason, 0, 0, 0, 0, 0}, + {{"rs", (sizeof("rs") - 1)}, /* */ + PVT_OTHER, pv_get_status, 0, 0, 0, 0, 0}, + {{"rsi", (sizeof("rsi") - 1)}, /* */ + PVT_OTHER, pv_get_statusi, 0, 0, 0, 0, 0}, + {{"rt", (sizeof("rt") - 1)}, /* */ + PVT_OTHER, pv_get_refer_to, 0, 0, 0, 0, 0}, + {{"ru", (sizeof("ru") - 1)}, /* */ + PVT_RURI, pv_get_ruri, pv_set_ruri, 0, 0, 0, 0}, + {{"ruri", (sizeof("ruri") - 1)}, /* */ + PVT_RURI, pv_get_ruri, pv_set_ruri, 0, 0, 0, 0}, + {{"rU", (sizeof("rU") - 1)}, /* */ + PVT_RURI_USERNAME, pv_get_ruri_attr, pv_set_ruri_user, 0, 0, + pv_init_iname, 1}, + {{"ruri.user", (sizeof("ruri.user") - 1)}, /* */ + PVT_RURI_USERNAME, pv_get_ruri_attr, pv_set_ruri_user, 0, 0, + pv_init_iname, 1}, + {{"rUl", (sizeof("rUl") - 1)}, /* */ + PVT_RURI_USERNAME, pv_get_ruri_attr, 0, 0, 0, pv_init_iname, 6}, + {{"rv", (sizeof("rv") - 1)}, /* */ + PVT_OTHER, pv_get_version, 0, 0, 0, 0, 0}, + {{"rz", (sizeof("rz") - 1)}, /* */ + PVT_OTHER, pv_get_ruri_attr, 0, 0, 0, pv_init_iname, 5}, + {{"Ras", (sizeof("Ras") - 1)}, /* */ + PVT_OTHER, pv_get_rcvaddr_socket, 0, 0, 0, 0, 0}, + {{"Ri", (sizeof("Ri") - 1)}, /* */ + PVT_OTHER, pv_get_rcvip, 0, 0, 0, 0, 0}, + {{"Rp", (sizeof("Rp") - 1)}, /* */ + PVT_OTHER, pv_get_rcvport, 0, 0, 0, 0, 0}, + {{"Ru", (sizeof("Ru") - 1)}, /* */ + PVT_OTHER, pv_get_rcvaddr_uri, 0, 0, 0, 0, 0}, + {{"Rut", (sizeof("Rut") - 1)}, /* */ + PVT_OTHER, pv_get_rcvaddr_uri_full, 0, 0, 0, 0, 0}, + {{"Rn", (sizeof("Rn") - 1)}, /* */ + PVT_OTHER, pv_get_rcvsname, 0, 0, 0, 0, 0}, + {{"RAi", (sizeof("RAi") - 1)}, /* */ + PVT_OTHER, pv_get_rcv_advertised_ip, 0, 0, 0, 0, 0}, + {{"RAp", (sizeof("RAp") - 1)}, /* */ + PVT_OTHER, pv_get_rcv_advertised_port, 0, 0, 0, 0, 0}, + {{"RAu", (sizeof("RAu") - 1)}, /* */ + PVT_OTHER, pv_get_rcvadv_uri, 0, 0, 0, 0, 0}, + {{"RAut", (sizeof("RAut") - 1)}, /* */ + PVT_OTHER, pv_get_rcvadv_uri_full, 0, 0, 0, 0, 0}, + {{"sas", (sizeof("sas") - 1)}, /* */ + PVT_OTHER, pv_get_srcaddr_socket, 0, 0, 0, 0, 0}, + {{"sf", (sizeof("sf") - 1)}, /* */ + PVT_OTHER, pv_get_sflags, pv_set_sflags, 0, 0, 0, 0}, + {{"sF", (sizeof("sF") - 1)}, /* */ + PVT_OTHER, pv_get_hexsflags, pv_set_sflags, 0, 0, 0, 0}, + {{"Sf", (sizeof("sf") - 1)}, /* */ + PVT_OTHER, pv_get_sflag, pv_set_sflag, pv_parse_flag_param, 0, + 0, 0}, + {{"src_ip", (sizeof("src_ip") - 1)}, /* */ + PVT_OTHER, pv_get_srcip, 0, 0, 0, 0, 0}, + {{"si", (sizeof("si") - 1)}, /* */ + PVT_OTHER, pv_get_srcip, 0, 0, 0, 0, 0}, + {{"siz", (sizeof("siz") - 1)}, /* */ + PVT_OTHER, pv_get_srcipz, 0, 0, 0, 0, 0}, + {{"sid", (sizeof("sid") - 1)}, /* server id */ + PVT_OTHER, pv_get_server_id, 0, 0, 0, 0, 0}, + {{"sp", (sizeof("sp") - 1)}, /* */ + PVT_OTHER, pv_get_srcport, 0, 0, 0, 0, 0}, + {{"su", (sizeof("su") - 1)}, /* */ + PVT_OTHER, pv_get_srcaddr_uri, 0, 0, 0, 0, 0}, + {{"sut", (sizeof("sut") - 1)}, /* */ + PVT_OTHER, pv_get_srcaddr_uri_full, 0, 0, 0, 0, 0}, + {{"td", (sizeof("td") - 1)}, /* */ + PVT_OTHER, pv_get_to_attr, pv_set_to_domain, 0, 0, + pv_init_iname, 3}, + {{"to.domain", (sizeof("to.domain") - 1)}, /* */ + PVT_OTHER, pv_get_to_attr, pv_set_to_domain, 0, 0, + pv_init_iname, 3}, + {{"tn", (sizeof("tn") - 1)}, /* */ + PVT_OTHER, pv_get_to_attr, pv_set_to_display, 0, 0, + pv_init_iname, 5}, + {{"tt", (sizeof("tt") - 1)}, /* */ + PVT_OTHER, pv_get_to_attr, 0, 0, 0, pv_init_iname, 4}, + {{"tu", (sizeof("tu") - 1)}, /* */ + PVT_TO, pv_get_to_attr, pv_set_to_uri, 0, 0, pv_init_iname, 1}, + {{"to", (sizeof("to") - 1)}, /* */ + PVT_TO, pv_get_to_attr, pv_set_to_uri, 0, 0, pv_init_iname, 1}, + {{"tU", (sizeof("tU") - 1)}, /* */ + PVT_OTHER, pv_get_to_attr, pv_set_to_username, 0, 0, + pv_init_iname, 2}, + {{"to.user", (sizeof("to.user") - 1)}, /* */ + PVT_OTHER, pv_get_to_attr, pv_set_to_username, 0, 0, + pv_init_iname, 2}, + {{"tUl", (sizeof("tUl") - 1)}, /* */ + PVT_OTHER, pv_get_to_attr, pv_set_to_username, 0, 0, + pv_init_iname, 6}, + {{"true", (sizeof("true") - 1)}, /* */ + PVT_OTHER, pv_get_true, 0, 0, 0, 0, 0}, + {{"Tb", (sizeof("Tb") - 1)}, /* */ + PVT_OTHER, pv_get_timeb, 0, 0, 0, 0, 0}, + {{"Tf", (sizeof("Tf") - 1)}, /* */ + PVT_CONTEXT, pv_get_timef, 0, 0, 0, 0, 0}, + {{"TF", (sizeof("TF") - 1)}, /* */ + PVT_OTHER, pv_get_timenowf, 0, 0, 0, 0, 0}, + {{"Ts", (sizeof("Ts") - 1)}, /* */ + PVT_CONTEXT, pv_get_times, 0, 0, 0, 0, 0}, + {{"TS", (sizeof("TS") - 1)}, /* */ + PVT_OTHER, pv_get_timenows, 0, 0, 0, 0, 0}, + {{"ua", (sizeof("ua") - 1)}, /* */ + PVT_OTHER, pv_get_useragent, 0, 0, 0, 0, 0}, + {{"ruid", (sizeof("ruid") - 1)}, /* */ + PVT_OTHER, pv_get_ruid, 0, 0, 0, 0, 0}, + {{"location_ua", (sizeof("location_ua") - 1)}, /* */ + PVT_OTHER, pv_get_location_ua, 0, 0, 0, 0, 0}, + + {{"shv", (sizeof("shv") - 1)}, PVT_OTHER, pv_get_shvar, pv_set_shvar, + pv_parse_shvar_name, 0, 0, 0}, + {{"shvinc", (sizeof("shvinc") - 1)}, PVT_OTHER, pv_get_shvinc, 0, + pv_parse_shvar_name, 0, 0, 0}, + {{"time", (sizeof("time") - 1)}, PVT_CONTEXT, pv_get_local_time, 0, + pv_parse_time_name, 0, 0, 0}, + {{"timef", (sizeof("timef") - 1)}, PVT_CONTEXT, pv_get_local_strftime, + 0, pv_parse_strftime_name, 0, 0, 0}, + {{"utime", (sizeof("utime") - 1)}, PVT_CONTEXT, pv_get_utc_time, 0, + pv_parse_time_name, 0, 0, 0}, + {{"utimef", (sizeof("utimef") - 1)}, PVT_CONTEXT, pv_get_utc_strftime, + 0, pv_parse_strftime_name, 0, 0, 0}, + {{"TV", (sizeof("TV") - 1)}, PVT_OTHER, pv_get_timeval, 0, + pv_parse_timeval_name, 0, 0, 0}, + {{"nh", (sizeof("nh") - 1)}, PVT_OTHER, pv_get_nh, 0, pv_parse_nh_name, + 0, 0, 0}, + {{"version", (sizeof("version") - 1)}, PVT_OTHER, pv_get_sr_version, 0, + pv_parse_sr_version_name, 0, 0, 0}, + {{"K", (sizeof("K") - 1)}, PVT_OTHER, pv_get_K, 0, pv_parse_K_name, 0, + 0, 0}, + {{"expires", (sizeof("expires") - 1)}, PVT_OTHER, pv_get_expires, 0, + pv_parse_expires_name, 0, 0, 0}, + {{"msg", (sizeof("msg") - 1)}, PVT_OTHER, pv_get_msg_attrs, 0, + pv_parse_msg_attrs_name, 0, 0, 0}, + {{"ksr", (sizeof("ksr") - 1)}, PVT_OTHER, pv_get_ksr_attrs, 0, + pv_parse_ksr_attrs_name, 0, 0, 0}, + {{"rpl", (sizeof("rpl") - 1)}, PVT_OTHER, pv_get_rpl_attrs, 0, + pv_parse_rpl_attrs_name, 0, 0, 0}, + {{"ccp", (sizeof("ccp") - 1)}, PVT_OTHER, pv_get_ccp_attrs, + pv_set_ccp_attrs, pv_parse_ccp_attrs_name, 0, 0, 0}, + {{"via0", (sizeof("via0") - 1)}, PVT_OTHER, pv_get_via0, 0, + pv_parse_via_name, 0, 0, 0}, + {{"via1", (sizeof("via1") - 1)}, PVT_OTHER, pv_get_via1, 0, + pv_parse_via_name, 0, 0, 0}, + {{"viaZ", (sizeof("viaZ") - 1)}, PVT_OTHER, pv_get_viaZ, 0, + pv_parse_via_name, 0, 0, 0}, + {{"msgbuf", (sizeof("msgbuf") - 1)}, PVT_OTHER, pv_get_msgbuf, + pv_set_msgbuf, pv_parse_msgbuf_name, 0, 0, 0}, + + {{0, 0}, 0, 0, 0, 0, 0, 0, 0} +}; static param_export_t params[] = { - {"shvset", PARAM_STRING | USE_FUNC_PARAM, (void *)param_set_shvar}, - {"varset", PARAM_STRING | USE_FUNC_PARAM, (void *)param_set_var}, - {"avp_aliases", PARAM_STRING | USE_FUNC_PARAM, (void *)add_avp_aliases}, - {0, 0, 0}}; + {"shvset", PARAM_STRING | USE_FUNC_PARAM, (void *)param_set_shvar}, + {"varset", PARAM_STRING | USE_FUNC_PARAM, (void *)param_set_var}, + {"avp_aliases", PARAM_STRING | USE_FUNC_PARAM, (void *)add_avp_aliases}, + + {0, 0, 0} +}; +/* clang-format on */ static int mod_init(void); static void mod_destroy(void); @@ -475,6 +466,8 @@ static int w_xavp_copy_dst(sip_msg_t *msg, char *src_name, char *src_idx, char *dst_name, char *dst_idx); static int w_xavp_params_explode(sip_msg_t *msg, char *pparams, char *pxname); static int w_xavp_params_implode(sip_msg_t *msg, char *pxname, char *pvname); +static int w_xavp_params_implode_qval( + sip_msg_t *msg, char *pxname, char *pvname); static int w_xavu_params_explode(sip_msg_t *msg, char *pparams, char *pxname); static int w_xavu_params_implode(sip_msg_t *msg, char *pxname, char *pvname); static int w_xavp_slist_explode( @@ -511,80 +504,87 @@ static int fixup_free_xavp_child_seti(void **param, int param_no); static int pv_init_rpc(void); int pv_register_api(pv_api_t *); +/* clang-format off */ static cmd_export_t cmds[] = { - {"pv_isset", (cmd_function)pv_isset, 1, fixup_pvar_null, 0, ANY_ROUTE}, - {"pv_unset", (cmd_function)pv_unset, 1, fixup_pvar_null, 0, ANY_ROUTE}, - {"pv_xavp_print", (cmd_function)pv_xavp_print, 0, 0, 0, ANY_ROUTE}, - {"pv_xavu_print", (cmd_function)pv_xavu_print, 0, 0, 0, ANY_ROUTE}, - {"pv_xavi_print", (cmd_function)pv_xavi_print, 0, 0, 0, ANY_ROUTE}, - {"pv_var_to_xavp", (cmd_function)w_var_to_xavp, 2, fixup_spve_spve, - fixup_free_spve_spve, ANY_ROUTE}, - {"pv_xavp_to_var", (cmd_function)w_xavp_to_var, 1, fixup_spve_null, - fixup_free_spve_null, ANY_ROUTE}, - {"is_int", (cmd_function)is_int, 1, fixup_pvar_null, - fixup_free_pvar_null, ANY_ROUTE}, - {"typeof", (cmd_function)pv_typeof, 2, fixup_pvar_none, - fixup_free_pvar_none, ANY_ROUTE}, - {"not_empty", (cmd_function)pv_not_empty, 1, fixup_pvar_null, - fixup_free_pvar_null, ANY_ROUTE}, - {"xavp_copy", (cmd_function)w_xavp_copy, 3, pv_xavp_copy_fixup, 0, - ANY_ROUTE}, - {"xavp_copy", (cmd_function)w_xavp_copy_dst, 4, pv_xavp_copy_fixup, 0, - ANY_ROUTE}, - {"xavp_slist_explode", (cmd_function)w_xavp_slist_explode, 4, - fixup_spve_all, fixup_free_spve_all, ANY_ROUTE}, - {"xavp_params_explode", (cmd_function)w_xavp_params_explode, 2, - fixup_spve_spve, fixup_free_spve_spve, ANY_ROUTE}, - {"xavp_params_implode", (cmd_function)w_xavp_params_implode, 2, - fixup_spve_str, fixup_free_spve_str, ANY_ROUTE}, - {"xavu_params_explode", (cmd_function)w_xavu_params_explode, 2, - fixup_spve_spve, fixup_free_spve_spve, ANY_ROUTE}, - {"xavu_params_implode", (cmd_function)w_xavu_params_implode, 2, - fixup_spve_str, fixup_free_spve_str, ANY_ROUTE}, - {"xavp_child_seti", (cmd_function)w_xavp_child_seti, 3, - fixup_xavp_child_seti, fixup_free_xavp_child_seti, ANY_ROUTE}, - {"xavp_child_sets", (cmd_function)w_xavp_child_sets, 3, fixup_spve_all, - fixup_free_spve_all, ANY_ROUTE}, - {"xavp_rm", (cmd_function)w_xavp_rm, 1, fixup_spve_null, - fixup_free_spve_null, ANY_ROUTE}, - {"xavp_child_rm", (cmd_function)w_xavp_child_rm, 2, fixup_spve_spve, - fixup_free_spve_spve, ANY_ROUTE}, - {"xavi_child_seti", (cmd_function)w_xavi_child_seti, 3, - fixup_xavp_child_seti, fixup_free_xavp_child_seti, ANY_ROUTE}, - {"xavi_child_sets", (cmd_function)w_xavi_child_sets, 3, fixup_spve_all, - fixup_free_spve_all, ANY_ROUTE}, - {"xavi_rm", (cmd_function)w_xavi_rm, 1, fixup_spve_null, - fixup_free_spve_null, ANY_ROUTE}, - {"xavi_child_rm", (cmd_function)w_xavi_child_rm, 2, fixup_spve_spve, - fixup_free_spve_spve, ANY_ROUTE}, - {"xavp_lshift", (cmd_function)w_xavp_lshift, 2, fixup_spve_igp, - fixup_free_spve_igp, ANY_ROUTE}, - {"xavp_push_dst", (cmd_function)w_xavp_push_dst, 1, fixup_spve_null, - fixup_free_spve_null, - REQUEST_ROUTE | BRANCH_ROUTE | FAILURE_ROUTE}, - {"sbranch_set_ruri", (cmd_function)w_sbranch_set_ruri, 0, 0, 0, - ANY_ROUTE}, - {"sbranch_append", (cmd_function)w_sbranch_append, 0, 0, 0, ANY_ROUTE}, - {"sbranch_reset", (cmd_function)w_sbranch_reset, 0, 0, 0, ANY_ROUTE}, - {"pv_evalx", (cmd_function)w_pv_evalx, 2, pv_evalx_fixup, 0, ANY_ROUTE}, - /* API exports */ - {"pv_register_api", (cmd_function)pv_register_api, NO_SCRIPT, 0, 0}, - {0, 0, 0, 0, 0, 0}}; + {"pv_isset", (cmd_function)pv_isset, 1, fixup_pvar_null, 0, ANY_ROUTE}, + {"pv_unset", (cmd_function)pv_unset, 1, fixup_pvar_null, 0, ANY_ROUTE}, + {"pv_xavp_print", (cmd_function)pv_xavp_print, 0, 0, 0, ANY_ROUTE}, + {"pv_xavu_print", (cmd_function)pv_xavu_print, 0, 0, 0, ANY_ROUTE}, + {"pv_xavi_print", (cmd_function)pv_xavi_print, 0, 0, 0, ANY_ROUTE}, + {"pv_var_to_xavp", (cmd_function)w_var_to_xavp, 2, fixup_spve_spve, + fixup_free_spve_spve, ANY_ROUTE}, + {"pv_xavp_to_var", (cmd_function)w_xavp_to_var, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"is_int", (cmd_function)is_int, 1, fixup_pvar_null, + fixup_free_pvar_null, ANY_ROUTE}, + {"typeof", (cmd_function)pv_typeof, 2, fixup_pvar_none, + fixup_free_pvar_none, ANY_ROUTE}, + {"not_empty", (cmd_function)pv_not_empty, 1, fixup_pvar_null, + fixup_free_pvar_null, ANY_ROUTE}, + {"xavp_copy", (cmd_function)w_xavp_copy, 3, pv_xavp_copy_fixup, 0, + ANY_ROUTE}, + {"xavp_copy", (cmd_function)w_xavp_copy_dst, 4, pv_xavp_copy_fixup, 0, + ANY_ROUTE}, + {"xavp_slist_explode", (cmd_function)w_xavp_slist_explode, 4, + fixup_spve_all, fixup_free_spve_all, ANY_ROUTE}, + {"xavp_params_explode", (cmd_function)w_xavp_params_explode, 2, + fixup_spve_spve, fixup_free_spve_spve, ANY_ROUTE}, + {"xavp_params_implode", (cmd_function)w_xavp_params_implode, 2, + fixup_spve_str, fixup_free_spve_str, ANY_ROUTE}, + {"xavp_params_implode_qval", (cmd_function)w_xavp_params_implode_qval, + 2, fixup_spve_str, fixup_free_spve_str, ANY_ROUTE}, + {"xavu_params_explode", (cmd_function)w_xavu_params_explode, 2, + fixup_spve_spve, fixup_free_spve_spve, ANY_ROUTE}, + {"xavu_params_implode", (cmd_function)w_xavu_params_implode, 2, + fixup_spve_str, fixup_free_spve_str, ANY_ROUTE}, + {"xavp_child_seti", (cmd_function)w_xavp_child_seti, 3, + fixup_xavp_child_seti, fixup_free_xavp_child_seti, ANY_ROUTE}, + {"xavp_child_sets", (cmd_function)w_xavp_child_sets, 3, fixup_spve_all, + fixup_free_spve_all, ANY_ROUTE}, + {"xavp_rm", (cmd_function)w_xavp_rm, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"xavp_child_rm", (cmd_function)w_xavp_child_rm, 2, fixup_spve_spve, + fixup_free_spve_spve, ANY_ROUTE}, + {"xavi_child_seti", (cmd_function)w_xavi_child_seti, 3, + fixup_xavp_child_seti, fixup_free_xavp_child_seti, ANY_ROUTE}, + {"xavi_child_sets", (cmd_function)w_xavi_child_sets, 3, fixup_spve_all, + fixup_free_spve_all, ANY_ROUTE}, + {"xavi_rm", (cmd_function)w_xavi_rm, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"xavi_child_rm", (cmd_function)w_xavi_child_rm, 2, fixup_spve_spve, + fixup_free_spve_spve, ANY_ROUTE}, + {"xavp_lshift", (cmd_function)w_xavp_lshift, 2, fixup_spve_igp, + fixup_free_spve_igp, ANY_ROUTE}, + {"xavp_push_dst", (cmd_function)w_xavp_push_dst, 1, fixup_spve_null, + fixup_free_spve_null, + REQUEST_ROUTE | BRANCH_ROUTE | FAILURE_ROUTE}, + {"sbranch_set_ruri", (cmd_function)w_sbranch_set_ruri, 0, 0, 0, + ANY_ROUTE}, + {"sbranch_append", (cmd_function)w_sbranch_append, 0, 0, 0, ANY_ROUTE}, + {"sbranch_reset", (cmd_function)w_sbranch_reset, 0, 0, 0, ANY_ROUTE}, + {"pv_evalx", (cmd_function)w_pv_evalx, 2, pv_evalx_fixup, 0, ANY_ROUTE}, + + /* API exports */ + {"pv_register_api", (cmd_function)pv_register_api, NO_SCRIPT, 0, 0}, + + {0, 0, 0, 0, 0, 0} +}; /** module exports */ struct module_exports exports = { - "pv", /* module name */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* cmd (cfg function) exports */ - params, /* param exports */ - 0, /* RPC method exports */ - mod_pvs, /* pv exports */ - 0, /* response handling function */ - mod_init, /* module init function */ - 0, /* per-child init function */ - mod_destroy /* module destroy function */ + "pv", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* cmd (cfg function) exports */ + params, /* param exports */ + 0, /* RPC method exports */ + mod_pvs, /* pv exports */ + 0, /* response handling function */ + mod_init, /* module init function */ + 0, /* per-child init function */ + mod_destroy /* module destroy function */ }; +/* clang-format on */ static int mod_init(void) { @@ -1119,7 +1119,8 @@ static int ki_xavu_params_explode(sip_msg_t *msg, str *sparams, str *sxname) /** * */ -static int ki_xavp_params_implode(sip_msg_t *msg, str *sxname, str *svname) +static int ki_xavp_params_implode_mode( + sip_msg_t *msg, str *sxname, int mode, str *svname) { pv_spec_t *vspec = NULL; pv_value_t val; @@ -1144,7 +1145,8 @@ static int ki_xavp_params_implode(sip_msg_t *msg, str *sxname, str *svname) } val.rs.s = pv_get_buffer(); - val.rs.len = xavp_serialize_fields(sxname, val.rs.s, pv_get_buffer_size()); + val.rs.len = xavp_serialize_fields_style( + sxname, mode, val.rs.s, pv_get_buffer_size()); if(val.rs.len <= 0) { return -1; } @@ -1158,6 +1160,14 @@ static int ki_xavp_params_implode(sip_msg_t *msg, str *sxname, str *svname) return 1; } +/** + * + */ +static int ki_xavp_params_implode(sip_msg_t *msg, str *sxname, str *svname) +{ + return ki_xavp_params_implode_mode(msg, sxname, 0, svname); +} + /** * */ @@ -1173,6 +1183,30 @@ static int w_xavp_params_implode(sip_msg_t *msg, char *pxname, char *pvname) return ki_xavp_params_implode(msg, &sxname, (str *)pvname); } +/** + * + */ +static int ki_xavp_params_implode_qval(sip_msg_t *msg, str *sxname, str *svname) +{ + return ki_xavp_params_implode_mode(msg, sxname, XAVP_PRINT_QVAL, svname); +} + +/** + * + */ +static int w_xavp_params_implode_qval( + sip_msg_t *msg, char *pxname, char *pvname) +{ + str sxname; + + if(fixup_get_svalue(msg, (gparam_t *)pxname, &sxname) != 0) { + LM_ERR("cannot get the xavp name\n"); + return -1; + } + + return ki_xavp_params_implode_qval(msg, &sxname, (str *)pvname); +} + /** * */ @@ -2864,6 +2898,11 @@ static sr_kemi_t sr_kemi_pvx_exports[] = { { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, + { str_init("pvx"), str_init("xavp_params_implode_qval"), + SR_KEMIP_INT, ki_xavp_params_implode_qval, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, { str_init("pvx"), str_init("xavu_params_explode"), SR_KEMIP_INT, ki_xavu_params_explode, { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, @@ -3193,8 +3232,14 @@ static const char *rpc_shv_set_doc[2] = { static const char *rpc_shv_get_doc[2] = { "Get the value of a shared variable. If no argument, dumps all", 0}; -rpc_export_t pv_rpc[] = {{"pv.shvSet", rpc_shv_set, rpc_shv_set_doc, 0}, - {"pv.shvGet", rpc_shv_get, rpc_shv_get_doc, 0}, {0, 0, 0, 0}}; +/* clang-format off */ +rpc_export_t pv_rpc[] = { + {"pv.shvSet", rpc_shv_set, rpc_shv_set_doc, 0}, + {"pv.shvGet", rpc_shv_get, rpc_shv_get_doc, 0}, + + {0, 0, 0, 0} +}; +/* clang-format on */ static int pv_init_rpc(void) { diff --git a/src/modules/pv/pv_core.c b/src/modules/pv/pv_core.c index fc3cc7d12..129247f26 100644 --- a/src/modules/pv/pv_core.c +++ b/src/modules/pv/pv_core.c @@ -1100,7 +1100,7 @@ int pv_get_diversion(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) } if(param->pvn.u.isname.name.n == 1) { /* uri */ - return pv_get_strval(msg, param, res, &(get_diversion(msg)->uri)); + return pv_get_strval(msg, param, res, &(get_diversion(msg)->id->uri)); } if(param->pvn.u.isname.name.n == 2) { /* reason param */ @@ -2090,9 +2090,15 @@ int pv_get_hfl(sip_msg_t *msg, pv_param_t *param, pv_value_t *res) via_body_t *vb = NULL; rr_t *rrb = NULL; contact_t *cb = NULL; + diversion_body_t *db = NULL; + p_id_body_t *ppib = NULL; + p_id_body_t *paib = NULL; hdr_field_t *hf = NULL; hdr_field_t thdr = {0}; int n = 0; + int ppi_header_count = 0; + int pai_header_count = 0; + int innerIndex = 0; str sval = STR_NULL; if(msg == NULL || res == NULL || param == NULL) @@ -2143,7 +2149,7 @@ int pv_get_hfl(sip_msg_t *msg, pv_param_t *param, pv_value_t *res) return pv_get_null(msg, param, res); } if(idx < 0) { - n = 1; + n = 0; /* count Via header bodies */ for(hf = msg->h_via1; hf != NULL; hf = hf->next) { if(hf->type == HDR_VIA_T) { @@ -2201,7 +2207,7 @@ int pv_get_hfl(sip_msg_t *msg, pv_param_t *param, pv_value_t *res) } if(idx < 0) { - n = 1; + n = 0; /* count Record-Route/Route header bodies */ for(; hf != NULL; hf = hf->next) { if(hf->type == tv.ri) { @@ -2284,7 +2290,7 @@ int pv_get_hfl(sip_msg_t *msg, pv_param_t *param, pv_value_t *res) return pv_get_null(msg, param, res); } if(idx < 0) { - n = 1; + n = 0; /* count Contact header bodies */ for(hf = msg->contact; hf != NULL; hf = hf->next) { if(hf->type == HDR_CONTACT_T) { @@ -2335,6 +2341,162 @@ int pv_get_hfl(sip_msg_t *msg, pv_param_t *param, pv_value_t *res) return pv_get_null(msg, param, res); } + if((tv.flags == 0) && (tv.ri == HDR_DIVERSION_T)) { + if(msg->diversion == NULL) { + LM_WARN("no Diversion header\n"); + return pv_get_null(msg, param, res); + } + + if(parse_diversion_header(msg) < 0) { + LM_WARN("failed to parse Diversion headers\n"); + return pv_get_null(msg, param, res); + } + + db = (diversion_body_t *)msg->diversion->parsed; + n = 0; + + while(db != NULL) { + n += db->num_ids; + db = db->next; + } + + if(idx < 0) { + idx = -idx; + if(idx > n) { + LM_WARN("index out of range\n"); + return pv_get_null(msg, param, res); + } + idx = n - idx; + } + + n = 0; + db = (diversion_body_t *)msg->diversion->parsed; + /* loop through all parsed Diversion headers lists */ + while(db != NULL) { + if(n + db->num_ids > idx) { + /* Calculate the index within this specific list */ + innerIndex = idx - n; + + /* Access the desired element within this list */ + sval.s = db->id[innerIndex].body.s; + sval.len = db->id[innerIndex].body.len; + trim(&sval); + res->rs = sval; + return 0; + } + + /* Move to the next Diversion header list */ + n += db->num_ids; + db = db->next; + } + LM_DBG("unexpected diversion index out of range\n"); + return pv_get_null(msg, param, res); + } + + if((tv.flags == 0) && (tv.ri == HDR_PPI_T)) { + if(msg->ppi == NULL) { + LM_DBG("no PPI header\n"); + return pv_get_null(msg, param, res); + } + + if(parse_ppi_header(msg) < 0) { + LM_DBG("failed to parse PPI headers\n"); + return pv_get_null(msg, param, res); + } + + ppib = (p_id_body_t *)msg->ppi->parsed; + ppi_header_count = 0; + + while(ppib != NULL) { + ppi_header_count += ppib->num_ids; + ppib = ppib->next; + } + + if(idx < 0) { + idx = -idx; + if(idx > ppi_header_count) { + LM_DBG("index out of range\n"); + return pv_get_null(msg, param, res); + } + idx = ppi_header_count - idx; + } + + n = 0; + ppib = (p_id_body_t *)msg->ppi->parsed; + /* loop through all parsed ppi headers lists */ + while(ppib != NULL) { + if(n + ppib->num_ids > idx) { + /* Calculate the index within this specific list */ + innerIndex = idx - n; + + /* Access the desired element within this list */ + sval.s = ppib->id[innerIndex].body.s; + sval.len = ppib->id[innerIndex].body.len; + trim(&sval); + res->rs = sval; + return 0; + } + + /* Move to the next ppi header list */ + n += ppib->num_ids; + ppib = ppib->next; + } + LM_DBG("unexpected PPI index out of range\n"); + return pv_get_null(msg, param, res); + } + + if((tv.flags == 0) && (tv.ri == HDR_PAI_T)) { + if(msg->pai == NULL) { + LM_DBG("no PAI header\n"); + return pv_get_null(msg, param, res); + } + + if(parse_pai_header(msg) < 0) { + LM_DBG("failed to parse PAI headers\n"); + return pv_get_null(msg, param, res); + } + + paib = (p_id_body_t *)msg->pai->parsed; + pai_header_count = 0; + + while(paib != NULL) { + pai_header_count += paib->num_ids; + paib = paib->next; + } + + if(idx < 0) { + idx = -idx; + if(idx > pai_header_count) { + LM_DBG("index out of range\n"); + return pv_get_null(msg, param, res); + } + idx = pai_header_count - idx; + } + + n = 0; + paib = (p_id_body_t *)msg->pai->parsed; + /* loop through all parsed PAI headers lists */ + while(paib != NULL) { + if(n + paib->num_ids > idx) { + /* Calculate the index within this specific list */ + innerIndex = idx - n; + + /* Access the desired element within this list */ + sval.s = paib->id[innerIndex].body.s; + sval.len = paib->id[innerIndex].body.len; + trim(&sval); + res->rs = sval; + return 0; + } + + /* Move to the next PAI header list */ + n += paib->num_ids; + paib = paib->next; + } + LM_DBG("unexpected PAI index out of range\n"); + return pv_get_null(msg, param, res); + } + return pv_get_hdr_helper(msg, param, res, &tv, idx, idxf); } @@ -2347,6 +2509,8 @@ int pv_get_hflc(sip_msg_t *msg, pv_param_t *param, pv_value_t *res) via_body_t *vb = NULL; rr_t *rrb = NULL; contact_t *cb = NULL; + p_id_body_t *ppib = NULL; + p_id_body_t *paib = NULL; hdr_field_t *hf = NULL; hdr_field_t thdr = {0}; int n = 0; @@ -2452,6 +2616,64 @@ int pv_get_hflc(sip_msg_t *msg, pv_param_t *param, pv_value_t *res) return pv_get_sintval(msg, param, res, n); } + if((tv.flags == 0) && (tv.ri == HDR_DIVERSION_T)) { + if(msg->diversion == NULL) { + LM_DBG("no Diversion header\n"); + return pv_get_sintval(msg, param, res, 0); + } + if(parse_diversion_header(msg) < 0) { + LM_DBG("failed to parse Diversion headers\n"); + return pv_get_sintval(msg, param, res, 0); + } + + diversion_body_t *db = (diversion_body_t *)msg->diversion->parsed; + int diversion_body_count = 0; + while(db != NULL) { + diversion_body_count += db->num_ids; + db = db->next; + } + return pv_get_sintval(msg, param, res, diversion_body_count); + } + + if((tv.flags == 0) && (tv.ri == HDR_PPI_T)) { + if(msg->ppi == NULL) { + LM_DBG("no PPI header\n"); + return pv_get_sintval(msg, param, res, 0); + } + + if(parse_ppi_header(msg) < 0) { + LM_DBG("failed to parse PPI headers\n"); + return pv_get_sintval(msg, param, res, 0); + } + + ppib = (p_id_body_t *)msg->ppi->parsed; + n = 0; + while(ppib != NULL) { + n += ppib->num_ids; + ppib = ppib->next; + } + return pv_get_sintval(msg, param, res, n); + } + + if((tv.flags == 0) && (tv.ri == HDR_PAI_T)) { + if(msg->pai == NULL) { + LM_DBG("no PAI header\n"); + return pv_get_sintval(msg, param, res, 0); + } + if(parse_pai_header(msg) < 0) { + LM_DBG("failed to parse PAI headers\n"); + return pv_get_sintval(msg, param, res, 0); + } + + paib = (p_id_body_t *)msg->pai->parsed; + n = 0; + while(paib != NULL) { + n += paib->num_ids; + paib = paib->next; + } + return pv_get_sintval(msg, param, res, n); + } + for(hf = msg->headers; hf; hf = hf->next) { if(tv.flags == 0) { if(tv.ri == hf->type) { @@ -2551,7 +2773,7 @@ int pv_get_cnt(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) * But this would be less intuitive in our case for counting. */ pv_xavp_name_t *xname, *xname_sub; - sr_xavp_t *ravp, *sub_avp; + sr_xavp_t *ravp = NULL, *sub_avp = NULL; int root_idxf, root_idx_spec, root_idx; int sub_idxf, sub_idx_spec, sub_idx; int count; @@ -4488,6 +4710,12 @@ int pv_parse_via_name(pv_spec_p sp, str *in) else goto error; break; + case 2: + if(strncmp(in->s, "oc", 2) == 0) + sp->pvp.pvn.u.isname.name.n = 9; + else + goto error; + break; case 4: if(strncmp(in->s, "host", 4) == 0) sp->pvp.pvn.u.isname.name.n = 0; @@ -4501,18 +4729,32 @@ int pv_parse_via_name(pv_spec_p sp, str *in) sp->pvp.pvn.u.isname.name.n = 2; else if(strncmp(in->s, "rport", 5) == 0) sp->pvp.pvn.u.isname.name.n = 5; + else if(strncmp(in->s, "ocseq", 5) == 0) + sp->pvp.pvn.u.isname.name.n = 12; + else if(strncmp(in->s, "ocval", 5) == 0) + sp->pvp.pvn.u.isname.name.n = 14; else goto error; break; case 6: if(strncmp(in->s, "branch", 6) == 0) sp->pvp.pvn.u.isname.name.n = 4; + else if(strncmp(in->s, "params", 6) == 0) + sp->pvp.pvn.u.isname.name.n = 8; + else if(strncmp(in->s, "ocalgo", 6) == 0) + sp->pvp.pvn.u.isname.name.n = 10; + else if(strncmp(in->s, "oc-seq", 6) == 0) + sp->pvp.pvn.u.isname.name.n = 12; + else if(strncmp(in->s, "oc-val", 6) == 0) + sp->pvp.pvn.u.isname.name.n = 14; else goto error; break; case 7: if(strncmp(in->s, "protoid", 7) == 0) sp->pvp.pvn.u.isname.name.n = 3; + else if(strncmp(in->s, "oc-algo", 7) == 0) + sp->pvp.pvn.u.isname.name.n = 10; else goto error; break; @@ -4522,7 +4764,18 @@ int pv_parse_via_name(pv_spec_p sp, str *in) else goto error; break; - + case 10: + if(strncmp(in->s, "ocvalidity", 10) == 0) + sp->pvp.pvn.u.isname.name.n = 11; + else + goto error; + break; + case 11: + if(strncmp(in->s, "oc-validity", 11) == 0) + sp->pvp.pvn.u.isname.name.n = 11; + else + goto error; + break; default: goto error; } @@ -4542,6 +4795,8 @@ error: int pv_get_via_attr( sip_msg_t *msg, via_body_t *vb, pv_param_t *param, pv_value_t *res) { + via_oc_t ocv; + if(vb == NULL) { LM_DBG("null via header\n"); return pv_get_null(msg, param, res); @@ -4580,6 +4835,41 @@ int pv_get_via_attr( return pv_get_strval(msg, param, res, &vb->i->value); } break; + case 8: /* params */ + if(vb->params.s != NULL && vb->params.len > 0) { + return pv_get_strval(msg, param, res, &vb->params); + } + break; + case 9: /* oc */ + if(parse_via_oc(msg, vb, &ocv) < 0) { + return pv_get_null(msg, param, res); + } + return pv_get_sintval(msg, param, res, ocv.oc); + case 10: /* oc-algo */ + if(parse_via_oc(msg, vb, &ocv) < 0) { + return pv_get_null(msg, param, res); + } + if(ocv.algo.s != NULL && ocv.algo.len > 0) { + return pv_get_strval(msg, param, res, &ocv.algo); + } + return pv_get_null(msg, param, res); + case 11: /* oc-validity */ + if(parse_via_oc(msg, vb, &ocv) < 0) { + return pv_get_null(msg, param, res); + } + return pv_get_uintval(msg, param, res, ocv.validity); + case 12: /* oc-seq */ + if(parse_via_oc(msg, vb, &ocv) < 0) { + return pv_get_null(msg, param, res); + } + return pv_get_uintval(msg, param, res, (unsigned long)ocv.seq); + case 14: /* oc-val */ + if(parse_via_oc(msg, vb, &ocv) < 0) { + return pv_get_null(msg, param, res); + } + if(ocv.ocval.s != NULL && ocv.ocval.len > 0) { + return pv_get_strval(msg, param, res, &ocv.ocval); + } default: return pv_get_null(msg, param, res); diff --git a/src/modules/pv/pv_time.c b/src/modules/pv/pv_time.c index b74536a77..c7ee72488 100644 --- a/src/modules/pv/pv_time.c +++ b/src/modules/pv/pv_time.c @@ -151,30 +151,30 @@ int get_time( switch(param->pvn.u.isname.name.n) { case 1: return pv_get_uintval( - msg, param, res, (unsigned int)_cfgutils_ts->tm_min); + msg, param, res, (unsigned long)_cfgutils_ts->tm_min); case 2: return pv_get_uintval( - msg, param, res, (unsigned int)_cfgutils_ts->tm_hour); + msg, param, res, (unsigned long)_cfgutils_ts->tm_hour); case 3: return pv_get_uintval( - msg, param, res, (unsigned int)_cfgutils_ts->tm_mday); + msg, param, res, (unsigned long)_cfgutils_ts->tm_mday); case 4: return pv_get_uintval( - msg, param, res, (unsigned int)(_cfgutils_ts->tm_mon + 1)); + msg, param, res, (unsigned long)(_cfgutils_ts->tm_mon + 1)); case 5: return pv_get_uintval(msg, param, res, - (unsigned int)(_cfgutils_ts->tm_year + 1900)); + (unsigned long)(_cfgutils_ts->tm_year + 1900)); case 6: return pv_get_uintval( - msg, param, res, (unsigned int)(_cfgutils_ts->tm_wday + 1)); + msg, param, res, (unsigned long)(_cfgutils_ts->tm_wday + 1)); case 7: return pv_get_uintval( - msg, param, res, (unsigned int)(_cfgutils_ts->tm_yday + 1)); + msg, param, res, (unsigned long)(_cfgutils_ts->tm_yday + 1)); case 8: return pv_get_sintval(msg, param, res, _cfgutils_ts->tm_isdst); default: return pv_get_uintval( - msg, param, res, (unsigned int)_cfgutils_ts->tm_sec); + msg, param, res, (unsigned long)_cfgutils_ts->tm_sec); } } @@ -239,7 +239,7 @@ int pv_get_timenows(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { time_t t; t = time(NULL); - return pv_get_uintval(msg, param, res, (unsigned int)t); + return pv_get_uintval(msg, param, res, (unsigned long)t); } @@ -257,7 +257,7 @@ int pv_get_timenowf(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) } s.s = t_buf; s.len = strlen(s.s) - 1; - return pv_get_strintval(msg, param, res, &s, (int)t); + return pv_get_strintval(msg, param, res, &s, (long)t); } int pv_get_times(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) @@ -266,7 +266,7 @@ int pv_get_times(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) return -1; msg_set_time(msg); - return pv_get_uintval(msg, param, res, (unsigned int)msg->tval.tv_sec); + return pv_get_uintval(msg, param, res, (unsigned long)msg->tval.tv_sec); } @@ -286,14 +286,14 @@ int pv_get_timef(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) } s.s = t_buf; s.len = strlen(s.s) - 1; - return pv_get_strintval(msg, param, res, &s, (int)msg->tval.tv_sec); + return pv_get_strintval(msg, param, res, &s, (long)msg->tval.tv_sec); } int pv_get_timeb(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { if(msg == NULL) return -1; - return pv_get_uintval(msg, param, res, (unsigned int)up_since); + return pv_get_uintval(msg, param, res, (unsigned long)up_since); } static struct timeval _timeval_ts = {0}; @@ -314,24 +314,24 @@ int pv_get_timeval(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) case 1: msg_set_time(msg); return pv_get_uintval( - msg, param, res, (unsigned int)msg->tval.tv_usec); + msg, param, res, (unsigned long)msg->tval.tv_usec); case 2: if(gettimeofday(&_timeval_ts, NULL) != 0) { LM_ERR("unable to get time val attributes\n"); return pv_get_null(msg, param, res); } return pv_get_uintval( - msg, param, res, (unsigned int)_timeval_ts.tv_sec); + msg, param, res, (unsigned long)_timeval_ts.tv_sec); case 3: return pv_get_uintval( - msg, param, res, (unsigned int)_timeval_ts.tv_usec); + msg, param, res, (unsigned long)_timeval_ts.tv_usec); case 4: if(gettimeofday(&tv, NULL) != 0) { LM_ERR("unable to get time val attributes\n"); return pv_get_null(msg, param, res); } - s.len = snprintf(_timeval_ts_buf, 64, "%u.%06u", - (unsigned int)tv.tv_sec, (unsigned int)tv.tv_usec); + s.len = snprintf(_timeval_ts_buf, 64, "%lu.%06lu", + (unsigned long)tv.tv_sec, (unsigned long)tv.tv_usec); if(s.len < 0) return pv_get_null(msg, param, res); s.s = _timeval_ts_buf; @@ -346,8 +346,8 @@ int pv_get_timeval(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) LM_ERR("failed to format current time\n"); return pv_get_null(msg, param, res); } - s.len = snprintf(_timeval_ts_buf, 64, "%s.%06u", lbuf, - (unsigned int)tv.tv_usec); + s.len = snprintf(_timeval_ts_buf, 64, "%s.%06lu", lbuf, + (unsigned long)tv.tv_usec); if(s.len < 0) return pv_get_null(msg, param, res); s.s = _timeval_ts_buf; @@ -368,7 +368,7 @@ int pv_get_timeval(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) default: msg_set_time(msg); return pv_get_uintval( - msg, param, res, (unsigned int)msg->tval.tv_sec); + msg, param, res, (unsigned long)msg->tval.tv_sec); } } diff --git a/src/modules/pv/pv_trans.c b/src/modules/pv/pv_trans.c index e4754e719..0cc6f8f2e 100644 --- a/src/modules/pv/pv_trans.c +++ b/src/modules/pv/pv_trans.c @@ -59,7 +59,7 @@ static param_t *_tr_uri_params = NULL; /*! transformation buffer size */ #define TR_BUFFER_SIZE 65536 -#define TR_BUFFER_SLOTS 8 +#define TR_BUFFER_SLOTS 16 /*! transformation buffer */ static char **_tr_buffer_list = NULL; @@ -1011,7 +1011,7 @@ int tr_eval_string( return -1; } if(!(val->flags & PV_VAL_INT) - && (str2int(&val->rs, (unsigned int *)&val->ri) != 0)) { + && (str2slong(&val->rs, &val->ri) != 0)) { LM_ERR("value is not numeric (cfg line: %d)\n", get_cfg_crt_line()); return -1; @@ -1036,6 +1036,8 @@ int tr_eval_string( memcpy(s, st.s, st.len); s[st.len] = '\0'; t = val->ri; + memset(&tmv, 0, sizeof(struct tm)); + _tr_buffer[0] = '\0'; localtime_r(&t, &tmv); val->rs.len = strftime(_tr_buffer, TR_BUFFER_SIZE - 1, s, &tmv); pkg_free(s); @@ -2562,6 +2564,10 @@ int tr_eval_val( && (*_p == ' ' || *_p == '\t' || *_p == '\n')) \ _p++; \ while(is_in_str(_p, _in) && *_p >= '0' && *_p <= '9') { \ + if(_n > ((LONG_MAX / 10) - 10)) { \ + LM_ERR("number value is too large\n"); \ + goto error; \ + } \ _n = _n * 10 + *_p - '0'; \ _p++; \ } \ @@ -2572,7 +2578,7 @@ int tr_eval_val( } \ memset(_tp, 0, sizeof(tr_param_t)); \ _tp->type = TR_PARAM_NUMBER; \ - _tp->v.n = sign * n; \ + _tp->v.n = n * sign; \ } else { \ LM_ERR("tinvalid param in transformation: %.*s!!\n", _in->len, \ _in->s); \ @@ -2655,7 +2661,7 @@ char *tr_parse_string(str *in, trans_t *t) str name; str s; pv_spec_t *spec = NULL; - int n; + long n; int sign; tr_param_t *tp = NULL; @@ -3318,7 +3324,7 @@ char *tr_parse_paramlist(str *in, trans_t *t) char *start_pos; str s; str name; - int n; + long n; int sign; pv_spec_t *spec = NULL; tr_param_t *tp = NULL; @@ -3555,7 +3561,7 @@ char *tr_parse_line(str *in, trans_t *t) char *ps; str s; str name; - int n; + long n; int sign; pv_spec_t *spec = NULL; tr_param_t *tp = NULL; diff --git a/src/modules/pv_headers/pv_headers.c b/src/modules/pv_headers/pv_headers.c index a833b96ea..c6196a1f5 100644 --- a/src/modules/pv_headers/pv_headers.c +++ b/src/modules/pv_headers/pv_headers.c @@ -2,7 +2,7 @@ * pv_headers * * Copyright (C) - * 2020 Victor Seva + * 2020-2023 Victor Seva * 2018 Kirill Solomko * * This file is part of Kamailio, a free SIP server. @@ -39,27 +39,29 @@ MODULE_VERSION #define MODULE_NAME "pv_headers" #define XAVP_NAME "headers" -uac_api_t uac; -static tm_api_t tmb; - -str xavi_name = str_init(XAVP_NAME); -str xavi_helper_xname = str_init("modparam_pv_headers"); -str xavi_parsed_xname = str_init("parsed_pv_headers"); -unsigned int header_name_size = 255; -unsigned int header_value_size = 1024; -int FL_PV_HDRS_COLLECTED = 27; -int FL_PV_HDRS_APPLIED = 28; -static str skip_headers_param = - str_init("Record-Route,Via,Route,Content-Length,Max-Forwards,CSeq"); -static str split_headers_param = STR_NULL; -static str single_headers_param = str_init(""); -static int auto_msg_param = 1; - -str _hdr_from = {"From", 4}; -str _hdr_to = {"To", 2}; -str _hdr_reply_reason = {"@Reply-Reason", 13}; -int _branch = T_BR_UNDEFINED; -int _reply_counter = -1; +uac_api_t pvh_uac; +static tm_api_t pvh_tmb; + +_pvh_params_t _pvh_params = { + .xavi_name = str_init(XAVP_NAME), + .xavi_helper_xname = str_init("modparam_pv_headers"), + .xavi_parsed_xname = str_init("parsed_pv_headers"), + .hdr_value_size = 1024, + .flags[PVH_HDRS_COLLECTED] = 27, + .flags[PVH_HDRS_APPLIED] = 28, + .skip_hdrs = str_init( + "Record-Route,Via,Route,Content-Length,Max-Forwards,CSeq"), + .split_hdrs = STR_NULL, + .single_hdrs = str_init(""), + .auto_msg = 1, +}; + +unsigned int pvh_hdr_name_size = 255; +str pvh_hdr_from = {"From", 4}; +str pvh_hdr_to = {"To", 2}; +str pvh_hdr_reply_reason = {"@Reply-Reason", 13}; +int pvh_branch = T_BR_UNDEFINED; +int pvh_reply_counter = -1; static void mod_destroy(void); static int mod_init(void); @@ -80,9 +82,9 @@ static int pvh_get_branch_index(struct sip_msg *msg, int *br_idx) { int os = 0; int len = 0; - char parsed_br_idx[header_value_size]; + char parsed_br_idx[_pvh_params.hdr_value_size]; - if(msg->add_to_branch_len > header_value_size) { + if(msg->add_to_branch_len > _pvh_params.hdr_value_size) { LM_ERR("branch name is too long\n"); return -1; } @@ -106,10 +108,10 @@ static int w_pvh_collect_headers(struct sip_msg *msg, char *p1, char *p2) { sr_xavp_t **backup_xavis = NULL; - if(pvh_get_branch_index(msg, &_branch) < 0) + if(pvh_get_branch_index(msg, &pvh_branch) < 0) return -1; if(msg->first_line.type == SIP_REPLY) { - if((_reply_counter = pvh_reply_append(backup_xavis)) < 0) { + if((pvh_reply_counter = pvh_reply_append(backup_xavis)) < 0) { return -1; } } @@ -120,10 +122,10 @@ static int ki_pvh_collect_headers(struct sip_msg *msg) { sr_xavp_t **backup_xavis = NULL; - if(pvh_get_branch_index(msg, &_branch) < 0) + if(pvh_get_branch_index(msg, &pvh_branch) < 0) return -1; if(msg->first_line.type == SIP_REPLY) { - if((_reply_counter = pvh_reply_append(backup_xavis)) < 0) { + if((pvh_reply_counter = pvh_reply_append(backup_xavis)) < 0) { return -1; } } @@ -132,21 +134,21 @@ static int ki_pvh_collect_headers(struct sip_msg *msg) static int w_pvh_apply_headers(struct sip_msg *msg, char *p1, char *p2) { - if(pvh_get_branch_index(msg, &_branch) < 0) + if(pvh_get_branch_index(msg, &pvh_branch) < 0) return -1; return pvh_apply_headers(msg); } static int ki_pvh_apply_headers(struct sip_msg *msg) { - if(pvh_get_branch_index(msg, &_branch) < 0) + if(pvh_get_branch_index(msg, &pvh_branch) < 0) return -1; return pvh_apply_headers(msg); } static int w_pvh_reset_headers(struct sip_msg *msg, char *p1, char *p2) { - if(pvh_get_branch_index(msg, &_branch) < 0) + if(pvh_get_branch_index(msg, &pvh_branch) < 0) return -1; return pvh_reset_headers(msg); } @@ -224,12 +226,15 @@ static int w_pvh_header_param_exists(struct sip_msg *msg, char *p1, char *p2) static int ki_pvh_remove_header_param( struct sip_msg *msg, str *hname, str *toRemove) { - int idx; + int next; + int idx = 0; int new_size; str dst = STR_NULL; - sr_xavp_t *avi = pvh_xavi_get_child(msg, &xavi_name, hname); + sr_xavp_t *avi = pvh_xavi_get_child(msg, &_pvh_params.xavi_name, hname); - for(idx = 0; avi != NULL; avi = xavi_get_next(avi)) { + while(avi) { + next = 1; + LM_DBG("hname:%.*s[%d]\n", STR_FMT(hname), idx); if(avi->val.type == SR_XTYPE_STR && avi->val.v.s.s != NULL) { if(str_casesearch(&avi->val.v.s, toRemove) != NULL) { new_size = pvh_remove_header_param_helper( @@ -239,15 +244,20 @@ static int ki_pvh_remove_header_param( STR_FMT(hname), idx); if(pvh_remove_header(msg, hname, idx) < 0) return -1; + avi = pvh_xavi_get_child( + msg, &_pvh_params.xavi_name, hname); + if(idx > 0) + idx = 0; + next = 0; } else if(dst.len < 0 || new_size == avi->val.v.s.len) { LM_DBG("'%.*s' not found at '%.*s'\n", STR_FMT(toRemove), STR_FMT(&avi->val.v.s)); } else { LM_DBG("old_value:'%.*s' new_value:'%.*s'\n", STR_FMT(&avi->val.v.s), STR_FMT(&dst)); - if(pvh_set_xavi(msg, &xavi_name, hname, &dst, SR_XTYPE_STR, - idx, 0) - < 0) { + avi = pvh_set_xavi(msg, &_pvh_params.xavi_name, hname, &dst, + SR_XTYPE_STR, idx, 0); + if(avi == NULL) { LM_ERR("can't set new value\n"); return -1; } @@ -257,7 +267,10 @@ static int ki_pvh_remove_header_param( STR_FMT(&avi->val.v.s)); } } - idx++; + if(next) { + avi = xavi_get_next(avi); + idx++; + } } return 1; } @@ -334,13 +347,13 @@ static pv_export_t mod_pvs[] = { }; static param_export_t params[] = { - {"xavi_name", PARAM_STR, &xavi_name}, - {"header_value_size", PARAM_INT, &header_value_size}, - {"header_collect_flag", PARAM_INT, &FL_PV_HDRS_COLLECTED}, - {"header_apply_flag", PARAM_INT, &FL_PV_HDRS_APPLIED}, - {"skip_headers", PARAM_STR, &skip_headers_param}, - {"split_headers", PARAM_STR, &split_headers_param}, - {"auto_msg", PARAM_INT, &auto_msg_param}, + {"xavi_name", PARAM_STR, &_pvh_params.xavi_name}, + {"header_value_size", PARAM_INT, &_pvh_params.hdr_value_size}, + {"header_collect_flag", PARAM_INT, &_pvh_params.flags[PVH_HDRS_COLLECTED]}, + {"header_apply_flag", PARAM_INT, &_pvh_params.flags[PVH_HDRS_APPLIED]}, + {"skip_headers", PARAM_STR, &_pvh_params.skip_hdrs}, + {"split_headers", PARAM_STR, &_pvh_params.split_hdrs}, + {"auto_msg", PARAM_INT, &_pvh_params.auto_msg}, {0, 0, 0} }; @@ -362,17 +375,17 @@ int mod_init(void) { LM_INFO("%s module init...\n", MODULE_NAME); - if(load_uac_api(&uac) < 0) { + if(load_uac_api(&pvh_uac) < 0) { LM_NOTICE("could not bind to the 'uac' module, From/To headers will " "not be modified\n"); } - if(load_tm_api(&tmb) < 0) { + if(load_tm_api(&pvh_tmb) < 0) { LM_NOTICE("could not bind to the 'tm' module, automatic headers " "collect/apply is disabled\n"); - auto_msg_param = 0; + _pvh_params.auto_msg = 0; } - if(auto_msg_param) { + if(_pvh_params.auto_msg) { if(register_script_cb(handle_msg_cb, PRE_SCRIPT_CB | REQUEST_CB, 0) < 0) { LM_ERR("cannot register PRE_SCRIPT_CB REQUEST_CB callbacks\n"); @@ -398,9 +411,9 @@ int mod_init(void) } } - pvh_str_hash_init(&skip_headers, &skip_headers_param, "skip_headers"); - pvh_str_hash_init(&split_headers, &split_headers_param, "split_headers"); - pvh_str_hash_init(&single_headers, &single_headers_param, "single_headers"); + pvh_str_hash_init(&skip_hdrs, &_pvh_params.skip_hdrs, "skip_headers"); + pvh_str_hash_init(&split_hdrs, &_pvh_params.split_hdrs, "split_headers"); + pvh_str_hash_init(&single_hdrs, &_pvh_params.single_hdrs, "single_headers"); return 0; } @@ -515,11 +528,11 @@ void handle_tm_t(tm_cell_t *t, int type, struct tmcb_params *params) LM_DBG("T:%p picked_branch:%d label:%d branches:%d\n", t, - tmb.t_get_picked_branch(), t->label, t->nr_of_outgoings); + pvh_tmb.t_get_picked_branch(), t->label, t->nr_of_outgoings); if(msg != NULL && msg != FAKED_REPLY) { - pvh_get_branch_index(msg, &_branch); - LM_DBG("T:%p set branch:%d\n", t, _branch); + pvh_get_branch_index(msg, &pvh_branch); + LM_DBG("T:%p set branch:%d\n", t, pvh_branch); pvh_apply_headers(msg); } return; @@ -532,8 +545,8 @@ int handle_msg_failed_cb(struct sip_msg *msg, unsigned int flags, void *cb) if(pvh_parse_msg(msg) != 0) return 1; - _branch = 0; - LM_DBG("msg:%p set branch:%d\n", msg, _branch); + pvh_branch = 0; + LM_DBG("msg:%p set branch:%d\n", msg, pvh_branch); return 1; } @@ -547,13 +560,13 @@ int handle_msg_cb(struct sip_msg *msg, unsigned int flags, void *cb) if(pvh_parse_msg(msg) != 0) return 1; - if(tmb.register_tmcb(msg, 0, msg_cbs, handle_tm_t, 0, 0) <= 0) { + if(pvh_tmb.register_tmcb(msg, 0, msg_cbs, handle_tm_t, 0, 0) <= 0) { LM_ERR("cannot register TM callbacks\n"); return -1; } - _branch = 0; - LM_DBG("msg:%p set branch:%d\n", msg, _branch); + pvh_branch = 0; + LM_DBG("msg:%p set branch:%d\n", msg, pvh_branch); pvh_collect_headers(msg); return 1; } @@ -561,13 +574,13 @@ int handle_msg_cb(struct sip_msg *msg, unsigned int flags, void *cb) int handle_msg_branch_cb(struct sip_msg *msg, unsigned int flags, void *cb) { - LM_DBG("msg:%p previous branch:%d\n", msg, _branch); + LM_DBG("msg:%p previous branch:%d\n", msg, pvh_branch); print_cb_flags(flags); if(flags & PRE_SCRIPT_CB) { - pvh_get_branch_index(msg, &_branch); - LM_DBG("msg:%p set branch:%d\n", msg, _branch); - pvh_clone_branch_xavi(msg, &xavi_name); + pvh_get_branch_index(msg, &pvh_branch); + LM_DBG("msg:%p set branch:%d\n", msg, pvh_branch); + pvh_clone_branch_xavi(msg, &_pvh_params.xavi_name); } return 1; @@ -585,22 +598,22 @@ int handle_msg_reply_cb(struct sip_msg *msg, unsigned int flags, void *cb) if(msg == FAKED_REPLY) { LM_DBG("FAKED_REPLY\n"); } - LM_DBG("msg:%p previous branch:%d\n", msg, _branch); + LM_DBG("msg:%p previous branch:%d\n", msg, pvh_branch); print_cb_flags(flags); - t = tmb.t_find(msg, &_branch, &vref); + t = pvh_tmb.t_find(msg, &pvh_branch, &vref); if(t != NULL && t != T_UNDEFINED) { - LM_DBG("T:%p t_check-branch:%d xavi_list:%p branches:%d\n", t, _branch, - &t->xavis_list, t->nr_of_outgoings); + LM_DBG("T:%p t_check-branch:%d xavi_list:%p branches:%d\n", t, + pvh_branch, &t->xavis_list, t->nr_of_outgoings); list = &t->xavis_list; backup_xavis = xavi_set_list(&t->xavis_list); } - pvh_get_branch_index(msg, &_branch); - LM_DBG("T:%p set branch:%d picked_branch:%d\n", t, _branch, - tmb.t_get_picked_branch()); + pvh_get_branch_index(msg, &pvh_branch); + LM_DBG("T:%p set branch:%d picked_branch:%d\n", t, pvh_branch, + pvh_tmb.t_get_picked_branch()); - if((_reply_counter = pvh_reply_append(list)) < 0) { + if((pvh_reply_counter = pvh_reply_append(list)) < 0) { return -1; } pvh_collect_headers(msg); @@ -611,7 +624,7 @@ int handle_msg_reply_cb(struct sip_msg *msg, unsigned int flags, void *cb) if(t != NULL && t != T_UNDEFINED && vref != 0) { /* t_find() above has the side effect of setting T and REFerencing T => we must unref and unset it */ - tmb.t_unset(); + pvh_tmb.t_unset(); LM_DBG("T:%p unref\n", t); } diff --git a/src/modules/pv_headers/pv_headers.h b/src/modules/pv_headers/pv_headers.h index 5ee4efc2f..81e2b5c8d 100644 --- a/src/modules/pv_headers/pv_headers.h +++ b/src/modules/pv_headers/pv_headers.h @@ -2,7 +2,7 @@ * pv_headers * * Copyright (C) - * 2020 Victor Seva + * 2020-2023 Victor Seva * 2018 Kirill Solomko * * This file is part of Kamailio, a free SIP server. @@ -36,22 +36,29 @@ typedef struct _xavp_c_data str value; } xavp_c_data_t; -extern uac_api_t uac; +extern uac_api_t pvh_uac; -extern str xavi_name; -extern str xavi_parsed_xname; -extern str xavi_helper_xname; - -extern unsigned int header_name_size; -extern unsigned int header_value_size; - -extern str _hdr_from; -extern str _hdr_to; -extern str _hdr_reply_reason; -extern int _branch; -extern int _reply_counter; +#define PVH_HDRS_COLLECTED 0 +#define PVH_HDRS_APPLIED 1 +typedef struct _pvh_params +{ + str xavi_name; + str xavi_helper_xname; + str xavi_parsed_xname; + unsigned int hdr_value_size; + int flags[2]; + str skip_hdrs; + str split_hdrs; + str single_hdrs; + unsigned int auto_msg; +} _pvh_params_t; +extern _pvh_params_t _pvh_params; -extern int FL_PV_HDRS_COLLECTED; -extern int FL_PV_HDRS_APPLIED; +extern unsigned int pvh_hdr_name_size; +extern str pvh_hdr_from; +extern str pvh_hdr_to; +extern str pvh_hdr_reply_reason; +extern int pvh_branch; +extern int pvh_reply_counter; #endif /* PV_HEADERS_H */ diff --git a/src/modules/pv_headers/pvh_func.c b/src/modules/pv_headers/pvh_func.c index 7b1c6f983..f809c3c33 100644 --- a/src/modules/pv_headers/pvh_func.c +++ b/src/modules/pv_headers/pvh_func.c @@ -2,7 +2,7 @@ * pv_headers * * Copyright (C) - * 2020 Victor Seva + * 2020-2023 Victor Seva * 2018 Kirill Solomko * * This file is part of Kamailio, a free SIP server. @@ -59,7 +59,7 @@ int pvh_collect_headers(struct sip_msg *msg) struct hdr_field *hf = NULL; str name = STR_NULL; str val = STR_NULL; - char hvals[header_name_size][header_value_size]; + char hvals[pvh_hdr_name_size][_pvh_params.hdr_value_size]; int idx = 0, d_size = 0; str val_part = STR_NULL; char *marker = NULL; @@ -80,13 +80,13 @@ int pvh_collect_headers(struct sip_msg *msg) switch(hf->type) { case HDR_FROM_T: - name.len = _hdr_from.len; - name.s = _hdr_from.s; + name.len = pvh_hdr_from.len; + name.s = pvh_hdr_from.s; LM_DBG("force [From] as key\n"); break; case HDR_TO_T: - name.len = _hdr_to.len; - name.s = _hdr_to.s; + name.len = pvh_hdr_to.len; + name.s = pvh_hdr_to.s; LM_DBG("force [To] as key\n"); break; default: @@ -97,7 +97,7 @@ int pvh_collect_headers(struct sip_msg *msg) val.s = hf->body.s; if((marker = pvh_detect_split_char(val.s)) != NULL - && str_hash_case_get(&split_headers, name.s, name.len)) { + && str_hash_case_get(&split_hdrs, name.s, name.len)) { if(pvh_split_values(&val, hvals, &d_size, 1, marker) < 0) { LM_ERR("could not parse %.*s header comma separated " @@ -109,19 +109,21 @@ int pvh_collect_headers(struct sip_msg *msg) for(idx = 0; idx < d_size; idx++) { val_part.s = hvals[idx]; val_part.len = strlen(hvals[idx]); - if(pvh_set_xavi(msg, &xavi_name, &name, &val_part, SR_XTYPE_STR, - 0, 1) + if(pvh_set_xavi(msg, &_pvh_params.xavi_name, &name, &val_part, + SR_XTYPE_STR, 0, 1) < 0) return -1; } continue; } - if(pvh_set_xavi(msg, &xavi_name, &name, &val, SR_XTYPE_STR, 0, 1) < 0) + if(pvh_set_xavi( + msg, &_pvh_params.xavi_name, &name, &val, SR_XTYPE_STR, 0, 1) + < 0) return -1; } - if(pvh_set_xavi(msg, &xavi_helper_xname, &xavi_helper_name, &xavi_name, - SR_XTYPE_STR, 0, 0) + if(pvh_set_xavi(msg, &_pvh_params.xavi_helper_xname, &xavi_helper_name, + &_pvh_params.xavi_name, SR_XTYPE_STR, 0, 0) < 0) return -1; @@ -136,11 +138,11 @@ int pvh_apply_headers(struct sip_msg *msg) sr_xavp_t *sub = NULL; struct str_hash_table rm_hdrs; int from_cnt = 0, to_cnt = 0; - char t[header_name_size]; - char tv[2][header_value_size]; - str display = {tv[0], header_value_size}; - str uri = {tv[1], header_value_size}; - str br_xname = {t, header_name_size}; + char t[pvh_hdr_name_size]; + char tv[2][_pvh_params.hdr_value_size]; + str display = {tv[0], _pvh_params.hdr_value_size}; + str uri = {tv[1], _pvh_params.hdr_value_size}; + str br_xname = {t, pvh_hdr_name_size}; int skip_from_to = 0, keys_count = 0; int res = -1; @@ -156,26 +158,29 @@ int pvh_apply_headers(struct sip_msg *msg) return -1; } - pvh_get_branch_xname(msg, &xavi_name, &br_xname); + pvh_get_branch_xname(msg, &_pvh_params.xavi_name, &br_xname); if((xavi = xavi_get(&br_xname, NULL)) == NULL - && (xavi = xavi_get(&xavi_name, NULL)) == NULL) { + && (xavi = xavi_get(&_pvh_params.xavi_name, NULL)) == NULL) { LM_ERR("missing xavi %.*s, run pv_collect_headers() first\n", - xavi_name.len, xavi_name.s); + _pvh_params.xavi_name.len, _pvh_params.xavi_name.s); return -1; } if(xavi->val.type != SR_XTYPE_XAVP) { - LM_ERR("not xavp child type %.*s\n", xavi_name.len, xavi_name.s); + LM_ERR("not xavp child type %.*s\n", _pvh_params.xavi_name.len, + _pvh_params.xavi_name.s); return -1; } if((sub = xavi->val.v.xavp) == NULL) { - LM_ERR("invalid xavp structure: %.*s\n", xavi_name.len, xavi_name.s); + LM_ERR("invalid xavp structure: %.*s\n", _pvh_params.xavi_name.len, + _pvh_params.xavi_name.s); return -1; } keys_count = pvh_xavi_keys_count(&sub); if(keys_count <= 0) { - LM_ERR("no keys found: %.*s\n", xavi_name.len, xavi_name.s); + LM_ERR("no keys found: %.*s\n", _pvh_params.xavi_name.len, + _pvh_params.xavi_name.s); return -1; } if(str_hash_alloc(&rm_hdrs, keys_count) < 0) { @@ -194,7 +199,7 @@ int pvh_apply_headers(struct sip_msg *msg) if(msg->to == NULL) { LM_DBG("no To header, can't store To info in parsed\n"); } else { - if(pvh_set_parsed(msg, &_hdr_to, &msg->to->body, NULL) == NULL) + if(pvh_set_parsed(msg, &pvh_hdr_to, &msg->to->body, NULL) == NULL) LM_ERR("can't store To info in parsed\n"); } } @@ -203,7 +208,7 @@ int pvh_apply_headers(struct sip_msg *msg) if(pvh_skip_header(&sub->name)) continue; - if(cmpi_str(&sub->name, &_hdr_from) == 0) { + if(cmpi_str(&sub->name, &pvh_hdr_from) == 0) { if(skip_from_to) { LM_DBG("skip From header change in reply messages\n"); continue; @@ -215,27 +220,27 @@ int pvh_apply_headers(struct sip_msg *msg) if(from_cnt > 0) continue; - memset(display.s, 0, header_value_size); - memset(uri.s, 0, header_value_size); + memset(display.s, 0, _pvh_params.hdr_value_size); + memset(uri.s, 0, _pvh_params.hdr_value_size); if(pvh_extract_display_uri(sub->val.v.s.s, &display, &uri) < 0) { LM_ERR("error parsing From header\n"); goto err; } - if(uac.replace_from != NULL) { + if(pvh_uac.replace_from != NULL) { LM_DBG("replace_from[%s]: %s %s\n", sub->name.s, display.s, uri.s); if(display.len == 0) pvh_real_hdr_remove_display(msg, &sub->name); - uac.replace_from(msg, &display, &uri); + pvh_uac.replace_from(msg, &display, &uri); } from_cnt++; continue; } - if(cmpi_str(&sub->name, &_hdr_to) == 0) { + if(cmpi_str(&sub->name, &pvh_hdr_to) == 0) { if(skip_from_to) { LM_DBG("skip To header change in reply messages\n"); continue; @@ -247,27 +252,27 @@ int pvh_apply_headers(struct sip_msg *msg) if(to_cnt > 0) continue; - memset(display.s, 0, header_value_size); - memset(uri.s, 0, header_value_size); + memset(display.s, 0, _pvh_params.hdr_value_size); + memset(uri.s, 0, _pvh_params.hdr_value_size); if(pvh_extract_display_uri(sub->val.v.s.s, &display, &uri) < 0) { LM_ERR("error parsing To header\n"); goto err; } - if(uac.replace_to != NULL) { + if(pvh_uac.replace_to != NULL) { LM_DBG("replace_to[%s]: %s %s\n", sub->name.s, display.s, uri.s); if(display.len == 0) pvh_real_hdr_remove_display(msg, &sub->name); - uac.replace_to(msg, &display, &uri); + pvh_uac.replace_to(msg, &display, &uri); } to_cnt++; continue; } - if(cmpi_str(&sub->name, &_hdr_reply_reason) == 0) { + if(cmpi_str(&sub->name, &pvh_hdr_reply_reason) == 0) { if(str_hash_case_get(&rm_hdrs, sub->name.s, sub->name.len)) continue; pvh_real_replace_reply_reason(msg, &sub->val.v.s); @@ -299,13 +304,13 @@ err: int pvh_reset_headers(struct sip_msg *msg) { - char t[header_name_size]; - str br_xname = {t, header_name_size}; + char t[pvh_hdr_name_size]; + str br_xname = {t, pvh_hdr_name_size}; - pvh_get_branch_xname(msg, &xavi_name, &br_xname); + pvh_get_branch_xname(msg, &_pvh_params.xavi_name, &br_xname); LM_DBG("clean xavi:%.*s\n", br_xname.len, br_xname.s); xavi_rm_by_name(&br_xname, 1, NULL); - pvh_get_branch_xname(msg, &xavi_parsed_xname, &br_xname); + pvh_get_branch_xname(msg, &_pvh_params.xavi_parsed_xname, &br_xname); LM_DBG("clean xavi:%.*s\n", br_xname.len, br_xname.s); xavi_rm_by_name(&br_xname, 1, NULL); @@ -317,7 +322,7 @@ int pvh_reset_headers(struct sip_msg *msg) int pvh_check_header(struct sip_msg *msg, str *hname) { - if(pvh_xavi_get_child(msg, &xavi_name, hname) == NULL) + if(pvh_xavi_get_child(msg, &_pvh_params.xavi_name, hname) == NULL) return -1; return 1; @@ -325,12 +330,20 @@ int pvh_check_header(struct sip_msg *msg, str *hname) int pvh_append_header(struct sip_msg *msg, str *hname, str *hvalue) { - return pvh_set_xavi(msg, &xavi_name, hname, hvalue, SR_XTYPE_STR, 0, 1); + if(pvh_set_xavi( + msg, &_pvh_params.xavi_name, hname, hvalue, SR_XTYPE_STR, 0, 1) + == NULL) + return -1; + return 1; } int pvh_modify_header(struct sip_msg *msg, str *hname, str *hvalue, int indx) { - return pvh_set_xavi(msg, &xavi_name, hname, hvalue, SR_XTYPE_STR, indx, 0); + if(pvh_set_xavi(msg, &_pvh_params.xavi_name, hname, hvalue, SR_XTYPE_STR, + indx, 0) + == NULL) + return -1; + return 1; } int pvh_remove_header(struct sip_msg *msg, str *hname, int indx) @@ -338,20 +351,21 @@ int pvh_remove_header(struct sip_msg *msg, str *hname, int indx) sr_xavp_t *avp = NULL; int count = 0; - if((avp = pvh_xavi_get_child(msg, &xavi_name, hname)) == NULL) + if((avp = pvh_xavi_get_child(msg, &_pvh_params.xavi_name, hname)) == NULL) return 1; if(indx < 0) { count = xavi_count(hname, &avp); do { - if(pvh_set_xavi( - msg, &xavi_name, hname, NULL, SR_XTYPE_STR, indx++, 0) - < 1) + if(pvh_set_xavi(msg, &_pvh_params.xavi_name, hname, NULL, + SR_XTYPE_STR, indx++, 0) + == NULL) return -1; } while(indx < count); } else { - if(pvh_set_xavi(msg, &xavi_name, hname, NULL, SR_XTYPE_STR, indx, 0) - < 1) + if(pvh_set_xavi(msg, &_pvh_params.xavi_name, hname, NULL, SR_XTYPE_STR, + indx, 0) + == NULL) return -1; } @@ -361,11 +375,11 @@ int pvh_remove_header(struct sip_msg *msg, str *hname, int indx) int pvh_header_param_exists(struct sip_msg *msg, str *hname, str *hvalue) { sr_xavp_t *avi = NULL; - char head_name[header_name_size]; - str br_xname = {head_name, header_name_size}; + char head_name[pvh_hdr_name_size]; + str br_xname = {head_name, pvh_hdr_name_size}; - avi = xavi_get(&xavi_name, NULL); - pvh_get_branch_xname(msg, &xavi_name, &br_xname); + avi = xavi_get(&_pvh_params.xavi_name, NULL); + pvh_get_branch_xname(msg, &_pvh_params.xavi_name, &br_xname); avi = xavi_get_child(&br_xname, hname); @@ -388,7 +402,7 @@ int pvh_remove_header_param_helper(str *orig, const str *toRemove, str *dst) int offset = 0; char *saveptr = NULL; char *token; - char t[header_value_size]; + char t[_pvh_params.hdr_value_size]; char *result = pv_get_buffer(); int maxSize = pv_get_buffer_size(); diff --git a/src/modules/pv_headers/pvh_func.h b/src/modules/pv_headers/pvh_func.h index 737212c3f..54f8b45c6 100644 --- a/src/modules/pv_headers/pvh_func.h +++ b/src/modules/pv_headers/pvh_func.h @@ -2,7 +2,7 @@ * pv_headers * * Copyright (C) - * 2020 Victor Seva + * 2020-2023 Victor Seva * 2018 Kirill Solomko * * This file is part of Kamailio, a free SIP server. diff --git a/src/modules/pv_headers/pvh_hash.c b/src/modules/pv_headers/pvh_hash.c index 545fcd057..b0aea1abb 100644 --- a/src/modules/pv_headers/pvh_hash.c +++ b/src/modules/pv_headers/pvh_hash.c @@ -2,7 +2,7 @@ * pv_headers * * Copyright (C) - * 2020 Victor Seva + * 2020-2023 Victor Seva * 2018 Kirill Solomko * * This file is part of Kamailio, a free SIP server. @@ -27,13 +27,13 @@ #include "pvh_hash.h" #include "pvh_str.h" -struct str_hash_table skip_headers; -struct str_hash_table split_headers; -struct str_hash_table single_headers; +struct str_hash_table skip_hdrs; +struct str_hash_table split_hdrs; +struct str_hash_table single_hdrs; int pvh_str_hash_init(struct str_hash_table *ht, str *keys, char *desc) { - char split[header_name_size][header_value_size]; + char split[pvh_hdr_name_size][_pvh_params.hdr_value_size]; int idx = 0, d_size = 0; str val = STR_NULL; @@ -117,7 +117,7 @@ int pvh_skip_header(str *hname) if(hname == NULL) return 0; - if(str_hash_case_get(&skip_headers, hname->s, hname->len)) + if(str_hash_case_get(&skip_hdrs, hname->s, hname->len)) return 1; return 0; @@ -128,7 +128,7 @@ int pvh_single_header(str *hname) if(hname == NULL) return 0; - if(str_hash_case_get(&single_headers, hname->s, hname->len)) + if(str_hash_case_get(&single_hdrs, hname->s, hname->len)) return 1; return 0; diff --git a/src/modules/pv_headers/pvh_hash.h b/src/modules/pv_headers/pvh_hash.h index d7e25f8b5..b458e9f0b 100644 --- a/src/modules/pv_headers/pvh_hash.h +++ b/src/modules/pv_headers/pvh_hash.h @@ -2,7 +2,7 @@ * pv_headers * * Copyright (C) - * 2020 Victor Seva + * 2020-2023 Victor Seva * 2018 Kirill Solomko * * This file is part of Kamailio, a free SIP server. @@ -28,9 +28,9 @@ #include "../../core/str_hash.h" -extern struct str_hash_table skip_headers; -extern struct str_hash_table split_headers; -extern struct str_hash_table single_headers; +extern struct str_hash_table skip_hdrs; +extern struct str_hash_table split_hdrs; +extern struct str_hash_table single_hdrs; int pvh_str_hash_init(struct str_hash_table *ht, str *keys, char *desc); int pvh_str_hash_add_key(struct str_hash_table *ht, str *key); diff --git a/src/modules/pv_headers/pvh_hdr.c b/src/modules/pv_headers/pvh_hdr.c index fbb471ccd..472b10e6b 100644 --- a/src/modules/pv_headers/pvh_hdr.c +++ b/src/modules/pv_headers/pvh_hdr.c @@ -2,7 +2,7 @@ * pv_headers * * Copyright (C) - * 2020 Victor Seva + * 2020-2023 Victor Seva * 2018 Kirill Solomko * * This file is part of Kamailio, a free SIP server. @@ -31,11 +31,11 @@ int pvh_hdrs_collected(struct sip_msg *msg) { if(msg->first_line.type == SIP_REPLY) { - if(isflagset(msg, FL_PV_HDRS_COLLECTED) == 1) { + if(isflagset(msg, _pvh_params.flags[PVH_HDRS_COLLECTED]) == 1) { return 1; } } else { - if(isbflagset(_branch, FL_PV_HDRS_COLLECTED) == 1) { + if(isbflagset(pvh_branch, _pvh_params.flags[PVH_HDRS_COLLECTED]) == 1) { return 1; } } @@ -45,11 +45,11 @@ int pvh_hdrs_collected(struct sip_msg *msg) int pvh_hdrs_applied(struct sip_msg *msg) { if(msg->first_line.type == SIP_REPLY) { - if(isflagset(msg, FL_PV_HDRS_APPLIED) == 1) { + if(isflagset(msg, _pvh_params.flags[PVH_HDRS_APPLIED]) == 1) { return 1; } } else { - if(isbflagset(_branch, FL_PV_HDRS_APPLIED) == 1) { + if(isbflagset(pvh_branch, _pvh_params.flags[PVH_HDRS_APPLIED]) == 1) { return 1; } } @@ -59,29 +59,29 @@ int pvh_hdrs_applied(struct sip_msg *msg) void pvh_hdrs_set_applied(struct sip_msg *msg) { if(msg->first_line.type == SIP_REPLY) { - setflag(msg, FL_PV_HDRS_APPLIED); + setflag(msg, _pvh_params.flags[PVH_HDRS_APPLIED]); } else { - setbflag(_branch, FL_PV_HDRS_APPLIED); + setbflag(pvh_branch, _pvh_params.flags[PVH_HDRS_APPLIED]); } } void pvh_hdrs_set_collected(struct sip_msg *msg) { if(msg->first_line.type == SIP_REPLY) { - setflag(msg, FL_PV_HDRS_COLLECTED); + setflag(msg, _pvh_params.flags[PVH_HDRS_COLLECTED]); } else { - setbflag(_branch, FL_PV_HDRS_COLLECTED); + setbflag(pvh_branch, _pvh_params.flags[PVH_HDRS_COLLECTED]); } } void pvh_hdrs_reset_flags(struct sip_msg *msg) { if(msg->first_line.type == SIP_REPLY) { - resetflag(msg, FL_PV_HDRS_COLLECTED); - resetflag(msg, FL_PV_HDRS_APPLIED); + resetflag(msg, _pvh_params.flags[PVH_HDRS_COLLECTED]); + resetflag(msg, _pvh_params.flags[PVH_HDRS_APPLIED]); } else { - resetbflag(_branch, FL_PV_HDRS_COLLECTED); - resetbflag(_branch, FL_PV_HDRS_APPLIED); + resetbflag(pvh_branch, _pvh_params.flags[PVH_HDRS_COLLECTED]); + resetbflag(pvh_branch, _pvh_params.flags[PVH_HDRS_APPLIED]); } } diff --git a/src/modules/pv_headers/pvh_hdr.h b/src/modules/pv_headers/pvh_hdr.h index a5ad4157f..289ae9a2a 100644 --- a/src/modules/pv_headers/pvh_hdr.h +++ b/src/modules/pv_headers/pvh_hdr.h @@ -2,7 +2,7 @@ * pv_headers * * Copyright (C) - * 2020 Victor Seva + * 2020-2023 Victor Seva * 2018 Kirill Solomko * * This file is part of Kamailio, a free SIP server. @@ -43,4 +43,4 @@ int pvh_real_hdr_remove_display(struct sip_msg *msg, str *hname); int pvh_real_replace_reply_reason(struct sip_msg *msg, str *value); int pvh_create_hdr_str(str *hname, str *hvalue, str *dst); -#endif /* PV_HDR_H */ \ No newline at end of file +#endif /* PV_HDR_H */ diff --git a/src/modules/pv_headers/pvh_str.c b/src/modules/pv_headers/pvh_str.c index 60c1a2fe4..9b7cf0130 100644 --- a/src/modules/pv_headers/pvh_str.c +++ b/src/modules/pv_headers/pvh_str.c @@ -2,7 +2,7 @@ * pv_headers * * Copyright (C) - * 2020 Victor Seva + * 2020-2023 Victor Seva * 2018 Kirill Solomko * * This file is part of Kamailio, a free SIP server. @@ -132,7 +132,7 @@ char *pvh_detect_split_char(char *val) return pvh_detect_split_char(val + (quote_b - val + 1)); } -int pvh_split_values(str *s, char d[][header_value_size], int *d_size, +int pvh_split_values(str *s, char d[][_pvh_params.hdr_value_size], int *d_size, int keep_spaces, char *marker) { char *p = NULL; @@ -157,7 +157,7 @@ int pvh_split_values(str *s, char d[][header_value_size], int *d_size, } if(c_idx == 0) continue; - if(c_idx + 1 < header_value_size) + if(c_idx + 1 < _pvh_params.hdr_value_size) c_idx++; d[*d_size][c_idx] = '\0'; c_idx = 0; @@ -169,7 +169,7 @@ int pvh_split_values(str *s, char d[][header_value_size], int *d_size, } if(c_idx > 0) { - if(c_idx >= header_value_size) + if(c_idx >= _pvh_params.hdr_value_size) c_idx--; d[*d_size][c_idx] = '\0'; } @@ -177,4 +177,4 @@ int pvh_split_values(str *s, char d[][header_value_size], int *d_size, (*d_size)++; return 1; -} \ No newline at end of file +} diff --git a/src/modules/pv_headers/pvh_str.h b/src/modules/pv_headers/pvh_str.h index 24feb330c..8ca80394b 100644 --- a/src/modules/pv_headers/pvh_str.h +++ b/src/modules/pv_headers/pvh_str.h @@ -2,7 +2,7 @@ * pv_headers * * Copyright (C) - * 2020 Victor Seva + * 2020-2023 Victor Seva * 2018 Kirill Solomko * * This file is part of Kamailio, a free SIP server. @@ -35,7 +35,7 @@ int pvh_str_free(str *s); int pvh_str_copy(str *dst, str *src, unsigned int max_size); int pvh_extract_display_uri(char *suri, str *display, str *duri); char *pvh_detect_split_char(char *s); -int pvh_split_values(str *s, char d[][header_value_size], int *d_size, +int pvh_split_values(str *s, char d[][_pvh_params.hdr_value_size], int *d_size, int keep_spaces, char *marker); -#endif /* PV_STR_H */ \ No newline at end of file +#endif /* PV_STR_H */ diff --git a/src/modules/pv_headers/pvh_xavp.c b/src/modules/pv_headers/pvh_xavp.c index e52f9dab0..f3675881e 100644 --- a/src/modules/pv_headers/pvh_xavp.c +++ b/src/modules/pv_headers/pvh_xavp.c @@ -2,7 +2,7 @@ * pv_headers * * Copyright (C) - * 2020 Victor Seva + * 2020-2023 Victor Seva * 2018 Kirill Solomko * * This file is part of Kamailio, a free SIP server. @@ -62,8 +62,8 @@ int pvh_reply_append(sr_xavp_t **start) sr_xavp_t *xavi = NULL; sr_xval_t xval; - xavi = pvh_xavi_get_child_with_ival( - &xavi_helper_xname, &reply_counter, start ? *start : NULL); + xavi = pvh_xavi_get_child_with_ival(&_pvh_params.xavi_helper_xname, + &reply_counter, start ? *start : NULL); if(xavi) { xavi->val.v.l++; LM_DBG("reply message: %ld\n", xavi->val.v.l); @@ -74,17 +74,18 @@ int pvh_reply_append(sr_xavp_t **start) xval.type = SR_XTYPE_LONG; xval.v.l = 0; - xavi = xavi_get(&xavi_helper_xname, start ? *start : NULL); + xavi = xavi_get(&_pvh_params.xavi_helper_xname, start ? *start : NULL); if(xavi == NULL) { - if(xavi_add_xavi_value(&xavi_helper_xname, &reply_counter, &xval, - start ? start : NULL) + if(xavi_add_xavi_value(&_pvh_params.xavi_helper_xname, &reply_counter, + &xval, start ? start : NULL) == NULL) { - LM_ERR("can't create xavi:%.*s\n", xavi_helper_xname.len, - xavi_helper_xname.s); + LM_ERR("can't create xavi:%.*s\n", + _pvh_params.xavi_helper_xname.len, + _pvh_params.xavi_helper_xname.s); return -1; } - LM_DBG("xavi_name:%.*s created\n", xavi_helper_xname.len, - xavi_helper_xname.s); + LM_DBG("xavi_name:%.*s created\n", _pvh_params.xavi_helper_xname.len, + _pvh_params.xavi_helper_xname.s); } else { if(xavi_add_value(&reply_counter, &xval, &xavi->val.v.xavp) == NULL) { LM_ERR("can't add reply_counter value\n"); @@ -131,18 +132,19 @@ static sr_xavp_t *pvh_xavi_new_value(str *name, sr_xval_t *val) return avp; } -int pvh_xavi_append_value(str *name, sr_xval_t *val, sr_xavp_t **start) +static sr_xavp_t *pvh_xavi_append_value( + str *name, sr_xval_t *val, sr_xavp_t **start) { sr_xavp_t *last = NULL; sr_xavp_t *xavi = NULL; if((xavi = pvh_xavi_new_value(name, val)) == NULL) - return -1; + return xavi; if(*start == NULL) { xavi->next = *start; *start = xavi; - return 1; + return xavi; } last = *start; @@ -150,13 +152,13 @@ int pvh_xavi_append_value(str *name, sr_xval_t *val, sr_xavp_t **start) last = last->next; last->next = xavi; - return 1; + return xavi; } /** * */ -static int pvh_xavi_set_value( +static sr_xavp_t *pvh_xavi_set_value( str *name, sr_xval_t *val, int idx, sr_xavp_t **start) { int cnt = 0; @@ -166,14 +168,11 @@ static int pvh_xavi_set_value( idx = idx + cnt; if(idx < 0) { LM_ERR("wrong calculated idx:%d\n", idx); - return -1; + return NULL; } } LM_DBG("xavi name: %.*s\n", name->len, name->s); - if(xavi_set_value(name, idx, val, start) == NULL) - return -1; - - return 1; + return xavi_set_value(name, idx, val, start); } /** @@ -182,8 +181,8 @@ static int pvh_xavi_set_value( static sr_xavp_t *pvh_get_xavi(struct sip_msg *msg, str *xname) { sr_xavp_t *xavi = NULL; - char t[header_name_size]; - str br_xname = {t, header_name_size}; + char t[pvh_hdr_name_size]; + str br_xname = {t, pvh_hdr_name_size}; pvh_get_branch_xname(msg, xname, &br_xname); if((xavi = xavi_get(&br_xname, NULL)) == NULL) { @@ -230,7 +229,7 @@ int pvh_parse_header_name(pv_spec_p sp, str *hname) return -1; } - if(hname->len >= header_name_size) { + if(hname->len >= pvh_hdr_name_size) { LM_ERR("header name is too long\n"); return -1; } @@ -282,8 +281,8 @@ static sr_xval_t *pvh_xavi_get_value( sr_xavp_t *pvh_xavi_get_child(struct sip_msg *msg, str *xname, str *name) { sr_xavp_t *xavi = NULL; - char t[header_name_size]; - str br_xname = {t, header_name_size}; + char t[pvh_hdr_name_size]; + str br_xname = {t, pvh_hdr_name_size}; pvh_get_branch_xname(msg, xname, &br_xname); xavi = xavi_get_child(&br_xname, name); @@ -356,19 +355,20 @@ int pvh_xavi_keys_count(sr_xavp_t **start) /** * */ -int pvh_set_xavi(struct sip_msg *msg, str *xname, str *name, void *data, +sr_xavp_t *pvh_set_xavi(struct sip_msg *msg, str *xname, str *name, void *data, sr_xtype_t type, int idx, int append) { sr_xavp_t **xavi = NULL; sr_xavp_t *root = NULL; + sr_xavp_t *result = NULL; sr_xval_t root_xval; sr_xval_t xval; - char t[header_name_size]; - str br_xname = {t, header_name_size}; + char t[pvh_hdr_name_size]; + str br_xname = {t, pvh_hdr_name_size}; if(xname == NULL || name == NULL) { LM_ERR("missing xavi/pv name\n"); - return -1; + return result; } pvh_get_branch_xname(msg, xname, &br_xname); @@ -385,7 +385,7 @@ int pvh_set_xavi(struct sip_msg *msg, str *xname, str *name, void *data, xval.v.data = (sr_data_t *)shm_malloc(sizeof(sr_data_t)); if(xval.v.data == NULL) { SHM_MEM_ERROR; - return -1; + return result; } memset(xval.v.data, 0, sizeof(sr_data_t)); xval.v.data->p = data; @@ -394,7 +394,7 @@ int pvh_set_xavi(struct sip_msg *msg, str *xname, str *name, void *data, root = xavi_get(&br_xname, NULL); - if(root == NULL && _branch > 0) { + if(root == NULL && pvh_branch > 0) { pvh_clone_branch_xavi(msg, xname); root = xavi_get(&br_xname, NULL); } @@ -409,7 +409,7 @@ int pvh_set_xavi(struct sip_msg *msg, str *xname, str *name, void *data, if((root = xavi_add_value(&br_xname, &root_xval, NULL)) == NULL) { LM_ERR("error create xavi %.*s\n", br_xname.len, br_xname.s); - return -1; + return NULL; } xavi = &root->val.v.xavp; } else if(xavi_get_child(&br_xname, name) == NULL) { @@ -417,20 +417,18 @@ int pvh_set_xavi(struct sip_msg *msg, str *xname, str *name, void *data, } if(append) { - if(pvh_xavi_append_value(name, &xval, xavi) < 0) { + if((result = pvh_xavi_append_value(name, &xval, xavi)) == NULL) { LM_ERR("error append xavi=>name %.*s=>%.*s\n", br_xname.len, br_xname.s, name->len, name->s); - return -1; } } else { - if(pvh_xavi_set_value(name, &xval, idx, xavi) < 0) { + if((result = pvh_xavi_set_value(name, &xval, idx, xavi)) == NULL) { LM_ERR("error modify xavi=>name %.*s=>%.*s idx=%d\n", br_xname.len, br_xname.s, name->len, name->s, idx); - return -1; } } - return 1; + return result; } @@ -450,8 +448,8 @@ int pvh_get_branch_xname(struct sip_msg *msg, str *xname, str *dst) memcpy(dst->s, xname->s, xname->len); os += xname->len; - if(_branch > 0) { - snprintf(br_idx_s, 32, "%d", _branch - 1); + if(pvh_branch > 0) { + snprintf(br_idx_s, 32, "%d", pvh_branch - 1); br_idx_len = strlen(br_idx_s); memcpy(dst->s + os, ".", 1); os += 1; @@ -459,7 +457,7 @@ int pvh_get_branch_xname(struct sip_msg *msg, str *xname, str *dst) os += br_idx_len; } if(msg->first_line.type == SIP_REPLY) { - snprintf(br_idx_s, 32, ".r.%d", _reply_counter); + snprintf(br_idx_s, 32, ".r.%d", pvh_reply_counter); br_idx_len = strlen(br_idx_s); memcpy(dst->s + os, br_idx_s, br_idx_len); os += br_idx_len; @@ -479,8 +477,8 @@ int pvh_clone_branch_xavi(struct sip_msg *msg, str *xname) sr_xavp_t *br_xavi = NULL; sr_xavp_t *sub = NULL; sr_xval_t root_xval; - char t[header_name_size]; - str br_xname = {t, header_name_size}; + char t[pvh_hdr_name_size]; + str br_xname = {t, pvh_hdr_name_size}; int i = 0; if((xavi = xavi_get(xname, NULL)) == NULL) { @@ -490,12 +488,14 @@ int pvh_clone_branch_xavi(struct sip_msg *msg, str *xname) } if(xavi->val.type != SR_XTYPE_XAVP) { - LM_ERR("not xavp child type %.*s\n", xavi_name.len, xavi_name.s); + LM_ERR("not xavp child type %.*s\n", _pvh_params.xavi_name.len, + _pvh_params.xavi_name.s); return -1; } if((sub = xavi->val.v.xavp) == NULL) { - LM_ERR("invalid xavi structure: %.*s\n", xavi_name.len, xavi_name.s); + LM_ERR("invalid xavi structure: %.*s\n", _pvh_params.xavi_name.len, + _pvh_params.xavi_name.s); return -1; } @@ -510,7 +510,7 @@ int pvh_clone_branch_xavi(struct sip_msg *msg, str *xname) return -1; } - if(cmp_str(xname, &xavi_parsed_xname) == 0) { + if(cmp_str(xname, &_pvh_params.xavi_parsed_xname) == 0) { return 1; } @@ -554,7 +554,8 @@ int pvh_get_header(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) } if(idx < 0) { - if((xavi = pvh_xavi_get_child(msg, &xavi_name, hname)) == NULL) + if((xavi = pvh_xavi_get_child(msg, &_pvh_params.xavi_name, hname)) + == NULL) cnt = 0; else cnt = xavi_count(hname, &xavi); @@ -563,7 +564,7 @@ int pvh_get_header(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) return pv_get_null(msg, param, res); } - xval = pvh_xavi_get_value(msg, &xavi_name, hname, idx); + xval = pvh_xavi_get_value(msg, &_pvh_params.xavi_name, hname, idx); if(xval == NULL || !xval->v.s.s) return pv_get_null(msg, param, res); @@ -596,8 +597,9 @@ int pvh_set_header( return -1; } - if((xavi = pvh_get_xavi(msg, &xavi_name)) == NULL) { - LM_ERR("xavi %.*s not found\n", xavi_name.len, xavi_name.s); + if((xavi = pvh_get_xavi(msg, &_pvh_params.xavi_name)) == NULL) { + LM_ERR("xavi %.*s not found\n", _pvh_params.xavi_name.len, + _pvh_params.xavi_name.s); return -1; } avi = xavi->val.v.xavp; @@ -621,12 +623,14 @@ int pvh_set_header( LM_DBG("removed %d values of %.*s=>%.*s, set $null\n", cnt, xavi->name.len, xavi->name.s, hname->len, hname->s); } - if(pvh_set_xavi(msg, &xavi_name, hname, NULL, SR_XTYPE_NULL, 0, 0) - < 0) + if(pvh_set_xavi(msg, &_pvh_params.xavi_name, hname, NULL, + SR_XTYPE_NULL, 0, 0) + == NULL) goto err; } else { - if(pvh_set_xavi(msg, &xavi_name, hname, NULL, SR_XTYPE_NULL, idx, 0) - < 0) + if(pvh_set_xavi(msg, &_pvh_params.xavi_name, hname, NULL, + SR_XTYPE_NULL, idx, 0) + == NULL) goto err; } } else if(val->flags & (PV_VAL_STR | PV_TYPE_INT | PV_VAL_INT)) { @@ -644,8 +648,9 @@ int pvh_set_header( goto err; } if(idx == 0 && idxf == PV_IDX_NONE) { - if(pvh_set_xavi(msg, &xavi_name, hname, &fval, SR_XTYPE_STR, 0, 1) - < 0) + if(pvh_set_xavi(msg, &_pvh_params.xavi_name, hname, &fval, + SR_XTYPE_STR, 0, 1) + == NULL) goto err; } else if(idxf == PV_IDX_ALL) { if(hname_cnt > 1) { @@ -653,13 +658,14 @@ int pvh_set_header( LM_DBG("removed %d values of %.*s=>%.*s\n", cnt, xavi->name.len, xavi->name.s, hname->len, hname->s); } - if(pvh_set_xavi(msg, &xavi_name, hname, &fval, SR_XTYPE_STR, 0, - hname_cnt ? 0 : 1) - < 0) + if(pvh_set_xavi(msg, &_pvh_params.xavi_name, hname, &fval, + SR_XTYPE_STR, 0, hname_cnt ? 0 : 1) + == NULL) goto err; } else { - if(pvh_set_xavi(msg, &xavi_name, hname, &fval, SR_XTYPE_STR, idx, 0) - < 0) + if(pvh_set_xavi(msg, &_pvh_params.xavi_name, hname, &fval, + SR_XTYPE_STR, idx, 0) + == NULL) goto err; } if(pv_format) @@ -696,8 +702,9 @@ xavp_c_data_t *pvh_set_parsed( val = cur; if(pvh_merge_uri(msg, SET_URI_T, cur, val, c_data) < 0) goto err; - if(pvh_set_xavi(msg, &xavi_parsed_xname, hname, c_data, SR_XTYPE_DATA, 0, 0) - < 0) + if(pvh_set_xavi(msg, &_pvh_params.xavi_parsed_xname, hname, c_data, + SR_XTYPE_DATA, 0, 0) + == NULL) goto err; LM_DBG("c_data from pvh_merge_uri hname:%.*s\n", hname->len, hname->s); @@ -720,23 +727,24 @@ int pvh_get_uri(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) str sval = STR_NULL; int ival = 0; int is_strint = 0; - char t[header_name_size]; - str hname = {t, header_name_size - 1}; + char t[pvh_hdr_name_size]; + str hname = {t, pvh_hdr_name_size - 1}; p_no = param->pvn.u.isname.name.n; if(p_no >= 1 && p_no <= 5) - pvh_str_copy(&hname, &_hdr_from, header_name_size); + pvh_str_copy(&hname, &pvh_hdr_from, pvh_hdr_name_size); else if(p_no >= 6 && p_no <= 10) - pvh_str_copy(&hname, &_hdr_to, header_name_size); + pvh_str_copy(&hname, &pvh_hdr_to, pvh_hdr_name_size); - xval = pvh_xavi_get_value(msg, &xavi_name, &hname, 0); + xval = pvh_xavi_get_value(msg, &_pvh_params.xavi_name, &hname, 0); if(xval == NULL || !xval->v.s.s) { /* LM_DBG("xavi:%.*s hname:%.*s is null\n", xavi_name.len, xavi_name.s, hname.len, hname.s); */ goto err; } - xval_pd = pvh_xavi_get_value(msg, &xavi_parsed_xname, &hname, 0); + xval_pd = + pvh_xavi_get_value(msg, &_pvh_params.xavi_parsed_xname, &hname, 0); if(xval_pd) { /* LM_DBG("p_no:%d c_data from xavi_parsed_xname hname:%.*s\n", p_no, @@ -798,15 +806,15 @@ int pvh_set_uri(struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val) pv_elem_p pv_format = NULL; int p_no = 0; enum action_type a_type; - char t[header_name_size]; - str hname = {t, header_name_size - 1}; + char t[pvh_hdr_name_size]; + str hname = {t, pvh_hdr_name_size - 1}; str fval; p_no = param->pvn.u.isname.name.n; if(p_no >= 1 && p_no <= 5) - pvh_str_copy(&hname, &_hdr_from, header_name_size); + pvh_str_copy(&hname, &pvh_hdr_from, pvh_hdr_name_size); else if(p_no >= 6 && p_no <= 10) - pvh_str_copy(&hname, &_hdr_to, header_name_size); + pvh_str_copy(&hname, &pvh_hdr_to, pvh_hdr_name_size); switch(p_no) { case 1: // uri from @@ -845,7 +853,7 @@ int pvh_set_uri(struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val) goto err; } - xval = pvh_xavi_get_value(msg, &xavi_name, &hname, 0); + xval = pvh_xavi_get_value(msg, &_pvh_params.xavi_name, &hname, 0); if(xval == NULL || !xval->v.s.s) goto err; @@ -857,15 +865,16 @@ int pvh_set_uri(struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val) memset(c_data, 0, sizeof(xavp_c_data_t)); if(pvh_merge_uri(msg, a_type, &xval->v.s, &fval, c_data) < 0) goto err; - /* LM_DBG("xavi:%.*s hname:%.*s value:%.*s\n", xavi_name.len, xavi_name.s, + /* LM_DBG("xavi:%.*s hname:%.*s value:%.*s\n", _pvh_params.xavi_name.len, _pvh_params.xavi_name.s, hname.len, hname.s, c_data->value.len, c_data->value.s); */ - if(pvh_set_xavi(msg, &xavi_name, &hname, &c_data->value, SR_XTYPE_STR, 0, 0) - < 0) + if(pvh_set_xavi(msg, &_pvh_params.xavi_name, &hname, &c_data->value, + SR_XTYPE_STR, 0, 0) + == NULL) goto err; - if(pvh_set_xavi( - msg, &xavi_parsed_xname, &hname, c_data, SR_XTYPE_DATA, 0, 0) - < 0) + if(pvh_set_xavi(msg, &_pvh_params.xavi_parsed_xname, &hname, c_data, + SR_XTYPE_DATA, 0, 0) + == NULL) goto err; if(pv_format) @@ -907,7 +916,7 @@ int pvh_merge_uri(struct sip_msg *msg, enum action_type type, str *cur, } puri = tb.parsed_uri; - c_data->value.s = (char *)shm_malloc(header_value_size); + c_data->value.s = (char *)shm_malloc(_pvh_params.hdr_value_size); if(c_data->value.s == NULL) { SHM_MEM_ERROR; goto err; @@ -915,7 +924,7 @@ int pvh_merge_uri(struct sip_msg *msg, enum action_type type, str *cur, merged = &c_data->value; if(type == SET_URI_T && strchr(new->s, '<')) { - pvh_str_copy(merged, new, header_value_size); + pvh_str_copy(merged, new, _pvh_params.hdr_value_size); goto reparse; } @@ -1057,7 +1066,8 @@ int pvh_get_reply_sr(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) &msg->first_line.u.reply.status); break; case 2: // reason - xval = pvh_xavi_get_value(msg, &xavi_name, &_hdr_reply_reason, 0); + xval = pvh_xavi_get_value( + msg, &_pvh_params.xavi_name, &pvh_hdr_reply_reason, 0); return pv_get_strval(msg, param, res, xval && xval->v.s.s ? &xval->v.s : &msg->first_line.u.reply.reason); @@ -1128,9 +1138,9 @@ int pvh_set_reply_sr( msg->first_line.u.reply.status.s[0] = code + '0'; break; case 2: // reason - if(pvh_set_xavi(msg, &xavi_name, &_hdr_reply_reason, &fval, - SR_XTYPE_STR, 0, 0) - < 0) { + if(pvh_set_xavi(msg, &_pvh_params.xavi_name, &pvh_hdr_reply_reason, + &fval, SR_XTYPE_STR, 0, 0) + == NULL) { LM_ERR("set reply: cannot set reply reason\n"); goto err; } diff --git a/src/modules/pv_headers/pvh_xavp.h b/src/modules/pv_headers/pvh_xavp.h index 646ebd74f..b2e201d87 100644 --- a/src/modules/pv_headers/pvh_xavp.h +++ b/src/modules/pv_headers/pvh_xavp.h @@ -2,7 +2,7 @@ * pv_headers * * Copyright (C) - * 2020 Victor Seva + * 2020-2023 Victor Seva * 2018 Kirill Solomko * * This file is part of Kamailio, a free SIP server. @@ -33,7 +33,7 @@ int pvh_reply_append(sr_xavp_t **start); -int pvh_set_xavi(struct sip_msg *msg, str *xname, str *name, void *data, +sr_xavp_t *pvh_set_xavi(struct sip_msg *msg, str *xname, str *name, void *data, sr_xtype_t type, int idx, int append); int pvh_xavi_keys_count(sr_xavp_t **start); sr_xavp_t *pvh_xavi_get_child(struct sip_msg *msg, str *xname, str *name); diff --git a/src/modules/qos/README b/src/modules/qos/README index 83363771e..41d6e8898 100644 --- a/src/modules/qos/README +++ b/src/modules/qos/README @@ -174,11 +174,12 @@ Chapter 2. Developer Guide Register a new callback to the qos. Meaning of the parameters is as follows: - * struct qos_ctx_st* qos - qos to register callback to. If maybe NULL - only for QOSCB_CREATED callback type, which is not a per qos type. - * int type - types of callbacks; more types may be register for the - same callback function; only QOSCB_CREATED must be register alone. - Possible types: + * struct qos_ctx_st* qos - qos to register callback to. It may be + NULL only for QOSCB_CREATED callback type, which is not a per qos + type. + * int type - types of callbacks; more types may be registered for the + same callback function; only QOSCB_CREATED must be registered + alone. Possible types: + QOSCB_CREATED - called when a new qos context is created - it's a global type (not associated to any qos). + QOSCB_ADD_SDP - called when a new SDP was added to the qos diff --git a/src/modules/qos/doc/qos_devel.xml b/src/modules/qos/doc/qos_devel.xml index 97e302d59..13e13dc47 100644 --- a/src/modules/qos/doc/qos_devel.xml +++ b/src/modules/qos/doc/qos_devel.xml @@ -24,14 +24,14 @@ struct qos_ctx_st* qos - qos to - register callback to. If maybe NULL only for QOSCB_CREATED callback + register callback to. It may be NULL only for QOSCB_CREATED callback type, which is not a per qos type. int type - types of callbacks; more - types may be register for the same callback function; only - QOSCB_CREATED must be register alone. Possible types: + types may be registered for the same callback function; only + QOSCB_CREATED must be registered alone. Possible types: QOSCB_CREATED - called when a new diff --git a/src/modules/qos/qos.c b/src/modules/qos/qos.c index 7bac7248b..e6fba965c 100644 --- a/src/modules/qos/qos.c +++ b/src/modules/qos/qos.c @@ -83,7 +83,7 @@ int load_qos(struct qos_binds *qosb) * the script. This function is called only once. * * Bind to the dialog module and setup the callbacks. Also initialize - * the shared memory to store our interninal information in. + * the shared memory to store our internal information in. */ static int mod_init(void) { diff --git a/src/modules/qos/qos_cb.c b/src/modules/qos/qos_cb.c index af46689f8..c8f760117 100644 --- a/src/modules/qos/qos_cb.c +++ b/src/modules/qos/qos_cb.c @@ -76,13 +76,13 @@ int register_qoscb(qos_ctx_t *qos, int types, qos_cb f, void *param) if(types & QOSCB_CREATED) { if(types != QOSCB_CREATED) { - LM_CRIT("QOSCB_CREATED type must be register alone!\n"); + LM_CRIT("QOSCB_CREATED type must be registered alone!\n"); return -1; } } else { if(qos == 0) { LM_CRIT("non-QOSCB_CREATED type " - "must be register to a qos (qos missing)!\n"); + "must be registered to a qos (qos missing)!\n"); return -1; } } diff --git a/src/modules/qos/qos_handlers.c b/src/modules/qos/qos_handlers.c index 467ace077..c612e98a9 100644 --- a/src/modules/qos/qos_handlers.c +++ b/src/modules/qos/qos_handlers.c @@ -67,7 +67,7 @@ static void qos_dialog_rpc_context_CB( /** * A helper function to setup all the callbacks from the dialog module - * after we find intrest in the dialog. + * after we find interest in the dialog. * * @param did The Dialog ID. * @param info The qos information. diff --git a/src/modules/rabbitmq/Makefile b/src/modules/rabbitmq/Makefile index 72633cc9c..09023aaf8 100644 --- a/src/modules/rabbitmq/Makefile +++ b/src/modules/rabbitmq/Makefile @@ -10,6 +10,10 @@ RMQ_BUILDER=$(shell \ if pkg-config --exists librabbitmq && pkg-config --exists uuid; then \ echo 'pkg-config librabbitmq uuid'; \ fi) + + ifeq ($(shell pkg-config --atleast-version=0.13.0 librabbitmq; echo $$?),0) + DEFS += -DRABBITMQ_DEPRECATION + endif endif ifneq ($(RMQ_BUILDER),) diff --git a/src/modules/rabbitmq/README b/src/modules/rabbitmq/README index 942afffa8..889512b6a 100644 --- a/src/modules/rabbitmq/README +++ b/src/modules/rabbitmq/README @@ -176,7 +176,7 @@ modparam("rabbitmq", "direct_reply_to", 1) * content_type - the content_type of the messagebody. * messagebody - the messagebody to be published. - This function can be used from REQUEST_ROUTE. + This function can be used from any route. Example 1.5. rabbitmq_publish usage rabbitmq_publish("exchange", "routing_key", "application/json", "$avp(json_reque diff --git a/src/modules/rabbitmq/doc/rabbitmq_admin.xml b/src/modules/rabbitmq/doc/rabbitmq_admin.xml index 5799c75a2..179ba237b 100644 --- a/src/modules/rabbitmq/doc/rabbitmq_admin.xml +++ b/src/modules/rabbitmq/doc/rabbitmq_admin.xml @@ -204,7 +204,7 @@ modparam("rabbitmq", "direct_reply_to", 1) - This function can be used from REQUEST_ROUTE. + This function can be used from any route. diff --git a/src/modules/rabbitmq/rabbitmq.c b/src/modules/rabbitmq/rabbitmq.c index 626029d80..8547bacac 100644 --- a/src/modules/rabbitmq/rabbitmq.c +++ b/src/modules/rabbitmq/rabbitmq.c @@ -51,9 +51,18 @@ #include #include + +#if RABBITMQ_DEPRECATION +#include +#include +#include +#include +#else #include +#include #include #include +#endif #include @@ -73,10 +82,12 @@ static amqp_connection_state_t amqp_conn = NULL; /* module parameters */ static struct amqp_connection_info amqp_info; static char *amqp_url = RABBITMQ_DEFAULT_AMQP_URL; +static char *rmq_amqps_ca_file = NULL; static int max_reconnect_attempts = 1; static int timeout_sec = 1; static int timeout_usec = 0; static int direct_reply_to = 0; +static int amqp_ssl_init_called = 0; /* module helper functions */ static int rabbitmq_connect(amqp_connection_state_t *conn); @@ -117,13 +128,14 @@ static int rbmq_fixup_free_params(void **param, int param_no) /* module commands */ static cmd_export_t cmds[] = { {"rabbitmq_publish", (cmd_function)rabbitmq_publish, 4, fixup_spve_all, - fixup_free_spve_all, REQUEST_ROUTE}, + fixup_free_spve_all, ANY_ROUTE}, {"rabbitmq_publish_consume", (cmd_function)rabbitmq_publish_consume, 5, rbmq_fixup_params, rbmq_fixup_free_params, REQUEST_ROUTE}, {0, 0, 0, 0, 0, 0}}; /* module parameters */ static param_export_t params[] = {{"url", PARAM_STRING, &amqp_url}, + {"amqps_ca_file", PARAM_STRING, &rmq_amqps_ca_file}, {"timeout_sec", PARAM_INT, &timeout_sec}, {"timeout_usec", PARAM_INT, &timeout_usec}, {"direct_reply_to", PARAM_INT, &direct_reply_to}, {0, 0, 0}}; @@ -558,6 +570,13 @@ static int rabbitmq_connect(amqp_connection_state_t *conn) int log_ret; // amqp_rpc_reply_t reply; + // amqp_ssl_init_called should only be called once + if(amqp_info.ssl && !amqp_ssl_init_called) { + amqp_set_initialize_ssl_library(1); + amqp_ssl_init_called = 1; + LM_DBG("AMQP SSL library initialized\n"); + } + // establish a new connection to RabbitMQ server *conn = amqp_new_connection(); if(!*conn) { @@ -570,16 +589,32 @@ static int rabbitmq_connect(amqp_connection_state_t *conn) return RABBITMQ_ERR_CONNECT; } - amqp_sock = amqp_tcp_socket_new(*conn); + amqp_sock = (amqp_info.ssl) ? amqp_ssl_socket_new(*conn) + : amqp_tcp_socket_new(*conn); if(!amqp_sock) { LM_ERR("FAIL: create TCP amqp_sock"); amqp_destroy_connection(*conn); return RABBITMQ_ERR_SOCK; } + if(rmq_amqps_ca_file) { + if(amqp_ssl_socket_set_cacert(amqp_sock, rmq_amqps_ca_file)) { + LM_ERR("Failed to set CA certificate for amqps connection\n"); + return RABBITMQ_ERR_SSL_CACERT; + } + } + +#if AMQP_VERSION_MAJOR == 0 && AMQP_VERSION_MINOR < 8 + amqp_ssl_socket_set_verify(amqp_sock, (rmq_amqps_ca_file) ? 1 : 0); +#else + amqp_ssl_socket_set_verify_peer(amqp_sock, (rmq_amqps_ca_file) ? 1 : 0); + amqp_ssl_socket_set_verify_hostname(amqp_sock, (rmq_amqps_ca_file) ? 1 : 0); +#endif + ret = amqp_socket_open(amqp_sock, amqp_info.host, amqp_info.port); if(ret != AMQP_STATUS_OK) { - LM_ERR("FAIL: open TCP sock, amqp_status=%d", ret); + LM_ERR("FAIL: open %s sock, amqp_status=%d", + (amqp_info.ssl) ? "SSL" : "TCP", ret); // amqp_destroy_connection(*conn); return RABBITMQ_ERR_SOCK; } diff --git a/src/modules/rabbitmq/rabbitmq.h b/src/modules/rabbitmq/rabbitmq.h index 4eb319586..b37c84674 100644 --- a/src/modules/rabbitmq/rabbitmq.h +++ b/src/modules/rabbitmq/rabbitmq.h @@ -52,6 +52,7 @@ typedef enum RABBITMQ_ERR_CREATE, RABBITMQ_ERR_SOCK, RABBITMQ_ERR_CONSUME, + RABBITMQ_ERR_SSL_CACERT, RABBITMQ_ERR_NULL, } RABBITMQ_ENUM; diff --git a/src/modules/rabbitmq/utils.c b/src/modules/rabbitmq/utils.c index 6edbc22ea..e40492a3c 100644 --- a/src/modules/rabbitmq/utils.c +++ b/src/modules/rabbitmq/utils.c @@ -44,8 +44,14 @@ #include #include + +#if RABBITMQ_DEPRECATION +#include +#include +#else #include #include +#endif #include "utils.h" diff --git a/src/modules/ratelimit/README b/src/modules/ratelimit/README index 210b7692d..bace90fe3 100644 --- a/src/modules/ratelimit/README +++ b/src/modules/ratelimit/README @@ -490,8 +490,8 @@ modparam("ratelimit", "pipe", "4:NETWORK:10000") Name: rl.push_load Parameters: - * load - the forced value of load (it must be greater then 0.0 and - smaller then 1.0). + * load - the forced value of load (it must be greater than 0.0 and + less than 1.0). RPC Command Format: kamcmd rl.push_load 0.85 diff --git a/src/modules/ratelimit/doc/ratelimit_admin.xml b/src/modules/ratelimit/doc/ratelimit_admin.xml index cbccf4905..52b985957 100644 --- a/src/modules/ratelimit/doc/ratelimit_admin.xml +++ b/src/modules/ratelimit/doc/ratelimit_admin.xml @@ -538,7 +538,7 @@ modparam("ratelimit", "pipe", "4:NETWORK:10000") load - the forced value of load - (it must be greater then 0.0 and smaller then 1.0). + (it must be greater than 0.0 and less than 1.0). diff --git a/src/modules/ratelimit/ratelimit.c b/src/modules/ratelimit/ratelimit.c index edcb389b7..5cac92464 100644 --- a/src/modules/ratelimit/ratelimit.c +++ b/src/modules/ratelimit/ratelimit.c @@ -331,11 +331,13 @@ int get_num_cpus() /* not using /proc/loadavg because it only works when our_timer_interval == theirs */ static int get_cpuload(double *load) { - static long long o_user, o_nice, o_sys, o_idle, o_iow, o_irq, o_sirq, o_stl; - long long n_user, n_nice, n_sys, n_idle, n_iow, n_irq, n_sirq, n_stl; + static long long o_user = 0, o_nice = 0, o_sys = 0, o_idle = 0, o_iow = 0, + o_irq = 0, o_sirq = 0, o_stl = 0; + long long n_user = 0, n_nice = 0, n_sys = 0, n_idle = 0, n_iow = 0, + n_irq = 0, n_sirq = 0, n_stl = 0; static int first_time = 1; FILE *f = fopen("/proc/stat", "r"); - double vload; + double vload = 0.0; static int errormsg = 0; if(!f) { @@ -348,7 +350,7 @@ static int get_cpuload(double *load) } if(fscanf(f, "cpu %lld%lld%lld%lld%lld%lld%lld%lld", &n_user, &n_nice, &n_sys, &n_idle, &n_iow, &n_irq, &n_sirq, &n_stl) - < 0) { + < 8) { LM_ERR("could not parse load information\n"); fclose(f); return -1; @@ -922,7 +924,7 @@ static int init_params(void) * parses a "pipe_no:algorithm:bandwidth" line * \return 0 on success */ -static int parse_pipe_params(char *line, pipe_params_t *params) +static int parse_pipe_params(char *line, pipe_params_t *pparams) { regmatch_t m[4]; str algo_str; @@ -936,12 +938,12 @@ static int parse_pipe_params(char *line, pipe_params_t *params) LM_DBG("pipe: [%.*s|%.*s|%.*s]\n", RXLS(m, line, 1), RXLS(m, line, 2), RXLS(m, line, 3)); - params->no = atoi(RXS(m, line, 1)); - params->limit = atoi(RXS(m, line, 3)); + pparams->no = atoi(RXS(m, line, 1)); + pparams->limit = atoi(RXS(m, line, 3)); algo_str.s = RXS(m, line, 2); algo_str.len = RXL(m, line, 2); - if(str_map_str(algo_names, &algo_str, ¶ms->algo)) + if(str_map_str(algo_names, &algo_str, &pparams->algo)) return -1; return 0; @@ -951,7 +953,7 @@ static int parse_pipe_params(char *line, pipe_params_t *params) * parses a "pipe_no:method" line * \return 0 on success */ -static int parse_queue_params(char *line, rl_queue_params_t *params) +static int parse_queue_params(char *line, rl_queue_params_t *qparams) { regmatch_t m[3]; int len; @@ -964,16 +966,16 @@ static int parse_queue_params(char *line, rl_queue_params_t *params) } LM_DBG("queue: [%.*s|%.*s]\n", RXLS(m, line, 1), RXLS(m, line, 2)); - params->pipe = atoi(RXS(m, line, 1)); + qparams->pipe = atoi(RXS(m, line, 1)); len = RXL(m, line, 2); - params->method.s = (char *)pkg_malloc(len + 1); - if(params->method.s == 0) { + qparams->method.s = (char *)pkg_malloc(len + 1); + if(qparams->method.s == 0) { LM_ERR("no memory left for method in params\n"); return -1; } - params->method.len = len; - memcpy(params->method.s, RXS(m, line, 2), len + 1); + qparams->method.len = len; + memcpy(qparams->method.s, RXS(m, line, 2), len + 1); return 0; } @@ -1015,19 +1017,19 @@ static int check_feedback_setpoints(int modparam) static int add_pipe_params(modparam_t type, void *val) { char *param_line = val; - pipe_params_t params; + pipe_params_t pparams; - if(parse_pipe_params(param_line, ¶ms)) + if(parse_pipe_params(param_line, &pparams)) return -1; - if(params.no < 0 || params.no >= MAX_PIPES) { + if(pparams.no < 0 || pparams.no >= MAX_PIPES) { LM_ERR("pipe number %d not allowed (MAX_PIPES=%d, 0-based)\n", - params.no, MAX_PIPES); + pparams.no, MAX_PIPES); return -1; } - pipes[params.no].algo_mp = params.algo; - pipes[params.no].limit_mp = params.limit; + pipes[pparams.no].algo_mp = pparams.algo; + pipes[pparams.no].limit_mp = pparams.limit; return check_feedback_setpoints(1); } @@ -1035,24 +1037,24 @@ static int add_pipe_params(modparam_t type, void *val) static int add_queue_params(modparam_t type, void *val) { char *param_line = val; - rl_queue_params_t params; + rl_queue_params_t qparams; if(nqueues_mp >= MAX_QUEUES) { LM_ERR("MAX_QUEUES reached (%d)\n", MAX_QUEUES); return -1; } - if(parse_queue_params(param_line, ¶ms)) + if(parse_queue_params(param_line, &qparams)) return -1; - if(params.pipe >= MAX_PIPES) { + if(qparams.pipe >= MAX_PIPES) { LM_ERR("pipe number %d not allowed (MAX_PIPES=%d, 0-based)\n", - params.pipe, MAX_PIPES); + qparams.pipe, MAX_PIPES); return -1; } - queues[nqueues_mp].pipe_mp = params.pipe; - queues[nqueues_mp].method_mp = params.method; + queues[nqueues_mp].pipe_mp = qparams.pipe; + queues[nqueues_mp].method_mp = qparams.method; nqueues_mp++; return 0; @@ -1104,6 +1106,17 @@ static ticks_t rl_timer_handle(ticks_t ticks, struct timer_ln *tl, void *data) return (ticks_t)(-1); /* periodical */ } +static int ki_rl_check(struct sip_msg *msg) +{ + return rl_check(msg, -1); +} + +static int ki_rl_check_pipe(struct sip_msg *msg, int pipe) +{ + + LM_DBG("trying kemi pipe %d\n", pipe); + return rl_check(msg, pipe); +} /* rpc function documentation */ static const char *rpc_stats_doc[2] = { @@ -1243,7 +1256,7 @@ static void rpc_set_queue(rpc_t *rpc, void *c) if(rpc->scan(c, "dSd", &queue_no, &method, &pipe_no) < 3) return; - if(pipe_no >= MAX_PIPES || (int)pipe_no < 0) { + if(pipe_no >= MAX_PIPES) { LM_ERR("Invalid pipe number: %d\n", pipe_no); rpc->fault(c, 400, "Invalid pipe number"); return; @@ -1347,29 +1360,23 @@ static rpc_export_t rpc_methods[] = {{"rl.stats", rpc_stats, rpc_stats_doc, 0}, {"rl.push_load", rpc_push_load, rpc_push_load_doc, 0}, {"rl.set_dbg", rpc_set_dbg, rpc_set_dbg_doc, 0}, {0, 0, 0, 0}}; +/* clang-format off */ static sr_kemi_t sr_kemi_ratelimit_exports[] = { - {str_init("ratelimit"), str_init("rl_check"), SR_KEMIP_INT, ki_rl_check, - {SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, - SR_KEMIP_NONE, SR_KEMIP_NONE}}, - {str_init("ratelimit"), str_init("rl_check_pipe"), SR_KEMIP_INT, - ki_rl_check_pipe, - {SR_KEMIP_INT, 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}} - + { str_init("ratelimit"), str_init("rl_check"), + SR_KEMIP_INT, ki_rl_check, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("ratelimit"), str_init("rl_check_pipe"), + SR_KEMIP_INT, ki_rl_check_pipe, + { SR_KEMIP_INT, 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} } }; +/* clang-format on */ -static int ki_rl_check(struct sip_msg *msg) -{ - return rl_check(msg, -1); -} - -static int ki_rl_check_pipe(struct sip_msg *msg, int pipe) -{ - - LM_DBG("trying kemi pipe %d\n", pipe); - return rl_check(msg, pipe); -} int mod_register(char *path, int *dlflags, void *p1, void *p2) { diff --git a/src/modules/ratelimit/rl_statistics.c b/src/modules/ratelimit/rl_statistics.c index 237c7acd9..4e00dbeda 100644 --- a/src/modules/ratelimit/rl_statistics.c +++ b/src/modules/ratelimit/rl_statistics.c @@ -182,7 +182,7 @@ int get_socket_list_from_proto_and_family( return 0; } - *ipList = pkg_malloc(numberOfSockets * (num_ip_octets + 1) * sizeof(int)); + *ipList = pkg_malloc(sizeof(int) * numberOfSockets * (num_ip_octets + 1)); /* We couldn't allocate memory for the IP List. So all we can do is * fail. */ diff --git a/src/modules/regex/Makefile b/src/modules/regex/Makefile index 3b8758a03..db036b67d 100644 --- a/src/modules/regex/Makefile +++ b/src/modules/regex/Makefile @@ -5,20 +5,15 @@ auto_gen= NAME=regex.so ifeq ($(CROSS_COMPILE),) -PCRE_BUILDER = $(shell \ - if pkg-config --exists libcre; then \ - echo 'pkg-config libpcre'; \ - else \ - which pcre-config; \ - fi) +PCRE_BUILDER = $(shell command -v pcre2-config) endif ifeq ($(PCRE_BUILDER),) PCREDEFS=-I$(LOCALBASE)/include - PCRELIBS=-L$(LOCALBASE)/lib -lpcre + PCRELIBS=-L$(LOCALBASE)/lib -lpcre2-8 else PCREDEFS = $(shell $(PCRE_BUILDER) --cflags) - PCRELIBS = $(shell $(PCRE_BUILDER) --libs) + PCRELIBS = $(shell $(PCRE_BUILDER) --libs8) endif DEFS+=$(PCREDEFS) diff --git a/src/modules/regex/regex_mod.c b/src/modules/regex/regex_mod.c index 72247ca45..e7aaada85 100644 --- a/src/modules/regex/regex_mod.c +++ b/src/modules/regex/regex_mod.c @@ -2,6 +2,7 @@ * regex module - pcre operations * * Copyright (C) 2008 Iñaki Baz Castillo + * Copyright (C) 2023 Victor Seva * * This file is part of Kamailio, a free SIP server. * @@ -25,6 +26,7 @@ * \file * \brief REGEX :: Perl-compatible regular expressions using PCRE library * Copyright (C) 2008 Iñaki Baz Castillo + * Copyright (C) 2023 Victor Seva * \ingroup regex */ @@ -32,7 +34,8 @@ #include #include #include -#include +#define PCRE2_CODE_UNIT_WIDTH 8 +#include #include "../../core/sr_module.h" #include "../../core/dprint.h" #include "../../core/pt.h" @@ -77,8 +80,11 @@ static int pcre_extended = 0; /* * Module internal parameter variables */ -static pcre **pcres; -static pcre ***pcres_addr; +static pcre2_general_context *pcres_gctx = NULL; +static pcre2_match_context *pcres_mctx = NULL; +static pcre2_compile_context *pcres_ctx = NULL; +static pcre2_code **pcres; +static pcre2_code ***pcres_addr; static int *num_pcres; static int pcre_options = 0x00000000; @@ -151,6 +157,17 @@ struct module_exports exports = { }; +static void *pcre2_malloc(size_t size, void *ext) +{ + return shm_malloc(size); +} + +static void pcre2_free(void *ptr, void *ext) +{ + shm_free(ptr); + ptr = NULL; +} + /*! \brief * Init module function */ @@ -180,31 +197,46 @@ static int mod_init(void) /* PCRE options */ if(pcre_caseless != 0) { LM_DBG("PCRE CASELESS enabled\n"); - pcre_options = pcre_options | PCRE_CASELESS; + pcre_options = pcre_options | PCRE2_CASELESS; } if(pcre_multiline != 0) { LM_DBG("PCRE MULTILINE enabled\n"); - pcre_options = pcre_options | PCRE_MULTILINE; + pcre_options = pcre_options | PCRE2_MULTILINE; } if(pcre_dotall != 0) { LM_DBG("PCRE DOTALL enabled\n"); - pcre_options = pcre_options | PCRE_DOTALL; + pcre_options = pcre_options | PCRE2_DOTALL; } if(pcre_extended != 0) { LM_DBG("PCRE EXTENDED enabled\n"); - pcre_options = pcre_options | PCRE_EXTENDED; + pcre_options = pcre_options | PCRE2_EXTENDED; } LM_DBG("PCRE options: %i\n", pcre_options); + if((pcres_gctx = pcre2_general_context_create( + pcre2_malloc, pcre2_free, NULL)) + == NULL) { + LM_ERR("pcre2 general context creation failed\n"); + return -1; + } + if((pcres_ctx = pcre2_compile_context_create(pcres_gctx)) == NULL) { + LM_ERR("pcre2 compile context creation failed\n"); + return -1; + } + if((pcres_mctx = pcre2_match_context_create(pcres_gctx)) == NULL) { + LM_ERR("pcre2 match context creation failed\n"); + return -1; + } + /* Pointer to pcres */ - if((pcres_addr = shm_malloc(sizeof(pcre **))) == 0) { - LM_ERR("no memory for pcres_addr\n"); + if((pcres_addr = shm_malloc(sizeof(pcre2_code **))) == 0) { + SHM_MEM_ERROR; goto err; } /* Integer containing the number of pcres */ if((num_pcres = shm_malloc(sizeof(int))) == 0) { - LM_ERR("no memory for num_pcres\n"); + SHM_MEM_ERROR; goto err; } @@ -227,23 +259,33 @@ err: static void destroy(void) { free_shared_memory(); + + if(pcres_ctx) { + pcre2_compile_context_free(pcres_ctx); + } + + if(pcres_mctx) { + pcre2_match_context_free(pcres_mctx); + } + + if(pcres_gctx) { + pcre2_general_context_free(pcres_gctx); + } } -/*! \brief Convert the file content into regular expresions and store them in pcres */ +/*! \brief Convert the file content into regular expressions and store them in pcres */ static int load_pcres(int action) { int i, j; FILE *f; char line[FILE_MAX_LINE]; char **patterns = NULL; - pcre *pcre_tmp = NULL; - size_t pcre_size; - int pcre_rc; - const char *pcre_error; - int pcre_erroffset; + int pcre_error_num = 0; + char pcre_error[128]; + size_t pcre_erroffset; int num_pcres_tmp = 0; - pcre **pcres_tmp = NULL; + pcre2_code **pcres_tmp = NULL; int llen; /* Get the lock */ @@ -307,7 +349,7 @@ static int load_pcres(int action) } llen = strlen(line); - /* Check if the patter size is too big (aprox) */ + /* Check if the pattern size is too big (approx) */ if(strlen(patterns[i]) + llen >= group_max_size - 4) { LM_ERR("pattern max file exceeded\n"); fclose(f); @@ -379,38 +421,34 @@ static int load_pcres(int action) } /* Temporal pointer of pcres */ - if((pcres_tmp = pkg_malloc(sizeof(pcre *) * num_pcres_tmp)) == 0) { + if((pcres_tmp = pkg_malloc(sizeof(pcre2_code *) * num_pcres_tmp)) == 0) { LM_ERR("no more memory for pcres_tmp\n"); goto err; } - for(i = 0; i < num_pcres_tmp; i++) { - pcres_tmp[i] = NULL; - } + memset(pcres_tmp, 0, sizeof(pcre2_code *) * num_pcres_tmp); - /* Compile the patters */ + /* Compile the patterns */ for(i = 0; i < num_pcres_tmp; i++) { - - pcre_tmp = pcre_compile( - patterns[i], pcre_options, &pcre_error, &pcre_erroffset, NULL); - if(pcre_tmp == NULL) { - LM_ERR("pcre_tmp compilation of '%s' failed at offset %d: %s\n", + pcres_tmp[i] = pcre2_compile((PCRE2_SPTR)patterns[i], + PCRE2_ZERO_TERMINATED, pcre_options, &pcre_error_num, + &pcre_erroffset, pcres_ctx); + if(pcres_tmp[i] == NULL) { + switch(pcre2_get_error_message( + pcre_error_num, (PCRE2_UCHAR *)pcre_error, 128)) { + case PCRE2_ERROR_NOMEMORY: + snprintf(pcre_error, 128, + "unknown error[%d]: pcre2 error buffer too small", + pcre_error_num); + break; + case PCRE2_ERROR_BADDATA: + snprintf(pcre_error, 128, "unknown pcre2 error[%d]", + pcre_error_num); + break; + } + LM_ERR("pcre_tmp compilation of '%s' failed at offset %zu: %s\n", patterns[i], pcre_erroffset, pcre_error); goto err; } - pcre_rc = pcre_fullinfo(pcre_tmp, NULL, PCRE_INFO_SIZE, &pcre_size); - if(pcre_rc) { - printf("pcre_fullinfo on compiled pattern[%i] yielded error: %d\n", - i, pcre_rc); - goto err; - } - - if((pcres_tmp[i] = pkg_malloc(pcre_size)) == 0) { - LM_ERR("no more memory for pcres_tmp[%i]\n", i); - goto err; - } - - memcpy(pcres_tmp[i], pcre_tmp, pcre_size); - pcre_free(pcre_tmp); pkg_free(patterns[i]); patterns[i] = NULL; } @@ -419,31 +457,15 @@ static int load_pcres(int action) if(action == RELOAD) { for(i = 0; i < *num_pcres; i++) { /* Use the previous num_pcres value */ if(pcres[i]) { - shm_free(pcres[i]); + pcre2_code_free(pcres[i]); } } shm_free(pcres); } - if((pcres = shm_malloc(sizeof(pcre *) * num_pcres_tmp)) == 0) { - LM_ERR("no more memory for pcres\n"); - goto err; - } - memset(pcres, 0, sizeof(pcre *) * num_pcres_tmp); - for(i = 0; i < num_pcres_tmp; i++) { - pcre_rc = pcre_fullinfo(pcres_tmp[i], NULL, PCRE_INFO_SIZE, &pcre_size); - if((pcres[i] = shm_malloc(pcre_size)) == 0) { - LM_ERR("no more memory for pcres[%i]\n", i); - goto err; - } - memcpy(pcres[i], pcres_tmp[i], pcre_size); - } *num_pcres = num_pcres_tmp; + *pcres = *pcres_tmp; *pcres_addr = pcres; - /* Free used memory */ - for(i = 0; i < num_pcres_tmp; i++) { - pkg_free(pcres_tmp[i]); - } pkg_free(pcres_tmp); /* Free allocated slots for unused patterns */ for(i = num_pcres_tmp; i < max_groups; i++) { @@ -466,7 +488,7 @@ err: if(pcres_tmp) { for(i = 0; i < num_pcres_tmp; i++) { if(pcres_tmp[i]) { - pkg_free(pcres_tmp[i]); + pcre2_code_free(pcres_tmp[i]); } } pkg_free(pcres_tmp); @@ -520,42 +542,73 @@ static void free_shared_memory(void) /*! \brief Return true if the argument matches the regular expression parameter */ static int ki_pcre_match(sip_msg_t *msg, str *string, str *regex) { - pcre *pcre_re = NULL; + pcre2_code *pcre_re = NULL; + pcre2_match_data *pcre_md = NULL; int pcre_rc; - const char *pcre_error; - int pcre_erroffset; + int pcre_error_num = 0; + char pcre_error[128]; + size_t pcre_erroffset; - pcre_re = pcre_compile( - regex->s, pcre_options, &pcre_error, &pcre_erroffset, NULL); + pcre_re = pcre2_compile((PCRE2_SPTR)regex->s, PCRE2_ZERO_TERMINATED, + pcre_options, &pcre_error_num, &pcre_erroffset, pcres_ctx); if(pcre_re == NULL) { - LM_ERR("pcre_re compilation of '%s' failed at offset %d: %s\n", + switch(pcre2_get_error_message( + pcre_error_num, (PCRE2_UCHAR *)pcre_error, 128)) { + case PCRE2_ERROR_NOMEMORY: + snprintf(pcre_error, 128, + "unknown error[%d]: pcre2 error buffer too small", + pcre_error_num); + break; + case PCRE2_ERROR_BADDATA: + snprintf(pcre_error, 128, "unknown pcre2 error[%d]", + pcre_error_num); + break; + } + LM_ERR("pcre_re compilation of '%s' failed at offset %zu: %s\n", regex->s, pcre_erroffset, pcre_error); return -4; } - pcre_rc = pcre_exec(pcre_re, /* the compiled pattern */ - NULL, /* no extra data - we didn't study the pattern */ - string->s, /* the matching string */ - (int)(string->len), /* the length of the subject */ - 0, /* start at offset 0 in the string */ - 0, /* default options */ - NULL, /* output vector for substring information */ - 0); /* number of elements in the output vector */ + pcre_md = pcre2_match_data_create_from_pattern(pcre_re, pcres_gctx); + pcre_rc = pcre2_match(pcre_re, /* the compiled pattern */ + (PCRE2_SPTR)string->s, /* the matching string */ + (PCRE2_SIZE)(string->len), /* the length of the subject */ + 0, /* start at offset 0 in the string */ + 0, /* default options */ + pcre_md, /* the match data block */ + pcres_mctx); /* a match context; NULL means use defaults */ /* Matching failed: handle error cases */ if(pcre_rc < 0) { switch(pcre_rc) { - case PCRE_ERROR_NOMATCH: + case PCRE2_ERROR_NOMATCH: LM_DBG("'%s' doesn't match '%s'\n", string->s, regex->s); break; default: - LM_DBG("matching error '%d'\n", pcre_rc); + switch(pcre2_get_error_message( + pcre_rc, (PCRE2_UCHAR *)pcre_error, 128)) { + case PCRE2_ERROR_NOMEMORY: + snprintf(pcre_error, 128, + "unknown error[%d]: pcre2 error buffer too " + "small", + pcre_rc); + break; + case PCRE2_ERROR_BADDATA: + snprintf(pcre_error, 128, "unknown pcre2 error[%d]", + pcre_rc); + break; + } + LM_ERR("matching error:'%s' failed[%d]\n", pcre_error, pcre_rc); break; } - pcre_free(pcre_re); + if(pcre_md) + pcre2_match_data_free(pcre_md); + pcre2_code_free(pcre_re); return -1; } - pcre_free(pcre_re); + if(pcre_md) + pcre2_match_data_free(pcre_md); + pcre2_code_free(pcre_re); LM_DBG("'%s' matches '%s'\n", string->s, regex->s); return 1; } @@ -592,6 +645,8 @@ static int w_pcre_match(struct sip_msg *_msg, char *_s1, char *_s2) static int ki_pcre_match_group(sip_msg_t *_msg, str *string, int num_pcre) { int pcre_rc; + pcre2_match_data *pcre_md = NULL; + char pcre_error[128]; /* Check if group matching feature is enabled */ if(file == NULL) { @@ -606,26 +661,41 @@ static int ki_pcre_match_group(sip_msg_t *_msg, str *string, int num_pcre) } lock_get(reload_lock); - - pcre_rc = pcre_exec((*pcres_addr)[num_pcre], /* the compiled pattern */ - NULL, /* no extra data - we didn't study the pattern */ - string->s, /* the matching string */ - (int)(string->len), /* the length of the subject */ - 0, /* start at offset 0 in the string */ - 0, /* default options */ - NULL, /* output vector for substring information */ - 0); /* number of elements in the output vector */ + pcre_md = pcre2_match_data_create_from_pattern( + (*pcres_addr)[num_pcre], pcres_gctx); + pcre_rc = pcre2_match((*pcres_addr)[num_pcre], /* the compiled pattern */ + (PCRE2_SPTR)string->s, /* the matching string */ + (PCRE2_SIZE)(string->len), /* the length of the subject */ + 0, /* start at offset 0 in the string */ + 0, /* default options */ + pcre_md, /* the match data block */ + pcres_mctx); /* a match context; NULL means use defaults */ lock_release(reload_lock); + if(pcre_md) + pcre2_match_data_free(pcre_md); /* Matching failed: handle error cases */ if(pcre_rc < 0) { switch(pcre_rc) { - case PCRE_ERROR_NOMATCH: + case PCRE2_ERROR_NOMATCH: LM_DBG("'%s' doesn't match pcres[%i]\n", string->s, num_pcre); break; default: - LM_DBG("matching error '%d'\n", pcre_rc); + switch(pcre2_get_error_message( + pcre_rc, (PCRE2_UCHAR *)pcre_error, 128)) { + case PCRE2_ERROR_NOMEMORY: + snprintf(pcre_error, 128, + "unknown error[%d]: pcre2 error buffer too " + "small", + pcre_rc); + break; + case PCRE2_ERROR_BADDATA: + snprintf(pcre_error, 128, "unknown pcre2 error[%d]", + pcre_rc); + break; + } + LM_ERR("matching error:'%s' failed[%d]\n", pcre_error, pcre_rc); break; } return -1; diff --git a/src/modules/registrar/README b/src/modules/registrar/README index 360577c8d..fea39e0a6 100644 --- a/src/modules/registrar/README +++ b/src/modules/registrar/README @@ -646,7 +646,7 @@ modparam("registrar", "method_filtering", 1) 3.20. use_path (integer) - If set to 1, the “Path:” header is handled according to the parameter + If set to 1, the “Path:” header is handled according to the parameter. This parameter can be modified via Kamailio config framework. “path_mode”. @@ -686,7 +686,7 @@ modparam("registrar", "path_mode", 0) registration is set as received-uri and the NAT branch flag is set for this contact. This is useful if the registrar is placed behind a SIP loadbalancer, which passes the nat'ed UAC address as “received” - parameter in it's Path uri. + parameter in its Path uri. Default value is 0 (disabled). @@ -745,8 +745,12 @@ modparam("registrar", "reg_callid_avp", "$avp(s:avp)") * socket - the string representing the socket on which the register request was received, as alternative to using the sock_hdr. Used in save(). + * tcpconn_id This can be set with $conid, the TCP connection ID of + the connection the current message. This is useful when calling + save() on a reply route to set the connecion of the original + request. Used in save(). - For example. if this parameter is set to 'reg', then the number of + For example if this parameter is set to 'reg', then the number of maximum contacts can be set in $xavp(reg=>max_contacts). Default value is NULL (disabled). @@ -1026,16 +1030,16 @@ kamcmd cfg.set_now_int registrar use_expired_contacts 0 is set. The flags may be given in decimal or hexadecimal format. * uri (optional - flags param has to be set and can be 0 for default - behavior) - SIP URI to do be used instead of To header URI. It can - be a dynamic string with pseudo-variables. + behavior) - SIP URI to be used instead of To header URI. It can be + a dynamic string with pseudo-variables. Return codes: * -2 - error, too many contacts for AOR. - -1 - error. - 1 - contacts inserted. - 2 - contacts updated. - 3 - contacts deleted. - 4 - contacts returned. + * -1 - error. + * 1 - contacts inserted. + * 2 - contacts updated. + * 3 - contacts deleted. + * 4 - contacts returned. This function can be used from REQUEST_ROUTE, FAILURE_ROUTE and REPLY_ROUTE. @@ -1063,14 +1067,14 @@ save("location", "0x00", "sip:test@kamailio.org"); Meaning of the parameters is as follows: * domain - Name of table that should be used for the lookup. - * uri (optional) - SIP URI to do be used instead of R-URI. It can be - a dynamic string with pseudo-variables. + * uri (optional) - SIP URI to be used instead of R-URI. It can be a + dynamic string with pseudo-variables. Return codes: * 1 - contacts found and returned. - -1 - no contact found. - -2 - contacts found, but method not supported. - -3 - internal error during processing. + * -1 - no contact found. + * -2 - contacts found, but method not supported. + * -3 - internal error during processing. This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. @@ -1159,8 +1163,8 @@ xinfo("first contact record - socket: $xavp(cul>socket)\n"); Meaning of the parameters is as follows: * domain - Name of table that should be used for the lookup. - * uri (optional) - SIP URI to do be used instead of Request/To-URI. - It can be a dynamic string with pseudo-variables. + * uri (optional) - SIP URI to be used instead of Request/To-URI. It + can be a dynamic string with pseudo-variables. * match_option (optional) - flag parameter to restrict contact search. use xavp_cfg to set the values to compare to. flag values is as follows: @@ -1482,9 +1486,11 @@ Chapter 2. Frequently Asked Questions First at all check if your question was already answered on one of our mailing lists: * User Mailing List - - https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users + https://lists.kamailio.org/mailman3/postorius/lists/sr-users.lists. + kamailio.org/ * Developer Mailing List - - https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-dev + https://lists.kamailio.org/mailman3/postorius/lists/sr-dev.lists.ka + mailio.org/ E-mails regarding any stable Kamailio release should be sent to and e-mails regarding development diff --git a/src/modules/registrar/api.c b/src/modules/registrar/api.c index 684e39c92..eb3f09d1f 100644 --- a/src/modules/registrar/api.c +++ b/src/modules/registrar/api.c @@ -39,7 +39,7 @@ int regapi_save(sip_msg_t *msg, str *table, int flags) { udomain_t *d; - if(ul.get_udomain(table->s, &d) < 0) { + if(_reg_ul.get_udomain(table->s, &d) < 0) { LM_ERR("usrloc domain [%s] not found\n", table->s); return -1; } @@ -54,7 +54,7 @@ int regapi_save_uri(sip_msg_t *msg, str *table, int flags, str *uri) { udomain_t *d; - if(ul.get_udomain(table->s, &d) < 0) { + if(_reg_ul.get_udomain(table->s, &d) < 0) { LM_ERR("usrloc domain [%s] not found\n", table->s); return -1; } @@ -69,7 +69,7 @@ int regapi_lookup(sip_msg_t *msg, str *table) { udomain_t *d; - if(ul.get_udomain(table->s, &d) < 0) { + if(_reg_ul.get_udomain(table->s, &d) < 0) { LM_ERR("usrloc domain [%s] not found\n", table->s); return -1; } @@ -84,7 +84,7 @@ int regapi_lookup_uri(sip_msg_t *msg, str *table, str *uri) { udomain_t *d; - if(ul.get_udomain(table->s, &d) < 0) { + if(_reg_ul.get_udomain(table->s, &d) < 0) { LM_ERR("usrloc domain [%s] not found\n", table->s); return -1; } @@ -99,7 +99,7 @@ int regapi_registered(sip_msg_t *msg, str *table) { udomain_t *d; - if(ul.get_udomain(table->s, &d) < 0) { + if(_reg_ul.get_udomain(table->s, &d) < 0) { LM_ERR("usrloc domain [%s] not found\n", table->s); return -1; } @@ -127,7 +127,7 @@ int regapi_lookup_to_dset(sip_msg_t *msg, str *table, str *uri) { udomain_t *d; - if(ul.get_udomain(table->s, &d) < 0) { + if(_reg_ul.get_udomain(table->s, &d) < 0) { LM_ERR("usrloc domain [%s] not found\n", table->s); return -1; } diff --git a/src/modules/registrar/doc/registrar_admin.xml b/src/modules/registrar/doc/registrar_admin.xml index fdd2df888..848e5ae40 100644 --- a/src/modules/registrar/doc/registrar_admin.xml +++ b/src/modules/registrar/doc/registrar_admin.xml @@ -588,7 +588,7 @@ modparam("registrar", "method_filtering", 1)
<varname>use_path</varname> (integer) - If set to 1, the Path: header is handled according to the parameter + If set to 1, the Path: header is handled according to the parameter. This parameter can be modified via &kamailio; config framework. path_mode. @@ -663,8 +663,7 @@ modparam("registrar", "path_mode", 0) URI of a registration is set as received-uri and the NAT branch flag is set for this contact. This is useful if the registrar is placed behind a SIP loadbalancer, which passes the nat'ed UAC address as - received parameter - in it's Path uri. + received parameter in its Path uri. @@ -798,9 +797,16 @@ modparam("registrar", "reg_callid_avp", "$avp(s:avp)") Used in save(). + + + tcpconn_id This can be set with $conid, the TCP connection ID of the connection the current message. + This is useful when calling save() on a reply route to set the connecion of the original request. + Used in save(). + + - For example. if this parameter is set to 'reg', then the number + For example if this parameter is set to 'reg', then the number of maximum contacts can be set in $xavp(reg=>max_contacts). @@ -1275,7 +1281,7 @@ kamcmd cfg.set_now_int registrar use_expired_contacts 0 uri (optional - flags param has to be set and - can be 0 for default behavior) - SIP URI to do be used instead of To + can be 0 for default behavior) - SIP URI to be used instead of To header URI. It can be a dynamic string with pseudo-variables. @@ -1286,18 +1292,23 @@ kamcmd cfg.set_now_int registrar use_expired_contacts 0 -2 - error, too many contacts for AOR. + -1 - error. + 1 - contacts inserted. + 2 - contacts updated. + 3 - contacts deleted. + 4 - contacts returned. @@ -1348,7 +1359,7 @@ save("location", "0x00", "sip:test@kamailio.org"); - uri (optional) - SIP URI to do be used instead + uri (optional) - SIP URI to be used instead of R-URI. It can be a dynamic string with pseudo-variables. @@ -1359,12 +1370,15 @@ save("location", "0x00", "sip:test@kamailio.org"); 1 - contacts found and returned. + -1 - no contact found. + -2 - contacts found, but method not supported. + -3 - internal error during processing. @@ -1549,7 +1563,7 @@ xinfo("first contact record - socket: $xavp(cul>socket)\n"); - uri (optional) - SIP URI to do be used instead + uri (optional) - SIP URI to be used instead of Request/To-URI. It can be a dynamic string with pseudo-variables. diff --git a/src/modules/registrar/lookup.c b/src/modules/registrar/lookup.c index 89a469e88..1e9f8f93b 100644 --- a/src/modules/registrar/lookup.c +++ b/src/modules/registrar/lookup.c @@ -321,17 +321,17 @@ int lookup_helper(struct sip_msg *_m, udomain_t *_d, str *_uri, int _mode) if(puri.gr.s == NULL || puri.gr_val.len > 0) { /* aor or pub-gruu lookup */ - ul.lock_udomain(_d, &aor); - res = ul.get_urecord(_d, &aor, &r); + _reg_ul.lock_udomain(_d, &aor); + res = _reg_ul.get_urecord(_d, &aor, &r); if(res > 0) { LM_DBG("'%.*s' Not found in usrloc\n", aor.len, ZSW(aor.s)); - ul.unlock_udomain(_d, &aor); + _reg_ul.unlock_udomain(_d, &aor); return -1; } ptr = r->contacts; ret = -1; - /* look first for an un-expired and suported contact */ + /* look first for an un-expired and supported contact */ while(ptr) { if(VALID_CONTACT(ptr, act_time) || cfg_get( @@ -370,14 +370,14 @@ int lookup_helper(struct sip_msg *_m, udomain_t *_d, str *_uri, int _mode) } } else { /* temp-gruu lookup */ - res = ul.get_urecord_by_ruid(_d, ahash, &inst, &r, &ptr); + res = _reg_ul.get_urecord_by_ruid(_d, ahash, &inst, &r, &ptr); if(res < 0) { LM_DBG("temp gruu '%.*s' not found in usrloc\n", aor.len, ZSW(aor.s)); return -1; } aor = *ptr->aor; - /* test if not expired and contact with suported method */ + /* test if not expired and contact with supported method */ if(ptr) { if(!(VALID_CONTACT(ptr, act_time) || cfg_get(registrar, registrar_cfg, @@ -594,8 +594,8 @@ int lookup_helper(struct sip_msg *_m, udomain_t *_d, str *_uri, int _mode) } done: - ul.release_urecord(r); - ul.unlock_udomain(_d, &aor); + _reg_ul.release_urecord(r); + _reg_ul.unlock_udomain(_d, &aor); return ret; } @@ -842,11 +842,11 @@ int registered4(struct sip_msg *_m, udomain_t *_d, str *_uri, int match_flag, return -1; } - ul.lock_udomain(_d, &aor); - res = ul.get_urecord(_d, &aor, &r); + _reg_ul.lock_udomain(_d, &aor); + res = _reg_ul.get_urecord(_d, &aor, &r); if(res < 0) { - ul.unlock_udomain(_d, &aor); + _reg_ul.unlock_udomain(_d, &aor); LM_ERR("failed to query usrloc\n"); return -1; } @@ -935,15 +935,15 @@ int registered4(struct sip_msg *_m, udomain_t *_d, str *_uri, int match_flag, } } - ul.release_urecord(r); - ul.unlock_udomain(_d, &aor); + _reg_ul.release_urecord(r); + _reg_ul.unlock_udomain(_d, &aor); LM_DBG("'%.*s' found in usrloc\n", aor.len, ZSW(aor.s)); return 1; } } - ul.unlock_udomain(_d, &aor); + _reg_ul.unlock_udomain(_d, &aor); LM_DBG("'%.*s' not found in usrloc\n", aor.len, ZSW(aor.s)); return -1; } diff --git a/src/modules/registrar/registrar.c b/src/modules/registrar/registrar.c index b771e2918..172985c5b 100644 --- a/src/modules/registrar/registrar.c +++ b/src/modules/registrar/registrar.c @@ -59,7 +59,7 @@ MODULE_VERSION -usrloc_api_t ul; /*!< Structure containing pointers to usrloc functions*/ +usrloc_api_t _reg_ul; /*!< Structure containing pointers to usrloc functions*/ /*! \brief Module init & destroy function */ static int mod_init(void); @@ -159,7 +159,7 @@ stat_var *default_expire_stat; stat_var *default_expire_range_stat; stat_var *expire_range_stat; /** SL API structure */ -sl_api_t slb; +sl_api_t _reg_slb; /*! \brief * Exported PV @@ -311,7 +311,7 @@ static int mod_init(void) #endif /* bind the SL API */ - if(sl_load_api(&slb) != 0) { + if(sl_load_api(&_reg_slb) != 0) { LM_ERR("Cannot bind to SL API. Please load the SL module before" " loading this module.\n"); return -1; @@ -361,11 +361,11 @@ static int mod_init(void) } cfg_get(registrar, registrar_cfg, default_q) = dq; - if(bind_usrloc(&ul) < 0) { + if(bind_usrloc(&_reg_ul) < 0) { return -1; } - if(ul.register_ulcb != NULL) { + if(_reg_ul.register_ulcb != NULL) { if(reg_event_callback.s == NULL || reg_event_callback.len <= 0) { reg_expire_event_rt = route_lookup(&event_rt, "usrloc:contact-expired"); @@ -382,7 +382,8 @@ static int mod_init(void) if(reg_expire_event_rt >= 0 || (reg_event_callback.s != NULL && keng != NULL)) { set_child_rpc_sip_mode(); - if(ul.register_ulcb(UL_CONTACT_EXPIRE, reg_ul_expired_contact, 0) + if(_reg_ul.register_ulcb( + UL_CONTACT_EXPIRE, reg_ul_expired_contact, 0) < 0) { LM_ERR("Can not register callback for expired contacts" " (usrloc module)\n"); @@ -393,7 +394,7 @@ static int mod_init(void) /* * Import use_domain parameter from usrloc */ - reg_use_domain = ul.use_domain; + reg_use_domain = _reg_ul.use_domain; if(sock_hdr_name.s) { if(sock_hdr_name.len == 0 || sock_flag == -1) { @@ -523,7 +524,7 @@ static int ki_lookup_branches(sip_msg_t *_m, str *_dtable) { udomain_t *d; - if(ul.get_udomain(_dtable->s, &d) < 0) { + if(_reg_ul.get_udomain(_dtable->s, &d) < 0) { LM_ERR("usrloc domain [%s] not found\n", _dtable->s); return -1; } @@ -598,7 +599,7 @@ static int ki_registered_uri(sip_msg_t *_m, str *_dtable, str *_uri) { udomain_t *d; - if(ul.get_udomain(_dtable->s, &d) < 0) { + if(_reg_ul.get_udomain(_dtable->s, &d) < 0) { LM_ERR("usrloc domain [%s] not found\n", _dtable->s); return -1; } @@ -628,7 +629,7 @@ static int ki_registered_flags(sip_msg_t *_m, str *_dtable, str *_uri, int _f) { udomain_t *d; - if(ul.get_udomain(_dtable->s, &d) < 0) { + if(_reg_ul.get_udomain(_dtable->s, &d) < 0) { LM_ERR("usrloc domain [%s] not found\n", _dtable->s); return -1; } @@ -668,7 +669,7 @@ static int ki_registered_action( { udomain_t *d; - if(ul.get_udomain(_dtable->s, &d) < 0) { + if(_reg_ul.get_udomain(_dtable->s, &d) < 0) { LM_ERR("usrloc domain [%s] not found\n", _dtable->s); return -1; } @@ -696,7 +697,7 @@ static int ki_unregister(sip_msg_t *_m, str *_dtable, str *_uri) LM_ERR("invalid uri parameter\n"); return -1; } - if(ul.get_udomain(_dtable->s, &d) < 0) { + if(_reg_ul.get_udomain(_dtable->s, &d) < 0) { LM_ERR("usrloc domain [%s] not found\n", _dtable->s); return -1; } @@ -729,7 +730,7 @@ static int ki_unregister_ruid( LM_ERR("invalid uri parameter\n"); return -1; } - if(ul.get_udomain(_dtable->s, &d) < 0) { + if(_reg_ul.get_udomain(_dtable->s, &d) < 0) { LM_ERR("usrloc domain [%s] not found\n", _dtable->s); return -1; } @@ -763,7 +764,7 @@ static int domain_fixup(void **param, int param_no) udomain_t *d; if(param_no == 1) { - if(ul.register_udomain((char *)*param, &d) < 0) { + if(_reg_ul.register_udomain((char *)*param, &d) < 0) { LM_ERR("failed to register domain\n"); return E_UNSPEC; } @@ -835,7 +836,7 @@ static int save_fixup(void **param, int param_no) LM_ERR("bad flags <%s>\n", (char *)(*param)); return E_CFG; } - if(ul.db_mode == DB_ONLY && flags & REG_SAVE_MEM_FL) { + if(_reg_ul.db_mode == DB_ONLY && flags & REG_SAVE_MEM_FL) { LM_ERR("MEM flag set while using the DB_ONLY mode in USRLOC\n"); return E_CFG; } diff --git a/src/modules/registrar/registrar.h b/src/modules/registrar/registrar.h index bd28b5bd8..40b18148b 100644 --- a/src/modules/registrar/registrar.h +++ b/src/modules/registrar/registrar.h @@ -106,9 +106,10 @@ extern int reg_sock_mode; extern str reg_xavp_cfg; extern str reg_xavp_rcd; extern int reg_xavp_rcd_mask; -extern usrloc_api_t ul; /*!< Structure containing pointers to usrloc functions*/ +/*!< Structure containing pointers to usrloc functions*/ +extern usrloc_api_t _reg_ul; -extern sl_api_t slb; +extern sl_api_t _reg_slb; extern int reg_expire_event_rt; extern int reg_min_expires_mode; diff --git a/src/modules/registrar/regpv.c b/src/modules/registrar/regpv.c index ccaa0027f..722f977a4 100644 --- a/src/modules/registrar/regpv.c +++ b/src/modules/registrar/regpv.c @@ -260,6 +260,8 @@ int pv_get_ulc(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) return pv_get_strval(msg, param, res, &c->instance); break; case 21: /* conid */ + if(c->tcpconn_id > 0) + return pv_get_sintval(msg, param, res, c->tcpconn_id); if(c->sock && (c->sock->proto == PROTO_TCP || c->sock->proto == PROTO_TLS @@ -572,11 +574,11 @@ int pv_fetch_contacts_helper( /* copy contacts */ ilen = sizeof(ucontact_t); - ul.lock_udomain(dt, &aor); - res = ul.get_urecord(dt, &aor, &r); + _reg_ul.lock_udomain(dt, &aor); + res = _reg_ul.get_urecord(dt, &aor, &r); if(res > 0) { LM_DBG("'%.*s' Not found in usrloc\n", aor.len, ZSW(aor.s)); - ul.unlock_udomain(dt, &aor); + _reg_ul.unlock_udomain(dt, &aor); return -1; } @@ -592,8 +594,8 @@ int pv_fetch_contacts_helper( c0 = (ucontact_t *)pkg_malloc(olen); if(c0 == NULL) { LM_ERR("no more pkg\n"); - ul.release_urecord(r); - ul.unlock_udomain(dt, &aor); + _reg_ul.release_urecord(r); + _reg_ul.unlock_udomain(dt, &aor); goto error; } memcpy(c0, ptr, ilen); @@ -649,6 +651,10 @@ int pv_fetch_contacts_helper( || ptr->sock->proto == PROTO_WSS)) { c0->tcpconn_id = ptr->tcpconn_id; } + if(ptr->tcpconn_id > 0) { + LM_DBG("preset tcpconn_id : %d\n", ptr->tcpconn_id); + c0->tcpconn_id = ptr->tcpconn_id; + } if(ptr0 == NULL) { rpp->contacts = c0; @@ -660,8 +666,8 @@ int pv_fetch_contacts_helper( ptr0 = c0; ptr = ptr->next; } - ul.release_urecord(r); - ul.unlock_udomain(dt, &aor); + _reg_ul.release_urecord(r); + _reg_ul.unlock_udomain(dt, &aor); rpp->nrc = n; LM_DBG("fetched <%d> contacts for <%.*s> in [%.*s]\n", n, aor.len, aor.s, rpp->pname.len, rpp->pname.s); @@ -688,7 +694,7 @@ int ki_reg_fetch_contacts(sip_msg_t *msg, str *dtable, str *uri, str *profile) { udomain_t *d; - if(ul.get_udomain(dtable->s, &d) < 0) { + if(_reg_ul.get_udomain(dtable->s, &d) < 0) { LM_ERR("usrloc domain [%s] not found\n", dtable->s); return -1; } @@ -864,7 +870,7 @@ int ki_lookup_xavp( return -1; } - if(ul.get_udomain(utname->s, &dt) < 0) { + if(_reg_ul.get_udomain(utname->s, &dt) < 0) { LM_ERR("usrloc domain [%s] not found\n", utname->s); return -1; } @@ -880,11 +886,11 @@ int ki_lookup_xavp( } /* copy contacts */ - ul.lock_udomain(dt, &aor); - res = ul.get_urecord(dt, &aor, &r); + _reg_ul.lock_udomain(dt, &aor); + res = _reg_ul.get_urecord(dt, &aor, &r); if(res > 0) { LM_DBG("'%.*s' not found in usrloc\n", aor.len, ZSW(aor.s)); - ul.unlock_udomain(dt, &aor); + _reg_ul.unlock_udomain(dt, &aor); xavp_destroy_list(&rxavp); return -1; } @@ -933,8 +939,8 @@ int ki_lookup_xavp( n++; ptr = ptr->next; } - ul.release_urecord(r); - ul.unlock_udomain(dt, &aor); + _reg_ul.release_urecord(r); + _reg_ul.unlock_udomain(dt, &aor); /* add record count field */ memset(&nxval, 0, sizeof(sr_xval_t)); @@ -962,8 +968,8 @@ int ki_lookup_xavp( return 1; error: - ul.release_urecord(r); - ul.unlock_udomain(dt, &aor); + _reg_ul.release_urecord(r); + _reg_ul.unlock_udomain(dt, &aor); if(cxavp != NULL) { xavp_destroy_list(&cxavp); } @@ -994,17 +1000,17 @@ int ki_reg_from_user(sip_msg_t *msg, str *utname, str *uri, int vmode) return -1; } - if(ul.get_udomain(utname->s, &dt) < 0) { + if(_reg_ul.get_udomain(utname->s, &dt) < 0) { LM_ERR("usrloc domain [%s] not found\n", utname->s); return -1; } /* copy contacts */ - ul.lock_udomain(dt, &aor); - res = ul.get_urecord(dt, &aor, &r); + _reg_ul.lock_udomain(dt, &aor); + res = _reg_ul.get_urecord(dt, &aor, &r); if(res > 0) { LM_DBG("'%.*s' not found in usrloc\n", aor.len, ZSW(aor.s)); - ul.unlock_udomain(dt, &aor); + _reg_ul.unlock_udomain(dt, &aor); return -1; } @@ -1045,13 +1051,13 @@ int ki_reg_from_user(sip_msg_t *msg, str *utname, str *uri, int vmode) ret = 1; break; } - ul.release_urecord(r); - ul.unlock_udomain(dt, &aor); + _reg_ul.release_urecord(r); + _reg_ul.unlock_udomain(dt, &aor); return ret; error: - ul.release_urecord(r); - ul.unlock_udomain(dt, &aor); + _reg_ul.release_urecord(r); + _reg_ul.unlock_udomain(dt, &aor); return -1; } diff --git a/src/modules/registrar/reply.c b/src/modules/registrar/reply.c index bf4a2a527..67600d6ab 100644 --- a/src/modules/registrar/reply.c +++ b/src/modules/registrar/reply.c @@ -278,7 +278,7 @@ int build_contact(sip_msg_t *msg, ucontact_t *c, str *host) memcpy(p, c->ruid.s, c->ruid.len); p += c->ruid.len; *p++ = '-'; - ahash = ul.get_aorhash(c->aor); + ahash = _reg_ul.get_aorhash(c->aor); while(ahash != 0) { digit = ahash & 0x0f; *p++ = (digit >= 10) ? digit + 'a' - 10 : digit + '0'; @@ -748,7 +748,7 @@ int reg_reply_helper(struct sip_msg *_m, int _mode) } if(likely(_mode)) { - if(slb.freply(_m, code, &msg) < 0) { + if(_reg_slb.freply(_m, code, &msg) < 0) { LM_ERR("failed to send %ld %.*s\n", code, msg.len, msg.s); return -1; } diff --git a/src/modules/registrar/save.c b/src/modules/registrar/save.c index e62893542..c94f56563 100644 --- a/src/modules/registrar/save.c +++ b/src/modules/registrar/save.c @@ -71,6 +71,29 @@ extern sruid_t _reg_sruid; static int q_override_msg_id; static qvalue_t q_override_value; + +/** + * + */ +static int reg_get_cfg_tcpconnid(void) +{ + int n; + sr_xavp_t *vavp = NULL; + str vname = {"tcpconn_id", 10}; + + n = 0; + + if(reg_xavp_cfg.s != NULL) { + vavp = xavp_get_child_with_ival(®_xavp_cfg, &vname); + if(vavp != NULL) { + n = (int)vavp->val.v.l; + LM_DBG("using tcpconn_id value from xavp: %d\n", n); + } + } + + return n; +} + /*! \brief * Process request that contained a star (*) as a contact, in that case, * we will remove all bindings with the given username @@ -81,9 +104,9 @@ static inline int star(sip_msg_t *_m, udomain_t *_d, str *_a, str *_h) urecord_t *r; ucontact_t *c; - ul.lock_udomain(_d, _a); + _reg_ul.lock_udomain(_d, _a); - if(!ul.get_urecord(_d, _a, &r)) { + if(!_reg_ul.get_urecord(_d, _a, &r)) { c = r->contacts; while(c) { if(mem_only) { @@ -97,7 +120,7 @@ static inline int star(sip_msg_t *_m, udomain_t *_d, str *_a, str *_h) r = NULL; } - if(ul.delete_urecord(_d, _a, r) < 0) { + if(_reg_ul.delete_urecord(_d, _a, r) < 0) { LM_ERR("failed to remove record from usrloc\n"); /* Delete failed, try to get corresponding @@ -105,14 +128,14 @@ static inline int star(sip_msg_t *_m, udomain_t *_d, str *_a, str *_h) * contacts */ rerrno = R_UL_DEL_R; - if(!ul.get_urecord(_d, _a, &r)) { + if(!_reg_ul.get_urecord(_d, _a, &r)) { build_contact(_m, r->contacts, _h); - ul.release_urecord(r); + _reg_ul.release_urecord(r); } - ul.unlock_udomain(_d, _a); + _reg_ul.unlock_udomain(_d, _a); return -1; } - ul.unlock_udomain(_d, _a); + _reg_ul.unlock_udomain(_d, _a); return 0; } @@ -192,22 +215,22 @@ static inline int no_contacts(sip_msg_t *_m, udomain_t *_d, str *_a, str *_h) urecord_t *r; int res; - ul.lock_udomain(_d, _a); - res = ul.get_urecord(_d, _a, &r); + _reg_ul.lock_udomain(_d, _a); + res = _reg_ul.get_urecord(_d, _a, &r); if(res < 0) { rerrno = R_UL_GET_R; LM_ERR("failed to retrieve record from usrloc\n"); - ul.unlock_udomain(_d, _a); + _reg_ul.unlock_udomain(_d, _a); return -1; } if(res == 0) { /* Contacts found */ build_contact(_m, r->contacts, _h); - ul.release_urecord(r); + _reg_ul.release_urecord(r); } else { /* No contacts found */ build_contact(_m, NULL, _h); } - ul.unlock_udomain(_d, _a); + _reg_ul.unlock_udomain(_d, _a); return 0; } @@ -229,6 +252,7 @@ static inline ucontact_info_t *pack_ci(struct sip_msg *_m, contact_t *_c, static struct sip_msg *m = 0; static struct socket_info si = {0}; int_str val; + int tcid; if(_m != 0) { memset(&ci, 0, sizeof(ucontact_info_t)); @@ -273,6 +297,11 @@ static inline ucontact_info_t *pack_ci(struct sip_msg *_m, contact_t *_c, } else { ci.tcpconn_id = -1; } + /* if a tcp connectionid is set via xavp, use it */ + tcid = reg_get_cfg_tcpconnid(); + if(tcid > 0) { + ci.tcpconn_id = tcid; + } /* additional info from message */ if(parse_headers(_m, HDR_USERAGENT_F, 0) != -1 && _m->user_agent @@ -309,7 +338,7 @@ static inline ucontact_info_t *pack_ci(struct sip_msg *_m, contact_t *_c, /* get received */ if(path_received.len && path_received.s) { - ci.cflags |= ul.nat_flag; + ci.cflags |= _reg_ul.nat_flag; ci.received = path_received; } @@ -509,7 +538,7 @@ static inline int insert_contacts(struct sip_msg *_m, udomain_t *_d, str *_a, num++; if(r == 0) { - if(ul.insert_urecord(_d, _a, &r) < 0) { + if(_reg_ul.insert_urecord(_d, _a, &r) < 0) { rerrno = R_UL_NEW_R; LM_ERR("failed to insert new record structure\n"); goto error; @@ -528,16 +557,16 @@ static inline int insert_contacts(struct sip_msg *_m, udomain_t *_d, str *_a, * one already added, then update */ ci->cseq++; if(r->contacts == 0 - || ul.get_ucontact_by_instance(r, &_c->uri, ci, &c) != 0) { + || _reg_ul.get_ucontact_by_instance(r, &_c->uri, ci, &c) != 0) { ci->cseq--; - if(ul.insert_ucontact(r, &_c->uri, ci, &c) < 0) { + if(_reg_ul.insert_ucontact(r, &_c->uri, ci, &c) < 0) { rerrno = R_UL_INS_C; LM_ERR("failed to insert contact\n"); goto error; } } else { ci->cseq--; - if(ul.update_ucontact(r, c, ci) < 0) { + if(_reg_ul.update_ucontact(r, c, ci) < 0) { rerrno = R_UL_UPD_C; LM_ERR("failed to update contact\n"); goto error; @@ -566,7 +595,7 @@ static inline int insert_contacts(struct sip_msg *_m, udomain_t *_d, str *_a, if(r) { if(r->contacts) build_contact(_m, r->contacts, &u->host); - ul.release_urecord(r); + _reg_ul.release_urecord(r); } else { /* No contacts found */ build_contact(_m, NULL, &u->host); } @@ -582,7 +611,7 @@ static inline int insert_contacts(struct sip_msg *_m, udomain_t *_d, str *_a, return 0; error: if(r) - ul.delete_urecord(_d, _a, r); + _reg_ul.delete_urecord(_d, _a, r); return -1; } @@ -610,7 +639,7 @@ static int test_max_contacts(struct sip_msg *_m, urecord_t *_r, contact_t *_c, /* calculate expires */ calc_contact_expires(_m, _c->expires, &e, 0); - ret = ul.get_ucontact_by_instance(_r, &_c->uri, ci, &cont); + ret = _reg_ul.get_ucontact_by_instance(_r, &_c->uri, ci, &cont); if(ret == -1) { LM_ERR("invalid cseq for aor <%.*s>\n", _r->aor.len, _r->aor.s); rerrno = R_INV_CSEQ; @@ -714,7 +743,7 @@ static inline int update_contacts(struct sip_msg *_m, urecord_t *_r, int _mode, } /* search for the contact*/ - ret = ul.get_ucontact_by_instance(_r, &_c->uri, ci, &c); + ret = _reg_ul.get_ucontact_by_instance(_r, &_c->uri, ci, &c); if(ret == -1) { LM_ERR("invalid cseq for aor <%.*s>\n", _r->aor.len, _r->aor.s); rerrno = R_INV_CSEQ; @@ -730,7 +759,7 @@ static inline int update_contacts(struct sip_msg *_m, urecord_t *_r, int _mode, if(expires == 0) continue; - if(ul.insert_ucontact(_r, &_c->uri, ci, &c) < 0) { + if(_reg_ul.insert_ucontact(_r, &_c->uri, ci, &c) < 0) { rerrno = R_UL_INS_C; LM_ERR("failed to insert contact\n"); goto error; @@ -741,7 +770,7 @@ static inline int update_contacts(struct sip_msg *_m, urecord_t *_r, int _mode, while(ptr) { ptr0 = ptr->next; if(ptr != c) - ul.delete_ucontact(_r, ptr); + _reg_ul.delete_ucontact(_r, ptr); ptr = ptr0; } updated = 1; @@ -756,7 +785,7 @@ static inline int update_contacts(struct sip_msg *_m, urecord_t *_r, int _mode, c->flags &= ~FL_MEM; } - if(ul.delete_ucontact(_r, c) < 0) { + if(_reg_ul.delete_ucontact(_r, c) < 0) { rerrno = R_UL_DEL_C; LM_ERR("failed to delete contact\n"); goto error; @@ -769,7 +798,7 @@ static inline int update_contacts(struct sip_msg *_m, urecord_t *_r, int _mode, while(ptr) { ptr0 = ptr->next; if(ptr != c) - ul.delete_ucontact(_r, ptr); + _reg_ul.delete_ucontact(_r, ptr); ptr = ptr0; } updated = 1; @@ -788,13 +817,13 @@ static inline int update_contacts(struct sip_msg *_m, urecord_t *_r, int _mode, && strncmp(ptr->instance.s, c->instance.s, ptr->instance.len) == 0) { - ul.delete_ucontact(_r, ptr); + _reg_ul.delete_ucontact(_r, ptr); } ptr = ptr0; } updated = 1; } - if(ul.update_ucontact(_r, c, ci) < 0) { + if(_reg_ul.update_ucontact(_r, c, ci) < 0) { rerrno = R_UL_UPD_C; LM_ERR("failed to update contact\n"); goto error; @@ -856,38 +885,38 @@ static inline int add_contacts(struct sip_msg *_m, udomain_t *_d, str *_a, return -2; ret = 0; - ul.lock_udomain(_d, _a); - res = ul.get_urecord(_d, _a, &r); + _reg_ul.lock_udomain(_d, _a); + res = _reg_ul.get_urecord(_d, _a, &r); if(res < 0) { rerrno = R_UL_GET_R; LM_ERR("failed to retrieve record from usrloc\n"); - ul.unlock_udomain(_d, _a); + _reg_ul.unlock_udomain(_d, _a); return -2; } if(res == 0) { /* Contacts found */ if((ret = update_contacts(_m, r, _mode, _use_regid, novariation)) < 0) { build_contact(_m, r->contacts, &u->host); - ul.release_urecord(r); - ul.unlock_udomain(_d, _a); + _reg_ul.release_urecord(r); + _reg_ul.unlock_udomain(_d, _a); return -3; } build_contact(_m, r->contacts, &u->host); - ul.release_urecord(r); + _reg_ul.release_urecord(r); } else { if(insert_contacts(_m, _d, _a, _use_regid, novariation) < 0) { - ul.unlock_udomain(_d, _a); + _reg_ul.unlock_udomain(_d, _a); return -4; } ret = 1; } - ul.unlock_udomain(_d, _a); + _reg_ul.unlock_udomain(_d, _a); return ret; } /*!\brief - * Process REGISTER request and save it's contacts + * Process REGISTER request and save its contacts */ #define is_cflag_set(_name) (((unsigned int)_cflags) & (_name)) int save(struct sip_msg *_m, udomain_t *_d, int _cflags, str *_uri) @@ -1097,21 +1126,22 @@ int unregister(struct sip_msg *_m, udomain_t *_d, str *_uri, str *_ruid) return -1; } - if(ul.get_urecord_by_ruid(_d, ul.get_aorhash(&aor), _ruid, &r, &c) + if(_reg_ul.get_urecord_by_ruid( + _d, _reg_ul.get_aorhash(&aor), _ruid, &r, &c) != 0) { LM_WARN("AOR/Contact not found\n"); return -3; } - if(ul.delete_ucontact(r, c) != 0) { - ul.unlock_udomain(_d, &aor); + if(_reg_ul.delete_ucontact(r, c) != 0) { + _reg_ul.unlock_udomain(_d, &aor); LM_WARN("could not delete contact\n"); return -2; } - ul.unlock_udomain(_d, &aor); + _reg_ul.unlock_udomain(_d, &aor); } else { - res = ul.delete_urecord_by_ruid(_d, _ruid); + res = _reg_ul.delete_urecord_by_ruid(_d, _ruid); switch(res) { case -1: LM_ERR("could not delete contact\n"); diff --git a/src/modules/registrar/save.h b/src/modules/registrar/save.h index 65376ff49..e6ad4d266 100644 --- a/src/modules/registrar/save.h +++ b/src/modules/registrar/save.h @@ -37,7 +37,7 @@ /*! \brief - * Process REGISTER request and save it's contacts + * Process REGISTER request and save its contacts */ int save(struct sip_msg *_m, udomain_t *_d, int _cflags, str *_uri); int unregister(struct sip_msg *_m, udomain_t *_d, str *_uri, str *_ruid); diff --git a/src/modules/registrar/sip_msg.c b/src/modules/registrar/sip_msg.c index 9ef2c37db..69e8606fb 100644 --- a/src/modules/registrar/sip_msg.c +++ b/src/modules/registrar/sip_msg.c @@ -48,15 +48,17 @@ static struct hdr_field *act_contact; */ static inline int randomize_expires(int expires, int range) { - int range_min; + float range_min; /* if no range is given just return expires */ if(range == 0) return expires; - range_min = expires - (float)range / 100 * expires; + range_min = (float)expires * (1.0 - ((float)range / 100)); - return range_min + (float)(kam_rand() % 100) / 100 * (expires - range_min); + return (int)(range_min + + ((float)(kam_rand() % 100) / 100) + * ((float)expires - range_min)); } diff --git a/src/modules/rls/notify.c b/src/modules/rls/notify.c index 84cb54fb0..011a382f1 100644 --- a/src/modules/rls/notify.c +++ b/src/modules/rls/notify.c @@ -167,7 +167,7 @@ int send_full_notify( } /* Allocate an initial buffer for the multipart body. - * This buffer will be reallocated if neccessary */ + * This buffer will be reallocated if necessary */ multipart_body = (str *)pkg_malloc(sizeof(str)); if(multipart_body == NULL) { ERR_MEM(PKG_MEM_STR); diff --git a/src/modules/rls/resource_notify.c b/src/modules/rls/resource_notify.c index 8189377c1..c0b308a76 100644 --- a/src/modules/rls/resource_notify.c +++ b/src/modules/rls/resource_notify.c @@ -193,7 +193,7 @@ static void send_notifies(db1_res_t *result, int did_col, int resource_uri_col, bstr.s[bstr.len] = '\0'; /* Allocate an initial buffer for the multipart body. - * This buffer will be reallocated if neccessary */ + * This buffer will be reallocated if necessary */ buf = pkg_malloc(size * sizeof(char)); if(buf == NULL) { ERR_MEM(PKG_MEM_STR); @@ -248,7 +248,7 @@ static void send_notifies(db1_res_t *result, int did_col, int resource_uri_col, resource_added = 0; /* !!!! for now I will include the auth state without checking if - * it has changed - > in future chech if it works */ + * it has changed - > in future check if it works */ } /* add a node in rlmi_doc and if any presence state registered add @@ -1084,7 +1084,7 @@ void timer_send_notify(unsigned int ticks, void *param) } -/* function to periodicaly clean the rls_presentity table */ +/* function to periodically clean the rls_presentity table */ void rls_presentity_clean(unsigned int ticks, void *param) { diff --git a/src/modules/rls/rls.c b/src/modules/rls/rls.c index 657e6f477..9dec88122 100644 --- a/src/modules/rls/rls.c +++ b/src/modules/rls/rls.c @@ -616,7 +616,7 @@ static int mod_init(void) return -1; } if(lock_init(rls_update_subs_lock) == NULL) { - LM_ERR("Failed to init rls_updae_subs_lock\n"); + LM_ERR("Failed to init rls_update_subs_lock\n"); return -1; } @@ -844,7 +844,7 @@ int rls_restore_db_subs(void) if(db_fetch_query(&rls_dbf, rls_fetch_rows, rls_db, 0, 0, 0, result_cols, 0, n_result_cols, 0, &res) < 0) { - LM_ERR("while querrying table\n"); + LM_ERR("while querying table\n"); if(res) { rls_dbf.free_result(rls_db, res); res = NULL; diff --git a/src/modules/rls/subscribe.c b/src/modules/rls/subscribe.c index 3de91a986..b1d2b9a65 100644 --- a/src/modules/rls/subscribe.c +++ b/src/modules/rls/subscribe.c @@ -565,7 +565,7 @@ int rls_handle_subscribe( if(rls_get_service_list(&subs.pres_uri, &subs.watcher_user, &subs.watcher_domain, &service_node, &doc) < 0) { - LM_ERR("while attepmting to get a resource list\n"); + LM_ERR("while attempting to get a resource list\n"); goto error; } if(doc == NULL) { diff --git a/src/modules/rr/README b/src/modules/rr/README index efaf0df8e..41bccc788 100644 --- a/src/modules/rr/README +++ b/src/modules/rr/README @@ -765,7 +765,7 @@ record_route_advertised_address("1.2.3.4:5090"); 1.3. add_rr_param(msg, param) - Adds a parameter to the requests's Record-Route URI (param must be in + Adds a parameter to the requests' Record-Route URI (param must be in “;name=value” format). The function returns 0 on success. Otherwise, -1 is returned. diff --git a/src/modules/rr/doc/rr_devel.xml b/src/modules/rr/doc/rr_devel.xml index 461cbd96d..69e8af632 100644 --- a/src/modules/rr/doc/rr_devel.xml +++ b/src/modules/rr/doc/rr_devel.xml @@ -97,7 +97,7 @@ record_route_advertised_address("1.2.3.4:5090"); add_rr_param(msg, param) - Adds a parameter to the requests's Record-Route URI (param must be in + Adds a parameter to the requests' Record-Route URI (param must be in ;name=value format). diff --git a/src/modules/rtimer/README b/src/modules/rtimer/README index e0c1e626b..5bb7795ed 100644 --- a/src/modules/rtimer/README +++ b/src/modules/rtimer/README @@ -119,7 +119,7 @@ modparam("rtimer", "default_interval", 300) ... # time interval set to 10 seconds modparam("rtimer", "timer", "name=ta;interval=10;mode=1;") -# time interval set to 100 mili-seconds +# time interval set to 100 milliseconds modparam("rtimer", "timer", "name=ta;interval=100000u;mode=1;") ... diff --git a/src/modules/rtimer/doc/rtimer_admin.xml b/src/modules/rtimer/doc/rtimer_admin.xml index 676bf2f5a..289e04b47 100644 --- a/src/modules/rtimer/doc/rtimer_admin.xml +++ b/src/modules/rtimer/doc/rtimer_admin.xml @@ -124,7 +124,7 @@ modparam("rtimer", "default_interval", 300) ... # time interval set to 10 seconds modparam("rtimer", "timer", "name=ta;interval=10;mode=1;") -# time interval set to 100 mili-seconds +# time interval set to 100 milliseconds modparam("rtimer", "timer", "name=ta;interval=100000u;mode=1;") ... diff --git a/src/modules/rtp_media_server/README b/src/modules/rtp_media_server/README index 769af8435..a74f7a14e 100644 --- a/src/modules/rtp_media_server/README +++ b/src/modules/rtp_media_server/README @@ -129,7 +129,7 @@ Chapter 1. Admin Guide If you want to build oRTP and mediastreamer from source, you can use the provided script for Debian "install_bc.sh". * oRTP git clone git://git.linphone.org/ortp.git - oRTP is a library implemeting Real-time Transport Protocol (RFC + oRTP is a library implementing Real-time Transport Protocol (RFC 3550), distributed under GNU GPLv2 or proprietary license. * mediastreamer2 git clone git://git.linphone.org/mediastreamer2.git Mediastreamer2 is a powerful and lightweight streaming engine @@ -278,8 +278,8 @@ e in-dialog request needs to be handled by it. 5.6. rms_play (file, event_route) - Play a wav file, a resampler is automaticaly configured to resample and - convert stereo to mono if needed. + Play a wav file, a resampler is automatically configured to resample + and convert stereo to mono if needed. The second parameter is the event route that will be called when the file was played. diff --git a/src/modules/rtp_media_server/doc/rtp_media_server_admin.xml b/src/modules/rtp_media_server/doc/rtp_media_server_admin.xml index 2e36eb755..44dda416d 100644 --- a/src/modules/rtp_media_server/doc/rtp_media_server_admin.xml +++ b/src/modules/rtp_media_server/doc/rtp_media_server_admin.xml @@ -69,7 +69,7 @@ oRTP git clone git://git.linphone.org/ortp.git - oRTP is a library implemeting Real-time Transport Protocol (RFC 3550), distributed under GNU GPLv2 or proprietary license. + oRTP is a library implementing Real-time Transport Protocol (RFC 3550), distributed under GNU GPLv2 or proprietary license. @@ -263,7 +263,7 @@ route {
<varname>rms_play</varname> (file, event_route) - Play a wav file, a resampler is automaticaly configured to resample + Play a wav file, a resampler is automatically configured to resample and convert stereo to mono if needed. The second parameter is the event route that will be called when the file was played. diff --git a/src/modules/rtp_media_server/rms_sdp.c b/src/modules/rtp_media_server/rms_sdp.c index 04438fbe9..d3305d842 100644 --- a/src/modules/rtp_media_server/rms_sdp.c +++ b/src/modules/rtp_media_server/rms_sdp.c @@ -269,7 +269,7 @@ PayloadType *rms_sdp_select_payload(rms_sdp_info_t *sdp) payload_type_number = strtok(NULL, " "); } if(!pt->mime_type) { - LM_INFO("unsuported codec\n"); + LM_INFO("unsupported codec\n"); shm_free(pt); // payload_type_destroy(pt); return NULL; } diff --git a/src/modules/rtp_media_server/rtp_media_server.c b/src/modules/rtp_media_server/rtp_media_server.c index 4f9f22069..a41b57150 100644 --- a/src/modules/rtp_media_server/rtp_media_server.c +++ b/src/modules/rtp_media_server/rtp_media_server.c @@ -209,7 +209,7 @@ static int mod_init(void) } /** - * Called only once when Kamailio is shuting down to clean up module + * Called only once when Kamailio is shutting down to clean up module * resources. */ static void mod_destroy() @@ -346,7 +346,7 @@ static void rms_dialog_manage_loop() * The rank will be o for the main process calling this function, * or 1 through n for each listener process. The rank can have a negative * value if it is a special process calling the child init function. - * Other then the listeners, the rank will equal one of these values: + * Other than the listeners, the rank will equal one of these values: * PROC_MAIN 0 Main ser process * PROC_TIMER -1 Timer attendant process * PROC_FIFO -2 FIFO attendant process @@ -408,12 +408,27 @@ static int rms_sip_reply( return 1; } +static str _rms_default_user = str_init("rms"); +static void rms_link_user(str *suri, str *suser) +{ + sip_uri_t puri; + if(parse_uri(suri->s, suri->len, &puri) < 0 || puri.user.s == NULL + || puri.user.len <= 0) { + suser->s = _rms_default_user.s; + suser->len = _rms_default_user.len; + return; + } + suser->s = puri.user.s; + suser->len = puri.user.len; +} + static int rms_answer_call( struct cell *cell, rms_dialog_info_t *di, rms_sdp_info_t *sdp_info) { - char buffer[128]; + char buffer[256]; str reason = str_init("OK"); str contact_hdr; + str luser; if(di->state == RMS_ST_CONNECTED) { return 1; } @@ -428,9 +443,10 @@ static int rms_answer_call( sdp_info->local_ip.s = di->local_ip.s; sdp_info->local_ip.len = di->local_ip.len; - snprintf(buffer, 128, - "Contact: \r\nContent-Type: application/sdp\r\n", - di->local_ip.s, di->local_port); + rms_link_user(&di->local_uri, &luser); + snprintf(buffer, 256, + "Contact: \r\nContent-Type: application/sdp\r\n", + luser.len, luser.s, di->local_ip.s, di->local_port); contact_hdr.len = strlen(buffer); contact_hdr.s = buffer; @@ -592,6 +608,7 @@ static int rms_bridging_call(rms_dialog_info_t *di, rms_action_t *a) int result; str method_invite = str_init("INVITE"); str headers; + str luser; struct sip_uri ruri_t; str *param_uri = &a->param; @@ -609,10 +626,11 @@ static int rms_bridging_call(rms_dialog_info_t *di, rms_action_t *a) goto error; } + rms_link_user(&di->local_uri, &luser); snprintf(buff, 256, "Max-Forwards: 70\r\nContact: " - "\r\nContent-Type: application/sdp\r\n", - di->local_ip.s, di->local_port); + "\r\nContent-Type: application/sdp\r\n", + luser.len, luser.s, di->local_ip.s, di->local_port); headers.len = strlen(buff); headers.s = buff; LM_INFO("si[%p]call-id[%.*s]cseq[%d]ruri[%d|%s]remote_uri[%s]local_uri[%s]" @@ -997,6 +1015,7 @@ static int rms_sip_forward( int result; str headers; char buff[1024]; + str luser; if(!rms_create_trans(msg)) return 0; @@ -1020,10 +1039,11 @@ static int rms_sip_forward( return 0; } + rms_link_user(&di->local_uri, &luser); snprintf(buff, 256, "Max-Forwards: 70\r\nContact: " - "\r\nContent-Type: application/sdp\r\n", - di->local_ip.s, di->local_port); + "\r\nContent-Type: application/sdp\r\n", + luser.len, luser.s, di->local_ip.s, di->local_port); headers.len = strlen(buff); headers.s = buff; @@ -1096,7 +1116,7 @@ static int rms_sip_request_f(struct sip_msg *msg) if(di->bridged_di) { // bridged LM_NOTICE("BYE in brigde mode\n"); rms_sip_forward(di, msg, method); - } else { // connected localy + } else { // connected locally LM_NOTICE("BYE in local mode\n"); rms_disconnect(msg); return 1; diff --git a/src/modules/rtpengine/README b/src/modules/rtpengine/README index de4e15310..da6751c42 100644 --- a/src/modules/rtpengine/README +++ b/src/modules/rtpengine/README @@ -26,6 +26,8 @@ Richard Fuchs Sipwise GmbH +Joey Golan + Copyright © 2003-2008 Sippy Software, Inc. Copyright © 2005 Voice Sistem SRL @@ -126,9 +128,15 @@ Richard Fuchs 4.74. mos_average_roundtrip_B_pv (string) 4.75. mos_average_roundtrip_leg_B_pv (string) 4.76. mos_average_samples_B_pv (string) - 4.77. control_cmd_tos (integer) - 4.78. hash_algo (integer) - 4.79. wsapi (string) + 4.77. dtmf_event_callid (string) + 4.78. dtmf_event_source_tag (string) + 4.79. dtmf_event_timestamp (string) + 4.80. dtmf_event (string) + 4.81. control_cmd_tos (integer) + 4.82. hash_algo (integer) + 4.83. wsapi (string) + 4.84. dtmf_events_sock (string) + 4.85. ping_mode (integer) 5. Functions @@ -167,6 +175,10 @@ Richard Fuchs 7.4. rtpengine.ping proxy_url/all 7.5. rtpengine.get_hash_total + 8. Event routes + + 8.1. rtpengine:dtmf-event + 2. Frequently Asked Questions List of Examples @@ -248,37 +260,43 @@ Richard Fuchs 1.75. Set mos_average_roundtrip_B_pv parameter 1.76. Set mos_average_roundtrip_leg_B_pv parameter 1.77. Set mos_average_samples_B_pv parameter - 1.78. Set control_cmd_tos parameter - 1.79. Set hash_algo parameter - 1.80. Set wsapi parameter - 1.81. set_rtpengine_set usage - 1.82. rtpengine_offer usage - 1.83. rtpengine_offer usage to force transcoding from opus to PCMU - 1.84. rtpengine_answer usage - 1.85. rtpengine_info usage - 1.86. rtpengine_delete usage - 1.87. rtpengine_query usage - 1.88. rtpengine_query_v usage - 1.89. rtpengine_manage usage - 1.90. start_recording usage - 1.91. stop_recording usage - 1.92. block_dtmf usage - 1.93. unblock_dtmf usage - 1.94. block_media usage - 1.95. unblock_media usage - 1.96. silence_media usage - 1.97. unsilence_media usage - 1.98. start_forwarding usage - 1.99. stop_forwarding usage - 1.100. play_media usage - 1.101. stop_media usage - 1.102. play_dtmf usage - 1.103. $rtpestat Usage - 1.104. rtpengine.reload usage - 1.105. rtpengine.enable usage - 1.106. rtpengine.show usage - 1.107. rtpengine.ping usage - 1.108. rtpengine.get_hash_total usage + 1.78. Set dtmf_event_callid parameter + 1.79. Set dtmf_event_source_tag parameter + 1.80. Set dtmf_event_timestamp parameter + 1.81. Set dtmf_event parameter + 1.82. Set control_cmd_tos parameter + 1.83. Set hash_algo parameter + 1.84. Set wsapi parameter + 1.85. Set dtmf_events_sock parameter + 1.86. Set ping_mode parameter + 1.87. set_rtpengine_set usage + 1.88. rtpengine_offer usage + 1.89. rtpengine_offer usage to force transcoding from opus to PCMU + 1.90. rtpengine_answer usage + 1.91. rtpengine_info usage + 1.92. rtpengine_delete usage + 1.93. rtpengine_query usage + 1.94. rtpengine_query_v usage + 1.95. rtpengine_manage usage + 1.96. start_recording usage + 1.97. stop_recording usage + 1.98. block_dtmf usage + 1.99. unblock_dtmf usage + 1.100. block_media usage + 1.101. unblock_media usage + 1.102. silence_media usage + 1.103. unsilence_media usage + 1.104. start_forwarding usage + 1.105. stop_forwarding usage + 1.106. play_media usage + 1.107. stop_media usage + 1.108. play_dtmf usage + 1.109. $rtpestat Usage + 1.110. rtpengine.reload usage + 1.111. rtpengine.enable usage + 1.112. rtpengine.show usage + 1.113. rtpengine.ping usage + 1.114. rtpengine.get_hash_total usage Chapter 1. Admin Guide @@ -369,9 +387,15 @@ Chapter 1. Admin Guide 4.74. mos_average_roundtrip_B_pv (string) 4.75. mos_average_roundtrip_leg_B_pv (string) 4.76. mos_average_samples_B_pv (string) - 4.77. control_cmd_tos (integer) - 4.78. hash_algo (integer) - 4.79. wsapi (string) + 4.77. dtmf_event_callid (string) + 4.78. dtmf_event_source_tag (string) + 4.79. dtmf_event_timestamp (string) + 4.80. dtmf_event (string) + 4.81. control_cmd_tos (integer) + 4.82. hash_algo (integer) + 4.83. wsapi (string) + 4.84. dtmf_events_sock (string) + 4.85. ping_mode (integer) 5. Functions @@ -410,6 +434,10 @@ Chapter 1. Admin Guide 7.4. rtpengine.ping proxy_url/all 7.5. rtpengine.get_hash_total + 8. Event routes + + 8.1. rtpengine:dtmf-event + 1. Overview This is a module that enables media streams to be proxied via an RTP @@ -438,8 +466,8 @@ Chapter 1. Admin Guide would specify the weight 2 for this server, for example. The selection of the set is done from script prior using - rtpengine_delete(), rtpengine_offer() or rtpengine_answer() functions - - see the set_rtpengine_set() function. + rtpengine_delete(), rtpengine_offer(), rtpengine_answer() or + rtpengine_manage() functions - see the set_rtpengine_set() function. Another way to select the set is to define setid_avp module parameter and assign setid to the defined avp before calling rtpengine_offer() or @@ -576,9 +604,15 @@ Chapter 1. Admin Guide 4.74. mos_average_roundtrip_B_pv (string) 4.75. mos_average_roundtrip_leg_B_pv (string) 4.76. mos_average_samples_B_pv (string) - 4.77. control_cmd_tos (integer) - 4.78. hash_algo (integer) - 4.79. wsapi (string) + 4.77. dtmf_event_callid (string) + 4.78. dtmf_event_source_tag (string) + 4.79. dtmf_event_timestamp (string) + 4.80. dtmf_event (string) + 4.81. control_cmd_tos (integer) + 4.82. hash_algo (integer) + 4.83. wsapi (string) + 4.84. dtmf_events_sock (string) + 4.85. ping_mode (integer) 4.1. rtpengine_sock (string) @@ -1970,7 +2004,55 @@ rip_leg_B)") modparam("rtpengine", "mos_average_samples_B_pv", "$avp(mos_average_samples_B)") ... -4.77. control_cmd_tos (integer) +4.77. dtmf_event_callid (string) + + The name of a pseudovariable to be filled in with the callid of the + triggered dtmf event. + + By default, this parameter is not set. + + Example 1.78. Set dtmf_event_callid parameter +... +modparam("rtpengine", "dtmf_event_callid", "$avp(dtmf_event_callid)") +... + +4.78. dtmf_event_source_tag (string) + + The name of a pseudovariable to be filled in with the source tag that + triggered the dtmf event. + + By default, this parameter is not set. + + Example 1.79. Set dtmf_event_source_tag parameter +... +modparam("rtpengine", "dtmf_event_source_tag", "$avp(dtmf_event_source_tag)") +... + +4.79. dtmf_event_timestamp (string) + + The name of a pseudovariable to be filled in with the timestamp when + the dtmf event was triggered. + + By default, this parameter is not set. + + Example 1.80. Set dtmf_event_timestamp parameter +... +modparam("rtpengine", "dtmf_event_timestamp", "$avp(dtmf_event_timestamp)") +... + +4.80. dtmf_event (string) + + The name of a pseudovariable to be filled in with the triggered DTMF + value. + + By default, this parameter is not set. + + Example 1.81. Set dtmf_event parameter +... +modparam("rtpengine", "dtmf_event", "$avp(dtmf_event)") +... + +4.81. control_cmd_tos (integer) The parameter is used to set the value of “type of service (tos)” for the control commands (such as rtpengine_offer(), rtpengine_answer() @@ -1980,12 +2062,12 @@ modparam("rtpengine", "mos_average_samples_B_pv", "$avp(mos_average_samples_B)") The values not falling into the range “0-255” will be simply ignored. - Example 1.78. Set control_cmd_tos parameter + Example 1.82. Set control_cmd_tos parameter ... modparam("rtpengine", "control_cmd_tos", 144) ... -4.78. hash_algo (integer) +4.82. hash_algo (integer) Hashing algorithm to be used in node selection algorithm. Now there are 3 possibilities: legacy algorithm - 0 (very basic hash over callid), @@ -1996,7 +2078,7 @@ modparam("rtpengine", "control_cmd_tos", 144) The values not falling into the range “0-2” are ignored. - Example 1.79. Set hash_algo parameter + Example 1.83. Set hash_algo parameter ... ### use SHA1 instead of legacy algorithm modparam("rtpengine", "hash_algo", 1) @@ -2005,17 +2087,45 @@ modparam("rtpengine", "hash_algo", 1) modparam("rtpengine", "hash_algo", 2) ... -4.79. wsapi (string) +4.83. wsapi (string) Configure a backend API for websocket usage. Currently the only supported setting is “lwsc” (libwebsockets). If unset, then the websocket protocol cannot be used. - Example 1.80. Set wsapi parameter + Example 1.84. Set wsapi parameter ... modparam("rtpengine", "wsapi", "lwsc") ... +4.84. dtmf_events_sock (string) + + Definition of IPv4/IPv6 UDP socket used to receive dtmf events from + RTPEngine. + + DTMF events coming from RTPEngine will trigger rtpengine:dtmf-event + route. + + Default value is “NONE” (disabled). + + Example 1.85. Set dtmf_events_sock parameter +... +modparam("rtpengine", "dtmf_events_sock", "127.0.0.1:2223") +... + +4.85. ping_mode (integer) + + Specify if the RTPEngine instances have to be pinged at startup to + detect if they are active. Set it to 0 to disable pinging and to 1 to + activate pinging. + + Default value is “1”. + + Example 1.86. Set ping_mode parameter +... +modparam("rtpengine", "ping_mode", 0) +... + 5. Functions 5.1. set_rtpengine_set(setid[, setid]) @@ -2057,12 +2167,11 @@ modparam("rtpengine", "wsapi", "lwsc") sends it back to the module to be placed back into the SIP message. This is useful if you have a set of RTP proxies that the caller must use, and another distinct set of RTP proxies that the callee must use. - This is supported by all rtpengine commands except rtpengine_manage(). This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE. - Example 1.81. set_rtpengine_set usage + Example 1.87. set_rtpengine_set usage ... set_rtpengine_set("2"); rtpengine_offer(); @@ -2327,6 +2436,9 @@ rtpengine_offer(); still be accepted towards the original offerer and then used for transcoding. It is a more selective version of what the `always transcode` flag does. + + codec-consume=... - Identical to mask but enables the + transcoding engine even if no other transcoding related + options are given. + T.38=decode - If the offered SDP contains a media section advertising T.38 over UDPTL, translate it to a regular audio media section over RTP. By default, PCMU and PCMA will be used @@ -2344,7 +2456,7 @@ rtpengine_offer(); This function can be used from ANY_ROUTE. - Example 1.82. rtpengine_offer usage + Example 1.88. rtpengine_offer usage route { ... if (is_method("INVITE")) { @@ -2384,7 +2496,7 @@ ranscode=PCMA")) ... - Example 1.83. rtpengine_offer usage to force transcoding from opus to + Example 1.89. rtpengine_offer usage to force transcoding from opus to PCMU route { ... @@ -2419,7 +2531,7 @@ onreply_route[1] This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE. - Example 1.84. rtpengine_answer usage + Example 1.90. rtpengine_answer usage See rtpengine_offer() function example above for example. @@ -2437,7 +2549,7 @@ onreply_route[1] This function can be used from ANY_ROUTE. - Example 1.85. rtpengine_info usage + Example 1.91. rtpengine_info usage ... rtpengine_info(); ... @@ -2452,7 +2564,7 @@ rtpengine_info(); This function can be used from ANY_ROUTE. - Example 1.86. rtpengine_delete usage + Example 1.92. rtpengine_delete usage ... rtpengine_delete(); ... @@ -2468,7 +2580,7 @@ rtpengine_delete(); This function can be used from ANY_ROUTE. - Example 1.87. rtpengine_query usage + Example 1.93. rtpengine_query usage ... rtpengine_query(); ... @@ -2486,7 +2598,7 @@ rtpengine_query(); This function can be used from ANY_ROUTE. - Example 1.88. rtpengine_query_v usage + Example 1.94. rtpengine_query_v usage ... if(rtpengine_query_v("j", "$var(rdata)")) { xinfo("rtpengine query response: $var(rdata)\n"); @@ -2524,7 +2636,7 @@ if(rtpengine_query_v("j", "$var(rdata)")) { This function can be used from ANY_ROUTE. - Example 1.89. rtpengine_manage usage + Example 1.95. rtpengine_manage usage ... rtpengine_manage(); ... @@ -2543,7 +2655,7 @@ rtpengine_manage(); This function can be used from REQUEST_ROUTE and ONREPLY_ROUTE. - Example 1.90. start_recording usage + Example 1.96. start_recording usage ... start_recording(); ... @@ -2562,7 +2674,7 @@ start_recording(); This function can be used from REQUEST_ROUTE and ONREPLY_ROUTE. - Example 1.91. stop_recording usage + Example 1.97. stop_recording usage ... stop_recording(); ... @@ -2586,7 +2698,7 @@ stop_recording(); This function can be used from REQUEST_ROUTE and ONREPLY_ROUTE. - Example 1.92. block_dtmf usage + Example 1.98. block_dtmf usage ... block_dtmf(); block_dtmf("directional"); @@ -2602,7 +2714,7 @@ block_dtmf("address=192.168.42.42"); unblocking DTMF events for the entire call (i.e. no flags given) will not remove these blocks. The flag “all” can be used to achieve this. - Example 1.93. unblock_dtmf usage + Example 1.99. unblock_dtmf usage ... unblock_dtmf(); unblock_dtmf("all"); @@ -2616,7 +2728,7 @@ unblock_dtmf("all"); See “block_dtmf” for a description of the flags that can be used. - Example 1.94. block_media usage + Example 1.100. block_media usage ... block_media(); block_media("directional"); @@ -2630,7 +2742,7 @@ block_media("address=192.168.42.42"); See “unblock_dtmf” for a description of the flags that can be used. - Example 1.95. unblock_media usage + Example 1.101. unblock_media usage ... unblock_media(); unblock_media("all"); @@ -2645,7 +2757,7 @@ unblock_media("all"); See “block_dtmf” for a description of the flags that can be used. - Example 1.96. silence_media usage + Example 1.102. silence_media usage ... silence_media(); silence_media("directional"); @@ -2659,7 +2771,7 @@ silence_media("address=192.168.42.42"); See “unblock_dtmf” for a description of the flags that can be used. - Example 1.97. unsilence_media usage + Example 1.103. unsilence_media usage ... unsilence_media(); unsilence_media("all"); @@ -2674,7 +2786,7 @@ unsilence_media("all"); See “block_dtmf” for a description of the flags that can be used. - Example 1.98. start_forwarding usage + Example 1.104. start_forwarding usage ... start_forwarding(); start_forwarding("directional"); @@ -2688,7 +2800,7 @@ start_forwarding("address=192.168.42.42"); See “unblock_dtmf” for a description of the flags that can be used. - Example 1.99. stop_forwarding usage + Example 1.105. stop_forwarding usage ... stop_forwarding(); stop_forwarding("all"); @@ -2707,7 +2819,7 @@ stop_forwarding("all"); the duration of the media being played, expressed in milliseconds. If the length of the media could not be determined, it's set to -1. - Example 1.100. play_media usage + Example 1.106. play_media usage ... play_media("file=/use/share/media/hello.wav"); play_media("from-tag=tfugklbildfydrtuykgfv db-id=12345"); @@ -2719,7 +2831,7 @@ play_media("from-tag=tfugklbildfydrtuykgfv db-id=12345"); playback is automatically stopped when the end of the media file is reached, so this function is only useful to prematurely stop playback. - Example 1.101. stop_media usage + Example 1.107. stop_media usage ... stop_media(); stop_media("from-tag=5yqaeriguhxcikxj"); @@ -2750,7 +2862,7 @@ stop_media("from-tag=5yqaeriguhxcikxj"); alternative pause length can be given through the “pause” option, between 100 and 5000 ms. - Example 1.102. play_dtmf usage + Example 1.108. play_dtmf usage ... play_dtmf("from-tag=5yqaeriguhxcikxj code=#"); play_dtmf("code=1 volume=5 duration=300 pause=150"); @@ -2768,7 +2880,7 @@ play_dtmf("code=1 volume=5 duration=300 pause=150"); packet counters. The statistics must be retrieved before the session is deleted (before rtpengine_delete()). - Example 1.103. $rtpestat Usage + Example 1.109. $rtpestat Usage ... append_hf("X-RTP-Statistics: $rtpestat\r\n"); ... @@ -2800,7 +2912,7 @@ ackets, 0 errors The execution of this command is limited to 10 seconds intervals. - Example 1.104. rtpengine.reload usage + Example 1.110. rtpengine.reload usage ... $ kamcmd rtpengine.reload ... @@ -2831,7 +2943,7 @@ $ kamcmd rtpengine.reload NOTE: If you specify an IPv6 RTP, the proxy url must be prefixed with :: to escape the :: from the IPv6 address. See the example below. - Example 1.105. rtpengine.enable usage + Example 1.111. rtpengine.enable usage ... $ kamcmd rtpengine.enable udp:192.168.2.133:8081 0 $ kamcmd rtpengine.enable ::udp6:fe80::9a90:96ff:fea8:fd99:9999 1 @@ -2854,7 +2966,7 @@ $ kamcmd rtpengine.enable all 1 NOTE: When specify the IPv6 RTP proxy url one must prefix it with :: to escape the :: from the IPv6 address. See the example below. - Example 1.106. rtpengine.show usage + Example 1.112. rtpengine.show usage ... $ kamcmd rtpengine.show udp:192.168.2.133:8081 $ kamcmd rtpengine.show ::udp6:fe80::9a90:96ff:fea8:fd99:9999 @@ -2874,7 +2986,7 @@ $ kamcmd rtpengine.show all NOTE: When specify the IPv6 RTP proxy url one must prefix it with :: to escape the :: from the IPv6 address. See the example below. - Example 1.107. rtpengine.ping usage + Example 1.113. rtpengine.ping usage ... $ kamcmd rtpengine.ping udp:192.168.2.133:8081 $ kamcmd rtpengine.ping ::udp6:fe80::9a90:96ff:fea8:fd99:9999 @@ -2886,11 +2998,28 @@ $ kamcmd rtpengine.ping all Print the total number of hash entries in the hash table at a given moment. - Example 1.108. rtpengine.get_hash_total usage + Example 1.114. rtpengine.get_hash_total usage ... $ kamcmd rtpengine.get_hash_total ... +8. Event routes + + 8.1. rtpengine:dtmf-event + +8.1. rtpengine:dtmf-event + + When defined, the module calls event_route[rtpengine:dtmf-event] when a + DTMF is received. +... +event_route[rtpengine:dtmf-event] { + xlog("L_INFO", "callid: $avp(dtmf_event_callid)\n"); + xlog("L_INFO", "source_tag: $avp(dtmf_event_source_tag)\n"); + xlog("L_INFO", "timestamp: $avp(dtmf_event_timestamp)\n"); + xlog("L_INFO", "dtmf: $avp(dtmf_event)\n"); +} +... + Chapter 2. Frequently Asked Questions 2.1. How do I migrate from “rtpproxy” or “rtpproxy-ng” to “rtpengine”? @@ -2937,9 +3066,11 @@ nnection ICE=force RTP/SAVPF"); First at all check if your question was already answered on one of our mailing lists: * User Mailing List - - https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users + https://lists.kamailio.org/mailman3/postorius/lists/sr-users.lists. + kamailio.org/ * Developer Mailing List - - https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-dev + https://lists.kamailio.org/mailman3/postorius/lists/sr-dev.lists.ka + mailio.org/ E-mails regarding any stable Kamailio release should be sent to and e-mails regarding development diff --git a/src/modules/rtpengine/bencode.h b/src/modules/rtpengine/bencode.h index 8f3b434e7..1a3562d9d 100644 --- a/src/modules/rtpengine/bencode.h +++ b/src/modules/rtpengine/bencode.h @@ -47,7 +47,7 @@ struct bencode_buffer { struct __bencode_buffer_piece *pieces; struct __bencode_free_list *free_list; - int error : 1; /* set to !0 if allocation failed at any point */ + unsigned int error : 1; /* set to !0 if allocation failed at any point */ }; diff --git a/src/modules/rtpengine/doc/rtpengine.xml b/src/modules/rtpengine/doc/rtpengine.xml index 5a6975cb7..9bbc79fa8 100644 --- a/src/modules/rtpengine/doc/rtpengine.xml +++ b/src/modules/rtpengine/doc/rtpengine.xml @@ -73,6 +73,13 @@ rfuchs@sipwise.com + + Joey + Golan +
+ joeygo@gmail.com +
+
2003-2008 diff --git a/src/modules/rtpengine/doc/rtpengine_admin.xml b/src/modules/rtpengine/doc/rtpengine_admin.xml index 1c7843c66..adb3af92b 100644 --- a/src/modules/rtpengine/doc/rtpengine_admin.xml +++ b/src/modules/rtpengine/doc/rtpengine_admin.xml @@ -52,8 +52,8 @@
The selection of the set is done from script prior using - rtpengine_delete(), rtpengine_offer() or rtpengine_answer() - functions - see the set_rtpengine_set() function. + rtpengine_delete(), rtpengine_offer(), rtpengine_answer() or + rtpengine_manage() functions - see the set_rtpengine_set() function. Another way to select the set is to define setid_avp @@ -2188,6 +2188,78 @@ modparam("rtpengine", "mos_average_samples_B_pv", "$avp(mos_average_samples_B)")
+
+ <varname>dtmf_event_callid</varname> (string) + + The name of a pseudovariable to be filled in with the callid of the triggered dtmf event. + + + By default, this parameter is not set. + + + Set <varname>dtmf_event_callid</varname> parameter + +... +modparam("rtpengine", "dtmf_event_callid", "$avp(dtmf_event_callid)") +... + + +
+ +
+ <varname>dtmf_event_source_tag</varname> (string) + + The name of a pseudovariable to be filled in with the source tag that triggered the dtmf event. + + + By default, this parameter is not set. + + + Set <varname>dtmf_event_source_tag</varname> parameter + +... +modparam("rtpengine", "dtmf_event_source_tag", "$avp(dtmf_event_source_tag)") +... + + +
+ +
+ <varname>dtmf_event_timestamp</varname> (string) + + The name of a pseudovariable to be filled in with the timestamp when the dtmf event was triggered. + + + By default, this parameter is not set. + + + Set <varname>dtmf_event_timestamp</varname> parameter + +... +modparam("rtpengine", "dtmf_event_timestamp", "$avp(dtmf_event_timestamp)") +... + + +
+ +
+ <varname>dtmf_event</varname> (string) + + The name of a pseudovariable to be filled in with the triggered DTMF value. + + + By default, this parameter is not set. + + + Set <varname>dtmf_event</varname> parameter + +... +modparam("rtpengine", "dtmf_event", "$avp(dtmf_event)") +... + + +
+
<varname>control_cmd_tos</varname> (integer) @@ -2253,7 +2325,50 @@ modparam("rtpengine", "wsapi", "lwsc")
+
+ <varname>dtmf_events_sock</varname> (string) + + Definition of IPv4/IPv6 UDP socket used to receive dtmf events from RTPEngine. + + + DTMF events coming from RTPEngine will trigger rtpengine:dtmf-event route. + + + + Default value is NONE (disabled). + + + + Set <varname>dtmf_events_sock</varname> parameter + +... +modparam("rtpengine", "dtmf_events_sock", "127.0.0.1:2223") +... + + +
+
+ <varname>ping_mode</varname> (integer) + + Specify if the RTPEngine instances have to be pinged at startup to + detect if they are active. Set it to 0 to disable pinging and to 1 + to activate pinging. + + + + Default value is 1. + + + + Set <varname>ping_mode</varname> parameter + +... +modparam("rtpengine", "ping_mode", 0) +... + + +
@@ -2281,8 +2396,7 @@ modparam("rtpengine", "wsapi", "lwsc") another time and sends it back to the module to be placed back into the &sip; message. This is useful if you have a set of &rtp; proxies that the caller must use, and another distinct set of &rtp; proxies that the - callee must use. This is supported by all rtpengine commands except - rtpengine_manage(). + callee must use.
This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, @@ -2654,6 +2768,11 @@ rtpengine_offer(); version of what the `always transcode` flag does.
+ + codec-consume=... - Identical to mask but enables the transcoding engine even if no other transcoding + related options are given. + + T.38=decode - If the offered &sdp; contains a media section advertising T.38 over UDPTL, translate it to a regular audio media section @@ -3485,4 +3604,26 @@ $ &kamcmd; rtpengine.get_hash_total
+
+ Event routes +
+ + <function moreinfo="none">rtpengine:dtmf-event</function> + + + When defined, the module calls event_route[rtpengine:dtmf-event] + when a DTMF is received. + + +... +event_route[rtpengine:dtmf-event] { + xlog("L_INFO", "callid: $avp(dtmf_event_callid)\n"); + xlog("L_INFO", "source_tag: $avp(dtmf_event_source_tag)\n"); + xlog("L_INFO", "timestamp: $avp(dtmf_event_timestamp)\n"); + xlog("L_INFO", "dtmf: $avp(dtmf_event)\n"); +} +... + +
+
diff --git a/src/modules/rtpengine/rtpengine.c b/src/modules/rtpengine/rtpengine.c index 442df8ddd..c0727ed4e 100644 --- a/src/modules/rtpengine/rtpengine.c +++ b/src/modules/rtpengine/rtpengine.c @@ -53,6 +53,7 @@ #include "../../core/data_lump.h" #include "../../core/data_lump_rpl.h" #include "../../core/error.h" +#include "../../core/fmsg.h" #include "../../core/forward.h" #include "../../core/mem/mem.h" #include "../../core/parser/parse_from.h" @@ -79,6 +80,7 @@ #include "../../core/kemi.h" #include "../../core/char_msg_val.h" #include "../../core/utils/srjson.h" +#include "../../core/cfg/cfg_struct.h" #include "../../modules/tm/tm_load.h" #include "../../modules/crypto/api.h" #include "../../modules/lwsc/api.h" @@ -109,8 +111,10 @@ MODULE_VERSION #define DEFAULT_RTPP_SET_ID 0 -enum -{ +#define RTPENGINE_DTMF_EVENT_BUFFER 32768 + +/* clang-format off */ +enum { RPC_FOUND_ALL = 2, RPC_FOUND_ONE = 1, RPC_FOUND_NONE = 0, @@ -118,38 +122,37 @@ enum #define CPORT "22222" -struct ng_flags_parse -{ +struct ng_flags_parse { int via, to, packetize, transport, directional; bencode_item_t *dict, *flags, *direction, *replace, *rtcp_mux, *sdes, *t38, *received_from, *codec, *codec_strip, *codec_offer, - *codec_transcode, *codec_mask, *codec_set, *codec_except; + *codec_transcode, *codec_mask, *codec_set, *codec_except, *codec_accept, + *codec_consume; str call_id, from_tag, to_tag; }; static const char *command_strings[] = { - [OP_OFFER] = "offer", - [OP_ANSWER] = "answer", - [OP_DELETE] = "delete", - [OP_START_RECORDING] = "start recording", - [OP_QUERY] = "query", - [OP_PING] = "ping", - [OP_STOP_RECORDING] = "stop recording", - [OP_BLOCK_DTMF] = "block DTMF", - [OP_UNBLOCK_DTMF] = "unblock DTMF", - [OP_BLOCK_MEDIA] = "block media", - [OP_UNBLOCK_MEDIA] = "unblock media", - [OP_SILENCE_MEDIA] = "silence media", - [OP_UNSILENCE_MEDIA] = "unsilence media", - [OP_START_FORWARDING] = "start forwarding", - [OP_STOP_FORWARDING] = "stop forwarding", - [OP_PLAY_MEDIA] = "play media", - [OP_STOP_MEDIA] = "stop media", - [OP_PLAY_DTMF] = "play DTMF", + [OP_OFFER] = "offer", + [OP_ANSWER] = "answer", + [OP_DELETE] = "delete", + [OP_START_RECORDING] = "start recording", + [OP_QUERY] = "query", + [OP_PING] = "ping", + [OP_STOP_RECORDING] = "stop recording", + [OP_BLOCK_DTMF] = "block DTMF", + [OP_UNBLOCK_DTMF] = "unblock DTMF", + [OP_BLOCK_MEDIA] = "block media", + [OP_UNBLOCK_MEDIA] = "unblock media", + [OP_SILENCE_MEDIA] = "silence media", + [OP_UNSILENCE_MEDIA] = "unsilence media", + [OP_START_FORWARDING] = "start forwarding", + [OP_STOP_FORWARDING] = "stop forwarding", + [OP_PLAY_MEDIA] = "play media", + [OP_STOP_MEDIA] = "stop media", + [OP_PLAY_DTMF] = "play DTMF", }; -struct minmax_mos_stats -{ +struct minmax_mos_stats { str mos_param; str at_param; str packetloss_param; @@ -166,8 +169,7 @@ struct minmax_mos_stats pv_elem_t *roundtrip_leg_pv; pv_elem_t *samples_pv; }; -struct minmax_mos_label_stats -{ +struct minmax_mos_label_stats { int got_any_pvs; str label_param; @@ -175,25 +177,25 @@ struct minmax_mos_label_stats struct minmax_mos_stats min, max, average; }; -struct minmax_stats_vals -{ - long long mos; - long long at; - long long packetloss; - long long jitter; - long long roundtrip; - long long roundtrip_leg; - long long samples; - long long avg_samples; /* our own running count to average the averages */ +struct minmax_stats_vals { + long long int mos; + long long int at; + long long int packetloss; + long long int jitter; + long long int roundtrip; + long long int roundtrip_leg; + long long int samples; + long long int + avg_samples; /* our own running count to average the averages */ }; #define RTPE_LIST_VERSION_DELAY 10 -typedef struct rtpe_list_version -{ +typedef struct rtpe_list_version { int vernum; time_t vertime; } rtpe_list_version_t; +/* clang-format on */ static rtpe_list_version_t *_rtpe_list_version = NULL; static int _rtpe_list_vernum_local = 0; @@ -244,6 +246,7 @@ static char *send_rtpp_command(struct rtpp_node *, bencode_item_t *, int *); static int get_extra_id(struct sip_msg *msg, str *id_str); static int rtpengine_set_store(modparam_t type, void *val); +static int rtpengine_set_dtmf_events_sock(modparam_t type, void *val); static int rtpengine_add_rtpengine_set(char *rtp_proxies, unsigned int weight, int disabled, unsigned int ticks); @@ -259,6 +262,9 @@ static int add_rtpp_node_info( void *ptrs, struct rtpp_node *crt_rtpp, struct rtpp_set *rtpp_list); static int rtpp_test_ping(struct rtpp_node *node); +static void rtpengine_dtmf_events_loop(void); +static int rtpengine_raise_dtmf_event(char *buffer, int len); + /* Pseudo-Variables */ static int pv_get_rtpestat_f(struct sip_msg *, pv_param_t *, pv_value_t *); static int set_rtp_inst_pvar(struct sip_msg *msg, const str *const uri); @@ -311,6 +317,18 @@ static pv_spec_t *read_sdp_pvar = NULL; static str media_duration_pvar_str = {NULL, 0}; static pv_spec_t *media_duration_pvar = NULL; +static str dtmf_event_callid_pvar_str = {NULL, 0}; +static pv_spec_t *dtmf_event_callid_pvar = NULL; + +static str dtmf_event_source_tag_pvar_str = {NULL, 0}; +static pv_spec_t *dtmf_event_source_tag_pvar = NULL; + +static str dtmf_event_timestamp_pvar_str = {NULL, 0}; +static pv_spec_t *dtmf_event_timestamp_pvar = NULL; + +static str dtmf_event_pvar_str = {NULL, 0}; +static pv_spec_t *dtmf_event_pvar = NULL; + #define RTPENGINE_SESS_LIMIT_MSG "Parallel session limit reached" #define RTPENGINE_SESS_LIMIT_MSG_LEN (sizeof(RTPENGINE_SESS_LIMIT_MSG) - 1) @@ -326,11 +344,17 @@ lwsc_api_t _rtpe_lwscb = {0}; static enum hash_algo_t hash_algo = RTP_HASH_CALLID; -typedef struct rtpp_set_link -{ +static str rtpengine_dtmf_event_sock; +static int rtpengine_dtmf_event_fd; +int dtmf_event_rt = -1; /* default disabled */ +static int rtpengine_ping_mode = 1; + +/* clang-format off */ +typedef struct rtpp_set_link { struct rtpp_set *rset; pv_spec_t *rpv; } rtpp_set_link_t; +/* clang-format on */ /* tm */ static struct tm_binds tmb; @@ -344,244 +368,256 @@ int got_any_mos_pvs; struct crypto_binds rtpengine_cb; +/* clang-format off */ static cmd_export_t cmds[] = { - {"set_rtpengine_set", (cmd_function)set_rtpengine_set_f, 1, - fixup_set_id, 0, ANY_ROUTE}, - {"set_rtpengine_set", (cmd_function)set_rtpengine_set_f, 2, - fixup_set_id, 0, ANY_ROUTE}, - {"start_recording", (cmd_function)start_recording_f, 0, 0, 0, - ANY_ROUTE}, - {"start_recording", (cmd_function)start_recording_f, 1, fixup_spve_null, - 0, ANY_ROUTE}, - {"stop_recording", (cmd_function)stop_recording_f, 0, 0, 0, ANY_ROUTE}, - {"stop_recording", (cmd_function)stop_recording_f, 1, fixup_spve_null, - 0, ANY_ROUTE}, - {"block_dtmf", (cmd_function)block_dtmf_f, 0, 0, 0, ANY_ROUTE}, - {"unblock_dtmf", (cmd_function)unblock_dtmf_f, 0, 0, 0, ANY_ROUTE}, - {"block_media", (cmd_function)block_media_f, 0, 0, 0, ANY_ROUTE}, - {"unblock_media", (cmd_function)unblock_media_f, 0, 0, 0, ANY_ROUTE}, - {"silence_media", (cmd_function)silence_media_f, 0, 0, 0, ANY_ROUTE}, - {"unsilence_media", (cmd_function)unsilence_media_f, 0, 0, 0, - ANY_ROUTE}, - {"block_dtmf", (cmd_function)block_dtmf_f, 1, fixup_spve_null, 0, - ANY_ROUTE}, - {"unblock_dtmf", (cmd_function)unblock_dtmf_f, 1, fixup_spve_null, 0, - ANY_ROUTE}, - {"block_media", (cmd_function)block_media_f, 1, fixup_spve_null, 0, - ANY_ROUTE}, - {"unblock_media", (cmd_function)unblock_media_f, 1, fixup_spve_null, 0, - ANY_ROUTE}, - {"silence_media", (cmd_function)silence_media_f, 1, fixup_spve_null, 0, - ANY_ROUTE}, - {"unsilence_media", (cmd_function)unsilence_media_f, 1, fixup_spve_null, - 0, ANY_ROUTE}, - {"start_forwarding", (cmd_function)start_forwarding_f, 0, 0, 0, - ANY_ROUTE}, - {"stop_forwarding", (cmd_function)stop_forwarding_f, 0, 0, 0, - ANY_ROUTE}, - {"start_forwarding", (cmd_function)start_forwarding_f, 1, - fixup_spve_null, 0, ANY_ROUTE}, - {"stop_forwarding", (cmd_function)stop_forwarding_f, 1, fixup_spve_null, - 0, ANY_ROUTE}, - {"play_media", (cmd_function)play_media_f, 1, fixup_spve_null, 0, - ANY_ROUTE}, - {"stop_media", (cmd_function)stop_media_f, 1, fixup_spve_null, 0, - ANY_ROUTE}, - {"stop_media", (cmd_function)stop_media_f, 0, 0, 0, ANY_ROUTE}, - {"play_dtmf", (cmd_function)play_dtmf_f, 1, fixup_spve_null, 0, - ANY_ROUTE}, - {"rtpengine_offer", (cmd_function)rtpengine_offer1_f, 0, 0, 0, - ANY_ROUTE}, - {"rtpengine_offer", (cmd_function)rtpengine_offer1_f, 1, - fixup_spve_null, 0, ANY_ROUTE}, - {"rtpengine_answer", (cmd_function)rtpengine_answer1_f, 0, 0, 0, - ANY_ROUTE}, - {"rtpengine_answer", (cmd_function)rtpengine_answer1_f, 1, - fixup_spve_null, 0, ANY_ROUTE}, - {"rtpengine_info", (cmd_function)rtpengine_info1_f, 0, 0, 0, ANY_ROUTE}, - {"rtpengine_info", (cmd_function)rtpengine_info1_f, 1, fixup_spve_null, - 0, ANY_ROUTE}, - {"rtpengine_manage", (cmd_function)rtpengine_manage1_f, 0, 0, 0, - ANY_ROUTE}, - {"rtpengine_manage", (cmd_function)rtpengine_manage1_f, 1, - fixup_spve_null, 0, ANY_ROUTE}, - {"rtpengine_delete", (cmd_function)rtpengine_delete1_f, 0, 0, 0, - ANY_ROUTE}, - {"rtpengine_delete", (cmd_function)rtpengine_delete1_f, 1, - fixup_spve_null, 0, ANY_ROUTE}, - {"rtpengine_query", (cmd_function)rtpengine_query1_f, 0, 0, 0, - ANY_ROUTE}, - {"rtpengine_query", (cmd_function)rtpengine_query1_f, 1, - fixup_spve_null, 0, ANY_ROUTE}, - {"rtpengine_query_v", (cmd_function)w_rtpengine_query_v, 2, - fixup_rtpengine_query_v, fixup_free_rtpengine_query_v, - ANY_ROUTE}, - {0, 0, 0, 0, 0, 0}}; + {"set_rtpengine_set", (cmd_function)set_rtpengine_set_f, 1, + fixup_set_id, 0, ANY_ROUTE}, + {"set_rtpengine_set", (cmd_function)set_rtpengine_set_f, 2, + fixup_set_id, 0, ANY_ROUTE}, + {"start_recording", (cmd_function)start_recording_f, 0, 0, 0, + ANY_ROUTE}, + {"start_recording", (cmd_function)start_recording_f, 1, fixup_spve_null, + 0, ANY_ROUTE}, + {"stop_recording", (cmd_function)stop_recording_f, 0, 0, 0, ANY_ROUTE}, + {"stop_recording", (cmd_function)stop_recording_f, 1, fixup_spve_null, + 0, ANY_ROUTE}, + {"block_dtmf", (cmd_function)block_dtmf_f, 0, 0, 0, ANY_ROUTE}, + {"unblock_dtmf", (cmd_function)unblock_dtmf_f, 0, 0, 0, ANY_ROUTE}, + {"block_media", (cmd_function)block_media_f, 0, 0, 0, ANY_ROUTE}, + {"unblock_media", (cmd_function)unblock_media_f, 0, 0, 0, ANY_ROUTE}, + {"silence_media", (cmd_function)silence_media_f, 0, 0, 0, ANY_ROUTE}, + {"unsilence_media", (cmd_function)unsilence_media_f, 0, 0, 0, + ANY_ROUTE}, + {"block_dtmf", (cmd_function)block_dtmf_f, 1, fixup_spve_null, 0, + ANY_ROUTE}, + {"unblock_dtmf", (cmd_function)unblock_dtmf_f, 1, fixup_spve_null, 0, + ANY_ROUTE}, + {"block_media", (cmd_function)block_media_f, 1, fixup_spve_null, 0, + ANY_ROUTE}, + {"unblock_media", (cmd_function)unblock_media_f, 1, fixup_spve_null, 0, + ANY_ROUTE}, + {"silence_media", (cmd_function)silence_media_f, 1, fixup_spve_null, 0, + ANY_ROUTE}, + {"unsilence_media", (cmd_function)unsilence_media_f, 1, fixup_spve_null, + 0, ANY_ROUTE}, + {"start_forwarding", (cmd_function)start_forwarding_f, 0, 0, 0, + ANY_ROUTE}, + {"stop_forwarding", (cmd_function)stop_forwarding_f, 0, 0, 0, + ANY_ROUTE}, + {"start_forwarding", (cmd_function)start_forwarding_f, 1, + fixup_spve_null, 0, ANY_ROUTE}, + {"stop_forwarding", (cmd_function)stop_forwarding_f, 1, fixup_spve_null, + 0, ANY_ROUTE}, + {"play_media", (cmd_function)play_media_f, 1, fixup_spve_null, 0, + ANY_ROUTE}, + {"stop_media", (cmd_function)stop_media_f, 1, fixup_spve_null, 0, + ANY_ROUTE}, + {"stop_media", (cmd_function)stop_media_f, 0, 0, 0, ANY_ROUTE}, + {"play_dtmf", (cmd_function)play_dtmf_f, 1, fixup_spve_null, 0, + ANY_ROUTE}, + {"rtpengine_offer", (cmd_function)rtpengine_offer1_f, 0, 0, 0, + ANY_ROUTE}, + {"rtpengine_offer", (cmd_function)rtpengine_offer1_f, 1, + fixup_spve_null, 0, ANY_ROUTE}, + {"rtpengine_answer", (cmd_function)rtpengine_answer1_f, 0, 0, 0, + ANY_ROUTE}, + {"rtpengine_answer", (cmd_function)rtpengine_answer1_f, 1, + fixup_spve_null, 0, ANY_ROUTE}, + {"rtpengine_info", (cmd_function)rtpengine_info1_f, 0, 0, 0, ANY_ROUTE}, + {"rtpengine_info", (cmd_function)rtpengine_info1_f, 1, fixup_spve_null, + 0, ANY_ROUTE}, + {"rtpengine_manage", (cmd_function)rtpengine_manage1_f, 0, 0, 0, + ANY_ROUTE}, + {"rtpengine_manage", (cmd_function)rtpengine_manage1_f, 1, + fixup_spve_null, 0, ANY_ROUTE}, + {"rtpengine_delete", (cmd_function)rtpengine_delete1_f, 0, 0, 0, + ANY_ROUTE}, + {"rtpengine_delete", (cmd_function)rtpengine_delete1_f, 1, + fixup_spve_null, 0, ANY_ROUTE}, + {"rtpengine_query", (cmd_function)rtpengine_query1_f, 0, 0, 0, + ANY_ROUTE}, + {"rtpengine_query", (cmd_function)rtpengine_query1_f, 1, + fixup_spve_null, 0, ANY_ROUTE}, + {"rtpengine_query_v", (cmd_function)w_rtpengine_query_v, 2, + fixup_rtpengine_query_v, fixup_free_rtpengine_query_v, + ANY_ROUTE}, + {0, 0, 0, 0, 0, 0} +}; static pv_export_t mod_pvs[] = { - {{"rtpstat", (sizeof("rtpstat") - 1)}, /* RTP-Statistics */ - PVT_OTHER, pv_get_rtpestat_f, 0, 0, 0, 0, 0}, - {{"rtpestat", (sizeof("rtpestat") - 1)}, /* RTP-Statistics */ - PVT_OTHER, pv_get_rtpestat_f, 0, 0, 0, 0, 0}, - {{0, 0}, 0, 0, 0, 0, 0, 0, 0}}; + {{"rtpstat", (sizeof("rtpstat") - 1)}, /* RTP-Statistics */ + PVT_OTHER, pv_get_rtpestat_f, 0, 0, 0, 0, 0}, + {{"rtpestat", (sizeof("rtpestat") - 1)}, /* RTP-Statistics */ + PVT_OTHER, pv_get_rtpestat_f, 0, 0, 0, 0, 0}, + {{0, 0}, 0, 0, 0, 0, 0, 0, 0} +}; static param_export_t params[] = { - {"rtpengine_sock", PARAM_STRING | USE_FUNC_PARAM, - (void *)rtpengine_set_store}, - {"rtpengine_disable_tout", INT_PARAM, - &default_rtpengine_cfg.rtpengine_disable_tout}, - {"aggressive_redetection", INT_PARAM, - &default_rtpengine_cfg.aggressive_redetection}, - {"rtpengine_retr", INT_PARAM, &default_rtpengine_cfg.rtpengine_retr}, - {"queried_nodes_limit", INT_PARAM, - &default_rtpengine_cfg.queried_nodes_limit}, - {"rtpengine_tout_ms", INT_PARAM, - &default_rtpengine_cfg.rtpengine_tout_ms}, - {"rtpengine_allow_op", INT_PARAM, &rtpengine_allow_op}, - {"control_cmd_tos", INT_PARAM, &control_cmd_tos}, - {"db_url", PARAM_STR, &rtpp_db_url}, - {"table_name", PARAM_STR, &rtpp_table_name}, - {"setid_col", PARAM_STR, &rtpp_setid_col}, - {"url_col", PARAM_STR, &rtpp_url_col}, - {"weight_col", PARAM_STR, &rtpp_weight_col}, - {"disabled_col", PARAM_STR, &rtpp_disabled_col}, - {"extra_id_pv", PARAM_STR, &extra_id_pv_param}, - {"setid_avp", PARAM_STRING, &setid_avp_param}, - {"force_send_interface", PARAM_STRING, &force_send_ip_str}, - {"rtp_inst_pvar", PARAM_STR, &rtp_inst_pv_param}, - {"write_sdp_pv", PARAM_STR, &write_sdp_pvar_str}, - {"read_sdp_pv", PARAM_STR, &read_sdp_pvar_str}, - {"hash_table_tout", INT_PARAM, &hash_table_tout}, - {"hash_table_size", INT_PARAM, &hash_table_size}, - {"setid_default", INT_PARAM, &setid_default}, - {"media_duration", PARAM_STR, &media_duration_pvar_str}, - {"hash_algo", INT_PARAM, &hash_algo}, - - /* MOS stats output */ - /* global averages */ - {"mos_min_pv", PARAM_STR, &global_mos_stats.min.mos_param}, - {"mos_min_at_pv", PARAM_STR, &global_mos_stats.min.at_param}, - {"mos_min_packetloss_pv", PARAM_STR, - &global_mos_stats.min.packetloss_param}, - {"mos_min_jitter_pv", PARAM_STR, &global_mos_stats.min.jitter_param}, - {"mos_min_roundtrip_pv", PARAM_STR, - &global_mos_stats.min.roundtrip_param}, - {"mos_min_roundtrip_leg_pv", PARAM_STR, - &global_mos_stats.min.roundtrip_leg_param}, - {"mos_max_pv", PARAM_STR, &global_mos_stats.max.mos_param}, - {"mos_max_at_pv", PARAM_STR, &global_mos_stats.max.at_param}, - {"mos_max_packetloss_pv", PARAM_STR, - &global_mos_stats.max.packetloss_param}, - {"mos_max_jitter_pv", PARAM_STR, &global_mos_stats.max.jitter_param}, - {"mos_max_roundtrip_pv", PARAM_STR, - &global_mos_stats.max.roundtrip_param}, - {"mos_max_roundtrip_leg_pv", PARAM_STR, - &global_mos_stats.max.roundtrip_leg_param}, - {"mos_average_pv", PARAM_STR, &global_mos_stats.average.mos_param}, - {"mos_average_packetloss_pv", PARAM_STR, - &global_mos_stats.average.packetloss_param}, - {"mos_average_jitter_pv", PARAM_STR, - &global_mos_stats.average.jitter_param}, - {"mos_average_roundtrip_pv", PARAM_STR, - &global_mos_stats.average.roundtrip_param}, - {"mos_average_roundtrip_leg_pv", PARAM_STR, - &global_mos_stats.average.roundtrip_leg_param}, - {"mos_average_samples_pv", PARAM_STR, - &global_mos_stats.average.samples_param}, - - /* designated side A */ - {"mos_A_label_pv", PARAM_STR, &side_A_mos_stats.label_param}, - {"mos_min_A_pv", PARAM_STR, &side_A_mos_stats.min.mos_param}, - {"mos_min_at_A_pv", PARAM_STR, &side_A_mos_stats.min.at_param}, - {"mos_min_packetloss_A_pv", PARAM_STR, - &side_A_mos_stats.min.packetloss_param}, - {"mos_min_jitter_A_pv", PARAM_STR, &side_A_mos_stats.min.jitter_param}, - {"mos_min_roundtrip_A_pv", PARAM_STR, - &side_A_mos_stats.min.roundtrip_param}, - {"mos_min_roundtrip_leg_A_pv", PARAM_STR, - &side_A_mos_stats.min.roundtrip_leg_param}, - {"mos_max_A_pv", PARAM_STR, &side_A_mos_stats.max.mos_param}, - {"mos_max_at_A_pv", PARAM_STR, &side_A_mos_stats.max.at_param}, - {"mos_max_packetloss_A_pv", PARAM_STR, - &side_A_mos_stats.max.packetloss_param}, - {"mos_max_jitter_A_pv", PARAM_STR, &side_A_mos_stats.max.jitter_param}, - {"mos_max_roundtrip_A_pv", PARAM_STR, - &side_A_mos_stats.max.roundtrip_param}, - {"mos_max_roundtrip_leg_A_pv", PARAM_STR, - &side_A_mos_stats.max.roundtrip_leg_param}, - {"mos_average_A_pv", PARAM_STR, &side_A_mos_stats.average.mos_param}, - {"mos_average_packetloss_A_pv", PARAM_STR, - &side_A_mos_stats.average.packetloss_param}, - {"mos_average_jitter_A_pv", PARAM_STR, - &side_A_mos_stats.average.jitter_param}, - {"mos_average_roundtrip_A_pv", PARAM_STR, - &side_A_mos_stats.average.roundtrip_param}, - {"mos_average_roundtrip_leg_A_pv", PARAM_STR, - &side_A_mos_stats.average.roundtrip_leg_param}, - {"mos_average_samples_A_pv", PARAM_STR, - &side_A_mos_stats.average.samples_param}, - - /* designated side B */ - {"mos_B_label_pv", PARAM_STR, &side_B_mos_stats.label_param}, - {"mos_min_B_pv", PARAM_STR, &side_B_mos_stats.min.mos_param}, - {"mos_min_at_B_pv", PARAM_STR, &side_B_mos_stats.min.at_param}, - {"mos_min_packetloss_B_pv", PARAM_STR, - &side_B_mos_stats.min.packetloss_param}, - {"mos_min_jitter_B_pv", PARAM_STR, &side_B_mos_stats.min.jitter_param}, - {"mos_min_roundtrip_B_pv", PARAM_STR, - &side_B_mos_stats.min.roundtrip_param}, - {"mos_min_roundtrip_leg_B_pv", PARAM_STR, - &side_B_mos_stats.min.roundtrip_leg_param}, - {"mos_max_B_pv", PARAM_STR, &side_B_mos_stats.max.mos_param}, - {"mos_max_at_B_pv", PARAM_STR, &side_B_mos_stats.max.at_param}, - {"mos_max_packetloss_B_pv", PARAM_STR, - &side_B_mos_stats.max.packetloss_param}, - {"mos_max_jitter_B_pv", PARAM_STR, &side_B_mos_stats.max.jitter_param}, - {"mos_max_roundtrip_B_pv", PARAM_STR, - &side_B_mos_stats.max.roundtrip_param}, - {"mos_max_roundtrip_leg_B_pv", PARAM_STR, - &side_B_mos_stats.max.roundtrip_leg_param}, - {"mos_average_B_pv", PARAM_STR, &side_B_mos_stats.average.mos_param}, - {"mos_average_packetloss_B_pv", PARAM_STR, - &side_B_mos_stats.average.packetloss_param}, - {"mos_average_jitter_B_pv", PARAM_STR, - &side_B_mos_stats.average.jitter_param}, - {"mos_average_roundtrip_B_pv", PARAM_STR, - &side_B_mos_stats.average.roundtrip_param}, - {"mos_average_roundtrip_leg_B_pv", PARAM_STR, - &side_B_mos_stats.average.roundtrip_leg_param}, - {"mos_average_samples_B_pv", PARAM_STR, - &side_B_mos_stats.average.samples_param}, - - {"wsapi", PARAM_STR, &_rtpe_wsapi}, - - {0, 0, 0}}; + {"rtpengine_sock", PARAM_STRING | USE_FUNC_PARAM, + (void *)rtpengine_set_store}, + {"rtpengine_disable_tout", INT_PARAM, + &default_rtpengine_cfg.rtpengine_disable_tout}, + {"aggressive_redetection", INT_PARAM, + &default_rtpengine_cfg.aggressive_redetection}, + {"rtpengine_retr", INT_PARAM, &default_rtpengine_cfg.rtpengine_retr}, + {"queried_nodes_limit", INT_PARAM, + &default_rtpengine_cfg.queried_nodes_limit}, + {"rtpengine_tout_ms", INT_PARAM, + &default_rtpengine_cfg.rtpengine_tout_ms}, + {"rtpengine_allow_op", INT_PARAM, &rtpengine_allow_op}, + {"control_cmd_tos", INT_PARAM, &control_cmd_tos}, + {"ping_mode", PARAM_INT, &rtpengine_ping_mode}, + {"db_url", PARAM_STR, &rtpp_db_url}, + {"table_name", PARAM_STR, &rtpp_table_name}, + {"setid_col", PARAM_STR, &rtpp_setid_col}, + {"url_col", PARAM_STR, &rtpp_url_col}, + {"weight_col", PARAM_STR, &rtpp_weight_col}, + {"disabled_col", PARAM_STR, &rtpp_disabled_col}, + {"extra_id_pv", PARAM_STR, &extra_id_pv_param}, + {"setid_avp", PARAM_STRING, &setid_avp_param}, + {"force_send_interface", PARAM_STRING, &force_send_ip_str}, + {"rtp_inst_pvar", PARAM_STR, &rtp_inst_pv_param}, + {"write_sdp_pv", PARAM_STR, &write_sdp_pvar_str}, + {"read_sdp_pv", PARAM_STR, &read_sdp_pvar_str}, + {"hash_table_tout", INT_PARAM, &hash_table_tout}, + {"hash_table_size", INT_PARAM, &hash_table_size}, + {"setid_default", INT_PARAM, &setid_default}, + {"media_duration", PARAM_STR, &media_duration_pvar_str}, + {"hash_algo", INT_PARAM, &hash_algo}, + {"dtmf_events_sock", STR_PARAM | USE_FUNC_PARAM, + (void *)rtpengine_set_dtmf_events_sock}, + {"dtmf_event_callid", PARAM_STR, &dtmf_event_callid_pvar_str}, + {"dtmf_event_source_tag", PARAM_STR, &dtmf_event_source_tag_pvar_str}, + {"dtmf_event_timestamp", PARAM_STR, &dtmf_event_timestamp_pvar_str}, + {"dtmf_event", PARAM_STR, &dtmf_event_pvar_str}, + + /* MOS stats output */ + /* global averages */ + {"mos_min_pv", PARAM_STR, &global_mos_stats.min.mos_param}, + {"mos_min_at_pv", PARAM_STR, &global_mos_stats.min.at_param}, + {"mos_min_packetloss_pv", PARAM_STR, + &global_mos_stats.min.packetloss_param}, + {"mos_min_jitter_pv", PARAM_STR, &global_mos_stats.min.jitter_param}, + {"mos_min_roundtrip_pv", PARAM_STR, + &global_mos_stats.min.roundtrip_param}, + {"mos_min_roundtrip_leg_pv", PARAM_STR, + &global_mos_stats.min.roundtrip_leg_param}, + {"mos_max_pv", PARAM_STR, &global_mos_stats.max.mos_param}, + {"mos_max_at_pv", PARAM_STR, &global_mos_stats.max.at_param}, + {"mos_max_packetloss_pv", PARAM_STR, + &global_mos_stats.max.packetloss_param}, + {"mos_max_jitter_pv", PARAM_STR, &global_mos_stats.max.jitter_param}, + {"mos_max_roundtrip_pv", PARAM_STR, + &global_mos_stats.max.roundtrip_param}, + {"mos_max_roundtrip_leg_pv", PARAM_STR, + &global_mos_stats.max.roundtrip_leg_param}, + {"mos_average_pv", PARAM_STR, &global_mos_stats.average.mos_param}, + {"mos_average_packetloss_pv", PARAM_STR, + &global_mos_stats.average.packetloss_param}, + {"mos_average_jitter_pv", PARAM_STR, + &global_mos_stats.average.jitter_param}, + {"mos_average_roundtrip_pv", PARAM_STR, + &global_mos_stats.average.roundtrip_param}, + {"mos_average_roundtrip_leg_pv", PARAM_STR, + &global_mos_stats.average.roundtrip_leg_param}, + {"mos_average_samples_pv", PARAM_STR, + &global_mos_stats.average.samples_param}, + + /* designated side A */ + {"mos_A_label_pv", PARAM_STR, &side_A_mos_stats.label_param}, + {"mos_min_A_pv", PARAM_STR, &side_A_mos_stats.min.mos_param}, + {"mos_min_at_A_pv", PARAM_STR, &side_A_mos_stats.min.at_param}, + {"mos_min_packetloss_A_pv", PARAM_STR, + &side_A_mos_stats.min.packetloss_param}, + {"mos_min_jitter_A_pv", PARAM_STR, &side_A_mos_stats.min.jitter_param}, + {"mos_min_roundtrip_A_pv", PARAM_STR, + &side_A_mos_stats.min.roundtrip_param}, + {"mos_min_roundtrip_leg_A_pv", PARAM_STR, + &side_A_mos_stats.min.roundtrip_leg_param}, + {"mos_max_A_pv", PARAM_STR, &side_A_mos_stats.max.mos_param}, + {"mos_max_at_A_pv", PARAM_STR, &side_A_mos_stats.max.at_param}, + {"mos_max_packetloss_A_pv", PARAM_STR, + &side_A_mos_stats.max.packetloss_param}, + {"mos_max_jitter_A_pv", PARAM_STR, &side_A_mos_stats.max.jitter_param}, + {"mos_max_roundtrip_A_pv", PARAM_STR, + &side_A_mos_stats.max.roundtrip_param}, + {"mos_max_roundtrip_leg_A_pv", PARAM_STR, + &side_A_mos_stats.max.roundtrip_leg_param}, + {"mos_average_A_pv", PARAM_STR, &side_A_mos_stats.average.mos_param}, + {"mos_average_packetloss_A_pv", PARAM_STR, + &side_A_mos_stats.average.packetloss_param}, + {"mos_average_jitter_A_pv", PARAM_STR, + &side_A_mos_stats.average.jitter_param}, + {"mos_average_roundtrip_A_pv", PARAM_STR, + &side_A_mos_stats.average.roundtrip_param}, + {"mos_average_roundtrip_leg_A_pv", PARAM_STR, + &side_A_mos_stats.average.roundtrip_leg_param}, + {"mos_average_samples_A_pv", PARAM_STR, + &side_A_mos_stats.average.samples_param}, + + /* designated side B */ + {"mos_B_label_pv", PARAM_STR, &side_B_mos_stats.label_param}, + {"mos_min_B_pv", PARAM_STR, &side_B_mos_stats.min.mos_param}, + {"mos_min_at_B_pv", PARAM_STR, &side_B_mos_stats.min.at_param}, + {"mos_min_packetloss_B_pv", PARAM_STR, + &side_B_mos_stats.min.packetloss_param}, + {"mos_min_jitter_B_pv", PARAM_STR, &side_B_mos_stats.min.jitter_param}, + {"mos_min_roundtrip_B_pv", PARAM_STR, + &side_B_mos_stats.min.roundtrip_param}, + {"mos_min_roundtrip_leg_B_pv", PARAM_STR, + &side_B_mos_stats.min.roundtrip_leg_param}, + {"mos_max_B_pv", PARAM_STR, &side_B_mos_stats.max.mos_param}, + {"mos_max_at_B_pv", PARAM_STR, &side_B_mos_stats.max.at_param}, + {"mos_max_packetloss_B_pv", PARAM_STR, + &side_B_mos_stats.max.packetloss_param}, + {"mos_max_jitter_B_pv", PARAM_STR, &side_B_mos_stats.max.jitter_param}, + {"mos_max_roundtrip_B_pv", PARAM_STR, + &side_B_mos_stats.max.roundtrip_param}, + {"mos_max_roundtrip_leg_B_pv", PARAM_STR, + &side_B_mos_stats.max.roundtrip_leg_param}, + {"mos_average_B_pv", PARAM_STR, &side_B_mos_stats.average.mos_param}, + {"mos_average_packetloss_B_pv", PARAM_STR, + &side_B_mos_stats.average.packetloss_param}, + {"mos_average_jitter_B_pv", PARAM_STR, + &side_B_mos_stats.average.jitter_param}, + {"mos_average_roundtrip_B_pv", PARAM_STR, + &side_B_mos_stats.average.roundtrip_param}, + {"mos_average_roundtrip_leg_B_pv", PARAM_STR, + &side_B_mos_stats.average.roundtrip_leg_param}, + {"mos_average_samples_B_pv", PARAM_STR, + &side_B_mos_stats.average.samples_param}, + + {"wsapi", PARAM_STR, &_rtpe_wsapi}, + + {0, 0, 0} +}; struct module_exports exports = { - "rtpengine", /* module name */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* cmd (cfg function) exports */ - params, /* param exports */ - 0, /* RPC method exports */ - mod_pvs, /* pseudo-variables exports */ - 0, /* response handling function */ - mod_init, /* module init function */ - child_init, /* per-child init function */ - mod_destroy /* module destroy function */ + "rtpengine", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* cmd (cfg function) exports */ + params, /* param exports */ + 0, /* RPC method exports */ + mod_pvs, /* pseudo-variables exports */ + 0, /* response handling function */ + mod_init, /* module init function */ + child_init, /* per-child init function */ + mod_destroy /* module destroy function */ }; +/* clang-format on */ /* check if the node is already queried */ static int is_queried_node(struct rtpp_node *node, - struct rtpp_node **queried_nodes_ptr, int queried_nodes) + struct rtpp_node **queried_nodes_list, int queried_nodes) { int i; - if(!queried_nodes_ptr) { + if(!queried_nodes_list) { return 0; } for(i = 0; i < queried_nodes; i++) { - if(node == queried_nodes_ptr[i]) { + if(node == queried_nodes_list[i]) { return 1; } } @@ -1240,6 +1276,251 @@ error: return -1; } +static int rtpengine_set_dtmf_events_sock(modparam_t type, void *val) +{ + char *p; + p = (char *)val; + + if(p == 0 || *p == '\0') { + return 0; + } + + rtpengine_dtmf_event_sock.s = p; + rtpengine_dtmf_event_sock.len = strlen(rtpengine_dtmf_event_sock.s); + + return 0; +} + +/** + * DTMF events loop + */ +static void rtpengine_dtmf_events_loop(void) +{ + int ret; + char *p; + str s_port; + unsigned int port; + unsigned int socket_len; + union sockaddr_union udp_addr; + char buffer[RTPENGINE_DTMF_EVENT_BUFFER]; + + p = q_memchr( + rtpengine_dtmf_event_sock.s, ':', rtpengine_dtmf_event_sock.len); + + if(!p) { + LM_ERR("failed to initialize dtmf event listener because no port was " + "specified %.*s!\n", + rtpengine_dtmf_event_sock.len, rtpengine_dtmf_event_sock.s); + return; + } + + s_port.s = p + 1; + s_port.len = rtpengine_dtmf_event_sock.s + rtpengine_dtmf_event_sock.len + - s_port.s; + + if(s_port.len <= 0 || str2int(&s_port, &port) < 0 || port > 65535) { + LM_ERR("failed to initialize dtmf event listener because port is " + "invalid %.*s\n", + rtpengine_dtmf_event_sock.len, rtpengine_dtmf_event_sock.s); + return; + } + rtpengine_dtmf_event_sock.len -= s_port.len + 1; + trim(&rtpengine_dtmf_event_sock); + rtpengine_dtmf_event_sock.s[rtpengine_dtmf_event_sock.len] = '\0'; + + memset(&udp_addr, 0, sizeof(union sockaddr_union)); + + if(rtpengine_dtmf_event_sock.s[0] == '[') { + udp_addr.sin6.sin6_family = AF_INET6; + udp_addr.sin6.sin6_port = htons(port); + socket_len = sizeof(struct sockaddr_in6); + ret = inet_pton(AF_INET6, rtpengine_dtmf_event_sock.s, + &udp_addr.sin6.sin6_addr); + } else { + udp_addr.sin.sin_family = AF_INET; + udp_addr.sin.sin_port = htons(port); + socket_len = sizeof(struct sockaddr_in); + ret = inet_pton( + AF_INET, rtpengine_dtmf_event_sock.s, &udp_addr.sin.sin_addr); + } + + if(ret != 1) { + LM_ERR("failed to initialize dtmf event listener because address could " + "not be created for %s\n", + rtpengine_dtmf_event_sock.s); + return; + } + + rtpengine_dtmf_event_fd = socket(udp_addr.s.sa_family, SOCK_DGRAM, 0); + + if(rtpengine_dtmf_event_fd < 0) { + LM_ERR("can't create socket\n"); + return; + } + + if(bind(rtpengine_dtmf_event_fd, &udp_addr.s, socket_len) < 0) { + LM_ERR("could not bind dtmf events socket %s:%u (%s:%d)\n", + rtpengine_dtmf_event_sock.s, port, strerror(errno), errno); + goto end; + } + LM_INFO("dtmf event listener started on %s:%u\n", + rtpengine_dtmf_event_sock.s, port); + + for(;;) { + do + ret = read(rtpengine_dtmf_event_fd, buffer, + RTPENGINE_DTMF_EVENT_BUFFER); + while(ret == -1 && errno == EINTR); + + if(ret < 0) { + LM_ERR("problem reading on socket %s:%u (%s:%d)\n", + rtpengine_dtmf_event_sock.s, port, strerror(errno), errno); + goto end; + } + + if(dtmf_event_rt == -1) { + LM_NOTICE("nothing to do - nobody is listening!\n"); + goto end; + } + + p = shm_malloc(ret + 1); + if(!p) { + LM_ERR("could not allocate %d for buffer %.*s\n", ret, ret, buffer); + goto end; + } + memcpy(p, buffer, ret); + p[ret] = '\0'; + + if(rtpengine_raise_dtmf_event(p, ret) < 0) { + LM_ERR("Failed to raise dtmf event\n"); + } + shm_free(p); + } + +end: + close(rtpengine_dtmf_event_fd); +} + +/** + * Raise DTMF event + */ +static int rtpengine_raise_dtmf_event(char *buffer, int len) +{ + srjson_doc_t jdoc; + srjson_t *it = NULL; + struct sip_msg *fmsg = NULL; + struct run_act_ctx ctx; + int rtb; + + LM_DBG("executing event_route[rtpengine:dtmf-event] (%d)\n", dtmf_event_rt); + LM_DBG("dispatching buffer: %s\n", buffer); + + srjson_InitDoc(&jdoc, NULL); + + jdoc.buf.s = buffer; + jdoc.buf.len = len; + + jdoc.root = srjson_Parse(&jdoc, jdoc.buf.s); + if(jdoc.root == NULL) { + LM_ERR("invalid json doc [[%s]]\n", jdoc.buf.s); + goto error; + } + + if(faked_msg_init() < 0) { + LM_ERR("Failed to initialize fake msg\n"); + goto error; + } + + /* iterate over keys */ + for(it = jdoc.root->child; it; it = it->next) { + LM_DBG("found field: %s\n", it->string); + if(strcmp(it->string, "callid") == 0) { + pv_value_t pv_val; + pv_val.rs.s = it->valuestring; + pv_val.rs.len = strlen(it->valuestring); + pv_val.flags = PV_VAL_STR; + + if(dtmf_event_callid_pvar->setf( + 0, &dtmf_event_callid_pvar->pvp, (int)EQ_T, &pv_val) + < 0) { + LM_ERR("error setting pvar <%.*s>\n", + dtmf_event_callid_pvar_str.len, + dtmf_event_callid_pvar_str.s); + goto error; + } + } else if(strcmp(it->string, "source_tag") == 0) { + pv_value_t pv_val; + pv_val.rs.s = it->valuestring; + pv_val.rs.len = strlen(it->valuestring); + pv_val.flags = PV_VAL_STR; + + if(dtmf_event_source_tag_pvar->setf( + 0, &dtmf_event_source_tag_pvar->pvp, (int)EQ_T, &pv_val) + < 0) { + LM_ERR("error setting pvar <%.*s>\n", + dtmf_event_source_tag_pvar_str.len, + dtmf_event_source_tag_pvar_str.s); + goto error; + } + } else if(strcmp(it->string, "timestamp") == 0) { + pv_value_t pv_val; + int_str val = {0}; + char intbuf[32]; + snprintf(intbuf, sizeof(intbuf), "%lld", SRJSON_GET_LLONG(it)); + memset(&val, 0, sizeof(val)); + + pv_val.rs.s = intbuf; + pv_val.rs.len = strlen(intbuf); + pv_val.flags = PV_VAL_STR; + + if(dtmf_event_timestamp_pvar->setf( + 0, &dtmf_event_timestamp_pvar->pvp, (int)EQ_T, &pv_val) + < 0) { + LM_ERR("error setting pvar <%.*s>\n", + dtmf_event_timestamp_pvar_str.len, + dtmf_event_timestamp_pvar_str.s); + goto error; + } + } else if(strcmp(it->string, "event") == 0) { + pv_value_t pv_val; + int_str val = {0}; + char intbuf[32]; + snprintf(intbuf, sizeof(intbuf), "%lld", SRJSON_GET_LLONG(it)); + memset(&val, 0, sizeof(val)); + + pv_val.rs.s = intbuf; + pv_val.rs.len = strlen(intbuf); + pv_val.flags = PV_VAL_STR; + + if(dtmf_event_pvar->setf( + 0, &dtmf_event_pvar->pvp, (int)EQ_T, &pv_val) + < 0) { + LM_ERR("error setting pvar <%.*s>\n", dtmf_event_pvar_str.len, + dtmf_event_pvar_str.s); + goto error; + } + } + } + + fmsg = faked_msg_next(); + rtb = get_route_type(); + set_route_type(REQUEST_ROUTE); + init_run_actions_ctx(&ctx); + run_top_route(event_rt.rlist[dtmf_event_rt], fmsg, &ctx); + set_route_type(rtb); + if(ctx.run_flags & DROP_R_F) { + LM_ERR("exit due to 'drop' in event route\n"); + goto error; + } + + srjson_DestroyDoc(&jdoc); + + return 0; + +error: + srjson_DestroyDoc(&jdoc); + return -1; +} static int fixup_set_id(void **param, int param_no) { @@ -1330,6 +1611,8 @@ error: static void rtpengine_rpc_reload(rpc_t *rpc, void *ctx) { time_t tnow; + int rping = 1; + int n = 0; if(rtpp_db_url.s == NULL) { // no database @@ -1342,6 +1625,13 @@ static void rtpengine_rpc_reload(rpc_t *rpc, void *ctx) return; } + n = rpc->scan(ctx, "*d", &rping); + if(n != 1) { + rping = 1; + } else if(rping != 0) { + rping = 1; + } + tnow = time(NULL); if(tnow - _rtpe_list_version->vertime < RTPE_LIST_VERSION_DELAY) { rpc->fault(ctx, 500, "Too short reload interval - try later"); @@ -1355,7 +1645,7 @@ static void rtpengine_rpc_reload(rpc_t *rpc, void *ctx) return; } - if(build_rtpp_socks(1, 1)) { + if(build_rtpp_socks(1, rping)) { rpc->fault(ctx, 500, "Failed to build rtpengine sockets"); return; } @@ -1858,6 +2148,68 @@ static int mod_init(void) } } + dtmf_event_rt = route_lookup(&event_rt, "rtpengine:dtmf-event"); + if(dtmf_event_rt >= 0 && event_rt.rlist[dtmf_event_rt] == 0) { + dtmf_event_rt = -1; /* disable */ + } else { + if(dtmf_event_callid_pvar_str.len > 0) { + dtmf_event_callid_pvar = pv_cache_get(&dtmf_event_callid_pvar_str); + if(dtmf_event_callid_pvar == NULL + || (dtmf_event_callid_pvar->type != PVT_AVP + && dtmf_event_callid_pvar->type != PVT_SCRIPTVAR)) { + LM_ERR("dtmf_event_callid_pv: not a valid AVP or VAR " + "definition <%.*s>\n", + dtmf_event_callid_pvar_str.len, + dtmf_event_callid_pvar_str.s); + return -1; + } + } + + if(dtmf_event_source_tag_pvar_str.len > 0) { + dtmf_event_source_tag_pvar = + pv_cache_get(&dtmf_event_source_tag_pvar_str); + if(dtmf_event_source_tag_pvar == NULL + || (dtmf_event_source_tag_pvar->type != PVT_AVP + && dtmf_event_source_tag_pvar->type + != PVT_SCRIPTVAR)) { + LM_ERR("dtmf_event_source_tag_pv: not a valid AVP or VAR " + "definition <%.*s>\n", + dtmf_event_source_tag_pvar_str.len, + dtmf_event_source_tag_pvar_str.s); + return -1; + } + } + + if(dtmf_event_timestamp_pvar_str.len > 0) { + dtmf_event_timestamp_pvar = + pv_cache_get(&dtmf_event_timestamp_pvar_str); + if(dtmf_event_timestamp_pvar == NULL + || (dtmf_event_timestamp_pvar->type != PVT_AVP + && dtmf_event_timestamp_pvar->type + != PVT_SCRIPTVAR)) { + LM_ERR("dtmf_event_timestamp_pv: not a valid AVP or VAR " + "definition <%.*s>\n", + dtmf_event_timestamp_pvar_str.len, + dtmf_event_timestamp_pvar_str.s); + return -1; + } + } + + if(dtmf_event_pvar_str.len > 0) { + dtmf_event_pvar = pv_cache_get(&dtmf_event_pvar_str); + if(dtmf_event_pvar == NULL + || (dtmf_event_pvar->type != PVT_AVP + && dtmf_event_pvar->type != PVT_SCRIPTVAR)) { + LM_ERR("event_pv: not a valid AVP or VAR definition <%.*s>\n", + dtmf_event_pvar_str.len, dtmf_event_pvar_str.s); + return -1; + } + } + + register_procs(1); + cfg_register_child(1); + } + return 0; } @@ -2125,11 +2477,35 @@ static int child_init(int rank) if(!rtpp_set_list) return 0; - /* do not init sockets for PROC_INIT and main process when fork=yes */ - if(rank == PROC_INIT || (rank == PROC_MAIN && dont_fork == 0)) { + /* do not init sockets for PROC_INIT */ + if(rank == PROC_INIT) { return 0; } + if(rank == PROC_MAIN) { + if(rtpengine_dtmf_event_sock.len > 0) { + LM_DBG("Register RTPENGINE DTMF WORKER %d\n", mypid); + /* fork worker process */ + mypid = fork_process(PROC_RPC, "RTPENGINE DTMF WORKER", 1); + if(mypid < 0) { + LM_ERR("failed to fork RTPENGINE DTMF WORKER process %d\n", + mypid); + return -1; + } else if(mypid == 0) { + if(cfg_child_init()) + return -1; + /* this will loop forever */ + rtpengine_dtmf_events_loop(); + } + + return 0; + } + + /* do not init sockets for main process when fork=yes */ + if(dont_fork == 0) + return 0; + } + mypid = getpid(); // vector of pointers to queried nodes @@ -2145,11 +2521,12 @@ static int child_init(int rank) /* Iterate known RTPEngine instances - create sockets */ if(rank == PROC_SIPINIT) { /* probe rtpengines only in first worker */ - if(build_rtpp_socks(0, 1)) - return -1; - } else { - if(build_rtpp_socks(0, 0)) + if(build_rtpp_socks(0, rtpengine_ping_mode)) return -1; + else { + if(build_rtpp_socks(0, 0)) + return -1; + } } return 0; @@ -2277,6 +2654,9 @@ static int parse_codec_flag(struct ng_flags_parse *ng_flags, const str *key, return 1; } +/** + * Parse the flags string + */ static int parse_flags(struct ng_flags_parse *ng_flags, struct sip_msg *msg, enum rtpe_operation *op, const char *flags_str) { @@ -2367,6 +2747,12 @@ static int parse_flags(struct ng_flags_parse *ng_flags, struct sip_msg *msg, if(parse_codec_flag(ng_flags, &key, &val, "codec-except", NULL, "except", &ng_flags->codec_except)) goto next; + if(parse_codec_flag(ng_flags, &key, &val, "codec-accept", NULL, + "accept", &ng_flags->codec_accept)) + goto next; + if(parse_codec_flag(ng_flags, &key, &val, "codec-consume", NULL, + "consume", &ng_flags->codec_consume)) + goto next; /* check for specially handled items */ switch(key.len) { @@ -2550,7 +2936,7 @@ error: static bencode_item_t *rtpp_function_call(bencode_buffer_t *bencbuf, struct sip_msg *msg, enum rtpe_operation op, const char *flags_str, - str *body_out) + str *body_out, str *cl_field) { struct ng_flags_parse ng_flags; bencode_item_t *item, *resp; @@ -2616,7 +3002,7 @@ static bencode_item_t *rtpp_function_call(bencode_buffer_t *bencbuf, body = pv_val.rs; } - } else if((cont_type = extract_body(msg, &body)) == -1) { + } else if((cont_type = extract_body(msg, &body, cl_field)) == -1) { LM_ERR("can't extract body from the message\n"); goto error; } @@ -2953,7 +3339,7 @@ static int rtpp_function_call_simple( bencode_buffer_t bencbuf; bencode_item_t *ret; - ret = rtpp_function_call(&bencbuf, msg, op, flags_str, NULL); + ret = rtpp_function_call(&bencbuf, msg, op, flags_str, NULL, NULL); if(!ret) return -1; @@ -2976,11 +3362,11 @@ static int rtpengine_simple_wrap( static bencode_item_t *rtpp_function_call_ok(bencode_buffer_t *bencbuf, struct sip_msg *msg, enum rtpe_operation op, const char *flags_str, - str *body) + str *body, str *cl_field) { bencode_item_t *ret; - ret = rtpp_function_call(bencbuf, msg, op, flags_str, body); + ret = rtpp_function_call(bencbuf, msg, op, flags_str, body, cl_field); if(!ret) return NULL; @@ -3263,7 +3649,7 @@ static struct rtpp_set *select_rtpp_set(unsigned int id_set) * run the selection algorithm and return the new selected node */ static struct rtpp_node *select_rtpp_node_new(str callid, str viabranch, - int do_test, struct rtpp_node **queried_nodes_ptr, int queried_nodes) + int do_test, struct rtpp_node **queried_nodes_list, int queried_nodes) { struct rtpp_node *node; unsigned i, sum, sumcut, weight_sum; @@ -3327,7 +3713,7 @@ retry: /* Select only between enabled machines */ if(!node->rn_disabled - && !is_queried_node(node, queried_nodes_ptr, queried_nodes)) { + && !is_queried_node(node, queried_nodes_list, queried_nodes)) { weight_sum += node->rn_weight; } } @@ -3378,7 +3764,7 @@ retry: continue; /* Select only between not already queried machines */ - if(is_queried_node(node, queried_nodes_ptr, queried_nodes)) + if(is_queried_node(node, queried_nodes_list, queried_nodes)) continue; /* Found machine */ @@ -3451,7 +3837,7 @@ unsigned int node_in_set(struct rtpp_node *node, struct rtpp_set *set) * the call if some proxies were disabled or enabled (e.g. kamctl command) */ static struct rtpp_node *select_rtpp_node(str callid, str viabranch, - int do_test, struct rtpp_node **queried_nodes_ptr, int queried_nodes, + int do_test, struct rtpp_node **queried_nodes_list, int queried_nodes, enum rtpe_operation op) { struct rtpp_node *node = NULL; @@ -3474,7 +3860,7 @@ static struct rtpp_node *select_rtpp_node(str callid, str viabranch, // lookup node node = select_rtpp_node_old(callid, viabranch, do_test, op); - if(node && is_queried_node(node, queried_nodes_ptr, queried_nodes)) { + if(node && is_queried_node(node, queried_nodes_list, queried_nodes)) { LM_ERR("rtpengine node for callid=%.*s is known (%.*s) but it has " "already been queried, therefore not returning it\n", callid.len, callid.s, node->rn_url.len, node->rn_url.s); @@ -3485,7 +3871,7 @@ static struct rtpp_node *select_rtpp_node(str callid, str viabranch, if(!node || (node_in_set(node, active_rtpp_set) == 0)) { // run the selection algorithm node = select_rtpp_node_new( - callid, viabranch, do_test, queried_nodes_ptr, queried_nodes); + callid, viabranch, do_test, queried_nodes_list, queried_nodes); // check node if(!node) { @@ -3594,12 +3980,13 @@ static void avp_print_decimal(pv_elem_t *pv, int num, struct sip_msg *msg) len = snprintf(buf, sizeof(buf), "%i.%i", num / 10, abs(num % 10)); avp_print_s(pv, buf, len, msg); } -static void avp_print_int(pv_elem_t *pv, int num, struct sip_msg *msg) +static void avp_print_llint( + pv_elem_t *pv, long long int num, struct sip_msg *msg) { int len; - char buf[8]; + char buf[20]; - len = snprintf(buf, sizeof(buf), "%i", num); + len = snprintf(buf, sizeof(buf), "%lld", num); avp_print_s(pv, buf, len, msg); } static void avp_print_time(pv_elem_t *pv, int num, struct sip_msg *msg) @@ -3619,12 +4006,13 @@ static void avp_print_mos(struct minmax_mos_stats *s, avp_print_decimal(s->mos_pv, vals->mos / vals->avg_samples, msg); avp_print_time(s->at_pv, vals->at - created, msg); - avp_print_int(s->packetloss_pv, vals->packetloss / vals->avg_samples, msg); - avp_print_int(s->jitter_pv, vals->jitter / vals->avg_samples, msg); - avp_print_int(s->roundtrip_pv, vals->roundtrip / vals->avg_samples, msg); - avp_print_int( + avp_print_llint( + s->packetloss_pv, vals->packetloss / vals->avg_samples, msg); + avp_print_llint(s->jitter_pv, vals->jitter / vals->avg_samples, msg); + avp_print_llint(s->roundtrip_pv, vals->roundtrip / vals->avg_samples, msg); + avp_print_llint( s->roundtrip_leg_pv, vals->roundtrip_leg / vals->avg_samples, msg); - avp_print_int(s->samples_pv, vals->samples / vals->avg_samples, msg); + avp_print_llint(s->samples_pv, vals->samples / vals->avg_samples, msg); } static int decode_mos_vals_dict( @@ -3804,7 +4192,7 @@ static int rtpengine_delete(struct sip_msg *msg, const char *flags) { bencode_buffer_t bencbuf; bencode_item_t *ret = - rtpp_function_call_ok(&bencbuf, msg, OP_DELETE, flags, NULL); + rtpp_function_call_ok(&bencbuf, msg, OP_DELETE, flags, NULL, NULL); if(!ret) return -1; parse_call_stats(ret, msg); @@ -3816,7 +4204,7 @@ static int rtpengine_query(struct sip_msg *msg, const char *flags) { bencode_buffer_t bencbuf; bencode_item_t *ret = - rtpp_function_call_ok(&bencbuf, msg, OP_QUERY, flags, NULL); + rtpp_function_call_ok(&bencbuf, msg, OP_QUERY, flags, NULL, NULL); if(!ret) return -1; parse_call_stats(ret, msg); @@ -4097,9 +4485,11 @@ static int rtpengine_offer_answer(struct sip_msg *msg, const char *flags, str body, newbody; struct lump *anchor; pv_value_t pv_val; - str cur_body = {0, 0}; + str cur_body = STR_NULL; + str cl_field = STR_NULL; + str cl_repl = STR_NULL; - dict = rtpp_function_call_ok(&bencbuf, msg, op, flags, &body); + dict = rtpp_function_call_ok(&bencbuf, msg, op, flags, &body, &cl_field); if(!dict) return -1; @@ -4129,6 +4519,21 @@ static int rtpengine_offer_answer(struct sip_msg *msg, const char *flags, pkg_free(newbody.s); } else { + if(cl_field.len) { + anchor = del_lump(msg, cl_field.s - msg->buf, cl_field.len, 0); + cl_repl.s = pkg_malloc(10); + if(!cl_repl.s) { + LM_ERR("pkg_malloc for Content-Length failed\n"); + goto error_free; + } + cl_repl.len = snprintf(cl_repl.s, 10, "%i", (int)newbody.len); + if(!insert_new_lump_after(anchor, cl_repl.s, cl_repl.len, 0)) { + LM_ERR("insert_new_lump_after failed\n"); + goto error_free; + } + cl_repl.s = NULL; + } + if(read_sdp_pvar_str.len > 0) { /* get the body from the message as body ptr may have changed * when using read_sdp_pv */ @@ -4156,6 +4561,8 @@ static int rtpengine_offer_answer(struct sip_msg *msg, const char *flags, error_free: pkg_free(newbody.s); + if(cl_repl.s) + pkg_free(cl_repl.s); error: bencode_buffer_free(&bencbuf); return -1; @@ -4219,7 +4626,7 @@ static int rtpengine_play_media( pv_value_t val; int retval = 1; - ret = rtpp_function_call_ok(&bencbuf, msg, OP_PLAY_MEDIA, d, NULL); + ret = rtpp_function_call_ok(&bencbuf, msg, OP_PLAY_MEDIA, d, NULL, NULL); if(!ret) return -1; if(media_duration_pvar) { @@ -4283,7 +4690,7 @@ static int rtpengine_rtpstat_wrap( param = parms[0]; res = parms[1]; - dict = rtpp_function_call_ok(&bencbuf, msg, OP_QUERY, NULL, NULL); + dict = rtpp_function_call_ok(&bencbuf, msg, OP_QUERY, NULL, NULL, NULL); if(!dict) return -1; @@ -4452,7 +4859,7 @@ static int rtpengine_query_v_wrap( fmt = parms[0]; dst = parms[1]; - dict = rtpp_function_call_ok(&bencbuf, msg, OP_QUERY, NULL, NULL); + dict = rtpp_function_call_ok(&bencbuf, msg, OP_QUERY, NULL, NULL, NULL); if(!dict) { return -1; } diff --git a/src/modules/rtpengine/rtpengine_funcs.c b/src/modules/rtpengine/rtpengine_funcs.c index 7ef7c8b7b..9b916c9f2 100644 --- a/src/modules/rtpengine/rtpengine_funcs.c +++ b/src/modules/rtpengine/rtpengine_funcs.c @@ -66,7 +66,7 @@ * 2: multipart * 3: trickle ice sdp fragment */ -int check_content_type(struct sip_msg *msg) +static int check_content_type(struct sip_msg *msg) { static unsigned int appl[16] = {0x6c707061 /*appl*/, 0x6c707041 /*Appl*/, 0x6c705061 /*aPpl*/, 0x6c705041 /*APpl*/, 0x6c507061 /*apPl*/, @@ -156,7 +156,7 @@ other: /* * Get message body and check Content-Type header field */ -int extract_body(struct sip_msg *msg, str *body) +int extract_body(struct sip_msg *msg, str *body, str *cl_field) { char c; int ret; @@ -234,7 +234,11 @@ int extract_body(struct sip_msg *msg, str *body) break; if(hf.type == HDR_ERROR_T) return -1; - if(hf.type == HDR_CONTENTTYPE_T) { + if(hf.type == HDR_CONTENTLENGTH_T) { + if (cl_field) + *cl_field = hf.body; + } + else if(hf.type == HDR_CONTENTTYPE_T) { if(decode_mime_type(hf.body.s, hf.body.s + hf.body.len, &mime) == NULL) return -1; diff --git a/src/modules/rtpengine/rtpengine_funcs.h b/src/modules/rtpengine/rtpengine_funcs.h index a1221bd20..ea0a720a2 100644 --- a/src/modules/rtpengine/rtpengine_funcs.h +++ b/src/modules/rtpengine/rtpengine_funcs.h @@ -27,8 +27,7 @@ #include "../../core/parser/msg_parser.h" #include "../../core/parser/contact/contact.h" -int extract_body(struct sip_msg *, str *); -int check_content_type(struct sip_msg *); +int extract_body(struct sip_msg *, str *, str *); int get_callid(struct sip_msg *, str *); int get_to_tag(struct sip_msg *, str *); int get_from_tag(struct sip_msg *, str *); diff --git a/src/modules/rtpproxy/README b/src/modules/rtpproxy/README index 976f393d6..b1a8a7949 100644 --- a/src/modules/rtpproxy/README +++ b/src/modules/rtpproxy/README @@ -22,7 +22,7 @@ Carsten Bock ng-voice GmbH - Copyright © 2003-2008 Sippy Software, Inc. + Copyright © 2003-2023 Sippy Software, Inc. Copyright © 2005 Voice Sistem SRL @@ -50,11 +50,12 @@ Carsten Bock 4.4. rtpproxy_retr (integer) 4.5. nortpproxy_str (string) 4.6. timeout_socket (string) - 4.7. ice_candidate_priority_avp (string) - 4.8. extra_id_pv (string) - 4.9. db_url (string) - 4.10. table_name (string) - 4.11. rtp_inst_pvar (string) + 4.7. timeout_tag_pv (string) + 4.8. ice_candidate_priority_avp (string) + 4.9. extra_id_pv (string) + 4.10. db_url (string) + 4.11. table_name (string) + 4.12. rtp_inst_pvar (string) 5. Functions @@ -90,23 +91,24 @@ Carsten Bock 1.4. Set rtpproxy_retr parameter 1.5. Set nortpproxy_str parameter 1.6. Set timeout_socket parameter - 1.7. Set ice_candidate_priority_avp parameter - 1.8. Set extra_id_pv parameter - 1.9. Set db_url parameter - 1.10. Set table_name parameter - 1.11. Set rtp_inst_pvar parameter - 1.12. rtp_inst_pvar usage - 1.13. set_rtp_proxy_set usage - 1.14. rtpproxy_offer usage - 1.15. rtpproxy_answer usage - 1.16. rtpproxy_destroy usage - 1.17. rtpproxy_manage usage - 1.18. rtpproxy_stream2xxx usage - 1.19. rtpproxy_stop_stream2uas usage - 1.20. start_recording usage - 1.21. $rtppstat Usage - 1.22. rtpproxy.enable usage - 1.23. rtpproxy.list usage + 1.7. Set timeout_tag_pv parameter + 1.8. Set ice_candidate_priority_avp parameter + 1.9. Set extra_id_pv parameter + 1.10. Set db_url parameter + 1.11. Set table_name parameter + 1.12. Set rtp_inst_pvar parameter + 1.13. rtp_inst_pvar usage + 1.14. set_rtp_proxy_set usage + 1.15. rtpproxy_offer usage + 1.16. rtpproxy_answer usage + 1.17. rtpproxy_destroy usage + 1.18. rtpproxy_manage usage + 1.19. rtpproxy_stream2xxx usage + 1.20. rtpproxy_stop_stream2uas usage + 1.21. start_recording usage + 1.22. $rtppstat Usage + 1.23. rtpproxy.enable usage + 1.24. rtpproxy.list usage Chapter 1. Admin Guide @@ -127,11 +129,12 @@ Chapter 1. Admin Guide 4.4. rtpproxy_retr (integer) 4.5. nortpproxy_str (string) 4.6. timeout_socket (string) - 4.7. ice_candidate_priority_avp (string) - 4.8. extra_id_pv (string) - 4.9. db_url (string) - 4.10. table_name (string) - 4.11. rtp_inst_pvar (string) + 4.7. timeout_tag_pv (string) + 4.8. ice_candidate_priority_avp (string) + 4.9. extra_id_pv (string) + 4.10. db_url (string) + 4.11. table_name (string) + 4.12. rtp_inst_pvar (string) 5. Functions @@ -159,12 +162,8 @@ Chapter 1. Admin Guide 1. Overview - This is a module that enables media streams to be proxied via an - rtpproxy. Rtpproxies know to work with this module are Sippy RTPproxy - http://www.rtpproxy.org and ngcp-rtpproxy-ng - http://deb.sipwise.com/spce/2.6/pool/main/n/ngcp-mediaproxy-ng. Some - features of the rtpproxy module apply only to one of the two - rtpproxies. + This is a module that enables media streams to be proxied via the Sippy + RTPproxy http://www.rtpproxy.org. 2. Multiple RTPProxy usage @@ -216,11 +215,12 @@ Chapter 1. Admin Guide 4.4. rtpproxy_retr (integer) 4.5. nortpproxy_str (string) 4.6. timeout_socket (string) - 4.7. ice_candidate_priority_avp (string) - 4.8. extra_id_pv (string) - 4.9. db_url (string) - 4.10. table_name (string) - 4.11. rtp_inst_pvar (string) + 4.7. timeout_tag_pv (string) + 4.8. ice_candidate_priority_avp (string) + 4.9. extra_id_pv (string) + 4.10. db_url (string) + 4.11. table_name (string) + 4.12. rtp_inst_pvar (string) 4.1. rtpproxy_sock (string) @@ -319,10 +319,29 @@ modparam("rtpproxy", "nortpproxy_str", "a=sdpmangled:yes\r\n") Example 1.6. Set timeout_socket parameter ... -modparam("rtpproxy", "timeout_socket", "xmlrpc:http://127.0.0.1:8000/RPC2") +modparam("rtpproxy", "timeout_socket", "tcp:127.0.0.1:8000") ... -4.7. ice_candidate_priority_avp (string) +4.7. timeout_tag_pv (string) + + The parameter devines the AVP of the string to be provided to the + RTP-Proxy. + + The content of the AVP must be a valid URL-encoded string with no + spaces. It will be decoded and send by the RTP proxy to the timeout + socket if the media timeout has happened. + + This parameter is required in order for the timeout notification + mechanism to work properly. + + Default value is “” (nothing). + + Example 1.7. Set timeout_tag_pv parameter +... +modparam("rtpproxy", "timeout_tag_pv", "$avp(rtpp_ntag)") +... + +4.8. ice_candidate_priority_avp (string) If specified and if value of the avp value is not 0, rtpproxy_manage function adds ICE relay candidate attributes to sdp stream(s) @@ -334,12 +353,12 @@ modparam("rtpproxy", "timeout_socket", "xmlrpc:http://127.0.0.1:8000/RPC2") There is no default value meaning that no ICE relay candidates are added in any circumstance. - Example 1.7. Set ice_candidate_priority_avp parameter + Example 1.8. Set ice_candidate_priority_avp parameter ... modparam("rtpproxy", "ice_candidate_priority_avp", "$avp(ice_priority)") ... -4.8. extra_id_pv (string) +4.9. extra_id_pv (string) The parameter sets the PV definition to use when the “b” parameter is used on unforce_rtp_proxy(), rtpproxy_offer(), rtpproxy_answer() or @@ -347,12 +366,12 @@ modparam("rtpproxy", "ice_candidate_priority_avp", "$avp(ice_priority)") Default is empty, the “b” parameter may not be used then. - Example 1.8. Set extra_id_pv parameter + Example 1.9. Set extra_id_pv parameter ... modparam("rtpproxy", "extra_id_pv", "$avp(extra_id)") ... -4.9. db_url (string) +4.10. db_url (string) The database URL to load rtp_proxy sets from. If this parameter is set, the module will attempt to load the rtpproxy sets from the specified @@ -360,23 +379,23 @@ modparam("rtpproxy", "extra_id_pv", "$avp(extra_id)") Default is empty, a database will not be used. - Example 1.9. Set db_url parameter + Example 1.10. Set db_url parameter ... -modparam("rtpproxy", "db_url", "mysql://user:passwb@localhost/database") +modparam("rtpproxy", "db_url", "mysql://user:passwd@localhost/database") ... -4.10. table_name (string) +4.11. table_name (string) The name of the table containing the rtpproxy sets. Default value is “rtpproxy”. - Example 1.10. Set table_name parameter + Example 1.11. Set table_name parameter ... modparam("rtpproxy", "table_name", "my_rtpp_sets") ... -4.11. rtp_inst_pvar (string) +4.12. rtp_inst_pvar (string) A pseudo variable to store the chosen RTPProxy address. If this parameter is set, the instance URL will be stored in the given @@ -384,12 +403,12 @@ modparam("rtpproxy", "table_name", "my_rtpp_sets") By default, this parameter is not set. - Example 1.11. Set rtp_inst_pvar parameter + Example 1.12. Set rtp_inst_pvar parameter ... modparam("rtpproxy", "rtp_inst_pvar", "$avp(RTP_INSTANCE)") ... - Example 1.12. rtp_inst_pvar usage + Example 1.13. rtp_inst_pvar usage modparam("rtpproxy", "rtpproxy_sock", "udp:localhost:12221 udp:localhost:12222") modparam("rtpproxy", "rtp_inst_pvar", "$var(RTP_INSTANCE)") @@ -423,7 +442,7 @@ xlog("L_INFO", "Chose rtpp instance $var(RTP_INSTANCE)\n"); This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE. - Example 1.13. set_rtp_proxy_set usage + Example 1.14. set_rtp_proxy_set usage ... set_rtp_proxy_set("2"); rtpproxy_offer(); @@ -501,9 +520,8 @@ rtpproxy_offer(); different m-lines with different IP-protocols grouped together. + f - instructs rtpproxy to ignore marks inserted by another - rtpproxy in transit to indicate that the session is already - goes through another proxy. Allows creating a chain of - proxies. + rtpproxy in transit to indicate that the session already goes + through another proxy. Allows creating a chain of proxies. + r - flags that IP address in SDP should be trusted. Without this flag, rtpproxy ignores address in the SDP and uses source address of the SIP message as media address which is passed to @@ -529,7 +547,7 @@ rtpproxy_offer(); This function can be used from ANY_ROUTE. - Example 1.14. rtpproxy_offer usage + Example 1.15. rtpproxy_offer usage route { ... if (is_method("INVITE")) { @@ -573,7 +591,7 @@ onreply_route[2] This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE. - Example 1.15. rtpproxy_answer usage + Example 1.16. rtpproxy_answer usage See rtpproxy_offer() function example above for example. @@ -608,7 +626,7 @@ onreply_route[2] rtpproxy call when 200 OK is received on a branch, where rtpproxy is not needed. - Example 1.16. rtpproxy_destroy usage + Example 1.17. rtpproxy_destroy usage ... rtpproxy_destroy(); ... @@ -648,7 +666,7 @@ rtpproxy_destroy(); This function can be used from ANY_ROUTE. - Example 1.17. rtpproxy_manage usage + Example 1.18. rtpproxy_manage usage ... rtpproxy_manage(); ... @@ -684,7 +702,7 @@ rtpproxy_manage(); -1 means that it will be streaming in a loop indefinitely, until the appropriate rtpproxy_stop_stream2xxx is issued. - Example 1.18. rtpproxy_stream2xxx usage + Example 1.19. rtpproxy_stream2xxx usage ... if (is_method("INVITE")) { rtpproxy_offer(); @@ -713,7 +731,7 @@ rtpproxy_manage(); See function rtpproxy_stop_stream2uac(). - Example 1.19. rtpproxy_stop_stream2uas usage + Example 1.20. rtpproxy_stop_stream2uas usage ... if (is_method("INVITE")) { rtpproxy_offer(); @@ -733,7 +751,7 @@ rtpproxy_manage(); This function can be used from REQUEST_ROUTE and ONREPLY_ROUTE. - Example 1.20. start_recording usage + Example 1.21. start_recording usage ... start_recording(); ... @@ -751,7 +769,7 @@ start_recording(); deleted (before unforce_rtpproxy()). It is the output of RTPProxy 'Q' command. - Example 1.21. $rtppstat Usage + Example 1.22. $rtppstat Usage ... append_hf("X-RTP-Statistics: $rtppstat\r\n"); ... @@ -778,7 +796,7 @@ start_recording(); NOTE: if a rtpproxy is defined multiple times (in the same or different sets), all of its instances will be enabled/disabled. - Example 1.22. rtpproxy.enable usage + Example 1.23. rtpproxy.enable usage ... $ kamcmd rtpproxy.enable udp:192.168.2.133:8081 0 ... @@ -790,7 +808,7 @@ $ kamcmd rtpproxy.enable udp:192.168.2.133:8081 0 No parameter. - Example 1.23. rtpproxy.list usage + Example 1.24. rtpproxy.list usage ... $ kamcmd rtpproxy.list ... @@ -823,9 +841,11 @@ Chapter 2. Frequently Asked Questions First at all check if your question was already answered on one of our mailing lists: * User Mailing List - - https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users + https://lists.kamailio.org/mailman3/postorius/lists/sr-users.lists. + kamailio.org/ * Developer Mailing List - - https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-dev + https://lists.kamailio.org/mailman3/postorius/lists/sr-dev.lists.ka + mailio.org/ E-mails regarding any stable Kamailio release should be sent to and e-mails regarding development diff --git a/src/modules/rtpproxy/doc/rtpproxy.xml b/src/modules/rtpproxy/doc/rtpproxy.xml index 2bc7c08f3..888de39b6 100644 --- a/src/modules/rtpproxy/doc/rtpproxy.xml +++ b/src/modules/rtpproxy/doc/rtpproxy.xml @@ -67,7 +67,7 @@ - 2003-2008 + 2003-2023 Sippy Software, Inc. diff --git a/src/modules/rtpproxy/doc/rtpproxy_admin.xml b/src/modules/rtpproxy/doc/rtpproxy_admin.xml index 10b2291c8..b04baa5e3 100644 --- a/src/modules/rtpproxy/doc/rtpproxy_admin.xml +++ b/src/modules/rtpproxy/doc/rtpproxy_admin.xml @@ -18,11 +18,7 @@ Overview This is a module that enables media streams to be proxied - via an rtpproxy. Rtpproxies know to work with this module - are Sippy RTPproxy - and ngcp-rtpproxy-ng - . - Some features of the rtpproxy module apply only to one of the two rtpproxies. + via the Sippy RTPproxy . @@ -235,7 +231,37 @@ modparam("rtpproxy", "nortpproxy_str", "a=sdpmangled:yes\r\n") Set <varname>timeout_socket</varname> parameter ... -modparam("rtpproxy", "timeout_socket", "xmlrpc:http://127.0.0.1:8000/RPC2") +modparam("rtpproxy", "timeout_socket", "tcp:127.0.0.1:8000") +... + + + +
+ <varname>timeout_tag_pv</varname> (string) + + The parameter devines the AVP of the string to be provided to the + RTP-Proxy. + + + The content of the AVP must be a valid URL-encoded string with + no spaces. + It will be decoded and send by the RTP proxy to the timeout socket if the + media timeout has happened. + + + This parameter is required in order for the timeout notification + mechanism to work properly. + + + + Default value is (nothing). + + + + Set <varname>timeout_tag_pv</varname> parameter + +... +modparam("rtpproxy", "timeout_tag_pv", "$avp(rtpp_ntag)") ... @@ -299,7 +325,7 @@ modparam("rtpproxy", "extra_id_pv", "$avp(extra_id)") Set <varname>db_url</varname> parameter ... -modparam("rtpproxy", "db_url", "mysql://user:passwb@localhost/database") +modparam("rtpproxy", "db_url", "mysql://user:passwd@localhost/database") ... @@ -475,7 +501,7 @@ rtpproxy_offer(); f - instructs rtpproxy to ignore marks inserted by another rtpproxy in transit to indicate that the - session is already goes through another proxy. Allows creating + session already goes through another proxy. Allows creating a chain of proxies. diff --git a/src/modules/rtpproxy/examples/4to6.cfg b/src/modules/rtpproxy/examples/4to6.cfg index 678b96d91..a80b60729 100644 --- a/src/modules/rtpproxy/examples/4to6.cfg +++ b/src/modules/rtpproxy/examples/4to6.cfg @@ -37,7 +37,7 @@ modparam("nathelper", "natping_interval", 15) request_route { # initial sanity checks -- messages with - # max_forwars == 0, or excessively long requests, + # max_forwards == 0, or excessively long requests, # or those that don't addressed to us if (!mf_process_maxfwd_header("10")) { sl_send_reply("483", "Too Many Hops"); diff --git a/src/modules/rtpproxy/examples/alg.cfg b/src/modules/rtpproxy/examples/alg.cfg index 21d463910..ac3a63366 100644 --- a/src/modules/rtpproxy/examples/alg.cfg +++ b/src/modules/rtpproxy/examples/alg.cfg @@ -33,7 +33,7 @@ modparam("nathelper", "natping_interval", 15) request_route { # initial sanity checks -- messages with - # max_forwars == 0, or excessively long requests, + # max_forwards == 0, or excessively long requests, # or those that don't addressed to us if (!mf_process_maxfwd_header("10")) { sl_send_reply("483", "Too Many Hops"); diff --git a/src/modules/rtpproxy/rtpproxy.c b/src/modules/rtpproxy/rtpproxy.c index 8c2b17444..f6ea6b1b1 100644 --- a/src/modules/rtpproxy/rtpproxy.c +++ b/src/modules/rtpproxy/rtpproxy.c @@ -1,6 +1,6 @@ /** * - * Copyright (C) 2003-2008 Sippy Software, Inc., http://www.sippysoft.com + * Copyright (C) 2003-2023 Sippy Software, Inc., http://www.sippysoft.com * * This file is part of Kamailio, a free SIP server. * @@ -187,6 +187,8 @@ static struct tm_binds tmb; unsigned int *natping_state = 0; static str timeout_socket_str = {0, 0}; +static str timeout_tag_pv_str = {0, 0}; +static pv_elem_t *timeout_tag_pv = NULL; static pv_elem_t *extra_id_pv = NULL; static cmd_export_t cmds[] = { @@ -243,6 +245,7 @@ static param_export_t params[] = { {"rtpproxy_retr", INT_PARAM, &rtpproxy_retr}, {"rtpproxy_tout", INT_PARAM, &rtpproxy_tout}, {"timeout_socket", PARAM_STR, &timeout_socket_str}, + {"timeout_tag_pv", PARAM_STR, &timeout_tag_pv_str}, {"ice_candidate_priority_avp", PARAM_STRING, &ice_candidate_priority_avp_param}, {"extra_id_pv", PARAM_STR, &extra_id_pv_param}, @@ -434,8 +437,8 @@ static int add_rtpproxy_socks(struct rtpp_set *rtpp_list, char *rtpproxy) } -/* 0-succes - * -1 - erorr +/* 0-success + * -1 - error * */ static int rtpproxy_add_rtpproxy_set(char *rtp_proxies) { @@ -735,6 +738,20 @@ static int mod_init(void) } else { extra_id_pv = NULL; } + if(timeout_socket_str.s != NULL && timeout_tag_pv_str.s == NULL) { + LM_ERR("The timeout_tag_pv has to be set along with timeout_socket\n"); + return -1; + } + if(timeout_tag_pv_str.s != NULL) { + if(timeout_tag_pv_str.len == 0) { + LM_ERR("Empty timeout_tag_pv is not allowed\n"); + return -1; + } + if(pv_parse_format(&timeout_tag_pv_str, &timeout_tag_pv) < 0) { + LM_ERR("malformed PV string: %s\n", timeout_tag_pv_str.s); + return -1; + } + } if(rtpp_strings) pkg_free(rtpp_strings); @@ -1488,6 +1505,21 @@ static int get_extra_id(struct sip_msg *msg, str *id_str) } +static int get_timeout_tag(struct sip_msg *msg, str *ntag_str) +{ + if(msg == NULL || timeout_tag_pv == NULL || ntag_str == NULL) { + LM_ERR("bad parameters\n"); + return 0; + } + if(pv_printf_s(msg, timeout_tag_pv, ntag_str) < 0) { + LM_ERR("cannot print the notify tag\n"); + return 0; + } + + return 1; +} + + static int unforce_rtp_proxy1_f(struct sip_msg *msg, char *str1, char *str2) { str flags; @@ -1667,7 +1699,7 @@ static int set_rtp_proxy_set_f(struct sip_msg *msg, char *str1, char *str2) static int rtpproxy_manage(struct sip_msg *msg, char *flags, char *ip) { - char *cp = NULL; + str cp = STR_NULL; char newip[IP_ADDR_MAX_STR_SIZE]; int method; int nosdp; @@ -1696,8 +1728,10 @@ static int rtpproxy_manage(struct sip_msg *msg, char *flags, char *ip) return unforce_rtp_proxy(msg, flags); if(ip == NULL) { - cp = ip_addr2a(&msg->rcv.dst_ip); - strcpy(newip, cp); + cp.s = ip_addr2a(&msg->rcv.dst_ip); + cp.len = strlen(cp.s); + /* Copy, including teminating \0 */ + memcpy(newip, cp.s, cp.len + 1); } if(msg->msg_flags & FL_SDP_BODY) @@ -1707,13 +1741,13 @@ static int rtpproxy_manage(struct sip_msg *msg, char *flags, char *ip) if(msg->first_line.type == SIP_REQUEST) { if(method == METHOD_ACK && nosdp == 0) - return force_rtp_proxy(msg, flags, (cp != NULL) ? newip : ip, 0, + return force_rtp_proxy(msg, flags, (cp.s != NULL) ? newip : ip, 0, (ip != NULL) ? 1 : 0); if(method == METHOD_PRACK && nosdp == 0) - return force_rtp_proxy(msg, flags, (cp != NULL) ? newip : ip, 1, + return force_rtp_proxy(msg, flags, (cp.s != NULL) ? newip : ip, 1, (ip != NULL) ? 1 : 0); if(method == METHOD_UPDATE && nosdp == 0) - return force_rtp_proxy(msg, flags, (cp != NULL) ? newip : ip, 1, + return force_rtp_proxy(msg, flags, (cp.s != NULL) ? newip : ip, 1, (ip != NULL) ? 1 : 0); if(method == METHOD_INVITE && nosdp == 0) { msg->msg_flags |= FL_SDP_BODY; @@ -1722,7 +1756,7 @@ static int rtpproxy_manage(struct sip_msg *msg, char *flags, char *ip) tmb.t_gett()->uas.request->msg_flags |= FL_SDP_BODY; if(route_type == FAILURE_ROUTE) return unforce_rtp_proxy(msg, flags); - return force_rtp_proxy(msg, flags, (cp != NULL) ? newip : ip, 1, + return force_rtp_proxy(msg, flags, (cp.s != NULL) ? newip : ip, 1, (ip != NULL) ? 1 : 0); } } else if(msg->first_line.type == SIP_REPLY) { @@ -1730,19 +1764,19 @@ static int rtpproxy_manage(struct sip_msg *msg, char *flags, char *ip) return unforce_rtp_proxy(msg, flags); if(nosdp == 0) { if(method == METHOD_PRACK) - return force_rtp_proxy(msg, flags, (cp != NULL) ? newip : ip, 0, - (ip != NULL) ? 1 : 0); + return force_rtp_proxy(msg, flags, (cp.s != NULL) ? newip : ip, + 0, (ip != NULL) ? 1 : 0); if(method == METHOD_UPDATE) - return force_rtp_proxy(msg, flags, (cp != NULL) ? newip : ip, 0, - (ip != NULL) ? 1 : 0); + return force_rtp_proxy(msg, flags, (cp.s != NULL) ? newip : ip, + 0, (ip != NULL) ? 1 : 0); if(tmb.t_gett == NULL || tmb.t_gett() == NULL || tmb.t_gett() == T_UNDEFINED) - return force_rtp_proxy(msg, flags, (cp != NULL) ? newip : ip, 0, - (ip != NULL) ? 1 : 0); + return force_rtp_proxy(msg, flags, (cp.s != NULL) ? newip : ip, + 0, (ip != NULL) ? 1 : 0); if(tmb.t_gett()->uas.request->msg_flags & FL_SDP_BODY) - return force_rtp_proxy(msg, flags, (cp != NULL) ? newip : ip, 0, - (ip != NULL) ? 1 : 0); - return force_rtp_proxy(msg, flags, (cp != NULL) ? newip : ip, 1, + return force_rtp_proxy(msg, flags, (cp.s != NULL) ? newip : ip, + 0, (ip != NULL) ? 1 : 0); + return force_rtp_proxy(msg, flags, (cp.s != NULL) ? newip : ip, 1, (ip != NULL) ? 1 : 0); } } @@ -1781,11 +1815,11 @@ static int rtpproxy_manage2(struct sip_msg *msg, char *flags, char *ip) static int rtpproxy_offer1_helper_f(struct sip_msg *msg, char *flags) { - char *cp; char newip[IP_ADDR_MAX_STR_SIZE]; + int len; - cp = ip_addr2a(&msg->rcv.dst_ip); - strcpy(newip, cp); + len = ip_addr2sbuf(&msg->rcv.dst_ip, newip, IP_ADDR_MAX_STR_SIZE - 1); + newip[len] = 0; return force_rtp_proxy(msg, flags, newip, 1, 0); } @@ -1823,15 +1857,17 @@ static int rtpproxy_offer2_f(struct sip_msg *msg, char *param1, char *param2) static int rtpproxy_answer1_helper_f(struct sip_msg *msg, char *flags) { - char *cp; + str cp = STR_NULL; char newip[IP_ADDR_MAX_STR_SIZE]; if(msg->first_line.type == SIP_REQUEST) if(msg->first_line.u.request.method_value != METHOD_ACK) return -1; - cp = ip_addr2a(&msg->rcv.dst_ip); - strcpy(newip, cp); + cp.s = ip_addr2a(&msg->rcv.dst_ip); + cp.len = strlen(cp.s); + /* Copy, including teminating \0 */ + memcpy(newip, cp.s, cp.len + 1); return force_rtp_proxy(msg, flags, newip, 0, 0); } @@ -1965,6 +2001,8 @@ static int force_rtp_proxy( {NULL, 0}, /* medianum */ {" ", 1}, /* separator */ {NULL, 0}, /* Timeout-Socket */ + {" ", 1}, /* separator */ + {NULL, 0}, /* Timeout-Tag */ }; int iovec_param_count; int autobridge_ipv4v6; @@ -2406,14 +2444,21 @@ static int force_rtp_proxy( } if(to_tag.len > 0) { iovec_param_count = 20; - if(opts.s.s[0] == 'U' && timeout_socket_str.len > 0) { - iovec_param_count = 22; - STR2IOVEC(timeout_socket_str, v[21]); - } } else { iovec_param_count = 16; } - + if(opts.s.s[0] == 'U' && timeout_socket_str.len > 0) { + str ntag = {0, 0}; + if(get_timeout_tag(msg, &ntag) == 0 || ntag.s == NULL + || ntag.len == 0) { + LM_ERR("can't get timeout notification tag\n"); + FORCE_RTP_PROXY_RET(-1); + } + STR2IOVEC(timeout_socket_str, v[iovec_param_count + 1]); + iovec_param_count += 2; + STR2IOVEC(ntag, v[iovec_param_count + 1]); + iovec_param_count += 2; + } cp = send_rtpp_command(node, v, iovec_param_count); } while(cp == NULL); LM_DBG("proxy reply: %s\n", cp); diff --git a/src/modules/rtpproxy/rtpproxy_funcs.c b/src/modules/rtpproxy/rtpproxy_funcs.c index 32bc02208..77e6eb00c 100644 --- a/src/modules/rtpproxy/rtpproxy_funcs.c +++ b/src/modules/rtpproxy/rtpproxy_funcs.c @@ -170,8 +170,8 @@ int extract_body(struct sip_msg *msg, str *body) /* * Better use the content-len value - no need of any explicit - * parcing as get_body() parsed all headers and Conten-Length - * body header is automaticaly parsed when found. + * parsing as get_body() parsed all headers and Content-Length + * body header is automatically parsed when found. */ if(msg->content_length == 0) { LM_ERR("failed to get the content length in message\n"); diff --git a/src/modules/rtpproxy/rtpproxy_stream.c b/src/modules/rtpproxy/rtpproxy_stream.c index e4a19a8b6..625a8e7f3 100644 --- a/src/modules/rtpproxy/rtpproxy_stream.c +++ b/src/modules/rtpproxy/rtpproxy_stream.c @@ -55,7 +55,7 @@ int fixup_var_str_int(void **param, int param_no) *param = (void *)model; } else if(param_no == 2) { /* According to - * http://www.kamailio.org/docs/modules/1.5.x/nathelper.html#rtpproxy_stream2xxx + * https://www.kamailio.org/docs/modules/1.5.x/nathelper.html#rtpproxy_stream2xxx * this could be -1 */ s.s = (char *)(*param); s.len = strlen(s.s); diff --git a/src/modules/rtpproxy/test/kamailio.cfg b/src/modules/rtpproxy/test/kamailio.cfg index 16b253962..75ba930f6 100644 --- a/src/modules/rtpproxy/test/kamailio.cfg +++ b/src/modules/rtpproxy/test/kamailio.cfg @@ -29,7 +29,7 @@ tos=0x80 # ------------------ module loading ---------------------------------- mpath="sip-router/modules_k:sip-router/modules" -# To Check/modufy the maximum forwards +# To Check/modify the maximum forwards loadmodule "maxfwd.so" # Transaction-Module loadmodule "tm.so" @@ -87,7 +87,7 @@ modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo") # The Port for incoming XML-RPC requests modparam("mi_xmlrpc", "port", 8000) # Method-Response: A single string parameter should be replied. -# See: http://www.kamailio.org/docs/modules/1.2.x/mi_xmlrpc.html#AEN102 +# See: https://www.kamailio.org/docs/modules/1.2.x/mi_xmlrpc.html#AEN102 modparam("mi_xmlrpc", "reply_option", 1) # The size of the Buffer used to create the XML-RPC-Request-Node modparam("mi_xmlrpc", "buffer_size", 8192) @@ -112,7 +112,7 @@ modparam("dialog", "dlg_match_mode", 1) # Describe how to push into the DB the dialogs' information from memory. # The supported modes are: # 0 - NO_DB - the memory content is not flushed into DB; -# 1 - REALTIME - any dialog information changes will be reflected into the database immediatly. +# 1 - REALTIME - any dialog information changes will be reflected into the database immediately. # 2 - DELAYED - the dialog information changes will be flushed into DB periodically, based on a timre routine. modparam("dialog", "db_mode", 0) # The interval (seconds) at which to update dialogs' information if you chose to store the dialogs' info at a given interval. @@ -224,7 +224,7 @@ route[1] { # * via sip version - (8) - not working because parser fails already when another version then 2.0 is present. # * via protocol - (16) - not working because parser fails already if an unsupported transport is present. # * cseq method - (32) - checks if the method from the cseq header is equal to the request method. - # * cseq value - (64) - checks if the number in the cseq header is a valid unsigend integer. + # * cseq value - (64) - checks if the number in the cseq header is a valid unsigned integer. # * content length - (128) - checks if the size of the body matches with the value from the content length header. # * expires value - (256) - checks if the value of the expires header is a valid unsigned integer. # * proxy require - (512) - checks if all items of the proxy require header are present in the list of the diff --git a/src/modules/ruxc/README b/src/modules/ruxc/README index 4e1f5e6fa..442edccc4 100644 --- a/src/modules/ruxc/README +++ b/src/modules/ruxc/README @@ -129,7 +129,7 @@ Chapter 1. Admin Guide 3.1. http_timeout (int) - The interval in miliseconds after which the HTTP GET or POST query + The interval in milliseconds after which the HTTP GET or POST query times out. It is the overall timeout, including DNS resolution, connecting time, redirects, and reading the response body. Slow DNS resolution may cause a request to exceed the timeout, because the DNS @@ -149,9 +149,9 @@ modparam("ruxc", "http_timeout", 2000) 3.2. http_timeout_connect (int) - The interval in miliseconds after which to give up on connecting to the - HTTP/S server. If http_timeout is set, this one takes precedence. The - library beneath has a default 30 seconds connect timeout. + The interval in milliseconds after which to give up on connecting to + the HTTP/S server. If http_timeout is set, this one takes precedence. + The library beneath has a default 30 seconds connect timeout. Use 0 to disable setting it in the library. @@ -164,7 +164,7 @@ modparam("ruxc", "http_timeout_connect", 2000) 3.3. http_timeout_read (int) - The interval in miliseconds after which the read on HTTP/S connection + The interval in milliseconds after which the read on HTTP/S connection socket timeouts. If http_timeout is set, it takes precedence. Use 0 to disable setting it in the library. @@ -178,7 +178,7 @@ modparam("ruxc", "http_timeout_read", 2000) 3.4. http_timeout_write (int) - The interval in miliseconds after which the write on HTTP/S connection + The interval in milliseconds after which the write on HTTP/S connection socket timeouts. If http_timeout is set, it takes precedence. Use 0 to disable setting it in the library. diff --git a/src/modules/ruxc/doc/ruxc_admin.xml b/src/modules/ruxc/doc/ruxc_admin.xml index dc557ad61..5d60476d5 100644 --- a/src/modules/ruxc/doc/ruxc_admin.xml +++ b/src/modules/ruxc/doc/ruxc_admin.xml @@ -61,7 +61,7 @@
<varname>http_timeout</varname> (int) - The interval in miliseconds after which the HTTP GET or POST query + The interval in milliseconds after which the HTTP GET or POST query times out. It is the overall timeout, including DNS resolution, connecting time, redirects, and reading the response body. Slow DNS resolution may cause a request to exceed the timeout, because the DNS request @@ -89,7 +89,7 @@ modparam("ruxc", "http_timeout", 2000)
<varname>http_timeout_connect</varname> (int) - The interval in miliseconds after which to give up on connecting to the + The interval in milliseconds after which to give up on connecting to the HTTP/S server. If http_timeout is set, this one takes precedence. The library beneath has a default 30 seconds connect timeout. @@ -113,7 +113,7 @@ modparam("ruxc", "http_timeout_connect", 2000)
<varname>http_timeout_read</varname> (int) - The interval in miliseconds after which the read on HTTP/S connection + The interval in milliseconds after which the read on HTTP/S connection socket timeouts. If http_timeout is set, it takes precedence. @@ -136,7 +136,7 @@ modparam("ruxc", "http_timeout_read", 2000)
<varname>http_timeout_write</varname> (int) - The interval in miliseconds after which the write on HTTP/S connection + The interval in milliseconds after which the write on HTTP/S connection socket timeouts. If http_timeout is set, it takes precedence. diff --git a/src/modules/sanity/sanity.c b/src/modules/sanity/sanity.c index 7ec9fc6c2..fa3d04938 100644 --- a/src/modules/sanity/sanity.c +++ b/src/modules/sanity/sanity.c @@ -81,12 +81,13 @@ int ki_sanity_reply(sip_msg_t *msg) || msg->id != _ksr_sanity_info.msgid || msg->pid != _ksr_sanity_info.msgpid) { LM_INFO("no sanity reply info set - sending 500\n"); - if(slb.zreply(msg, 500, "Server Sanity Failure") < 0) { + if(_sanity_slb.zreply(msg, 500, "Server Sanity Failure") < 0) { return -1; } return 1; } - if(slb.zreply(msg, _ksr_sanity_info.code, _ksr_sanity_info.reason) + if(_sanity_slb.zreply( + msg, _ksr_sanity_info.code, _ksr_sanity_info.reason) < 0) { return -1; } @@ -120,7 +121,7 @@ int sanity_reply(sip_msg_t *msg, int code, char *reason) _ksr_sanity_info.msgpid = msg->pid; } else { if(!(msg->msg_flags & FL_MSG_NOREPLY)) { - if(slb.zreply(msg, code, reason) < 0) { + if(_sanity_slb.zreply(msg, code, reason) < 0) { return -1; } } diff --git a/src/modules/sanity/sanity_mod.c b/src/modules/sanity/sanity_mod.c index 7a496ca2a..99f64fbf0 100644 --- a/src/modules/sanity/sanity_mod.c +++ b/src/modules/sanity/sanity_mod.c @@ -34,7 +34,7 @@ MODULE_VERSION #define PROXY_REQUIRE_DEF "" -str pr_str = STR_STATIC_INIT(PROXY_REQUIRE_DEF); +static str _sanity_prval = STR_STATIC_INIT(PROXY_REQUIRE_DEF); int default_msg_checks = SANITY_DEFAULT_CHECKS; int default_uri_checks = SANITY_DEFAULT_URI_CHECKS; @@ -43,7 +43,7 @@ int ksr_sanity_noreply = 0; str_list_t *proxyrequire_list = NULL; -sl_api_t slb; +sl_api_t _sanity_slb; static int mod_init(void); static int w_sanity_check(sip_msg_t *_msg, char *_msg_check, char *_uri_check); @@ -70,7 +70,7 @@ static cmd_export_t cmds[] = {{"sanity_check", (cmd_function)w_sanity_check, 0, static param_export_t params[] = { {"default_checks", PARAM_INT, &default_msg_checks}, {"uri_checks", PARAM_INT, &default_uri_checks}, - {"proxy_require", PARAM_STR, &pr_str}, + {"proxy_require", PARAM_STR, &_sanity_prval}, {"autodrop", PARAM_INT, &_sanity_drop}, {"noreply", PARAM_INT, &ksr_sanity_noreply}, {0, 0, 0}}; @@ -102,13 +102,13 @@ static int mod_init(void) ksr_sanity_info_init(); /* bind the SL API */ - if(sl_load_api(&slb) != 0) { + if(sl_load_api(&_sanity_slb) != 0) { LM_ERR("cannot bind to SL API\n"); return -1; } LM_DBG("parsing proxy requires string:\n"); - ptr = parse_str_list(&pr_str); + ptr = parse_str_list(&_sanity_prval); proxyrequire_list = ptr; diff --git a/src/modules/sanity/sanity_mod.h b/src/modules/sanity/sanity_mod.h index 4ad92850e..41e13359e 100644 --- a/src/modules/sanity/sanity_mod.h +++ b/src/modules/sanity/sanity_mod.h @@ -72,6 +72,6 @@ extern int default_checks; extern str_list_t *proxyrequire_list; -extern sl_api_t slb; +extern sl_api_t _sanity_slb; #endif /* MOD_SANITY_CHK_H */ diff --git a/src/modules/sca/sca_appearance.c b/src/modules/sca/sca_appearance.c index c467137a8..fcc94c4c2 100644 --- a/src/modules/sca/sca_appearance.c +++ b/src/modules/sca/sca_appearance.c @@ -60,7 +60,7 @@ void sca_appearance_state_to_str(int state, str *state_str) { assert(state_str != NULL); - if(state >= SCA_APPEARANCE_STATE_NAME_COUNT || state < 0) { + if(state < 0 || state >= SCA_APPEARANCE_STATE_NAME_COUNT) { state_str->len = SCA_APPEARANCE_STATE_STR_UNKNOWN.len; state_str->s = SCA_APPEARANCE_STATE_STR_UNKNOWN.s; diff --git a/src/modules/sca/sca_call_info.c b/src/modules/sca/sca_call_info.c index 838feca16..2694239cb 100644 --- a/src/modules/sca/sca_call_info.c +++ b/src/modules/sca/sca_call_info.c @@ -112,6 +112,7 @@ static int sca_call_info_header_append_appearances( str state_str; int slot_idx; int len = -1; + int l1 = -1; int usedlen = -1; slot_idx = @@ -153,9 +154,14 @@ static int sca_call_info_header_append_appearances( sca_appearance_state_to_str(app->state, &state_str); // state_str.s is a nul-terminated string literal - len += snprintf(hdrbuf + len, maxlen - len, + l1 = snprintf(hdrbuf + len, maxlen - len, ">;appearance-index=%d;appearance-state=%s", app->index, state_str.s); + if(l1 < 0 || l1 >= maxlen - len) { + LM_ERR("failed to print the header\n"); + return -1; + } + len += l1; if(!SCA_STR_EMPTY(&app->uri)) { hdrbuf[len] = ';'; @@ -1379,7 +1385,7 @@ void sca_call_info_ack_from_handler(sip_msg_t *msg, str *from_aor, str *to_aor) // Polycom's music-on-hold implementation uses an INVITE with // an empty body to get the remote party's SDP info, then INVITEs // a pre-defined URI on a media server, using the remote party's - // SDP as the INVITE body. the media server streams hold music to + // SDP as the INVITE body. The media server streams hold music to // the remote party. // // because the INVITE that triggers the hold in this case doesn't diff --git a/src/modules/sca/sca_rpc.c b/src/modules/sca/sca_rpc.c index c3b9b0f2b..bedfdaa01 100644 --- a/src/modules/sca/sca_rpc.c +++ b/src/modules/sca/sca_rpc.c @@ -199,10 +199,6 @@ void sca_rpc_deactivate_all_subscriptions(rpc_t *rpc, void *ctx) rpc->rpl_printf(ctx, "Deactivating %s subscription from %.*s", sca_event_name_from_type(sub->event), STR_FMT(&sub->subscriber)); - if(rc < 0) { - // make sure we unlock below - break; - } rc = sca_notify_subscriber( sca, sub, SCA_CALL_INFO_APPEARANCE_INDEX_ANY); diff --git a/src/modules/sca/sca_subscribe.c b/src/modules/sca/sca_subscribe.c index dc33f0057..895141e1e 100644 --- a/src/modules/sca/sca_subscribe.c +++ b/src/modules/sca/sca_subscribe.c @@ -133,7 +133,7 @@ void sca_subscription_purge_expired(unsigned int ticks, void *param) "subscribers failed\n", sca_event_name_from_type(sub->event), STR_FMT(&sub->target_aor)); - // fall through anyway. the state should propagate + // fall through anyway. The state should propagate // to subscribers when they renew call-info. } } @@ -669,7 +669,7 @@ sca_subscription *sca_subscription_create(str *aor, int event, str *subscriber, // dialog.id. // // we shm_malloc this separately in case we need to update in-memory - // dialog saved for this subscriber. this is likely to happen if the + // dialog saved for this subscriber. This is likely to happen if the // subscriber goes off-line for some reason. len = sizeof(char) * (call_id->len + from_tag->len + to_tag->len); sub->dialog.id.s = (char *)shm_malloc(len); @@ -905,6 +905,17 @@ static int sca_subscription_update_unsafe(sca_mod *scam, } SCA_STR_COPY(&update_sub->rr, &saved_sub->rr); + } else if(!SCA_STR_EMPTY(&update_sub->rr) + && !STR_EQ(update_sub->rr, saved_sub->rr)) { + if(!SCA_STR_EMPTY(&saved_sub->rr)) { + shm_free(saved_sub->rr.s); + saved_sub->rr.len = 0; + } + if((saved_sub->rr.s = (char *)shm_malloc(update_sub->rr.len)) == NULL) { + SHM_MEM_ERROR; + goto done; + } + SCA_STR_COPY(&saved_sub->rr, &update_sub->rr); } rc = 1; @@ -1415,7 +1426,7 @@ int sca_subscription_reply(sca_mod *scam, int status_code, char *status_msg, extra_headers.s = hdr_buf; len = snprintf(extra_headers.s, sizeof(hdr_buf), "Event: %s%s", sca_event_name_from_type(event_type), CRLF); - if(len >= sizeof(hdr_buf) || len < 0) { + if(len < 0 || len >= sizeof(hdr_buf)) { LM_ERR("sca_subscription_reply: extra headers too long\n"); return (-1); } @@ -1435,7 +1446,7 @@ int sca_subscription_reply(sca_mod *scam, int status_code, char *status_msg, len = snprintf(extra_headers.s + extra_headers.len, sizeof(hdr_buf) - extra_headers.len, "Expires: %d%s", expires, CRLF); - if(len >= (sizeof(hdr_buf) - extra_headers.len) || len < 0) { + if(len < 0 || len >= (sizeof(hdr_buf) - extra_headers.len)) { LM_ERR("sca_subscription_reply: extra headers too long\n"); return (-1); } diff --git a/src/modules/sca/sca_util.c b/src/modules/sca/sca_util.c index 4ab4c6ff9..e61fb749d 100644 --- a/src/modules/sca/sca_util.c +++ b/src/modules/sca/sca_util.c @@ -465,7 +465,7 @@ int sca_call_is_held(sip_msg_t *msg) return (0); } - // Cf. modules_k/textops's exported is_audio_on_hold + // Cf. modules_k/textops' exported is_audio_on_hold for(n_sess = 0, session = get_sdp_session(msg, n_sess); session != NULL; n_sess++, session = get_sdp_session(msg, n_sess)) { diff --git a/src/modules/sdpops/README b/src/modules/sdpops/README index 74aa3dc19..344c358ad 100644 --- a/src/modules/sdpops/README +++ b/src/modules/sdpops/README @@ -46,10 +46,17 @@ Daniel-Constantin Mierla 4.18. sdp_with_ice() 4.19. sdp_get_line_startswith(avpvar, string) 4.20. sdp_get_address_family() + 4.21. sdp_iterator_start(iname) + 4.22. sdp_iterator_end(iname) + 4.23. sdp_iterator_next(iname) + 4.24. sdp_iterator_rm(iname) + 4.25. sdp_iterator_append(iname, text) + 4.26. sdp_iterator_insert(iname, text) 5. Exported Variables 5.1. $sdp( ) + 5.2. $sdpitval( ) List of Examples @@ -73,6 +80,12 @@ Daniel-Constantin Mierla 1.18. sdp_with_ice usage 1.19. sdp_get_line_startswith usage 1.20. sdp_get_address_familyusage + 1.21. sdp_iterator_start usage + 1.22. sdp_iterator_end usage + 1.23. sdp_iterator_next usage + 1.24. sdp_iterator_rm usage + 1.25. sdp_iterator_append usage + 1.26. sdp_iterator_insert usage Chapter 1. Admin Guide @@ -107,10 +120,17 @@ Chapter 1. Admin Guide 4.18. sdp_with_ice() 4.19. sdp_get_line_startswith(avpvar, string) 4.20. sdp_get_address_family() + 4.21. sdp_iterator_start(iname) + 4.22. sdp_iterator_end(iname) + 4.23. sdp_iterator_next(iname) + 4.24. sdp_iterator_rm(iname) + 4.25. sdp_iterator_append(iname, text) + 4.26. sdp_iterator_insert(iname, text) 5. Exported Variables 5.1. $sdp( ) + 5.2. $sdpitval( ) 1. Overview @@ -164,6 +184,12 @@ Chapter 1. Admin Guide 4.18. sdp_with_ice() 4.19. sdp_get_line_startswith(avpvar, string) 4.20. sdp_get_address_family() + 4.21. sdp_iterator_start(iname) + 4.22. sdp_iterator_end(iname) + 4.23. sdp_iterator_next(iname) + 4.24. sdp_iterator_rm(iname) + 4.25. sdp_iterator_append(iname, text) + 4.26. sdp_iterator_insert(iname, text) 4.1. sdp_remove_codecs_by_id(list [, mtype]) @@ -518,9 +544,121 @@ if(is_method("INVITE") && has_body("application/sdp")){ } ... +4.21. sdp_iterator_start(iname) + + Start an iterator for lines in the body of the current SIP message. The + parameter iname is used to identify the iterator. There can be up to 4 + iterators at the same time, with different name. + + The parameter can be a dynamic string with variables. + + This function can be used from ANY_ROUTE. + + Example 1.21. sdp_iterator_start usage +... +sdp_iterator_start("s1"); +... + +4.22. sdp_iterator_end(iname) + + Close the iterator identified by iname parameter. The iname value must + be the same used for sdp_iterator_start(). + + The parameter can be dynamic string with variables. + + This function can be used from ANY_ROUTE. + + Example 1.22. sdp_iterator_end usage +... +sdp_iterator_end("s1"); +... + +4.23. sdp_iterator_next(iname) + + Move the iterator to the next line in the body. It must be called also + after sdp_iterator_start() to get the first header. + + The return code is false when there is no other header in the list. + + The SDP line is accessible via variable $sdpitval(iname) - it contains + also the EOL chars. + + The parameter can be dynamic string with variables. + + This function can be used from ANY_ROUTE. + + Example 1.23. sdp_iterator_next usage +... + sdp_iterator_start("s1"); + while(sdp_iterator_next("s1")) { + xlog("body line: $sdpitval(s1)"); + } + sdp_iterator_end("s1"); +... + +4.24. sdp_iterator_rm(iname) + + Remove the body line at the current iterator position. + + The parameter can be dynamic string with variables. + + This function can be used from ANY_ROUTE. + + Example 1.24. sdp_iterator_rm usage +... + sdp_iterator_start("s1"); + while(sdp_iterator_next("s1")) { + if($sdpitval(s1)=~"abc") { + sdp_iterator_rm("s1"); + } + } + sdp_iterator_end("s1"); +... + +4.25. sdp_iterator_append(iname, text) + + Add text after the line at the current iterator possition. + + The parameters can be dynamic strings with variables. + + This function can be used from ANY_ROUTE. + + Example 1.25. sdp_iterator_append usage +... + sdp_iterator_start("s1"); + while(sdp_iterator_next("s1")) { + if($sdpitval(s1)=~"^a=info:xyz") { + sdp_iterator_append("s1", "a=info:abc\r\n"); + break; + } + } + sdp_iterator_end("s1"); +... + +4.26. sdp_iterator_insert(iname, text) + + Add text before the line at the current iterator possition. + + The parameters can be dynamic strings with variables. + + This function can be used from ANY_ROUTE. + + Example 1.26. sdp_iterator_insert usage +... + sdp_iterator_start("s1"); + while(sdp_iterator_next("s1")) { + if($sdpitval(s1)=~"^a=info:xyz") { + sdp_iterator_insert("s1", "a=info:abc\r\n"); + break; + } + } + sdp_iterator_end("s1"); +... + 5. Exported Variables 5.1. $sdp( ) + 5.2. $sdpitval( ) 5.1. $sdp( ) @@ -529,6 +667,13 @@ if(is_method("INVITE") && has_body("application/sdp")){ * $sdp(sess_version) - sess-version -attribute from SDP o= -line. When set to special value -1, current value is incremented. (read + write) + * $sdp(c:ip) - connection IP (read only) - taken from first media + strea if specified, otherwise from first session. Exported pseudo-variables are also documented at https://www.kamailio.org/wikidocs/ + +5.2. $sdpitval( ) + + Return the value of to SDP line iterator with the given name: + $sdpitval(name). diff --git a/src/modules/sdpops/doc/sdpops_admin.xml b/src/modules/sdpops/doc/sdpops_admin.xml index 0bd00c5c9..3c802d4cd 100644 --- a/src/modules/sdpops/doc/sdpops_admin.xml +++ b/src/modules/sdpops/doc/sdpops_admin.xml @@ -595,7 +595,174 @@ if(is_method("INVITE") && has_body("application/sdp")){
- +
+ + <function moreinfo="none">sdp_iterator_start(iname)</function> + + + Start an iterator for lines in the body of the current SIP message. + The parameter iname is used to identify the iterator. There + can be up to 4 iterators at the same time, with different name. + + + The parameter can be a dynamic string with variables. + + + This function can be used from ANY_ROUTE. + + + <function>sdp_iterator_start</function> usage + +... +sdp_iterator_start("s1"); +... + + +
+
+ + <function moreinfo="none">sdp_iterator_end(iname)</function> + + + Close the iterator identified by iname parameter. The iname value + must be the same used for sdp_iterator_start(). + + + The parameter can be dynamic string with variables. + + + This function can be used from ANY_ROUTE. + + + <function>sdp_iterator_end</function> usage + +... +sdp_iterator_end("s1"); +... + + +
+
+ + <function moreinfo="none">sdp_iterator_next(iname)</function> + + + Move the iterator to the next line in the body. It must + be called also after sdp_iterator_start() to get the first + header. + + + The return code is false when there is no other header in the list. + + + The SDP line is accessible via variable $sdpitval(iname) - it contains + also the EOL chars. + + + The parameter can be dynamic string with variables. + + + This function can be used from ANY_ROUTE. + + + <function>sdp_iterator_next</function> usage + +... + sdp_iterator_start("s1"); + while(sdp_iterator_next("s1")) { + xlog("body line: $sdpitval(s1)"); + } + sdp_iterator_end("s1"); +... + + +
+
+ + <function moreinfo="none">sdp_iterator_rm(iname)</function> + + + Remove the body line at the current iterator position. + + + The parameter can be dynamic string with variables. + + + This function can be used from ANY_ROUTE. + + + <function>sdp_iterator_rm</function> usage + +... + sdp_iterator_start("s1"); + while(sdp_iterator_next("s1")) { + if($sdpitval(s1)=~"abc") { + sdp_iterator_rm("s1"); + } + } + sdp_iterator_end("s1"); +... + + +
+
+ + <function moreinfo="none">sdp_iterator_append(iname, text)</function> + + + Add text after the line at the current iterator possition. + + + The parameters can be dynamic strings with variables. + + + This function can be used from ANY_ROUTE. + + + <function>sdp_iterator_append</function> usage + +... + sdp_iterator_start("s1"); + while(sdp_iterator_next("s1")) { + if($sdpitval(s1)=~"^a=info:xyz") { + sdp_iterator_append("s1", "a=info:abc\r\n"); + break; + } + } + sdp_iterator_end("s1"); +... + + +
+
+ + <function moreinfo="none">sdp_iterator_insert(iname, text)</function> + + + Add text before the line at the current iterator possition. + + + The parameters can be dynamic strings with variables. + + + This function can be used from ANY_ROUTE. + + + <function>sdp_iterator_insert</function> usage + +... + sdp_iterator_start("s1"); + while(sdp_iterator_next("s1")) { + if($sdpitval(s1)=~"^a=info:xyz") { + sdp_iterator_insert("s1", "a=info:abc\r\n"); + break; + } + } + sdp_iterator_end("s1"); +... + + +
@@ -608,13 +775,25 @@ if(is_method("INVITE") && has_body("application/sdp")){ $sdp(body) - full SDP body (read only) - $sdp(sess_version) - sess-version -attribute from SDP o= -line. When set to special value -1, current value is incremented. (read + write) + $sdp(sess_version) - sess-version -attribute + from SDP o= -line. When set to special value -1, current value + is incremented. (read + write) + + + $sdp(c:ip) - connection IP (read only) + - taken from first media strea if specified, otherwise from + first session. Exported pseudo-variables are also documented at &kamwikilink;
+
+ <varname>$sdpitval( )</varname> + Return the value of to SDP line iterator with the given + name: $sdpitval(name). +
diff --git a/src/modules/sdpops/sdpops_mod.c b/src/modules/sdpops/sdpops_mod.c index 3fbc3698a..980c27506 100644 --- a/src/modules/sdpops/sdpops_mod.c +++ b/src/modules/sdpops/sdpops_mod.c @@ -66,6 +66,14 @@ static int w_sdp_content_sloppy(sip_msg_t *msg, char *foo, char *bar); static int w_sdp_with_ice(sip_msg_t *msg, char *foo, char *bar); static int w_sdp_get_line_startswith(sip_msg_t *msg, char *foo, char *bar); +static int w_sdp_iterator_start(sip_msg_t *msg, char *piname, char *p2); +static int w_sdp_iterator_next(sip_msg_t *msg, char *piname, char *p2); +static int w_sdp_iterator_end(sip_msg_t *msg, char *piname, char *p2); +static int w_sdp_iterator_rm(sip_msg_t *msg, char *piname, char *p2); +static int w_sdp_iterator_append(sip_msg_t *msg, char *piname, char *ptext); +static int w_sdp_iterator_insert(sip_msg_t *msg, char *piname, char *ptext); + + static int sdp_get_sess_version( sip_msg_t *msg, str *sess_version, long *sess_version_num); static int sdp_set_sess_version( @@ -77,80 +85,105 @@ static int pv_set_sdp( sip_msg_t *msg, pv_param_t *param, int op, pv_value_t *res); static int pv_parse_sdp_name(pv_spec_p sp, str *in); +static void sdp_iterator_init(void); +static int pv_parse_sdp_iterator_name(pv_spec_t *sp, str *in); +static int pv_get_sdp_iterator_value( + sip_msg_t *msg, pv_param_t *param, pv_value_t *res); + static int mod_init(void); +/* clang-format off */ static cmd_export_t cmds[] = { - {"sdp_remove_line_by_prefix", (cmd_function)w_sdp_remove_line_by_prefix, - 1, fixup_spve_null, 0, ANY_ROUTE}, - {"sdp_remove_line_by_prefix", (cmd_function)w_sdp_remove_line_by_prefix, - 2, fixup_spve_spve, 0, ANY_ROUTE}, - {"sdp_remove_codecs_by_id", (cmd_function)w_sdp_remove_codecs_by_id, 1, - fixup_spve_null, 0, ANY_ROUTE}, - {"sdp_remove_codecs_by_id", (cmd_function)w_sdp_remove_codecs_by_id, 2, - fixup_spve_spve, 0, ANY_ROUTE}, - {"sdp_remove_codecs_by_name", (cmd_function)w_sdp_remove_codecs_by_name, - 1, fixup_spve_null, 0, ANY_ROUTE}, - {"sdp_remove_codecs_by_name", (cmd_function)w_sdp_remove_codecs_by_name, - 2, fixup_spve_spve, 0, ANY_ROUTE}, - {"sdp_keep_codecs_by_id", (cmd_function)w_sdp_keep_codecs_by_id, 1, - fixup_spve_null, 0, ANY_ROUTE}, - {"sdp_keep_codecs_by_id", (cmd_function)w_sdp_keep_codecs_by_id, 2, - fixup_spve_spve, 0, ANY_ROUTE}, - {"sdp_keep_codecs_by_name", (cmd_function)w_sdp_keep_codecs_by_name, 1, - fixup_spve_null, 0, ANY_ROUTE}, - {"sdp_keep_codecs_by_name", (cmd_function)w_sdp_keep_codecs_by_name, 2, - fixup_spve_spve, 0, ANY_ROUTE}, - {"sdp_with_media", (cmd_function)w_sdp_with_media, 1, fixup_spve_null, - 0, ANY_ROUTE}, - {"sdp_with_active_media", (cmd_function)w_sdp_with_active_media, 1, - fixup_spve_null, 0, ANY_ROUTE}, - {"sdp_remove_media", (cmd_function)w_sdp_remove_media, 1, - fixup_spve_null, 0, ANY_ROUTE}, - {"sdp_with_transport", (cmd_function)w_sdp_with_transport, 1, - fixup_spve_null, 0, ANY_ROUTE}, - {"sdp_with_transport_like", (cmd_function)w_sdp_with_transport_like, 1, - fixup_spve_null, 0, ANY_ROUTE}, - {"sdp_remove_transport", (cmd_function)w_sdp_remove_transport, 1, - fixup_spve_null, 0, ANY_ROUTE}, - {"sdp_transport", (cmd_function)w_sdp_transport, 1, 0, 0, ANY_ROUTE}, - {"sdp_with_codecs_by_id", (cmd_function)w_sdp_with_codecs_by_id, 1, - fixup_spve_null, 0, ANY_ROUTE}, - {"sdp_with_codecs_by_name", (cmd_function)w_sdp_with_codecs_by_name, 1, - fixup_spve_null, 0, ANY_ROUTE}, - {"sdp_print", (cmd_function)w_sdp_print, 1, fixup_igp_null, 0, - ANY_ROUTE}, - {"sdp_get", (cmd_function)w_sdp_get, 1, 0, 0, ANY_ROUTE}, - {"sdp_content", (cmd_function)w_sdp_content, 0, 0, 0, ANY_ROUTE}, - {"sdp_content", (cmd_function)w_sdp_content_sloppy, 1, 0, 0, ANY_ROUTE}, - {"sdp_with_ice", (cmd_function)w_sdp_with_ice, 0, 0, 0, ANY_ROUTE}, - {"sdp_get_line_startswith", (cmd_function)w_sdp_get_line_startswith, 2, - fixup_none_spve, 0, ANY_ROUTE}, - {"sdp_get_address_family", (cmd_function)w_sdp_get_address_family, 0, 0, - 0, ANY_ROUTE}, - {"bind_sdpops", (cmd_function)bind_sdpops, 1, 0, 0, 0}, - {0, 0, 0, 0, 0, 0}}; + {"sdp_remove_line_by_prefix", (cmd_function)w_sdp_remove_line_by_prefix, + 1, fixup_spve_null, 0, ANY_ROUTE}, + {"sdp_remove_line_by_prefix", (cmd_function)w_sdp_remove_line_by_prefix, + 2, fixup_spve_spve, 0, ANY_ROUTE}, + {"sdp_remove_codecs_by_id", (cmd_function)w_sdp_remove_codecs_by_id, 1, + fixup_spve_null, 0, ANY_ROUTE}, + {"sdp_remove_codecs_by_id", (cmd_function)w_sdp_remove_codecs_by_id, 2, + fixup_spve_spve, 0, ANY_ROUTE}, + {"sdp_remove_codecs_by_name", (cmd_function)w_sdp_remove_codecs_by_name, + 1, fixup_spve_null, 0, ANY_ROUTE}, + {"sdp_remove_codecs_by_name", (cmd_function)w_sdp_remove_codecs_by_name, + 2, fixup_spve_spve, 0, ANY_ROUTE}, + {"sdp_keep_codecs_by_id", (cmd_function)w_sdp_keep_codecs_by_id, 1, + fixup_spve_null, 0, ANY_ROUTE}, + {"sdp_keep_codecs_by_id", (cmd_function)w_sdp_keep_codecs_by_id, 2, + fixup_spve_spve, 0, ANY_ROUTE}, + {"sdp_keep_codecs_by_name", (cmd_function)w_sdp_keep_codecs_by_name, 1, + fixup_spve_null, 0, ANY_ROUTE}, + {"sdp_keep_codecs_by_name", (cmd_function)w_sdp_keep_codecs_by_name, 2, + fixup_spve_spve, 0, ANY_ROUTE}, + {"sdp_with_media", (cmd_function)w_sdp_with_media, 1, fixup_spve_null, + 0, ANY_ROUTE}, + {"sdp_with_active_media", (cmd_function)w_sdp_with_active_media, 1, + fixup_spve_null, 0, ANY_ROUTE}, + {"sdp_remove_media", (cmd_function)w_sdp_remove_media, 1, + fixup_spve_null, 0, ANY_ROUTE}, + {"sdp_with_transport", (cmd_function)w_sdp_with_transport, 1, + fixup_spve_null, 0, ANY_ROUTE}, + {"sdp_with_transport_like", (cmd_function)w_sdp_with_transport_like, 1, + fixup_spve_null, 0, ANY_ROUTE}, + {"sdp_remove_transport", (cmd_function)w_sdp_remove_transport, 1, + fixup_spve_null, 0, ANY_ROUTE}, + {"sdp_transport", (cmd_function)w_sdp_transport, 1, 0, 0, ANY_ROUTE}, + {"sdp_with_codecs_by_id", (cmd_function)w_sdp_with_codecs_by_id, 1, + fixup_spve_null, 0, ANY_ROUTE}, + {"sdp_with_codecs_by_name", (cmd_function)w_sdp_with_codecs_by_name, 1, + fixup_spve_null, 0, ANY_ROUTE}, + {"sdp_print", (cmd_function)w_sdp_print, 1, fixup_igp_null, 0, + ANY_ROUTE}, + {"sdp_get", (cmd_function)w_sdp_get, 1, 0, 0, ANY_ROUTE}, + {"sdp_content", (cmd_function)w_sdp_content, 0, 0, 0, ANY_ROUTE}, + {"sdp_content", (cmd_function)w_sdp_content_sloppy, 1, 0, 0, ANY_ROUTE}, + {"sdp_with_ice", (cmd_function)w_sdp_with_ice, 0, 0, 0, ANY_ROUTE}, + {"sdp_get_line_startswith", (cmd_function)w_sdp_get_line_startswith, 2, + fixup_none_spve, 0, ANY_ROUTE}, + {"sdp_get_address_family", (cmd_function)w_sdp_get_address_family, 0, 0, + 0, ANY_ROUTE}, + + {"sdp_iterator_start", w_sdp_iterator_start, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"sdp_iterator_next", w_sdp_iterator_next, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"sdp_iterator_end", w_sdp_iterator_end, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"sdp_iterator_rm", w_sdp_iterator_rm, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"sdp_iterator_append", w_sdp_iterator_append, 2, fixup_spve_spve, + fixup_free_spve_spve, ANY_ROUTE}, + {"sdp_iterator_insert", w_sdp_iterator_insert, 2, fixup_spve_spve, + fixup_free_spve_spve, ANY_ROUTE}, + + {"bind_sdpops", (cmd_function)bind_sdpops, 1, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} +}; static pv_export_t mod_pvs[] = { - {{"sdp", (sizeof("sdp") - 1)}, /* */ - PVT_OTHER, pv_get_sdp, pv_set_sdp, pv_parse_sdp_name, 0, 0, 0}, + {{"sdp", (sizeof("sdp") - 1)}, /* */ + PVT_OTHER, pv_get_sdp, pv_set_sdp, pv_parse_sdp_name, 0, 0, 0}, + {{"sdpitval", sizeof("sdpitval") - 1}, PVT_OTHER, + pv_get_sdp_iterator_value, 0, pv_parse_sdp_iterator_name, 0, 0, 0}, - {{0, 0}, 0, 0, 0, 0, 0, 0, 0}}; + {{0, 0}, 0, 0, 0, 0, 0, 0, 0} +}; static param_export_t params[] = {{0, 0, 0}}; /** module exports */ struct module_exports exports = { - "sdpops", /* module name */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* cmd exports */ - params, /* param exports */ - 0, /* RPC method exports */ - mod_pvs, /* exported pseudo-variables */ - 0, /* response handling function */ - mod_init, /* module initialization function */ - 0, /* per-child init function */ - 0 /* module destroy function */ + "sdpops", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* cmd exports */ + params, /* param exports */ + 0, /* RPC method exports */ + mod_pvs, /* exported pseudo-variables */ + 0, /* response handling function */ + mod_init, /* module initialization function */ + 0, /* per-child init function */ + 0 /* module destroy function */ }; +/* clang-format on */ /** * @@ -158,6 +191,7 @@ struct module_exports exports = { static int mod_init(void) { LM_DBG("sdpops module loaded\n"); + sdp_iterator_init(); return 0; } @@ -2049,13 +2083,12 @@ static int pv_get_sdp(sip_msg_t *msg, pv_param_t *param, pv_value_t *res) } switch(param->pvn.u.isname.name.n) { - - /* body */ case 0: + /* body */ LM_DBG("param->pvn.u.isname.name.n=0\n"); return pv_get_strval(msg, param, res, &sdp->raw_sdp); - /* sess_version */ case 1: + /* sess_version */ if(sdp_get_sess_version(msg, &sess_version, &sess_version_num) == 1) { if(sess_version.len > 0 && sess_version.s != NULL) { @@ -2064,6 +2097,34 @@ static int pv_get_sdp(sip_msg_t *msg, pv_param_t *param, pv_value_t *res) } } return pv_get_null(msg, param, res); + case 2: + /* connection ip */ + if(sdp->sessions == NULL) { + return pv_get_null(msg, param, res); + } + if(sdp->sessions->streams == NULL) { + if(sdp->sessions->ip_addr.s != NULL + && sdp->sessions->ip_addr.len > 0) { + return pv_get_strval( + msg, param, res, &sdp->sessions->ip_addr); + } else { + return pv_get_null(msg, param, res); + } + } else { + if(sdp->sessions->streams->ip_addr.s != NULL + && sdp->sessions->streams->ip_addr.len > 0) { + return pv_get_strval( + msg, param, res, &sdp->sessions->streams->ip_addr); + } else { + if(sdp->sessions->ip_addr.s != NULL + && sdp->sessions->ip_addr.len > 0) { + return pv_get_strval( + msg, param, res, &sdp->sessions->ip_addr); + } else { + return pv_get_null(msg, param, res); + } + } + } default: return pv_get_null(msg, param, res); @@ -2110,6 +2171,10 @@ static int pv_parse_sdp_name(pv_spec_p sp, str *in) case 4: if(strncmp(in->s, "body", 4) == 0) sp->pvp.pvn.u.isname.name.n = 0; + else if(strncmp(in->s, "c:ip", 4) == 0) + sp->pvp.pvn.u.isname.name.n = 2; + else if(strncmp(in->s, "o:ip", 4) == 0) + sp->pvp.pvn.u.isname.name.n = 3; else goto error; break; @@ -2132,6 +2197,467 @@ error: return -1; } + +/*** body line iterator */ +#define SDP_ITERATOR_SIZE 4 +#define SDP_ITERATOR_NAME_SIZE 32 + +typedef struct sdp_iterator +{ + str name; + char bname[SDP_ITERATOR_NAME_SIZE]; + str body; + str it; + int eob; +} sdp_iterator_t; + +static sdp_iterator_t _sdp_iterators[SDP_ITERATOR_SIZE]; + +/** + * + */ +static void sdp_iterator_init(void) +{ + memset(_sdp_iterators, 0, SDP_ITERATOR_SIZE * sizeof(sdp_iterator_t)); +} + +/** + * + */ +static int ki_sdp_iterator_start(sip_msg_t *msg, str *iname) +{ + int i; + int k; + sdp_info_t *sdp = NULL; + + if(parse_sdp(msg) < 0) { + LM_ERR("Unable to parse sdp\n"); + return -1; + } + sdp = (sdp_info_t *)msg->body; + if(sdp == NULL) { + LM_DBG("No sdp body\n"); + return -1; + } + + k = -1; + for(i = 0; i < SDP_ITERATOR_SIZE; i++) { + if(_sdp_iterators[i].name.len > 0) { + if(_sdp_iterators[i].name.len == iname->len + && strncmp(_sdp_iterators[i].name.s, iname->s, iname->len) + == 0) { + k = i; + break; + } + } else { + if(k == -1) + k = i; + } + } + if(k == -1) { + LM_ERR("no iterator available - max number is %d\n", SDP_ITERATOR_SIZE); + return -1; + } + if(_sdp_iterators[k].name.len <= 0) { + if(iname->len >= SDP_ITERATOR_NAME_SIZE) { + LM_ERR("iterator name is too big [%.*s] (max %d)\n", iname->len, + iname->s, SDP_ITERATOR_NAME_SIZE); + return -1; + } + strncpy(_sdp_iterators[k].bname, iname->s, iname->len); + _sdp_iterators[k].bname[iname->len] = '\0'; + _sdp_iterators[k].name.len = iname->len; + _sdp_iterators[k].name.s = _sdp_iterators[k].bname; + } + _sdp_iterators[k].it.s = NULL; + _sdp_iterators[k].it.len = 0; + _sdp_iterators[k].eob = 0; + _sdp_iterators[k].body.s = sdp->raw_sdp.s; + if(_sdp_iterators[k].body.s == NULL) { + LM_DBG("no message sdp\n"); + return -1; + } + _sdp_iterators[k].body.len = sdp->raw_sdp.len; + return 1; +} + +/** + * + */ +static int w_sdp_iterator_start(sip_msg_t *msg, char *piname, char *p2) +{ + str iname = STR_NULL; + if(fixup_get_svalue(msg, (gparam_t *)piname, &iname) < 0) { + LM_ERR("failed to get iterator name\n"); + return -1; + } + return ki_sdp_iterator_start(msg, &iname); +} + +/** + * + */ +static int ki_sdp_iterator_next(sip_msg_t *msg, str *iname) +{ + int i; + int k; + char *p; + + k = -1; + for(i = 0; i < SDP_ITERATOR_SIZE; i++) { + if(_sdp_iterators[i].name.len > 0) { + if(_sdp_iterators[i].name.len == iname->len + && strncmp(_sdp_iterators[i].name.s, iname->s, iname->len) + == 0) { + k = i; + break; + } + } + } + if(k == -1) { + LM_ERR("iterator not available [%.*s]\n", iname->len, iname->s); + return -1; + } + if(_sdp_iterators[k].eob == 1) { + return -1; + } + + if(_sdp_iterators[k].it.s == NULL) { + _sdp_iterators[k].it.s = _sdp_iterators[k].body.s; + } + p = _sdp_iterators[k].it.s + _sdp_iterators[k].it.len; + if(p >= _sdp_iterators[k].body.s + _sdp_iterators[k].body.len) { + _sdp_iterators[k].it.s = NULL; + _sdp_iterators[k].it.len = 0; + _sdp_iterators[k].eob = 1; + return -1; + } + _sdp_iterators[k].it.s = p; + while(p < _sdp_iterators[k].body.s + _sdp_iterators[k].body.len) { + if(*p == '\n') { + break; + } + p++; + } + _sdp_iterators[k].it.len = p - _sdp_iterators[k].it.s + 1; + + return 1; +} + +/** + * + */ +static int w_sdp_iterator_next(sip_msg_t *msg, char *piname, char *p2) +{ + str iname = STR_NULL; + if(fixup_get_svalue(msg, (gparam_t *)piname, &iname) < 0) { + LM_ERR("failed to get iterator name\n"); + return -1; + } + return ki_sdp_iterator_next(msg, &iname); +} + +/** + * + */ +static int ki_sdp_iterator_end(sip_msg_t *msg, str *iname) +{ + int i; + int k; + + k = -1; + for(i = 0; i < SDP_ITERATOR_SIZE; i++) { + if(_sdp_iterators[i].name.len > 0) { + if(_sdp_iterators[i].name.len == iname->len + && strncmp(_sdp_iterators[i].name.s, iname->s, iname->len) + == 0) { + k = i; + break; + } + } + } + if(k == -1) { + LM_ERR("iterator not available [%.*s]\n", iname->len, iname->s); + return -1; + } + _sdp_iterators[k].it.s = NULL; + _sdp_iterators[k].it.len = 0; + _sdp_iterators[k].body.s = NULL; + _sdp_iterators[k].body.len = 0; + _sdp_iterators[k].eob = 0; + return 1; +} + +/** + * + */ +static int w_sdp_iterator_end(sip_msg_t *msg, char *piname, char *p2) +{ + str iname = STR_NULL; + if(fixup_get_svalue(msg, (gparam_t *)piname, &iname) < 0) { + LM_ERR("failed to get iterator name\n"); + return -1; + } + return ki_sdp_iterator_end(msg, &iname); +} + +/** + * + */ +static int ki_sdp_iterator_index(sip_msg_t *msg, str *iname) +{ + int i; + int k; + + k = -1; + for(i = 0; i < SDP_ITERATOR_SIZE; i++) { + if(_sdp_iterators[i].name.len > 0) { + if(_sdp_iterators[i].name.len == iname->len + && strncmp(_sdp_iterators[i].name.s, iname->s, iname->len) + == 0) { + k = i; + break; + } + } + } + if(k == -1) { + LM_ERR("iterator not available [%.*s]\n", iname->len, iname->s); + return -1; + } + + return k; +} + +/** + * + */ +static int ki_sdp_iterator_rm(sip_msg_t *msg, str *iname) +{ + int k; + sr_lump_t *anchor; + + k = ki_sdp_iterator_index(msg, iname); + if(k < 0 || _sdp_iterators[k].it.s == NULL + || _sdp_iterators[k].it.len <= 0) { + return -1; + } + anchor = del_lump(msg, _sdp_iterators[k].it.s - msg->buf, + _sdp_iterators[k].it.len, 0); + if(anchor == 0) { + LM_ERR("cannot remove line %.*s\n", _sdp_iterators[k].it.len, + _sdp_iterators[k].it.s); + return -1; + } + return 1; +} + +/** + * + */ +static int w_sdp_iterator_rm(sip_msg_t *msg, char *piname, char *p2) +{ + str iname = STR_NULL; + if(fixup_get_svalue(msg, (gparam_t *)piname, &iname) < 0) { + LM_ERR("failed to get iterator name\n"); + return -1; + } + return ki_sdp_iterator_rm(msg, &iname); +} + +/** + * + */ +static int ki_sdp_iterator_append(sip_msg_t *msg, str *iname, str *text) +{ + int k; + sr_lump_t *anchor; + str sval = STR_NULL; + + k = ki_sdp_iterator_index(msg, iname); + if(k < 0 || _sdp_iterators[k].it.s == NULL + || _sdp_iterators[k].it.len <= 0) { + return -1; + } + anchor = anchor_lump(msg, + _sdp_iterators[k].it.s + _sdp_iterators[k].it.len - msg->buf, 0, 0); + if(anchor == 0) { + LM_ERR("cannot append text after %.*s\n", _sdp_iterators[k].it.len, + _sdp_iterators[k].it.s); + return -1; + } + sval.s = (char *)pkg_malloc(text->len + 1); + if(sval.s == NULL) { + PKG_MEM_ERROR_FMT("failed append text after %.*s\n", + _sdp_iterators[k].it.len, _sdp_iterators[k].it.s); + return -1; + } + memcpy(sval.s, text->s, text->len); + sval.len = text->len; + sval.s[sval.len] = '\0'; + + if(insert_new_lump_before(anchor, sval.s, sval.len, 0) == 0) { + LM_ERR("cannot insert lump\n"); + pkg_free(sval.s); + return -1; + } + return 1; +} + +/** + * + */ +static int w_sdp_iterator_append(sip_msg_t *msg, char *piname, char *ptext) +{ + str iname = STR_NULL; + str text = STR_NULL; + if(fixup_get_svalue(msg, (gparam_t *)piname, &iname) < 0) { + LM_ERR("failed to get iterator name\n"); + return -1; + } + if(fixup_get_svalue(msg, (gparam_t *)ptext, &text) < 0) { + LM_ERR("failed to get text\n"); + return -1; + } + + return ki_sdp_iterator_append(msg, &iname, &text); +} + +/** + * + */ +static int ki_sdp_iterator_insert(sip_msg_t *msg, str *iname, str *text) +{ + int k; + sr_lump_t *anchor; + str sval = STR_NULL; + + k = ki_sdp_iterator_index(msg, iname); + if(k < 0 || _sdp_iterators[k].it.s == NULL + || _sdp_iterators[k].it.len <= 0) { + return -1; + } + anchor = anchor_lump(msg, _sdp_iterators[k].it.s - msg->buf, 0, 0); + if(anchor == 0) { + LM_ERR("cannot insert text after %.*s\n", _sdp_iterators[k].it.len, + _sdp_iterators[k].it.s); + return -1; + } + sval.s = (char *)pkg_malloc(text->len + 1); + if(sval.s == NULL) { + PKG_MEM_ERROR_FMT("failed to insert text after %.*s\n", + _sdp_iterators[k].it.len, _sdp_iterators[k].it.s); + return -1; + } + memcpy(sval.s, text->s, text->len); + sval.len = text->len; + sval.s[sval.len] = '\0'; + + if(insert_new_lump_before(anchor, sval.s, sval.len, 0) == 0) { + LM_ERR("cannot insert lump\n"); + pkg_free(sval.s); + return -1; + } + return 1; +} + +/** + * + */ +static int w_sdp_iterator_insert(sip_msg_t *msg, char *piname, char *ptext) +{ + str iname = STR_NULL; + str text = STR_NULL; + if(fixup_get_svalue(msg, (gparam_t *)piname, &iname) < 0) { + LM_ERR("failed to get iterator name\n"); + return -1; + } + if(fixup_get_svalue(msg, (gparam_t *)ptext, &text) < 0) { + LM_ERR("failed to get text\n"); + return -1; + } + + return ki_sdp_iterator_insert(msg, &iname, &text); +} + +/** + * + */ +static sr_kemi_xval_t _sr_kemi_sdp_iterator_xval = {0}; + +/** + * + */ +static sr_kemi_xval_t *ki_sdp_iterator_value(sip_msg_t *msg, str *iname) +{ + int k; + + memset(&_sr_kemi_sdp_iterator_xval, 0, sizeof(sr_kemi_xval_t)); + k = ki_sdp_iterator_index(msg, iname); + if(k < 0 || _sdp_iterators[k].it.s == NULL + || _sdp_iterators[k].it.len <= 0) { + sr_kemi_xval_null(&_sr_kemi_sdp_iterator_xval, 0); + return &_sr_kemi_sdp_iterator_xval; + } + if(_sdp_iterators[k].it.s == NULL) { + sr_kemi_xval_null(&_sr_kemi_sdp_iterator_xval, 0); + return &_sr_kemi_sdp_iterator_xval; + } + _sr_kemi_sdp_iterator_xval.vtype = SR_KEMIP_STR; + _sr_kemi_sdp_iterator_xval.v.s = _sdp_iterators[k].it; + return &_sr_kemi_sdp_iterator_xval; +} + +/** + * + */ +static int pv_parse_sdp_iterator_name(pv_spec_t *sp, str *in) +{ + if(in->len <= 0) { + return -1; + } + + sp->pvp.pvn.u.isname.name.s.s = in->s; + sp->pvp.pvn.u.isname.name.s.len = in->len; + sp->pvp.pvn.u.isname.type = 0; + sp->pvp.pvn.type = PV_NAME_INTSTR; + + return 0; +} + +/** + * + */ +static int pv_get_sdp_iterator_value( + sip_msg_t *msg, pv_param_t *param, pv_value_t *res) +{ + int i; + int k; + str *iname; + + iname = ¶m->pvn.u.isname.name.s; + k = -1; + for(i = 0; i < SDP_ITERATOR_SIZE; i++) { + if(_sdp_iterators[i].name.len > 0) { + if(_sdp_iterators[i].name.len == iname->len + && strncmp(_sdp_iterators[i].name.s, iname->s, iname->len) + == 0) { + k = i; + break; + } + } + } + if(k == -1) { + LM_ERR("iterator not available [%.*s]\n", iname->len, iname->s); + return pv_get_null(msg, param, res); + } + + if(_sdp_iterators[i].it.s == NULL) { + return pv_get_null(msg, param, res); + } + return pv_get_strval(msg, param, res, &_sdp_iterators[i].it); +} + + /** * */ @@ -2232,6 +2758,41 @@ static sr_kemi_t sr_kemi_sdpops_exports[] = { { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, + { str_init("sdpops"), str_init("sdp_iterator_start"), + SR_KEMIP_INT, ki_sdp_iterator_start, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("sdpops"), str_init("sdp_iterator_end"), + SR_KEMIP_INT, ki_sdp_iterator_end, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("sdpops"), str_init("sdp_iterator_next"), + SR_KEMIP_INT, ki_sdp_iterator_next, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("sdpops"), str_init("sdp_iterator_rm"), + SR_KEMIP_INT, ki_sdp_iterator_rm, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("sdpops"), str_init("sdp_iterator_append"), + SR_KEMIP_INT, ki_sdp_iterator_append, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("sdpops"), str_init("sdp_iterator_insert"), + SR_KEMIP_INT, ki_sdp_iterator_insert, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("sdpops"), str_init("sdp_iterator_value"), + SR_KEMIP_XVAL, ki_sdp_iterator_value, + { SR_KEMIP_STR, 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/seas/encode_allow.c b/src/modules/seas/encode_allow.c index 29d3e50cc..86074b09f 100644 --- a/src/modules/seas/encode_allow.c +++ b/src/modules/seas/encode_allow.c @@ -36,8 +36,9 @@ * * ===================================================================================== */ - +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include #include diff --git a/src/modules/seas/encode_contact.c b/src/modules/seas/encode_contact.c index bf49e7c0d..7afea86b7 100644 --- a/src/modules/seas/encode_contact.c +++ b/src/modules/seas/encode_contact.c @@ -36,8 +36,9 @@ * * ===================================================================================== */ - +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include "../../core/parser/contact/parse_contact.h" #include "../../core/parser/contact/contact.h" diff --git a/src/modules/seas/encode_content_disposition.c b/src/modules/seas/encode_content_disposition.c index 151baf96c..c366f6a45 100644 --- a/src/modules/seas/encode_content_disposition.c +++ b/src/modules/seas/encode_content_disposition.c @@ -36,8 +36,9 @@ * * ===================================================================================== */ - +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include "../../core/parser/parse_disposition.h" #include "encode_parameters.h" diff --git a/src/modules/seas/encode_content_length.c b/src/modules/seas/encode_content_length.c index 57ce014fb..05a2c5c09 100644 --- a/src/modules/seas/encode_content_length.c +++ b/src/modules/seas/encode_content_length.c @@ -36,8 +36,9 @@ * * ===================================================================================== */ - +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include #include diff --git a/src/modules/seas/encode_content_type.c b/src/modules/seas/encode_content_type.c index 5605b4025..84a16d463 100644 --- a/src/modules/seas/encode_content_type.c +++ b/src/modules/seas/encode_content_type.c @@ -36,8 +36,9 @@ * * ===================================================================================== */ - +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include #include diff --git a/src/modules/seas/encode_cseq.c b/src/modules/seas/encode_cseq.c index ab5dd928b..e272cc5d5 100644 --- a/src/modules/seas/encode_cseq.c +++ b/src/modules/seas/encode_cseq.c @@ -36,7 +36,9 @@ * * ===================================================================================== */ +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include #include diff --git a/src/modules/seas/encode_digest.c b/src/modules/seas/encode_digest.c index 51f287b33..70cea306e 100644 --- a/src/modules/seas/encode_digest.c +++ b/src/modules/seas/encode_digest.c @@ -36,7 +36,9 @@ * * ===================================================================================== */ +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include "../../core/parser/digest/digest_parser.h" diff --git a/src/modules/seas/encode_expires.c b/src/modules/seas/encode_expires.c index a467ac47a..bab6eace0 100644 --- a/src/modules/seas/encode_expires.c +++ b/src/modules/seas/encode_expires.c @@ -36,8 +36,9 @@ * * ===================================================================================== */ - +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include #include diff --git a/src/modules/seas/encode_header.c b/src/modules/seas/encode_header.c index 055821d37..fd4c640ea 100644 --- a/src/modules/seas/encode_header.c +++ b/src/modules/seas/encode_header.c @@ -36,7 +36,9 @@ * * ===================================================================================== */ +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include #include @@ -366,6 +368,7 @@ int print_encoded_header(FILE *fd, char *msg, int msglen, { char *hdr_start_ptr; short int start_idx, i; + int j; memcpy(&start_idx, payload, 2); start_idx = ntohs(start_idx); @@ -378,9 +381,9 @@ int print_encoded_header(FILE *fd, char *msg, int msglen, hdr_start_ptr); fprintf(fd, "%sHEADER:[%.*s]\n", prefix, i - 2, hdr_start_ptr); fprintf(fd, "%sHEADER CODE=", prefix); - for(i = 0; i < len; i++) - fprintf(fd, "%s%d%s", i == 0 ? "[" : ":", payload[i], - i == len - 1 ? "]\n" : ""); + for(j = 0; j < len; j++) + fprintf(fd, "%s%d%s", j == 0 ? "[" : ":", payload[j], + j == len - 1 ? "]\n" : ""); if(len == 4) return 1; switch(type) { diff --git a/src/modules/seas/encode_msg.c b/src/modules/seas/encode_msg.c index 179f570bf..5ee1b88be 100644 --- a/src/modules/seas/encode_msg.c +++ b/src/modules/seas/encode_msg.c @@ -36,8 +36,9 @@ * * ===================================================================================== */ - +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include #include diff --git a/src/modules/seas/encode_parameters.c b/src/modules/seas/encode_parameters.c index f30efb864..6513f3108 100644 --- a/src/modules/seas/encode_parameters.c +++ b/src/modules/seas/encode_parameters.c @@ -36,7 +36,9 @@ * * ===================================================================================== */ +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include "../../core/str.h" #include "../../core/parser/parse_param.h" diff --git a/src/modules/seas/encode_route.c b/src/modules/seas/encode_route.c index 589e955ea..81be7a539 100644 --- a/src/modules/seas/encode_route.c +++ b/src/modules/seas/encode_route.c @@ -36,8 +36,9 @@ * * ===================================================================================== */ - +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include "../../core/parser/parse_rr.h" diff --git a/src/modules/seas/encode_to_body.c b/src/modules/seas/encode_to_body.c index 801949abb..e29a86172 100644 --- a/src/modules/seas/encode_to_body.c +++ b/src/modules/seas/encode_to_body.c @@ -36,7 +36,9 @@ * * ===================================================================================== */ +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include #include diff --git a/src/modules/seas/encode_uri.c b/src/modules/seas/encode_uri.c index 2dc3bd778..0ebf4685e 100644 --- a/src/modules/seas/encode_uri.c +++ b/src/modules/seas/encode_uri.c @@ -36,8 +36,9 @@ * * ===================================================================================== */ - +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include #include diff --git a/src/modules/seas/encode_via.c b/src/modules/seas/encode_via.c index 49a1b1fd4..678d2b86b 100644 --- a/src/modules/seas/encode_via.c +++ b/src/modules/seas/encode_via.c @@ -36,8 +36,9 @@ * * ===================================================================================== */ - +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include "../../core/parser/parse_via.h" diff --git a/src/modules/seas/event_dispatcher.c b/src/modules/seas/event_dispatcher.c index a9216c617..e827629e5 100644 --- a/src/modules/seas/event_dispatcher.c +++ b/src/modules/seas/event_dispatcher.c @@ -312,9 +312,7 @@ int dispatcher_main_loop(void) poll_fds[3 + as_nr].revents = 0; as_nr++; /*not very sure if this is thread-safe*/ unc_as_nr--; - } else if( - fd - <= 0) { /* pull the upper set of incomplete AS down and take this one out*/ + } else { /* pull the upper set of incomplete AS down and take this one out*/ poll_tmp->revents = 0; for(k = i; k < (unc_as_nr - 1); k++) { j = 3 + as_nr + k; @@ -353,7 +351,7 @@ int dispatcher_main_loop(void) * address: * address to which to listen * port: - * base port to which to listen. then port+1 will be the socket + * base port to which to listen. Then port+1 will be the socket * for action's delivery. * fds: * in fd[0] the action socket will be put. diff --git a/src/modules/seas/utils.c b/src/modules/seas/utils.c index 051c58ee6..7ad8941e6 100644 --- a/src/modules/seas/utils.c +++ b/src/modules/seas/utils.c @@ -41,7 +41,9 @@ #include #include #include +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include #include diff --git a/src/modules/secsipid/README b/src/modules/secsipid/README index c2af1a471..5883eaa10 100644 --- a/src/modules/secsipid/README +++ b/src/modules/secsipid/README @@ -49,6 +49,7 @@ Daniel-Constantin Mierla origID, x5u, keyData) 4.8. secsipid_sign(sheaders, spaypload, keyPath) + 4.9. secsipid_sign_prvkey(sheaders, spaypload, keyData) 5. Installation @@ -68,7 +69,8 @@ Daniel-Constantin Mierla 1.12. secsipid_build_identity usage 1.13. secsipid_build_identity_prvkey usage 1.14. secsipid_sign usage - 1.15. Libsecsipid Usage + 1.15. secsipid_sign_prvkey usage + 1.16. Libsecsipid Usage Chapter 1. Admin Guide @@ -105,6 +107,7 @@ Chapter 1. Admin Guide origID, x5u, keyData) 4.8. secsipid_sign(sheaders, spaypload, keyPath) + 4.9. secsipid_sign_prvkey(sheaders, spaypload, keyData) 5. Installation @@ -243,6 +246,7 @@ modparam("secsipid", "libopt", "CacheExpires=0") x5u, keyData) 4.8. secsipid_sign(sheaders, spaypload, keyPath) + 4.9. secsipid_sign_prvkey(sheaders, spaypload, keyData) 4.1. secsipid_check_identity(keyPath) @@ -439,6 +443,30 @@ request_route { } ... +4.9. secsipid_sign_prvkey(sheaders, spaypload, keyData) + + Build Identity value using the private key given by "keyData" to sign + the JWT body. The sheaders and spayload have to be string + representation of JSON headers and payload to be signed. On success, + the Indentity value is stored in variable $secsipid(val). It also sets + $secsipid(ret) to the return value of the libsecsipid functions. + + The parameters can contain pseudo-variables. + + This function can be used from ANY_ROUTE. + + Example 1.15. secsipid_sign_prvkey usage +... +request_route { + ... + if(secsipid_sign_prvkey("_JSON_HEADERS_", "_JSON_PAYLOAD_", + "_PRIVATE_KEY_")) { + xinfo("Identity value: $secsipid(val)\n"); + } + ... +} +... + 5. Installation The module needs "secsipdi_proc.so" module that depends on @@ -453,7 +481,7 @@ request_route { installed and its environment configured, then run the following commands: - Example 1.15. Libsecsipid Usage + Example 1.16. Libsecsipid Usage ... export GO111MODULE=off go get https://github.com/asipto/secsipidx diff --git a/src/modules/secsipid/doc/secsipid_admin.xml b/src/modules/secsipid/doc/secsipid_admin.xml index 97306c649..7ea74f525 100644 --- a/src/modules/secsipid/doc/secsipid_admin.xml +++ b/src/modules/secsipid/doc/secsipid_admin.xml @@ -460,6 +460,39 @@ request_route { ... } ... + + +
+
+ + <function moreinfo="none">secsipid_sign_prvkey(sheaders, spaypload, keyData)</function> + + + Build Identity value using the private key given by "keyData" to sign the JWT body. + The sheaders and spayload have to be string representation of JSON + headers and payload to be signed. On success, the Indentity value is + stored in variable $secsipid(val). It also sets $secsipid(ret) to + the return value of the libsecsipid functions. + + + The parameters can contain pseudo-variables. + + + This function can be used from ANY_ROUTE. + + + <function>secsipid_sign_prvkey</function> usage + +... +request_route { + ... + if(secsipid_sign_prvkey("_JSON_HEADERS_", "_JSON_PAYLOAD_", + "_PRIVATE_KEY_")) { + xinfo("Identity value: $secsipid(val)\n"); + } + ... +} +...
diff --git a/src/modules/secsipid/secsipid_mod.c b/src/modules/secsipid/secsipid_mod.c index 4e41c272d..b8c80382a 100644 --- a/src/modules/secsipid/secsipid_mod.c +++ b/src/modules/secsipid/secsipid_mod.c @@ -66,6 +66,8 @@ static int w_secsipid_build_identity_prvkey(sip_msg_t *msg, char *porigtn, char *pkeydata); static int w_secsipid_sign( sip_msg_t *msg, char *phdrs, char *ppayload, char *pkeypath); +static int w_secsipid_sign_prvkey( + sip_msg_t *msg, char *phdrs, char *ppayload, char *pkeydata); static int w_secsipid_get_url(sip_msg_t *msg, char *purl, char *pout); static int secsipid_libopt_param(modparam_t type, void *val); @@ -102,6 +104,8 @@ static cmd_export_t cmds[]={ fixup_spve_all, fixup_free_spve_all, ANY_ROUTE}, {"secsipid_sign", (cmd_function)w_secsipid_sign, 3, fixup_spve_all, fixup_free_spve_all, ANY_ROUTE}, + {"secsipid_sign_prvkey", (cmd_function)w_secsipid_sign_prvkey, 3, + fixup_spve_all, fixup_free_spve_all, ANY_ROUTE}, {"secsipid_get_url", (cmd_function)w_secsipid_get_url, 2, fixup_spve_pvar, fixup_free_spve_pvar, ANY_ROUTE}, {0, 0, 0, 0, 0, 0} @@ -740,6 +744,81 @@ static int w_secsipid_sign( return ki_secsipid_sign(msg, &shdrs, &spayload, &keypath); } +/** + * + */ +static int ki_secsipid_sign_prvkey( + sip_msg_t *msg, str *sheaders, str *spayload, str *keydata) +{ +#if SECSIPID_VERSION >= 0x1030000 + str ibody = STR_NULL; + + if(secsipid_libopt_list_used == 0) { + str_list_t *sit; + for(sit = secsipid_libopt_list; sit != NULL; sit = sit->next) { + _secsipid_papi.SecSIPIDOptSetV(sit->s.s); + } + secsipid_libopt_list_used = 1; + } + + ibody.len = _secsipid_papi.SecSIPIDSignJSONHPPrvKey( + sheaders->s, spayload->s, keydata->s, &ibody.s); + + _secsipid_data.ret = ibody.len; + + if(ibody.len <= 0) { + LM_ERR("failed to get identity value (%d)\n", ibody.len); + goto error; + } + + LM_DBG("identity value: %.*s\n", ibody.len, ibody.s); + + if(_secsipid_data.value.s) { + free(_secsipid_data.value.s); + } + _secsipid_data.value = ibody; + return 1; + +error: + if(ibody.s) { + free(ibody.s); + } + return -1; +#else + LM_ERR("secsipid < 1.3.0, SecSIPIDSignJSONHPPrvKey not supported\n"); + return -1; +#endif +} + +/** + * + */ +static int w_secsipid_sign_prvkey( + sip_msg_t *msg, char *phdrs, char *ppayload, char *pkeydata) +{ + str shdrs = STR_NULL; + str spayload = STR_NULL; + str keydata = STR_NULL; + + if(fixup_get_svalue(msg, (gparam_t *)phdrs, &shdrs) < 0) { + LM_ERR("failed to get JSON headers parameter\n"); + return -1; + } + + if(fixup_get_svalue(msg, (gparam_t *)ppayload, &spayload) < 0) { + LM_ERR("failed to get JSON payload parameter\n"); + return -1; + } + + if(fixup_get_svalue(msg, (gparam_t *)pkeydata, &keydata) < 0) { + LM_ERR("failed to get keydata parameter\n"); + return -1; + } + + return ki_secsipid_sign_prvkey(msg, &shdrs, &spayload, &keydata); +} + + /** * */ @@ -961,6 +1040,16 @@ static sr_kemi_t sr_kemi_secsipid_exports[] = { { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR } }, + { str_init("secsipid"), str_init("secsipid_sign"), + SR_KEMIP_INT, ki_secsipid_sign, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("secsipid"), str_init("secsipid_sign_prvkey"), + SR_KEMIP_INT, ki_secsipid_sign_prvkey, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, { str_init("secsipid"), str_init("secsipid_get_val"), SR_KEMIP_XVAL, ki_secsipid_get_val, { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, diff --git a/src/modules/secsipid/secsipid_papi.h b/src/modules/secsipid/secsipid_papi.h index 51b83a8ea..8948316c7 100644 --- a/src/modules/secsipid/secsipid_papi.h +++ b/src/modules/secsipid/secsipid_papi.h @@ -29,6 +29,9 @@ typedef struct secsipid_papi int (*SecSIPIDSignJSONHP)(char *headerJSON, char *payloadJSON, char *prvkeyPath, char **outPtr); + int (*SecSIPIDSignJSONHPPrvKey)(char *headerJSON, char *payloadJSON, + char *prvkeyData, char **outPtr); + int (*SecSIPIDGetIdentity)(char *origTN, char *destTN, char *attestVal, char *origID, char *x5uVal, char *prvkeyPath, char **outPtr); diff --git a/src/modules/secsipid_proc/libsecsipid.h b/src/modules/secsipid_proc/libsecsipid.h deleted file mode 100644 index 03e20b2a2..000000000 --- a/src/modules/secsipid_proc/libsecsipid.h +++ /dev/null @@ -1,203 +0,0 @@ -/* Code generated by cmd/cgo; DO NOT EDIT. */ - -/* package command-line-arguments */ - - -#line 1 "cgo-builtin-export-prolog" - -#include /* for ptrdiff_t below */ - -#ifndef GO_CGO_EXPORT_PROLOGUE_H -#define GO_CGO_EXPORT_PROLOGUE_H - -#ifndef GO_CGO_GOSTRING_TYPEDEF -typedef struct -{ - const char *p; - ptrdiff_t n; -} _GoString_; -#endif - -#endif - -/* Start of preamble from import "C" comments. */ - - -/* End of preamble from import "C" comments. */ - - -/* Start of boilerplate cgo prologue. */ -#line 1 "cgo-gcc-export-header-prolog" - -#ifndef GO_CGO_PROLOGUE_H -#define GO_CGO_PROLOGUE_H - -typedef signed char GoInt8; -typedef unsigned char GoUint8; -typedef short GoInt16; -typedef unsigned short GoUint16; -typedef int GoInt32; -typedef unsigned int GoUint32; -typedef long long GoInt64; -typedef unsigned long long GoUint64; -typedef GoInt64 GoInt; -typedef GoUint64 GoUint; -typedef __SIZE_TYPE__ GoUintptr; -typedef float GoFloat32; -typedef double GoFloat64; -typedef float _Complex GoComplex64; -typedef double _Complex GoComplex128; - -/* - static assertion to make sure the file is being used on architecture - at least with matching size of GoInt. -*/ -typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void *) == 64 / 8 - ? 1 - : -1]; - -#ifndef GO_CGO_GOSTRING_TYPEDEF -typedef _GoString_ GoString; -#endif -typedef void *GoMap; -typedef void *GoChan; -typedef struct -{ - void *t; - void *v; -} GoInterface; -typedef struct -{ - void *data; - GoInt len; - GoInt cap; -} GoSlice; - -#endif - -/* End of boilerplate cgo prologue. */ - -#ifdef __cplusplus -extern "C" -{ -#endif - - - // SecSIPIDSignJSONHP -- - // * sign the JSON header and payload with provided private key - // * headerJSON - header part in JSON format (0-terminated string) - // * payloadJSON - payload part in JSON format (0-terminated string) - // * prvkeyPath - path to private key to be used to generate the signature - // * outPtr - to be set to the pointer containing the output (it is a - // 0-terminated string); the `*outPtr` must be freed after use - // * return: the length of `*outPtr` - extern int SecSIPIDSignJSONHP(char *headerJSON, char *payloadJSON, - char *prvkeyPath, char **outPtr); - - // SecSIPIDGetIdentity -- - // Generate the Identity header content using the input attributes - // * origTN - calling number - // * destTN - called number - // * attestVal - attestation level - // * origID - unique ID for tracking purposes, if empty string a UUID is generated - // * x5uVal - location of public certificate - // * prvkeyPath - path to private key to be used to generate the signature - // * outPtr - to be set to the pointer containing the output (it is a - // 0-terminated string); the `*outPtr` must be freed after use - // * return: the length of `*outPtr` - extern int SecSIPIDGetIdentity(char *origTN, char *destTN, char *attestVal, - char *origID, char *x5uVal, char *prvkeyPath, char **outPtr); - - // SecSIPIDGetIdentityPrvKey -- - // Generate the Identity header content using the input attributes - // * origTN - calling number - // * destTN - called number - // * attestVal - attestation level - // * origID - unique ID for tracking purposes, if empty string a UUID is generated - // * x5uVal - location of public certificate - // * prvkeyData - content of private key to be used to generate the signature - // * outPtr - to be set to the pointer containing the output (it is a - // 0-terminated string); the `*outPtr` must be freed after use - // * return: the length of `*outPtr` - extern int SecSIPIDGetIdentityPrvKey(char *origTN, char *destTN, - char *attestVal, char *origID, char *x5uVal, char *prvkeyData, - char **outPtr); - - // SecSIPIDCheck -- - // check the Identity header value - // * identityVal - identity header value - // * identityLen - length of identityVal, if is 0, identityVal is expected - // to be 0-terminated - // * expireVal - number of seconds until the validity is considered expired - // * pubkeyPath - file path or URL to public key - // * timeoutVal - timeout in seconds to try to fetch the public key via HTTP - // * return: 0 - if validity is ok; <0 - on error or validity is not ok - extern int SecSIPIDCheck(char *identityVal, int identityLen, int expireVal, - char *pubkeyPath, int timeoutVal); - - // SecSIPIDCheckFull -- - // check the Identity header value - // * identityVal - identity header value with header parameters - // * identityLen - length of identityVal, if it is 0, identityVal is expected - // to be 0-terminated - // * expireVal - number of seconds until the validity is considered expired - // * pubkeyPath - file path or URL to public key - // * timeoutVal - timeout in seconds to try to fetch the public key via HTTP - // * return: 0 - if validity is ok; <0 - on error or validity is not ok - extern int SecSIPIDCheckFull(char *identityVal, int identityLen, - int expireVal, char *pubkeyPath, int timeoutVal); - - // SecSIPIDCheckFullPubKey -- - // check the Identity header value - // * identityVal - identity header value with header parameters - // * identityLen - length of identityVal, if it is 0, identityVal is expected - // to be 0-terminated - // * expireVal - number of seconds until the validity is considered expired - // * pubkeyVal - the value of the public key - // * pubkeyLen - the length of the public key, if it is 0, then the pubkeyVal - // is expected to be 0-terminated - // * return: 0 - if validity is ok; <0 - on error or validity is not ok - extern int SecSIPIDCheckFullPubKey(char *identityVal, int identityLen, - int expireVal, char *pubkeyVal, int pubkeyLen); - - // SecSIPIDSetFileCacheOptions -- - // set the options for local file caching of public keys - // * dirPath - path to local directory where to store the files - // * expireVal - number of the seconds after which to invalidate the cached file - // * return: 0 - extern int SecSIPIDSetFileCacheOptions(char *dirPath, int expireVal); - - // SecSIPIDGetURLContent -- - // get the content of an URL - // * urlVal - the HTTP or HTTPS URL - // * timeoutVal - timeout in seconds to try to get the content of the HTTP URL - // * outPtr - to be set to the pointer containing the output (it is a - // 0-terminated string); the `*outPtr` must be freed after use - // * outLen: to be set to the length of `*outPtr` - // * return: 0 - on success; -1 - on failure - extern int SecSIPIDGetURLContent( - char *urlVal, int timeoutVal, char **outPtr, int *outLen); - - // SecSIPIDOptSetS -- - // set a string option for the library - // * optName - name of the option - // * optVal - value of the option - // * return: 0 if option was set, -1 otherwise - extern int SecSIPIDOptSetS(char *optName, char *optVal); - - // SecSIPIDOptSetN -- - // set a number (integer) option for the library - // * optName - name of the option - // * optVal - value of the option - // * 0 if option was set, -1 otherwise - extern int SecSIPIDOptSetN(char *optName, int optVal); - - // SecSIPIDOptSetV -- - // set an option for the library - // * optNameVal - string with name=value of the option - // * 0 if option was set, -1 otherwise - extern int SecSIPIDOptSetV(char *optNameVal); - -#ifdef __cplusplus -} -#endif diff --git a/src/modules/secsipid_proc/secsipid.h b/src/modules/secsipid_proc/secsipid.h deleted file mode 100644 index 81f9ad0b4..000000000 --- a/src/modules/secsipid_proc/secsipid.h +++ /dev/null @@ -1,16 +0,0 @@ -/* header file for secsipid library */ - -#ifndef __SECSIPID_H__ -#define __SECSIPID_H__ - -#include "libsecsipid.h" - -/** - * SECSIPID_VERSION = 0xAABBCC00 - * - corresponds to version AA.BB.CC - * - last two hexdigits are left for patch extensions - * - example: 0x1010000 corresponds to version 1.1.0 - */ -#define SECSIPID_VERSION 0x1010000 - -#endif diff --git a/src/modules/secsipid_proc/secsipid_proc_mod.c b/src/modules/secsipid_proc/secsipid_proc_mod.c index 0e00483ce..02a8b6eb4 100644 --- a/src/modules/secsipid_proc/secsipid_proc_mod.c +++ b/src/modules/secsipid_proc/secsipid_proc_mod.c @@ -38,6 +38,9 @@ MODULE_VERSION int secsipid_proc_bind(secsipid_papi_t *papi) { papi->SecSIPIDSignJSONHP = SecSIPIDSignJSONHP; +#if SECSIPID_VERSION >= 0x1030000 + papi->SecSIPIDSignJSONHPPrvKey = SecSIPIDSignJSONHPPrvKey; +#endif papi->SecSIPIDGetIdentity = SecSIPIDGetIdentity; papi->SecSIPIDGetIdentityPrvKey = SecSIPIDGetIdentityPrvKey; papi->SecSIPIDCheck = SecSIPIDCheck; diff --git a/src/modules/sipcapture/sipcapture.c b/src/modules/sipcapture/sipcapture.c index 90e10aa84..7dc3ae81f 100644 --- a/src/modules/sipcapture/sipcapture.c +++ b/src/modules/sipcapture/sipcapture.c @@ -176,7 +176,7 @@ static int hep_version(struct sip_msg *msg); static str db_url = str_init(DEFAULT_DB_URL); -static str table_name = str_init("sip_capture"); +static str _sipcap_table_name = str_init("sip_capture"); static str hash_source = str_init("call_id"); static str mt_mode = str_init("rand"); static str date_column = str_init("date"); @@ -298,8 +298,6 @@ static struct sock_filter BPF_code[] = { //str* table_names = NULL; -unsigned int no_tables = 0; - enum e_mt_mode mtmode = mode_random; enum hash_source source = hs_error; @@ -340,7 +338,7 @@ int capture_mode_param(modparam_t type, void *val); * Exported parameters */ static param_export_t params[] = {{"db_url", PARAM_STR, &db_url}, - {"table_name", PARAM_STR, &table_name}, + {"table_name", PARAM_STR, &_sipcap_table_name}, {"hash_source", PARAM_STR, &hash_source}, {"mt_mode", PARAM_STR, &mt_mode}, {"date_column", PARAM_STR, &date_column}, @@ -481,12 +479,12 @@ int parse_table_names(str table_name, str **table_names) { char *p = NULL; - unsigned int no_tables; + unsigned int l_no_tables; char *table_name_cpy; - unsigned int i; + int i; /*parse and save table names*/ - no_tables = 1; + l_no_tables = 1; i = 0; str *names; @@ -503,12 +501,12 @@ int parse_table_names(str table_name, str **table_names) while(*p) { if(*p == '|') { - no_tables++; + l_no_tables++; } p++; } - names = (str *)pkg_malloc(sizeof(str) * no_tables); + names = (str *)pkg_malloc(sizeof(str) * l_no_tables); if(names == NULL) { PKG_MEM_ERROR; pkg_free(table_name_cpy); @@ -539,7 +537,7 @@ int parse_table_names(str table_name, str **table_names) *table_names = names; - return no_tables; + return l_no_tables; } /* checks for some missing fields*/ @@ -820,9 +818,9 @@ static int mod_init(void) } } - /* Check the table name - if table_name is empty and no capture modes + /* Check the table name - if _sipcap_table_name is empty and no capture modes * are defined, then error*/ - if(!table_name.len && capture_modes_root == NULL) { + if(!_sipcap_table_name.len && capture_modes_root == NULL) { LM_ERR("ERROR: sipcapture: mod_init: table_name is not defined or " "empty\n"); return -1; @@ -833,14 +831,14 @@ static int mod_init(void) def_params = (char *)pkg_malloc( snprintf(NULL, 0, "db_url=%s;table_name=%s;mt_mode=%s;hash_source=%s", - db_url.s, table_name.s, mt_mode.s, hash_source.s) + db_url.s, _sipcap_table_name.s, mt_mode.s, hash_source.s) + 1); if(!def_params) { PKG_MEM_ERROR; return -1; } sprintf(def_params, "db_url=%s;table_name=%s;mt_mode=%s;hash_source=%s", - db_url.s, table_name.s, mt_mode.s, hash_source.s); + db_url.s, _sipcap_table_name.s, mt_mode.s, hash_source.s); str def_name, def_par; def_name.s = strdup("default"); @@ -1779,7 +1777,7 @@ static int sip_capture_store(struct _sipcapture_object *sco, str *dtable, } table = &c->table_names[ii]; } else { - table = &table_name; + table = &_sipcap_table_name; } tvsec_ = (time_t)(sco->tmstamp / 1000000); @@ -1849,6 +1847,7 @@ static int sip_capture( struct timeval tvb; struct timezone tz; char tmp_node[100]; + str ip; LM_DBG("CAPTURE DEBUG...\n"); @@ -2249,9 +2248,12 @@ static int sip_capture( /* IP source and destination */ - strcpy(buf_ip, ip_addr2a(&msg->rcv.src_ip)); + ip.s = ip_addr2a(&msg->rcv.src_ip); + ip.len = strlen(ip.s); + /* Copy, including teminating \0 */ + memcpy(buf_ip, ip.s, ip.len + 1); sco.source_ip.s = buf_ip; - sco.source_ip.len = strlen(buf_ip); + sco.source_ip.len = ip.len; sco.source_port = msg->rcv.src_port; /*source ip*/ @@ -2794,7 +2796,7 @@ static int report_capture(sip_msg_t *msg, str *_table, str *_corr, str *_data) struct timezone tz; char tmp_node[100]; time_t epoch_time_as_time_t; - str corrtmp = STR_NULL, tmp; + str corrtmp = STR_NULL, tmp, ip; _capture_mode_data_t *c = NULL; @@ -2834,10 +2836,12 @@ static int report_capture(sip_msg_t *msg, str *_table, str *_corr, str *_data) //EMPTY_STR(sco.msg); /* IP source and destination */ - - strcpy(buf_ip, ip_addr2a(&msg->rcv.src_ip)); + ip.s = ip_addr2a(&msg->rcv.src_ip); + ip.len = strlen(ip.s); + /* Copy, including teminating \0 */ + memcpy(buf_ip, ip.s, ip.len + 1); sco.source_ip.s = buf_ip; - sco.source_ip.len = strlen(buf_ip); + sco.source_ip.len = ip.len; sco.source_port = msg->rcv.src_port; /*source ip*/ diff --git a/src/modules/siptrace/README b/src/modules/siptrace/README index ee0784823..5d10f2a80 100644 --- a/src/modules/siptrace/README +++ b/src/modules/siptrace/README @@ -70,7 +70,8 @@ Camille Oudot 4.1. sip_trace([address][, correlation_id][, mode]) 4.2. sip_trace_mode(tmode) - 4.3. hlog([correlation_id,] message) + 4.3. sip_trace_msg(vmsg, saddr, taddr, daddr, corrid) + 4.4. hlog([correlation_id,] message) 5. RPC Commands @@ -112,8 +113,9 @@ Camille Oudot 1.25. Set trace_dialog_spiral parameter 1.26. sip_trace() usage 1.27. sip_trace_mode() usage - 1.28. hlog() usage - 1.29. Send relayed ACK message + 1.28. sip_trace_msg() usage + 1.29. hlog() usage + 1.30. Send relayed ACK message Chapter 1. Admin Guide @@ -158,7 +160,8 @@ Chapter 1. Admin Guide 4.1. sip_trace([address][, correlation_id][, mode]) 4.2. sip_trace_mode(tmode) - 4.3. hlog([correlation_id,] message) + 4.3. sip_trace_msg(vmsg, saddr, taddr, daddr, corrid) + 4.4. hlog([correlation_id,] message) 5. RPC Commands @@ -603,7 +606,8 @@ modparam("siptrace", "trace_dialog_spiral", 1) 4.1. sip_trace([address][, correlation_id][, mode]) 4.2. sip_trace_mode(tmode) - 4.3. hlog([correlation_id,] message) + 4.3. sip_trace_msg(vmsg, saddr, taddr, daddr, corrid) + 4.4. hlog([correlation_id,] message) 4.1. sip_trace([address][, correlation_id][, mode]) @@ -660,7 +664,23 @@ sip_trace("sip:10.1.1.2:5085", "$ci-abc", "d"); sip_trace_mode("t"); ... -4.3. hlog([correlation_id,] message) +4.3. sip_trace_msg(vmsg, saddr, taddr, daddr, corrid) + + Send the value of vmsg to the HEP capture server located at daddr, by + setting saddr as source address and taddr as target address for vmsg. + Correlation ID can be provided with corrid parameter or left as an + empty string. The saddr and taddr have to be provided in socket address + format (proto:ip:port) and the daddr in SIP URI format. + + This function can be used in ANY_ROUTE. + + Example 1.28. sip_trace_msg() usage +... +sip_trace_msg("$var(msg)", "udp:127.0.0.1:5062", "udp:127.0.0.1:5064", "sip:127. +0.0.1:5090", ""); +... + +4.4. hlog([correlation_id,] message) Sends a log event as a HEP3 packet to the homer host configured in duplicate_uri. @@ -672,7 +692,7 @@ sip_trace_mode("t"); * message - The text to send to Homer as log event. (This parameter may contain PVs) - Example 1.28. hlog() usage + Example 1.29. hlog() usage ... hlog("[cfg:$cfg(line)] This is a log from kamailio to Homer"); ... @@ -746,7 +766,7 @@ event_route[siptrace:msg] { this name will result in overlapping internal avp used by the module therefore causing unknown consequences. - Example 1.29. Send relayed ACK message + Example 1.30. Send relayed ACK message ... onsend_route { if (is_method("ACK")) { diff --git a/src/modules/siptrace/doc/siptrace_admin.xml b/src/modules/siptrace/doc/siptrace_admin.xml index f902651f4..2bf7c1e91 100644 --- a/src/modules/siptrace/doc/siptrace_admin.xml +++ b/src/modules/siptrace/doc/siptrace_admin.xml @@ -779,6 +779,30 @@ sip_trace_mode("t");
+
+ + <function moreinfo="none">sip_trace_msg(vmsg, saddr, taddr, daddr, corrid)</function> + + + Send the value of vmsg to the HEP capture server located at daddr, by + setting saddr as source address and taddr as target address for vmsg. + Correlation ID can be provided with corrid parameter or left as an + empty string. The saddr and taddr have to be provided in socket + address format (proto:ip:port) and the daddr in SIP URI format. + + + This function can be used in ANY_ROUTE. + + + <function>sip_trace_msg()</function> usage + +... +sip_trace_msg("$var(msg)", "udp:127.0.0.1:5062", "udp:127.0.0.1:5064", "sip:127.0.0.1:5090", ""); +... + + +
+
<function moreinfo="none">hlog([correlation_id,] message)</function> diff --git a/src/modules/siptrace/siptrace.c b/src/modules/siptrace/siptrace.c index d4b550ee4..561e6ac4b 100644 --- a/src/modules/siptrace/siptrace.c +++ b/src/modules/siptrace/siptrace.c @@ -72,11 +72,11 @@ MODULE_VERSION #define is_null_pv(_str) (!str_strcmp(&_str, pv_get_null_str())) -struct tm_binds tmb; -struct dlg_binds dlgb; +static struct tm_binds _siptrace_tmb; +static struct dlg_binds _siptrace_dlgb; /** SL API structure */ -sl_api_t slb; +static sl_api_t _siptrace_slb; /* module function prototypes */ static int mod_init(void); @@ -89,6 +89,8 @@ 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 w_sip_trace_msg(sip_msg_t *msg, char *vmsg, char *saddr, char *taddr, + char *duri, char *corrid); 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); @@ -114,9 +116,9 @@ static void trace_sl_ack_in(sl_cbp_t *slcb); static void trace_transaction( sip_msg_t *msg, siptrace_info_t *info, int dlg_tran); static void trace_dialog( - struct dlg_cell *dlg, int type, struct dlg_cb_params *params); + struct dlg_cell *dlg, int type, struct dlg_cb_params *cbp); static void trace_dialog_transaction( - struct dlg_cell *dlg, int type, struct dlg_cb_params *params); + struct dlg_cell *dlg, int type, struct dlg_cb_params *cbp); static void trace_free_info(void *trace_info); static int trace_add_info_xavp(siptrace_info_t *info); static inline int trace_parse_raw_uri(siptrace_info_t *info); @@ -218,6 +220,8 @@ static cmd_export_t cmds[] = { ANY_ROUTE}, {"sip_trace", (cmd_function)w_sip_trace3, 3, fixup_siptrace, fixup_free_siptrace, ANY_ROUTE}, + {"sip_trace_msg", (cmd_function)w_sip_trace_msg, 5, fixup_spve_all, fixup_free_spve_all, + ANY_ROUTE}, {"hlog", (cmd_function)w_hlog1, 1, fixup_spve_null, 0, ANY_ROUTE}, {"hlog", (cmd_function)w_hlog2, 2, fixup_spve_spve, 0, @@ -422,14 +426,14 @@ static int mod_init(void) } /* register callbacks to TM */ - if(load_tm_api(&tmb) != 0) { + if(load_tm_api(&_siptrace_tmb) != 0) { LM_WARN("can't load tm api. Will not install tm callbacks.\n"); } - if(load_dlg_api(&dlgb) < 0) { + if(load_dlg_api(&_siptrace_dlgb) < 0) { LM_INFO("can't load dlg api. Will not install dialog callbacks.\n"); } else { - if(dlgb.register_dlgcb( + if(_siptrace_dlgb.register_dlgcb( NULL, DLGCB_CREATED, trace_dialog, NULL, NULL) != 0) { LM_ERR("failed to register dialog callbacks! Tracing dialogs " @@ -438,7 +442,7 @@ static int mod_init(void) } /* bind the SL API */ - if(sl_load_api(&slb) != 0) { + if(sl_load_api(&_siptrace_slb) != 0) { LM_WARN("cannot bind to SL API. Will not install sl callbacks.\n"); } else { /* register sl callbacks */ @@ -446,7 +450,7 @@ static int mod_init(void) slcb.type = SLCB_REPLY_READY; slcb.cbf = trace_sl_onreply_out; - if(slb.register_cb(&slcb) != 0) { + if(_siptrace_slb.register_cb(&slcb) != 0) { LM_ERR("can't register for SLCB_REPLY_READY\n"); return -1; } @@ -454,7 +458,7 @@ static int mod_init(void) if(trace_sl_acks) { slcb.type = SLCB_ACK_FILTERED; slcb.cbf = trace_sl_ack_in; - if(slb.register_cb(&slcb) != 0) { + if(_siptrace_slb.register_cb(&slcb) != 0) { LM_ERR("can't register for SLCB_ACK_FILTERED\n"); return -1; } @@ -779,12 +783,12 @@ static int fixup_siptrace(void **param, int param_no) str sflags; enum siptrace_type_t trace_type; - if(param_no < 1 || param_no > 3) { + if(param_no < 1 || param_no > 4) { LM_DBG("params:%s\n", (char *)*param); return 0; } - if(param_no == 1 || param_no == 2) { + if(param_no == 1 || param_no == 2 || param_no == 4) { /* correlation id */ return fixup_spve_all(param, param_no); } else if(param_no == 3) { @@ -811,7 +815,7 @@ static int fixup_siptrace(void **param, int param_no) static int fixup_free_siptrace(void **param, int param_no) { - if(param_no == 1 || param_no == 2) { + if(param_no == 1 || param_no == 2 || param_no == 4) { /* correlation id */ return fixup_free_spve_all(param, param_no); } @@ -906,7 +910,7 @@ static int sip_trace_helper(sip_msg_t *msg, dest_info_t *dst, str *duri, * dialog: it's an INVITE; dialog module is loaded * * */ - if(tmb.t_gett == NULL) { + if(_siptrace_tmb.t_gett == NULL) { LM_WARN("TM module not loaded! Tracing only current message!\n"); goto trace_current; } @@ -915,14 +919,14 @@ static int sip_trace_helper(sip_msg_t *msg, dest_info_t *dst, str *duri, * capturing it if the cancelled transaction is already being traced */ if(msg->REQ_METHOD == METHOD_CANCEL) { - t_invite = tmb.t_lookup_original(msg); + t_invite = _siptrace_tmb.t_lookup_original(msg); if(t_invite != T_NULL_CELL) { if(t_invite->uas.request->msg_flags & FL_SIPTRACE) { LM_DBG("Transaction is already been traced, skipping.\n"); - tmb.t_unref(msg); + _siptrace_tmb.t_unref(msg); return 1; } - tmb.t_unref(msg); + _siptrace_tmb.t_unref(msg); } } @@ -931,25 +935,25 @@ static int sip_trace_helper(sip_msg_t *msg, dest_info_t *dst, str *duri, * an already traced transaction */ if(msg->REQ_METHOD == METHOD_ACK) { - orig_t = tmb.t_gett(); - if(tmb.t_lookup_request(msg, 0, &canceled)) { - t_invite = tmb.t_gett(); + orig_t = _siptrace_tmb.t_gett(); + if(_siptrace_tmb.t_lookup_request(msg, 0, &canceled)) { + t_invite = _siptrace_tmb.t_gett(); if(t_invite != T_NULL_CELL) { if(t_invite->uas.request->msg_flags & FL_SIPTRACE) { LM_DBG("Transaction is already been traced, " "skipping.\n"); ret = 1; } - tmb.t_release_transaction(t_invite); - tmb.t_unref(msg); + _siptrace_tmb.t_release_transaction(t_invite); + _siptrace_tmb.t_unref(msg); } } - tmb.t_sett(orig_t, T_BR_UNDEFINED); + _siptrace_tmb.t_sett(orig_t, T_BR_UNDEFINED); if(ret) return 1; } - if(trace_type == SIPTRACE_DIALOG && dlgb.get_dlg == NULL) { + if(trace_type == SIPTRACE_DIALOG && _siptrace_dlgb.get_dlg == NULL) { LM_WARN("DIALOG module not loaded! Tracing only current " "message!\n"); goto trace_current; @@ -1006,7 +1010,7 @@ static int sip_trace_helper(sip_msg_t *msg, dest_info_t *dst, str *duri, if(trace_type == SIPTRACE_TRANSACTION) { trace_transaction(msg, info, 0); } else if(trace_type == SIPTRACE_DIALOG) { - if(unlikely(dlgb.set_dlg_var == NULL)) { + if(unlikely(_siptrace_dlgb.set_dlg_var == NULL)) { /* FIXME should we abort tracing here? */ LM_WARN("Dialog api not loaded! will trace only current " "transaction!\n"); @@ -1185,6 +1189,85 @@ static int w_sip_trace3( (correlation_id) ? &correlation_id_str : NULL, NULL, trace_type); } +/** + * + */ +static int w_sip_trace_msg(sip_msg_t *msg, char *vmsg, char *saddr, char *taddr, + char *duri, char *corrid) +{ + str vmsg_str = {0, 0}; + str saddr_str = {0, 0}; + str taddr_str = {0, 0}; + str duri_str = {0, 0}; + str corrid_str = {0, 0}; + dest_info_t dest; + + if(fixup_get_svalue(msg, (gparam_t *)vmsg, &vmsg_str) != 0) { + LM_ERR("unable to get the msg data parameter\n"); + return -1; + } + if(vmsg_str.s == NULL || vmsg_str.len <= 0) { + LM_ERR("invalid msg data parameter\n"); + return -1; + } + if(fixup_get_svalue(msg, (gparam_t *)saddr, &saddr_str) != 0) { + LM_ERR("unable to get the msg source address parameter\n"); + return -1; + } + if(saddr_str.s == NULL || saddr_str.len <= 0) { + LM_ERR("invalid msg source address parameter\n"); + return -1; + } + if(fixup_get_svalue(msg, (gparam_t *)taddr, &taddr_str) != 0) { + LM_ERR("unable to get the msg target address parameter\n"); + return -1; + } + if(taddr_str.s == NULL || taddr_str.len <= 0) { + LM_ERR("invalid msg target address parameter\n"); + return -1; + } + if(duri != NULL) { + if(fixup_get_svalue(msg, (gparam_t *)duri, &duri_str) != 0) { + LM_ERR("unable to get mirroring destination uri parameter\n"); + return -1; + } + if(siptrace_parse_uri(&duri_str, &dest) < 0) { + LM_ERR("failed to parse mirroring destination uri\n"); + return -1; + } + } + if(corrid != NULL + && fixup_get_svalue(msg, (gparam_t *)corrid, &corrid_str) != 0) { + LM_ERR("unable to get correlation id parameter\n"); + return -1; + } + + trace_send_hep_duplicate(&vmsg_str, &saddr_str, &taddr_str, + (duri) ? &dest : NULL, (corrid) ? &corrid_str : NULL); + + return 1; +} + +/** + * + */ +static int ki_sip_trace_msg(sip_msg_t *msg, str *vmsg, str *saddr, str *taddr, + str *duri, str *corrid) +{ + dest_info_t dest; + if(duri && duri->len > 0) { + if(siptrace_parse_uri(duri, &dest) < 0) { + LM_ERR("failed to parse mirroring destination uri\n"); + return -1; + } + } + trace_send_hep_duplicate(vmsg, saddr, taddr, + (duri && duri->len > 0) ? &dest : NULL, + (corrid && corrid->len > 0) ? corrid : NULL); + + return 1; +} + /** * link call-id, method, from-tag and to-tag */ @@ -1388,7 +1471,7 @@ static void trace_cancel_in(struct cell *t, int type, struct tmcb_params *ps) info = (siptrace_info_t *)(*ps->param); msg = ps->req; - if(tmb.register_tmcb( + if(_siptrace_tmb.register_tmcb( msg, 0, TMCB_RESPONSE_READY, trace_onreply_out, info, 0) <= 0) { LM_ERR("can't register trace_onreply_out\n"); @@ -1979,22 +2062,24 @@ static void trace_transaction( } } - if(tmb.register_tmcb(msg, 0, TMCB_REQUEST_SENT, trace_onreq_out, info, 0) + if(_siptrace_tmb.register_tmcb( + msg, 0, TMCB_REQUEST_SENT, trace_onreq_out, info, 0) <= 0) { LM_ERR("can't register trace_onreq_out\n"); return; } /* trace reply on in */ - if(tmb.register_tmcb(msg, 0, TMCB_RESPONSE_IN, trace_onreply_in, info, 0) + if(_siptrace_tmb.register_tmcb( + msg, 0, TMCB_RESPONSE_IN, trace_onreply_in, info, 0) <= 0) { LM_ERR("can't register trace_onreply_in\n"); return; } /* trace reply on out */ - if(tmb.register_tmcb(msg, 0, TMCB_RESPONSE_SENT, trace_onreply_out, info, - dlg_tran ? 0 : trace_free_info) + if(_siptrace_tmb.register_tmcb(msg, 0, TMCB_RESPONSE_SENT, + trace_onreply_out, info, dlg_tran ? 0 : trace_free_info) <= 0) { LM_ERR("can't register trace_onreply_out\n"); return; @@ -2003,13 +2088,15 @@ static void trace_transaction( /* TODO */ /* check the following callbacks: TMCB_REQUEST_PENDING, TMCB_RESPONSE_READY, TMCB_ACK_NEG_IN */ /* trace reply on in */ - if(tmb.register_tmcb(msg, 0, TMCB_ACK_NEG_IN, trace_tm_neg_ack_in, info, 0) + if(_siptrace_tmb.register_tmcb( + msg, 0, TMCB_ACK_NEG_IN, trace_tm_neg_ack_in, info, 0) <= 0) { LM_ERR("can't register trace_onreply_in\n"); return; } - if(tmb.register_tmcb(msg, 0, TMCB_E2ECANCEL_IN, trace_cancel_in, info, 0) + if(_siptrace_tmb.register_tmcb( + msg, 0, TMCB_E2ECANCEL_IN, trace_cancel_in, info, 0) <= 0) { LM_ERR("can't register trace_onreply_in\n"); return; @@ -2018,24 +2105,24 @@ static void trace_transaction( //static void trace_dialog(sip_msg_t* msg, siptrace_info_t* info) static void trace_dialog( - struct dlg_cell *dlg, int type, struct dlg_cb_params *params) + struct dlg_cell *dlg, int type, struct dlg_cb_params *cbp) { sr_xavp_t *xavp; - if(!dlgb.get_dlg) { + if(!_siptrace_dlgb.get_dlg) { LM_ERR("Dialog API not loaded! Trace off...\n"); return; } - /* request - params->req */ - if(params == NULL || (!trace_dialog_spiral && params->req == NULL)) { + /* request - cbp->req */ + if(cbp == NULL || (!trace_dialog_spiral && cbp->req == NULL)) { LM_ERR("Invalid args!\n"); return; } - if(trace_dialog_spiral && *params->param == NULL) { + if(trace_dialog_spiral && *cbp->param == NULL) { LM_DBG("Spiraled dialog!\n"); - if(dlgb.register_dlgcb( + if(_siptrace_dlgb.register_dlgcb( dlg, DLGCB_SPIRALED, trace_dialog, &spiral_tracked, NULL) != 0) { LM_ERR("could not register consider_exporting() for dialog event " @@ -2043,7 +2130,7 @@ static void trace_dialog( } } - if(!trace_dialog_spiral && !(params->req->msg_flags & FL_SIPTRACE)) { + if(!trace_dialog_spiral && !(cbp->req->msg_flags & FL_SIPTRACE)) { LM_DBG("Trace is off for this request...\n"); return; } @@ -2060,8 +2147,8 @@ static void trace_dialog( return; } - if(dlgb.register_dlgcb(dlg, DLGCB_REQ_WITHIN, trace_dialog_transaction, - xavp->val.v.vptr, 0) + if(_siptrace_dlgb.register_dlgcb(dlg, DLGCB_REQ_WITHIN, + trace_dialog_transaction, xavp->val.v.vptr, 0) != 0) { LM_ERR("Failed to register DLGCB_REQ_WITHIN callback!\n"); return; @@ -2069,15 +2156,15 @@ static void trace_dialog( /* this will trace in-dialog ACK */ if(trace_dialog_ack - && dlgb.register_dlgcb(dlg, DLGCB_CONFIRMED, + && _siptrace_dlgb.register_dlgcb(dlg, DLGCB_CONFIRMED, trace_dialog_transaction, xavp->val.v.vptr, 0) != 0) { LM_ERR("Failed to register DLGCB_CONFIRMED callback!\n"); return; } - if(dlgb.register_dlgcb(dlg, DLGCB_TERMINATED, trace_dialog_transaction, - xavp->val.v.vptr, trace_free_info) + if(_siptrace_dlgb.register_dlgcb(dlg, DLGCB_TERMINATED, + trace_dialog_transaction, xavp->val.v.vptr, trace_free_info) != 0) { LM_ERR("Failed to register DLGCB_TERMINATED callback!\n"); return; @@ -2088,12 +2175,12 @@ static void trace_dialog( static void trace_dialog_transaction( - struct dlg_cell *dlg, int type, struct dlg_cb_params *params) + struct dlg_cell *dlg, int type, struct dlg_cb_params *cbp) { siptrace_info_t *info; /* coverity fix - there shouldn't be a scenario for this to happen */ - if(params == NULL || params->param == NULL) { + if(cbp == NULL || cbp->param == NULL) { LM_ERR("NULL dialog params!\n"); return; } @@ -2104,15 +2191,15 @@ static void trace_dialog_transaction( * transaction callbacks to catch caller and callee BYEs and their * responses */ - if(params->req == NULL && params->rpl == NULL) { + if(cbp->req == NULL && cbp->rpl == NULL) { LM_DBG("dual bye!\n"); return; } - info = (siptrace_info_t *)*params->param; + info = (siptrace_info_t *)*cbp->param; - trace_transaction(params->req, info, 1); + trace_transaction(cbp->req, info, 1); - sip_trace(params->req, &info->u.dest_info, &info->correlation_id, NULL); + sip_trace(cbp->req, &info->u.dest_info, &info->correlation_id, NULL); } static void trace_free_info(void *trace_info) @@ -2586,6 +2673,11 @@ static sr_kemi_t sr_kemi_siptrace_exports[] = { { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, + { str_init("siptrace"), str_init("sip_trace_msg"), + SR_KEMIP_INT, ki_sip_trace_msg, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, + SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE } + }, { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } } }; diff --git a/src/modules/siptrace/siptrace_send.c b/src/modules/siptrace/siptrace_send.c index bac4ad047..d8a5f974b 100644 --- a/src/modules/siptrace/siptrace_send.c +++ b/src/modules/siptrace/siptrace_send.c @@ -158,7 +158,8 @@ int sip_trace_xheaders_read(struct _siptrace_data *sto) char *searchend = NULL; char *eoh = NULL; char *xheaders = NULL; - long long unsigned int tv_sec, tv_usec; + long long unsigned int tv_sec = 0, tv_usec = 0; + int rv = 0; if(trace_xheaders_read == 0) { return 0; @@ -202,16 +203,17 @@ int sip_trace_xheaders_read(struct _siptrace_data *sto) } // Parse the x-headers: scanf() - if(sscanf(xheaders, - "\r\n" - "X-Siptrace-Fromip: %50s\r\n" - "X-Siptrace-Toip: %50s\r\n" - "X-Siptrace-Time: %llu %llu\r\n" - "X-Siptrace-Method: %50s\r\n" - "X-Siptrace-Dir: %3s", - sto->fromip.s, sto->toip.s, &tv_sec, &tv_usec, sto->method.s, - sto->dir) - == EOF) { + rv = sscanf(xheaders, + "\r\n" + "X-Siptrace-Fromip: %50s\r\n" + "X-Siptrace-Toip: %50s\r\n" + "X-Siptrace-Time: %llu %llu\r\n" + "X-Siptrace-Method: %50s\r\n" + "X-Siptrace-Dir: %3s", + sto->fromip.s, sto->toip.s, &tv_sec, &tv_usec, sto->method.s, + sto->dir); + + if(rv == EOF || rv < 6) { LM_ERR("malformed x-headers\n"); goto erroraftermalloc; } diff --git a/src/modules/siputils/README b/src/modules/siputils/README index 2700a647a..5ca3d55ce 100644 --- a/src/modules/siputils/README +++ b/src/modules/siputils/README @@ -74,35 +74,37 @@ Gabriel Vasile 4.8. get_uri_param(name, var) 4.9. uri_param_rm(param) 4.10. tel2sip(uri, hostpart, result) - 4.11. is_e164(pseudo-variable) - 4.12. is_uri_user_e164(pseudo-variable) - 4.13. is_uri(pseudo-variable) - 4.14. is_tel_number(tval) - 4.15. is_numeric(tval) - 4.16. is_alphanum(tval) - 4.17. is_alphanumex(tval, eset) - 4.18. encode_contact(encoding_prefix, hostpart) - 4.19. decode_contact() - 4.20. decode_contact_header() - 4.21. cmp_uri(str1, str2) - 4.22. cmp_aor(str1, str2) - 4.23. cmp_hdr_name(str1, str2) - 4.24. append_rpid_hf() - 4.25. append_rpid_hf(prefix, suffix) - 4.26. is_rpid_user_e164() - 4.27. set_uri_user(uri, user) - 4.28. set_uri_host(uri, host) - 4.29. is_request() - 4.30. is_reply() - 4.31. is_gruu([uri]) - 4.32. is_supported(option) - 4.33. is_first_hop([mode]) - 4.34. sip_p_charging_vector(flags) - 4.35. contact_param_encode(pname, saddr) - 4.36. contact_param_decode(pname) - 4.37. contact_param_decode_uri(pname) - 4.38. contact_param_rm(pname) - 4.39. hdr_date_check(tdiff) + 4.11. tel2sip2(uri, hostpart, result) + 4.12. is_e164(pseudo-variable) + 4.13. is_uri_user_e164(pseudo-variable) + 4.14. is_uri(pseudo-variable) + 4.15. is_tel_number(tval) + 4.16. is_numeric(tval) + 4.17. is_alphanum(tval) + 4.18. is_alphanumex(tval, eset) + 4.19. encode_contact(encoding_prefix, hostpart) + 4.20. decode_contact() + 4.21. decode_contact_header() + 4.22. cmp_uri(str1, str2) + 4.23. cmp_aor(str1, str2) + 4.24. cmp_hdr_name(str1, str2) + 4.25. append_rpid_hf() + 4.26. append_rpid_hf(prefix, suffix) + 4.27. is_rpid_user_e164() + 4.28. set_uri_user(uri, user) + 4.29. set_uri_host(uri, host) + 4.30. is_request() + 4.31. is_reply() + 4.32. is_gruu([uri]) + 4.33. is_supported(option) + 4.34. is_first_hop([mode]) + 4.35. sip_p_charging_vector(flags) + 4.36. contact_param_encode(pname, saddr) + 4.37. contact_param_decode(pname) + 4.38. contact_param_decode_uri(pname) + 4.39. contact_param_rm(pname) + 4.40. contact_param_check(pname) + 4.41. hdr_date_check(tdiff) 5. Exported pseudo-variables @@ -133,35 +135,37 @@ Gabriel Vasile 1.17. add_uri_param usage 1.18. uri_param_rm usage 1.19. tel2sip usage - 1.20. is_e164 usage - 1.21. is_uri_user_e164 usage - 1.22. is_uri usage - 1.23. is_tel_number usage - 1.24. is_numeric usage - 1.25. is_alphanum usage - 1.26. is_alphanumex usage - 1.27. encode_contact usage - 1.28. decode_contact usage - 1.29. decode_contact_header usage - 1.30. cmp_uri usage - 1.31. cmp_aor usage - 1.32. cmp_hdr_name usage - 1.33. append_rpid_hf usage - 1.34. append_rpid_hf(prefix, suffix) usage - 1.35. is_rpid_user_e164 usage - 1.36. set_uri_user usage - 1.37. set_uri_host usage - 1.38. is_request usage - 1.39. is_reply usage - 1.40. is_gruu() usage - 1.41. is_supported() usage - 1.42. is_first_hop() usage - 1.43. sip_p_charging_vector() usage - 1.44. contact_param_encode usage - 1.45. contact_param_decode usage - 1.46. contact_param_decode_ruri usage - 1.47. contact_param_rm usage - 1.48. hdr_date_check usage + 1.20. tel2sip2 usage + 1.21. is_e164 usage + 1.22. is_uri_user_e164 usage + 1.23. is_uri usage + 1.24. is_tel_number usage + 1.25. is_numeric usage + 1.26. is_alphanum usage + 1.27. is_alphanumex usage + 1.28. encode_contact usage + 1.29. decode_contact usage + 1.30. decode_contact_header usage + 1.31. cmp_uri usage + 1.32. cmp_aor usage + 1.33. cmp_hdr_name usage + 1.34. append_rpid_hf usage + 1.35. append_rpid_hf(prefix, suffix) usage + 1.36. is_rpid_user_e164 usage + 1.37. set_uri_user usage + 1.38. set_uri_host usage + 1.39. is_request usage + 1.40. is_reply usage + 1.41. is_gruu() usage + 1.42. is_supported() usage + 1.43. is_first_hop() usage + 1.44. sip_p_charging_vector() usage + 1.45. contact_param_encode usage + 1.46. contact_param_decode usage + 1.47. contact_param_decode_ruri usage + 1.48. contact_param_rm usage + 1.49. contact_param_check usage + 1.50. hdr_date_check usage Chapter 1. Admin Guide @@ -197,35 +201,37 @@ Chapter 1. Admin Guide 4.8. get_uri_param(name, var) 4.9. uri_param_rm(param) 4.10. tel2sip(uri, hostpart, result) - 4.11. is_e164(pseudo-variable) - 4.12. is_uri_user_e164(pseudo-variable) - 4.13. is_uri(pseudo-variable) - 4.14. is_tel_number(tval) - 4.15. is_numeric(tval) - 4.16. is_alphanum(tval) - 4.17. is_alphanumex(tval, eset) - 4.18. encode_contact(encoding_prefix, hostpart) - 4.19. decode_contact() - 4.20. decode_contact_header() - 4.21. cmp_uri(str1, str2) - 4.22. cmp_aor(str1, str2) - 4.23. cmp_hdr_name(str1, str2) - 4.24. append_rpid_hf() - 4.25. append_rpid_hf(prefix, suffix) - 4.26. is_rpid_user_e164() - 4.27. set_uri_user(uri, user) - 4.28. set_uri_host(uri, host) - 4.29. is_request() - 4.30. is_reply() - 4.31. is_gruu([uri]) - 4.32. is_supported(option) - 4.33. is_first_hop([mode]) - 4.34. sip_p_charging_vector(flags) - 4.35. contact_param_encode(pname, saddr) - 4.36. contact_param_decode(pname) - 4.37. contact_param_decode_uri(pname) - 4.38. contact_param_rm(pname) - 4.39. hdr_date_check(tdiff) + 4.11. tel2sip2(uri, hostpart, result) + 4.12. is_e164(pseudo-variable) + 4.13. is_uri_user_e164(pseudo-variable) + 4.14. is_uri(pseudo-variable) + 4.15. is_tel_number(tval) + 4.16. is_numeric(tval) + 4.17. is_alphanum(tval) + 4.18. is_alphanumex(tval, eset) + 4.19. encode_contact(encoding_prefix, hostpart) + 4.20. decode_contact() + 4.21. decode_contact_header() + 4.22. cmp_uri(str1, str2) + 4.23. cmp_aor(str1, str2) + 4.24. cmp_hdr_name(str1, str2) + 4.25. append_rpid_hf() + 4.26. append_rpid_hf(prefix, suffix) + 4.27. is_rpid_user_e164() + 4.28. set_uri_user(uri, user) + 4.29. set_uri_host(uri, host) + 4.30. is_request() + 4.31. is_reply() + 4.32. is_gruu([uri]) + 4.33. is_supported(option) + 4.34. is_first_hop([mode]) + 4.35. sip_p_charging_vector(flags) + 4.36. contact_param_encode(pname, saddr) + 4.37. contact_param_decode(pname) + 4.38. contact_param_decode_uri(pname) + 4.39. contact_param_rm(pname) + 4.40. contact_param_check(pname) + 4.41. hdr_date_check(tdiff) 5. Exported pseudo-variables @@ -410,35 +416,37 @@ modparam("siputils", "e164_max_len", 20) 4.8. get_uri_param(name, var) 4.9. uri_param_rm(param) 4.10. tel2sip(uri, hostpart, result) - 4.11. is_e164(pseudo-variable) - 4.12. is_uri_user_e164(pseudo-variable) - 4.13. is_uri(pseudo-variable) - 4.14. is_tel_number(tval) - 4.15. is_numeric(tval) - 4.16. is_alphanum(tval) - 4.17. is_alphanumex(tval, eset) - 4.18. encode_contact(encoding_prefix, hostpart) - 4.19. decode_contact() - 4.20. decode_contact_header() - 4.21. cmp_uri(str1, str2) - 4.22. cmp_aor(str1, str2) - 4.23. cmp_hdr_name(str1, str2) - 4.24. append_rpid_hf() - 4.25. append_rpid_hf(prefix, suffix) - 4.26. is_rpid_user_e164() - 4.27. set_uri_user(uri, user) - 4.28. set_uri_host(uri, host) - 4.29. is_request() - 4.30. is_reply() - 4.31. is_gruu([uri]) - 4.32. is_supported(option) - 4.33. is_first_hop([mode]) - 4.34. sip_p_charging_vector(flags) - 4.35. contact_param_encode(pname, saddr) - 4.36. contact_param_decode(pname) - 4.37. contact_param_decode_uri(pname) - 4.38. contact_param_rm(pname) - 4.39. hdr_date_check(tdiff) + 4.11. tel2sip2(uri, hostpart, result) + 4.12. is_e164(pseudo-variable) + 4.13. is_uri_user_e164(pseudo-variable) + 4.14. is_uri(pseudo-variable) + 4.15. is_tel_number(tval) + 4.16. is_numeric(tval) + 4.17. is_alphanum(tval) + 4.18. is_alphanumex(tval, eset) + 4.19. encode_contact(encoding_prefix, hostpart) + 4.20. decode_contact() + 4.21. decode_contact_header() + 4.22. cmp_uri(str1, str2) + 4.23. cmp_aor(str1, str2) + 4.24. cmp_hdr_name(str1, str2) + 4.25. append_rpid_hf() + 4.26. append_rpid_hf(prefix, suffix) + 4.27. is_rpid_user_e164() + 4.28. set_uri_user(uri, user) + 4.29. set_uri_host(uri, host) + 4.30. is_request() + 4.31. is_reply() + 4.32. is_gruu([uri]) + 4.33. is_supported(option) + 4.34. is_first_hop([mode]) + 4.35. sip_p_charging_vector(flags) + 4.36. contact_param_encode(pname, saddr) + 4.37. contact_param_decode(pname) + 4.38. contact_param_decode_uri(pname) + 4.39. contact_param_rm(pname) + 4.40. contact_param_check(pname) + 4.41. hdr_date_check(tdiff) 4.1. options_reply() @@ -623,14 +631,35 @@ tel2sip("$ru", $fd", "$ru"); # $ru: sip:+12345678;ext=200;isub=+123-456@foo.com;user=phone ... -4.11. is_e164(pseudo-variable) +4.11. tel2sip2(uri, hostpart, result) + + Alternative to sip2tel() function that tries to follow closer the RFC + requrements (e.g., sort tel: uri parameters copied to the sip: uri in + the manner defined in the standard; deletes the phone-context parameter + if it is a domain, and, takes visual separators from the phone-context + parameter if it is a telephone number). + + Its parameters have the same meaning as for tel2sip(). + + This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, + BRANCH_ROUTE, or ONREPLY_ROUTE. + + Example 1.20. tel2sip2 usage +... +# $ru: tel:+(34)-999-888-777 +# $fu: sip:test@foo.com +tel2sip2("$ru", $fd", "$ru"); +# $ru: sip:+34999888777@foo.com;user=phone +... + +4.12. is_e164(pseudo-variable) Checks if string value of pseudo variable argument is an E164 number. This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, and LOCAL_ROUTE. - Example 1.20. is_e164 usage + Example 1.21. is_e164 usage ... if (is_e164("$fU")) { # Check From header URI user part ... @@ -641,13 +670,13 @@ if (is_e164("$avp(i:705)") { }; ... -4.12. is_uri_user_e164(pseudo-variable) +4.13. is_uri_user_e164(pseudo-variable) Checks if userpart of URI stored in pseudo variable is E164 number. This function can be used from ANY_ROUTE. - Example 1.21. is_uri_user_e164 usage + Example 1.22. is_uri_user_e164 usage ... if (is_uri_user_e164("$fu")) { # Check From header URI user part ... @@ -658,13 +687,13 @@ if (is_uri_user_e164("$avp(i:705)") { }; ... -4.13. is_uri(pseudo-variable) +4.14. is_uri(pseudo-variable) Checks if string value of pseudo variable argument is a valid uri. This function can be used from ANY_ROUTE. - Example 1.22. is_uri usage + Example 1.23. is_uri usage ... if (is_uri("$var(x)")) { # Check if variable contains a uri ... @@ -675,14 +704,14 @@ if (is_uri("$avp(i:705)") { }; ... -4.14. is_tel_number(tval) +4.15. is_tel_number(tval) Checks if the parameter value is a telephone number: starting with one optional +, followed by digits. The parameter can include variables. This function can be used from ANY_ROUTE. - Example 1.23. is_tel_number usage + Example 1.24. is_tel_number usage ... if (is_tel_number("$rU")) { # Test if R-URI user is telephone number ... @@ -692,35 +721,35 @@ if (is_tel_number("+24242424")) { } ... -4.15. is_numeric(tval) +4.16. is_numeric(tval) Checks if the parameter value consists solely of decimal digits. The parameter can include variables. This function can be used from ANY_ROUTE. - Example 1.24. is_numeric usage + Example 1.25. is_numeric usage ... if (is_numeric("$rU")) { # Test if R-URI user consists of decimal digits ... } ... -4.16. is_alphanum(tval) +4.17. is_alphanum(tval) Checks if the parameter value consists solely of decimal digits or alphabetic ASCII characters. The parameter can include variables. This function can be used from ANY_ROUTE. - Example 1.25. is_alphanum usage + Example 1.26. is_alphanum usage ... if (is_alphanum("$rU")) { ... } ... -4.17. is_alphanumex(tval, eset) +4.18. is_alphanumex(tval, eset) Checks if the value of parameter 'tval' consists solely of decimal digits, alphabetic ASCII characters and the characters in the second @@ -728,14 +757,14 @@ if (is_alphanum("$rU")) { This function can be used from ANY_ROUTE. - Example 1.26. is_alphanumex usage + Example 1.27. is_alphanumex usage ... if (is_alphanumex("$rU", "+.-_")) { ... } ... -4.18. encode_contact(encoding_prefix, hostpart) +4.19. encode_contact(encoding_prefix, hostpart) This function will encode uri-s inside Contact header in the following manner sip:username:password@ip:port;transport=protocol goes @@ -757,12 +786,12 @@ if (is_alphanumex("$rU", "+.-_")) { This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - Example 1.27. encode_contact usage + Example 1.28. encode_contact usage ... if (src_ip == 10.0.0.0/8) encode_contact("natted_client","1.2.3.4"); ... -4.19. decode_contact() +4.20. decode_contact() This function will decode the request URI. If the RURI is in the format sip:encoding_prefix*username*password*ip*port*protocol@hostpart it will @@ -775,12 +804,12 @@ if (src_ip == 10.0.0.0/8) encode_contact("natted_client","1.2.3.4"); This function can be used from REQUEST_ROUTE. - Example 1.28. decode_contact usage + Example 1.29. decode_contact usage ... if (uri =~ "^sip:natted_client") { decode_contact(); } ... -4.20. decode_contact_header() +4.21. decode_contact_header() This function will decode URIs inside Contact header. If the URI in the format sip:encoding_prefix*username*ip*port*protocol@hostpart it will @@ -793,7 +822,7 @@ if (uri =~ "^sip:natted_client") { decode_contact(); } This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - Example 1.29. decode_contact_header usage + Example 1.30. decode_contact_header usage ... reply_route[2] { ... @@ -802,13 +831,13 @@ reply_route[2] { } ... -4.21. cmp_uri(str1, str2) +4.22. cmp_uri(str1, str2) The function returns true if the two parameters matches as SIP URI. This function can be used from ANY_ROUTE. - Example 1.30. cmp_uri usage + Example 1.31. cmp_uri usage ... if(cmp_uri("$ru", "sip:kamailio@kamailio.org")) { @@ -816,14 +845,14 @@ if(cmp_uri("$ru", "sip:kamailio@kamailio.org")) } ... -4.22. cmp_aor(str1, str2) +4.23. cmp_aor(str1, str2) The function returns true if the two parameters matches as AoR. The parameters have to be SIP URIs. This function can be used from ANY_ROUTE. - Example 1.31. cmp_aor usage + Example 1.32. cmp_aor usage ... if(cmp_aor("$rU@KaMaIlIo.org", "sip:kamailio@$fd")) { @@ -831,14 +860,14 @@ if(cmp_aor("$rU@KaMaIlIo.org", "sip:kamailio@$fd")) } ... -4.23. cmp_hdr_name(str1, str2) +4.24. cmp_hdr_name(str1, str2) The function returns true (return code 1) if the two parameters matches as header names. This function can be used from ANY_ROUTE. - Example 1.32. cmp_hdr_name usage + Example 1.33. cmp_hdr_name usage ... if(cmp_hdr_name("$var(hname)", "From")) { @@ -846,7 +875,7 @@ if(cmp_hdr_name("$var(hname)", "From")) } ... -4.24. append_rpid_hf() +4.25. append_rpid_hf() Appends to the message a Remote-Party-ID header that contains header 'Remote-Party-ID: ' followed by the saved value of the SIP URI received @@ -857,14 +886,14 @@ if(cmp_hdr_name("$var(hname)", "From")) This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE. - Example 1.33. append_rpid_hf usage + Example 1.34. append_rpid_hf usage ... append_rpid_hf(); # Append Remote-Party-ID header field ... -4.25. append_rpid_hf(prefix, suffix) +4.26. append_rpid_hf(prefix, suffix) - This function is the same as Section 4.24, “ append_rpid_hf()”. The + This function is the same as Section 4.25, “ append_rpid_hf()”. The only difference is that it accepts two parameters--prefix and suffix to be added to Remote-Party-ID header field. This function ignores rpid_prefix and rpid_suffix parameters, instead of that allows to set @@ -881,13 +910,13 @@ append_rpid_hf(); # Append Remote-Party-ID header field This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE. - Example 1.34. append_rpid_hf(prefix, suffix) usage + Example 1.35. append_rpid_hf(prefix, suffix) usage ... # Append Remote-Party-ID header field append_rpid_hf("", ";party=calling;id-type=subscriber;screen=yes"); ... -4.26. is_rpid_user_e164() +4.27. is_rpid_user_e164() The function checks if the SIP URI received from the database or radius server and will potentially be used in Remote-Party-ID header field @@ -897,68 +926,68 @@ append_rpid_hf("", ";party=calling;id-type=subscriber;screen=yes"); This function can be used from REQUEST_ROUTE. - Example 1.35. is_rpid_user_e164 usage + Example 1.36. is_rpid_user_e164 usage ... if (is_rpid_user_e164()) { # do something here }; ... -4.27. set_uri_user(uri, user) +4.28. set_uri_user(uri, user) Sets userpart of SIP URI stored in writable pseudo variable 'uri' to value of pseudo variable 'user'. This function can be used from ANY_ROUTE. - Example 1.36. set_uri_user usage + Example 1.37. set_uri_user usage ... $var(uri) = "sip:user@host"; $var(user) = "new_user"; set_uri_user("$var(uri)", "$var(user)"); ... -4.28. set_uri_host(uri, host) +4.29. set_uri_host(uri, host) Sets hostpart of SIP URI stored in writable pseudo variable 'uri' to value of pseudo variable 'host'. This function can be used from ANY_ROUTE. - Example 1.37. set_uri_host usage + Example 1.38. set_uri_host usage ... $var(uri) = "sip:user@host"; $var(host) = "new_host"; set_uri_host("$var(uri)", "$var(host)"); ... -4.29. is_request() +4.30. is_request() Return true if the SIP message is a request. This function can be used from ANY_ROUTE. - Example 1.38. is_request usage + Example 1.39. is_request usage ... if (is_request()) { ... } ... -4.30. is_reply() +4.31. is_reply() Return true if the SIP message is a reply. This function can be used from ANY_ROUTE. - Example 1.39. is_reply usage + Example 1.40. is_reply usage ... if (is_reply()) { ... } ... -4.31. is_gruu([uri]) +4.32. is_gruu([uri]) The function returns true if the uri is GRUU ('gr' parameter is present): 1 - pub-gruu; 2 - temp-gruu. @@ -969,12 +998,12 @@ if (is_reply()) { This function can be used from ANY_ROUTE. - Example 1.40. is_gruu() usage + Example 1.41. is_gruu() usage ... if(is_gruu()) { ... } ... -4.32. is_supported(option) +4.33. is_supported(option) Function returns true if given option is listed in Supported header(s) (if any) of the request. Currently the following options are known: @@ -982,12 +1011,12 @@ if(is_gruu()) { ... } This function can be used from ANY_ROUTE. - Example 1.41. is_supported() usage + Example 1.42. is_supported() usage ... if (is_supported("outbound")) { ... } ... -4.33. is_first_hop([mode]) +4.34. is_first_hop([mode]) The function returns true if the proxy is first hop after the original sender based on a best effort estimation by checking Via and @@ -1012,26 +1041,26 @@ if (is_supported("outbound")) { ... } This function can be used from ANY_ROUTE. - Example 1.42. is_first_hop() usage + Example 1.43. is_first_hop() usage ... if(is_first_hop()) { ... } ... if(is_first_hop("1")) { ... } ... -4.34. sip_p_charging_vector(flags) +4.35. sip_p_charging_vector(flags) Manage the P-Charging-Vector header (RFC7315). The flags can be: 'r' - remove; 'g' - generate; 'f' - force (remove + generate). This function can be used from ANY_ROUTE. - Example 1.43. sip_p_charging_vector() usage + Example 1.44. sip_p_charging_vector() usage ... sip_p_charging_vector("g"); ... -4.35. contact_param_encode(pname, saddr) +4.36. contact_param_encode(pname, saddr) This function encodes URI inside Contact headers by building a new URI from 'saddr' parameter and adding a parameter with the name 'pname' @@ -1044,14 +1073,14 @@ sip_p_charging_vector("g"); This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - Example 1.44. contact_param_encode usage + Example 1.45. contact_param_encode usage ... if (is_method("REGISTER") and src_ip == 10.0.0.0/8) { contact_param_encode("ksu", "sip:1.2.3.4:5060;transport=tcp"); } ... -4.36. contact_param_decode(pname) +4.37. contact_param_decode(pname) This function decodes URI inside Contact headers by building a new URI from 'pname' parameter, decoding its value from Base64URL. @@ -1062,14 +1091,14 @@ if (is_method("REGISTER") and src_ip == 10.0.0.0/8) { This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - Example 1.45. contact_param_decode usage + Example 1.46. contact_param_decode usage ... if (is_method("REGISTER") and src_ip == 1.2.3.4) { contact_param_decode("ksu"); } ... -4.37. contact_param_decode_uri(pname) +4.38. contact_param_decode_uri(pname) This function decodes R-URI (request URI) by building a new R-URI from 'pname' parameter, decoding its value from Base64URL. @@ -1080,14 +1109,14 @@ if (is_method("REGISTER") and src_ip == 1.2.3.4) { This function can be used from REQUEST_ROUTE. - Example 1.46. contact_param_decode_ruri usage + Example 1.47. contact_param_decode_ruri usage ... if (is_method("INVITE") and src_ip == 1.2.3.4) { contact_param_decode_ruri("ksu"); } ... -4.38. contact_param_rm(pname) +4.39. contact_param_rm(pname) This function removes the parameter from the URIs inside the Contact headers. @@ -1097,14 +1126,31 @@ if (is_method("INVITE") and src_ip == 1.2.3.4) { This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - Example 1.47. contact_param_rm usage + Example 1.48. contact_param_rm usage ... if (is_method("REGISTER") and src_ip == 1.2.3.4) { contact_param_rm("myparam"); } ... -4.39. hdr_date_check(tdiff) +4.40. contact_param_check(pname) + + This function returns true (1) if the URI inside the Contact header + contains the parameter with the name 'pname'. Otherwise it returns + false (-1). + + Meaning of the parameters is as follows: + * pname - name of the URI parameter. + + This function can be used from ANY_ROUTE. + + Example 1.49. contact_param_check usage +... +if (contact_param_check("myparam")) { +} +... + +4.41. hdr_date_check(tdiff) Returns true if sip message has Date header and its value is lower than 'NOW() - tdiff'. @@ -1115,7 +1161,7 @@ if (is_method("REGISTER") and src_ip == 1.2.3.4) { This function can be used from ANY_ROUTE. - Example 1.48. hdr_date_check usage + Example 1.50. hdr_date_check usage ... if (!hdr_date_check("10")) { sl_send_reply("403", "Outdated date"); diff --git a/src/modules/siputils/chargingvector.c b/src/modules/siputils/chargingvector.c index bc6adc364..5df2d34c2 100644 --- a/src/modules/siputils/chargingvector.c +++ b/src/modules/siputils/chargingvector.c @@ -34,13 +34,13 @@ #define LOOPBACK_IP 16777343 #define PCV_BUF_SIZE 256 -static char pcv_buf[PCV_BUF_SIZE]; -static str pcv = {pcv_buf, 0}; -static str pcv_id = {NULL, 0}; -static str pcv_host = {NULL, 0}; -static str pcv_orig = {NULL, 0}; -static str pcv_term = {NULL, 0}; -static uint64_t counter = 0; +static char _siputils_pcv_buf[PCV_BUF_SIZE]; +static str _siputils_pcv = {_siputils_pcv_buf, 0}; +static str _siputils_pcv_id = {NULL, 0}; +static str _siputils_pcv_host = {NULL, 0}; +static str _siputils_pcv_orig = {NULL, 0}; +static str _siputils_pcv_term = {NULL, 0}; +static uint64_t _siputils_pcv_counter = 0; enum PCV_Status @@ -50,8 +50,8 @@ enum PCV_Status PCV_GENERATED = 2 }; -static enum PCV_Status pcv_status = PCV_NONE; -static unsigned int current_msg_id = (unsigned int)-1; +static enum PCV_Status _siputils_pcv_status = PCV_NONE; +static unsigned int _siputils_pcv_current_msg_id = (unsigned int)-1; static void sip_generate_charging_vector(char *pcv) { @@ -88,9 +88,9 @@ static void sip_generate_charging_vector(char *pcv) } } - ct = counter++; - if(counter > 0xFFFFFFFF) - counter = 0; + ct = _siputils_pcv_counter++; + if(_siputils_pcv_counter > 0xFFFFFFFF) + _siputils_pcv_counter = 0; memset(newConferenceIdentifier, 0, SIZE_CONF_ID); newConferenceIdentifier[0] = 'I'; @@ -149,56 +149,56 @@ static int sip_parse_charging_vector(const char *pcv_value, unsigned int len) s = strstr(pcv_value, "icid-value="); if(s != NULL) { - pcv_id.s = s + strlen("icid-value="); - pcv_id.len = sip_param_end(pcv_id.s, len); - LM_DBG("parsed P-Charging-Vector icid-value=%.*s\n", pcv_id.len, - pcv_id.s); + _siputils_pcv_id.s = s + strlen("icid-value="); + _siputils_pcv_id.len = sip_param_end(_siputils_pcv_id.s, len); + LM_DBG("parsed P-Charging-Vector icid-value=%.*s\n", + _siputils_pcv_id.len, _siputils_pcv_id.s); } else { LM_WARN("mandatory icid-value not found\n"); - pcv_id.s = NULL; - pcv_id.len = 0; + _siputils_pcv_id.s = NULL; + _siputils_pcv_id.len = 0; } s = strstr(pcv_value, "icid-generated-at="); if(s != NULL) { - pcv_host.s = s + strlen("icid-generated-at="); - pcv_host.len = sip_param_end(pcv_host.s, len); + _siputils_pcv_host.s = s + strlen("icid-generated-at="); + _siputils_pcv_host.len = sip_param_end(_siputils_pcv_host.s, len); LM_DBG("parsed P-Charging-Vector icid-generated-at=%.*s\n", - pcv_host.len, pcv_host.s); + _siputils_pcv_host.len, _siputils_pcv_host.s); } else { LM_DBG("icid-generated-at not found\n"); - pcv_host.s = NULL; - pcv_host.len = 0; + _siputils_pcv_host.s = NULL; + _siputils_pcv_host.len = 0; } s = strstr(pcv_value, "orig-ioi="); if(s != NULL) { - pcv_orig.s = s + strlen("orig-ioi="); - pcv_orig.len = sip_param_end(pcv_orig.s, len); - LM_INFO("parsed P-Charging-Vector orig-ioi=%.*s\n", pcv_orig.len, - pcv_orig.s); + _siputils_pcv_orig.s = s + strlen("orig-ioi="); + _siputils_pcv_orig.len = sip_param_end(_siputils_pcv_orig.s, len); + LM_INFO("parsed P-Charging-Vector orig-ioi=%.*s\n", + _siputils_pcv_orig.len, _siputils_pcv_orig.s); } else { - pcv_orig.s = NULL; - pcv_orig.len = 0; + _siputils_pcv_orig.s = NULL; + _siputils_pcv_orig.len = 0; } s = strstr(pcv_value, "term-ioi="); if(s != NULL) { - pcv_term.s = s + strlen("term-ioi="); - pcv_term.len = sip_param_end(pcv_term.s, len); - LM_INFO("parsed P-Charging-Vector term-ioi=%.*s\n", pcv_term.len, - pcv_term.s); + _siputils_pcv_term.s = s + strlen("term-ioi="); + _siputils_pcv_term.len = sip_param_end(_siputils_pcv_term.s, len); + LM_INFO("parsed P-Charging-Vector term-ioi=%.*s\n", + _siputils_pcv_term.len, _siputils_pcv_term.s); } else { - pcv_term.s = NULL; - pcv_term.len = 0; + _siputils_pcv_term.s = NULL; + _siputils_pcv_term.len = 0; } // only icid-value is mandatory, log anyway when missing icid-generated-at - if(pcv_host.s == NULL && pcv_id.s != NULL && len > 0) { + if(_siputils_pcv_host.s == NULL && _siputils_pcv_id.s != NULL && len > 0) { LM_WARN("icid-generated-at is missing %.*s\n", len, pcv_value); } - return (pcv_id.s != NULL); + return (_siputils_pcv_id.s != NULL); } static int sip_get_charging_vector( @@ -224,30 +224,31 @@ static int sip_get_charging_vector( * append p charging vector values after the header name "P-Charging-Vector" and * the ": " (+2) */ - char *pcv_body = pcv_buf + strlen(P_CHARGING_VECTOR) + 2; + char *pcv_body = _siputils_pcv_buf + strlen(P_CHARGING_VECTOR) + 2; if(hf->body.len > 0) { memcpy(pcv_body, hf->body.s, hf->body.len); - pcv.len = hf->body.len + strlen(P_CHARGING_VECTOR) + 2; + _siputils_pcv.len = + hf->body.len + strlen(P_CHARGING_VECTOR) + 2; pcv_body[hf->body.len] = '\0'; if(sip_parse_charging_vector(pcv_body, hf->body.len) == 0) { LM_ERR("P-Charging-Vector header found but failed to parse " "value [%s].\n", pcv_body); - pcv_status = PCV_NONE; - pcv.s = NULL; - pcv.len = 0; + _siputils_pcv_status = PCV_NONE; + _siputils_pcv.s = NULL; + _siputils_pcv.len = 0; } else { - pcv_status = PCV_PARSED; - pcv.s = hf->body.s; - pcv.len = hf->body.len; + _siputils_pcv_status = PCV_PARSED; + _siputils_pcv.s = hf->body.s; + _siputils_pcv.len = hf->body.len; } return 2; } else { - pcv_id.s = 0; - pcv_id.len = 0; - pcv_host.s = 0; - pcv_host.len = 0; + _siputils_pcv_id.s = 0; + _siputils_pcv_id.len = 0; + _siputils_pcv_host.s = 0; + _siputils_pcv_host.len = 0; LM_WARN("P-Charging-Vector header found but no value.\n"); } *hf_pcv = hf; @@ -285,14 +286,14 @@ static int sip_add_charging_vector(struct sip_msg *msg) return -1; } - s = (char *)pkg_malloc(pcv.len); + s = (char *)pkg_malloc(_siputils_pcv.len); if(!s) { PKG_MEM_ERROR; return -1; } - memcpy(s, pcv.s, pcv.len); + memcpy(s, _siputils_pcv.s, _siputils_pcv.len); - if(insert_new_lump_before(anchor, s, pcv.len, 0) == 0) { + if(insert_new_lump_before(anchor, s, _siputils_pcv.len, 0) == 0) { LM_ERR("can't insert lump\n"); pkg_free(s); return -1; @@ -309,8 +310,8 @@ int sip_handle_pcv(struct sip_msg *msg, char *flags, char *str2) str flag_str; struct hdr_field *hf_pcv = NULL; - pcv.len = 0; - pcv_status = PCV_NONE; + _siputils_pcv.len = 0; + _siputils_pcv_status = PCV_NONE; if(fixup_get_svalue(msg, (gparam_p)flags, &flag_str) < 0) { LM_ERR("failed to retrieve parameter value\n"); @@ -347,7 +348,7 @@ int sip_handle_pcv(struct sip_msg *msg, char *flags, char *str2) * We need to remove the original PCV if it was present and either * we were asked to remove it or we were asked to replace it */ - if(pcv_status == PCV_PARSED && (replace_pcv || remove_pcv)) { + if(_siputils_pcv_status == PCV_PARSED && (replace_pcv || remove_pcv)) { i = sip_remove_charging_vector(msg, hf_pcv); if(i <= 0) return (i == 0) ? -1 : i; @@ -358,12 +359,12 @@ int sip_handle_pcv(struct sip_msg *msg, char *flags, char *str2) * - or if we were asked to replace it alltogether regardless its former value */ if(replace_pcv - || (generate_pcv && pcv_status != PCV_GENERATED - && pcv_status != PCV_PARSED)) { - strcpy(pcv_buf, P_CHARGING_VECTOR); - strcat(pcv_buf, ": "); + || (generate_pcv && _siputils_pcv_status != PCV_GENERATED + && _siputils_pcv_status != PCV_PARSED)) { + strcpy(_siputils_pcv_buf, P_CHARGING_VECTOR); + strcat(_siputils_pcv_buf, ": "); - char *pcv_body = pcv_buf + 19; + char *pcv_body = _siputils_pcv_buf + 19; char pcv_value[40]; /* We use the IP address of the interface that received the message as generated-at */ @@ -376,18 +377,19 @@ int sip_handle_pcv(struct sip_msg *msg, char *flags, char *str2) sip_generate_charging_vector(pcv_value); - pcv.len = snprintf(pcv_body, PCV_BUF_SIZE - 19, + _siputils_pcv.len = snprintf(pcv_body, PCV_BUF_SIZE - 19, "icid-value=%.*s; icid-generated-at=%.*s\r\n", 32, pcv_value, msg->rcv.bind_address->address_str.len, msg->rcv.bind_address->address_str.s); - pcv.len += 19; + _siputils_pcv.len += 19; - pcv_status = PCV_GENERATED; + _siputils_pcv_status = PCV_GENERATED; /* if generated, reparse it */ - sip_parse_charging_vector(pcv_body, pcv.len - 19); + sip_parse_charging_vector(pcv_body, _siputils_pcv.len - 19); /* if it was generated, we need to send it out as a header */ - LM_INFO("Generated PCV header %.*s\n", pcv.len - 2, pcv_buf); + LM_INFO("Generated PCV header %.*s\n", _siputils_pcv.len - 2, + _siputils_pcv_buf); i = sip_add_charging_vector(msg); if(i <= 0) { LM_ERR("Failed to add P-Charging-Vector header\n"); @@ -395,7 +397,7 @@ int sip_handle_pcv(struct sip_msg *msg, char *flags, char *str2) } } - current_msg_id = msg->id; + _siputils_pcv_current_msg_id = msg->id; return 1; } @@ -405,39 +407,41 @@ int pv_get_charging_vector( { str pcv_pv; - if(current_msg_id != msg->id || pcv_status == PCV_NONE) { + if(_siputils_pcv_current_msg_id != msg->id + || _siputils_pcv_status == PCV_NONE) { struct hdr_field *hf_pcv = NULL; if(sip_get_charging_vector(msg, &hf_pcv) > 0) { - current_msg_id = msg->id; + _siputils_pcv_current_msg_id = msg->id; } LM_DBG("Parsed charging vector for pseudo-var\n"); } else { - LM_DBG("Charging vector is in state %d for pseudo-var\n", pcv_status); + LM_DBG("Charging vector is in state %d for pseudo-var\n", + _siputils_pcv_status); } - switch(pcv_status) { + switch(_siputils_pcv_status) { case PCV_GENERATED: LM_DBG("pcv_status==PCV_GENERATED\n"); case PCV_PARSED: LM_DBG("pcv_status==PCV_PARSED\n"); switch(param->pvn.u.isname.name.n) { case 5: - pcv_pv = pcv_term; + pcv_pv = _siputils_pcv_term; break; case 4: - pcv_pv = pcv_orig; + pcv_pv = _siputils_pcv_orig; break; case 2: - pcv_pv = pcv_host; + pcv_pv = _siputils_pcv_host; break; case 3: - pcv_pv = pcv_id; + pcv_pv = _siputils_pcv_id; break; case 1: default: - pcv_pv = pcv; + pcv_pv = _siputils_pcv; break; } @@ -445,7 +449,7 @@ int pv_get_charging_vector( return pv_get_strval(msg, param, res, &pcv_pv); else LM_WARN("No value for pseudo-var $pcv but status was %d.\n", - pcv_status); + _siputils_pcv_status); break; diff --git a/src/modules/siputils/checks.c b/src/modules/siputils/checks.c index e3b4c97ff..2ba80b5be 100644 --- a/src/modules/siputils/checks.c +++ b/src/modules/siputils/checks.c @@ -662,6 +662,231 @@ int tel2sip(struct sip_msg *_msg, char *_uri, char *_hostpart, char *_res) } +/* + * Compare function to sort tel: uri options acording to standard + * before inserting into sip: uri + * + * See "RFC 3261 SIP: Session Initiation Protocol June 2002" + * 19.1.6 Relating SIP URIs and tel URLs + */ +typedef struct +{ + char *name; + char *value; +} tel_param_t; + +#define MAX_TEL_PARAMS 10 + +int compare_tel_options(const void *v1, const void *v2) +{ + tel_param_t *p1 = (tel_param_t *)v1; + tel_param_t *p2 = (tel_param_t *)v2; + + if(0 == strcasecmp(p1->name, "isdn-subaddress")) { + return -1; + } else if(0 == strcasecmp(p2->name, "isdn-subaddress")) { + return 1; + } else if(0 == strcasecmp(p1->name, "post-dial")) { + return -1; + } else if(0 == strcasecmp(p2->name, "post-dial")) { + return 1; + } else { + return strcasecmp(p1->name, p2->name); + } +} + +/* + * Remove visual separators from the phone number + * Assume it has been validated as a number containing + * ONLY leading '+', digits, and visual separators. + */ +static void remove_visual_separators_from_phone(char *p) +{ + char *p2; + p2 = p; + while(*p != '\0') { + /* Skip all visual separators */ + while((*p != '\0') + && ((*p == '.') || (*p == '-') || (*p == '(') || (*p == ')'))) { + p++; + } + *p2 = *p; /* Until the first visual separator, these both point to the same place. */ + /* but, more efficient to just do it than an if statement each time. */ + /* If we arrived at a terminator in the inner loop, time to exit */ + if(*p == '\0') + return; + /* Now we increment both pointers. */ + p++; + p2++; + } + *p2 = '\0'; /* Make sure that the string is terminated after the last valid digit. */ +} + +/* + * Check if this is a phone number. + * Assume possible leading '+' + * Assume separators '.', '-', '(', or ')' could be present. + */ +static int is_telnumber_format(const char *p) +{ + if(*p == '+') + p++; + while(*p != '\0') { + if((!isdigit(*p)) && (*p != '.') && (*p != '-') && (*p != '(') + && (*p != ')')) + return 0; + p++; + } + return 1; +} + + +/* + * Converts URI, if it is tel URI, to SIP URI. Returns 1, if + * conversion succeeded or if no conversion was needed, i.e., URI was not + * tel URI. Returns -1, if conversion failed. Takes SIP URI hostpart from + * second parameter and (if needed) writes the result to third parameter. + * This one attempts to be standards compliant and sort tel: uri parameters + * copied to the sip: uri in the manner defined in the standard. It also + * deletes the "phone-context" parameter if it is a domain, and, takes visual + * separators from the "phone-context" parameter if it is a telephone number. + */ +int tel2sip2(struct sip_msg *_msg, char *_uri, char *_hostpart, char *_res) +{ + str uri, hostpart, tel_uri, sip_uri; + char *at; + int i, j, in_tel_parameters = 0; + int n_tel_params = 0; + pv_spec_t *res; + pv_value_t res_val; + char *tmp_ptr = NULL; + tel_param_t params[MAX_TEL_PARAMS]; + + /* get parameters */ + if(get_str_fparam(&uri, _msg, (fparam_t *)_uri) < 0) { + LM_ERR("failed to get uri value\n"); + return -1; + } + if(get_str_fparam(&hostpart, _msg, (fparam_t *)_hostpart) < 0) { + LM_ERR("failed to get hostpart value\n"); + return -1; + } + res = (pv_spec_t *)_res; + + /* check if anything needs to be done */ + if(uri.len < 4) + return 1; + if(strncasecmp(uri.s, "tel:", 4) != 0) + return 1; + + /* reserve memory for clean tel uri */ + tel_uri.s = pkg_malloc(uri.len + 1); + if(tel_uri.s == 0) { + LM_ERR("no more pkg memory\n"); + return -1; + } + + /* Remove visual separators before converting to SIP URI. Don't remove + * visual separators in TEL URI parameters (after the first ";") */ + for(i = 0, j = 0; i < uri.len; i++) { + if(in_tel_parameters == 0) { + if(uri.s[i] == ';') + in_tel_parameters = 1; + } + if(in_tel_parameters == 0) { + if((uri.s[i] != '-') && (uri.s[i] != '.') && (uri.s[i] != '(') + && (uri.s[i] != ')')) + tel_uri.s[j++] = tolower(uri.s[i]); + } else { + tel_uri.s[j++] = tolower(uri.s[i]); + } + } + tel_uri.s[j] = '\0'; + tel_uri.len = strlen(tel_uri.s); + + /*** Start Code to sort tel: params ***/ + tmp_ptr = tel_uri.s + 4; /* skip tel: */ + + for(i = 0; i < MAX_TEL_PARAMS; i++) { + tmp_ptr = strchr(tmp_ptr, ';'); + if(tmp_ptr == NULL) { + break; + } + *tmp_ptr = '\0'; + tmp_ptr++; + n_tel_params++; + params[i].name = tmp_ptr; + } + for(i = 0; i < n_tel_params; i++) { + tmp_ptr = strchr(params[i].name, '='); + if(tmp_ptr == NULL) { + params[i].value = ""; + } else { + *tmp_ptr = '\0'; + tmp_ptr++; + params[i].value = tmp_ptr; + } + if((0 == strcasecmp(params[i].name, "phone-context")) + && (is_telnumber_format(params[i].value))) { + remove_visual_separators_from_phone(params[i].value); + } + } + if(n_tel_params > 1) { + qsort(¶ms[0], n_tel_params, sizeof(tel_param_t), + compare_tel_options); + } + /*** End Code to sort tel: params ***/ + + /* reserve memory for resulting sip uri */ + sip_uri.len = 4 + tel_uri.len - 4 + 1 + hostpart.len + 1 + 10; + sip_uri.s = pkg_malloc(sip_uri.len + 1); + if(sip_uri.s == 0) { + LM_ERR("no more pkg memory\n"); + pkg_free(tel_uri.s); + return -1; + } + + /* create resulting sip uri */ + at = sip_uri.s; + append_str(at, "sip:", 4); + /***** Start Code for sorted tel: parameters ****/ + /* This string was terminated after the number */ + append_str(at, tel_uri.s + 4, strlen(tel_uri.s + 4)); + /** Now we need to insert sorted tel: parameters **/ + for(i = 0; i < n_tel_params; i++) { + /* If the phone context is a domain, + * it has already been extracted and is in the "host part" */ + if((0 != strcasecmp(params[i].name, "phone-context")) + || (is_telnumber_format(params[i].value))) { + append_chr(at, ';'); + append_str(at, params[i].name, strlen(params[i].name)); + append_chr(at, '='); + append_str(at, params[i].value, strlen(params[i].value)); + } + } + /***** End Code for sort tel: parameters ****/ + append_chr(at, '@'); + append_str(at, hostpart.s, hostpart.len); + append_chr(at, ';'); + append_str(at, "user=phone", 10); + + /* tel_uri is not needed anymore */ + pkg_free(tel_uri.s); + + /* set result pv value and write sip uri to result pv */ + res_val.rs = sip_uri; + res_val.flags = PV_VAL_STR; + if(res->setf(_msg, &res->pvp, (int)EQ_T, &res_val) != 0) { + LM_ERR("failed to set result pvar\n"); + pkg_free(sip_uri.s); + return -1; + } + + /* free allocated pkg memory and return */ + pkg_free(sip_uri.s); + return 1; +} + /* * Check if parameter is an e164 number. */ diff --git a/src/modules/siputils/checks.h b/src/modules/siputils/checks.h index a5a36f43d..5aa67295b 100644 --- a/src/modules/siputils/checks.h +++ b/src/modules/siputils/checks.h @@ -74,6 +74,8 @@ int ki_add_uri_param(struct sip_msg *_msg, str *param); */ int tel2sip(struct sip_msg *_msg, char *_uri, char *_hostpart, char *_res); +int tel2sip2(struct sip_msg *_msg, char *_uri, char *_hostpart, char *_res); + /* * Check if pseudo variable contains a valid uri */ diff --git a/src/modules/siputils/contact_ops.c b/src/modules/siputils/contact_ops.c index 59fed951e..5f739d151 100644 --- a/src/modules/siputils/contact_ops.c +++ b/src/modules/siputils/contact_ops.c @@ -1027,3 +1027,76 @@ int ki_contact_param_rm(sip_msg_t *msg, str *nparam) return 1; } + +/** + * + */ +int ki_contact_param_check(sip_msg_t *msg, str *nparam) +{ + contact_body_t *cb; + contact_t *c; + sip_uri_t puri; + str sparams; + hdr_field_t *hf = NULL; + param_t *params = NULL; + param_hooks_t phooks; + param_t *pit; + + if(parse_contact_headers(msg) < 0 || msg->contact == NULL + || msg->contact->parsed == NULL) { + LM_DBG("no Contact header present\n"); + return 1; + } + + hf = msg->contact; + while(hf) { + if(hf->type != HDR_CONTACT_T) { + hf = hf->next; + continue; + } + cb = (contact_body_t *)hf->parsed; + for(c = cb->contacts; c != NULL; c = c->next) { + if(c->uri.len < 4) { + continue; + } + if(parse_uri(c->uri.s, c->uri.len, &puri) < 0) { + LM_ERR("failed to parse contact uri [%.*s]\n", c->uri.len, + c->uri.s); + return -1; + } + if(puri.sip_params.len > 0) { + sparams = puri.sip_params; + } else if(puri.params.len > 0) { + sparams = puri.params; + } else { + continue; + } + + if(parse_params2(&sparams, CLASS_ANY, &phooks, ¶ms, ';') < 0) { + LM_ERR("failed to parse uri params [%.*s]\n", c->uri.len, + c->uri.s); + continue; + } + + pit = params; + while(pit != NULL) { + if(pit->name.len == nparam->len + && strncasecmp(pit->name.s, nparam->s, nparam->len) + == 0) { + break; + } + pit = pit->next; + } + if(pit == NULL) { + free_params(params); + params = NULL; + continue; + } + free_params(params); + return 1; + } + hf = hf->next; + } + + return -1; +} diff --git a/src/modules/siputils/contact_ops.h b/src/modules/siputils/contact_ops.h index c44f20279..3f0e0b79d 100644 --- a/src/modules/siputils/contact_ops.h +++ b/src/modules/siputils/contact_ops.h @@ -76,5 +76,6 @@ int ki_contact_param_encode(sip_msg_t *msg, str *nparam, str *saddr); int ki_contact_param_decode(sip_msg_t *msg, str *nparam); int ki_contact_param_decode_ruri(sip_msg_t *msg, str *nparam); int ki_contact_param_rm(sip_msg_t *msg, str *nparam); +int ki_contact_param_check(sip_msg_t *msg, str *nparam); #endif diff --git a/src/modules/siputils/doc/siputils_admin.xml b/src/modules/siputils/doc/siputils_admin.xml index 63984c60c..ad30a1a9f 100644 --- a/src/modules/siputils/doc/siputils_admin.xml +++ b/src/modules/siputils/doc/siputils_admin.xml @@ -539,13 +539,15 @@ if (uri_param_rm("param1")) { <para> The conversion follows the rules in RFC 3261 section 19.1.6: <itemizedlist> - <listitem> - <para>Visual separators ( "-", ".", "(", ")" ) are removed from tel URI number before converting it to SIP URI userinfo.</para> + <listitem> + <para>Visual separators ( "-", ".", "(", ")" ) are removed + from tel URI number before converting it to SIP URI userinfo.</para> </listitem> <listitem> - <para>tel URI parameters are downcased before appending them to SIP URI userinfo</para> - </listitem> - </itemizedlist> + <para>tel URI parameters are downcased before appending them + to SIP URI userinfo</para> + </listitem> + </itemizedlist> </para> <para> The SIP URI hostpart is taken from second param @@ -569,6 +571,36 @@ tel2sip("$ru", $fd", "$ru"); tel2sip("$ru", $fd", "$ru"); # $ru: sip:+12345678;ext=200;isub=+123-456@foo.com;user=phone ... +</programlisting> + </example> + </section> + <section id="siputils.f.tel2sip2"> + <title> + <function moreinfo="none">tel2sip2(uri, hostpart, result)</function> + + + Alternative to sip2tel() function that tries to follow closer the RFC + requrements (e.g., sort tel: uri parameters copied to the sip: uri in + the manner defined in the standard; deletes the phone-context parameter + if it is a domain, and, takes visual separators from the phone-context + parameter if it is a telephone number). + + + Its parameters have the same meaning as for tel2sip(). + + + This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, + BRANCH_ROUTE, or ONREPLY_ROUTE. + + + <function>tel2sip2</function> usage + +... +# $ru: tel:+(34)-999-888-777 +# $fu: sip:test@foo.com +tel2sip2("$ru", $fd", "$ru"); +# $ru: sip:+34999888777@foo.com;user=phone +...
@@ -1340,6 +1372,35 @@ if (is_method("REGISTER") and src_ip == 1.2.3.4) { contact_param_rm("myparam"); } ... + + + +
+ + <function moreinfo="none">contact_param_check(pname)</function> + + + This function returns true (1) if the URI inside the Contact + header contains the parameter with the name 'pname'. Otherwise it + returns false (-1). + + Meaning of the parameters is as follows: + + + pname - name of the URI parameter. + + + + + This function can be used from ANY_ROUTE. + + + <function>contact_param_check</function> usage + +... +if (contact_param_check("myparam")) { +} +...
diff --git a/src/modules/siputils/siputils.c b/src/modules/siputils/siputils.c index 56232e0d8..d31671db7 100644 --- a/src/modules/siputils/siputils.c +++ b/src/modules/siputils/siputils.c @@ -107,6 +107,7 @@ static int w_contact_param_encode(sip_msg_t *msg, char *pnparam, char *psaddr); static int w_contact_param_decode(sip_msg_t *msg, char *pnparam, char *p2); static int w_contact_param_decode_ruri(sip_msg_t *msg, char *pnparam, char *p2); static int w_contact_param_rm(sip_msg_t *msg, char *pnparam, char *p2); +static int w_contact_param_check(sip_msg_t *msg, char *pnparam, char *p2); static int w_hdr_date_check(sip_msg_t *msg, char *ptdiff, char *p2); @@ -122,118 +123,129 @@ static int ki_is_gruu(sip_msg_t *msg); char *contact_flds_separator = DEFAULT_SEPARATOR; +/* clang-format off */ static cmd_export_t cmds[] = { - {"options_reply", (cmd_function)opt_reply, 0, 0, 0, REQUEST_ROUTE}, - {"is_user", (cmd_function)is_user, 1, fixup_spve_null, 0, - REQUEST_ROUTE | LOCAL_ROUTE}, - {"has_totag", (cmd_function)w_has_totag, 0, 0, 0, ANY_ROUTE}, - {"uri_param", (cmd_function)uri_param_1, 1, fixup_spve_null, 0, - REQUEST_ROUTE | BRANCH_ROUTE | FAILURE_ROUTE}, - {"uri_param", (cmd_function)uri_param_2, 2, fixup_spve_spve, 0, - REQUEST_ROUTE | BRANCH_ROUTE | FAILURE_ROUTE}, - {"uri_param_any", (cmd_function)w_uri_param_any, 1, fixup_spve_null, 0, - REQUEST_ROUTE | BRANCH_ROUTE | FAILURE_ROUTE}, - {"add_uri_param", (cmd_function)add_uri_param, 1, fixup_str_null, 0, - REQUEST_ROUTE}, - {"get_uri_param", (cmd_function)get_uri_param, 2, fixup_get_uri_param, - free_fixup_get_uri_param, REQUEST_ROUTE | LOCAL_ROUTE}, - {"uri_param_rm", (cmd_function)w_uri_param_rm, 1, fixup_spve_null, 0, - REQUEST_ROUTE | BRANCH_ROUTE | FAILURE_ROUTE}, - {"tel2sip", (cmd_function)tel2sip, 3, fixup_tel2sip, 0, - REQUEST_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE | ONREPLY_ROUTE}, - {"is_uri", (cmd_function)is_uri, 1, fixup_spve_null, - fixup_free_spve_null, ANY_ROUTE}, - {"is_e164", (cmd_function)w_is_e164, 1, fixup_pvar_null, - fixup_free_pvar_null, - REQUEST_ROUTE | FAILURE_ROUTE | LOCAL_ROUTE}, - {"is_uri_user_e164", (cmd_function)w_is_uri_user_e164, 1, - fixup_pvar_null, fixup_free_pvar_null, ANY_ROUTE}, - {"encode_contact", (cmd_function)encode_contact, 2, 0, 0, - REQUEST_ROUTE | ONREPLY_ROUTE}, - {"decode_contact", (cmd_function)decode_contact, 0, 0, 0, - REQUEST_ROUTE}, - {"decode_contact_header", (cmd_function)decode_contact_header, 0, 0, 0, - REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, - {"cmp_uri", (cmd_function)w_cmp_uri, 2, fixup_spve_spve, 0, ANY_ROUTE}, - {"cmp_aor", (cmd_function)w_cmp_aor, 2, fixup_spve_spve, 0, ANY_ROUTE}, - {"cmp_hdr_name", (cmd_function)w_cmp_hdr_name, 2, fixup_spve_spve, 0, - ANY_ROUTE}, - {"is_rpid_user_e164", (cmd_function)is_rpid_user_e164, 0, 0, 0, - REQUEST_ROUTE}, - {"append_rpid_hf", (cmd_function)append_rpid_hf, 0, 0, 0, - REQUEST_ROUTE | BRANCH_ROUTE | FAILURE_ROUTE}, - {"append_rpid_hf", (cmd_function)append_rpid_hf_p, 2, fixup_str_str, 0, - REQUEST_ROUTE | BRANCH_ROUTE | FAILURE_ROUTE}, - {"set_uri_user", (cmd_function)set_uri_user, 2, fixup_set_uri, - fixup_free_set_uri, ANY_ROUTE}, - {"set_uri_host", (cmd_function)set_uri_host, 2, fixup_set_uri, - fixup_free_set_uri, ANY_ROUTE}, - {"is_request", (cmd_function)w_is_request, 0, 0, 0, ANY_ROUTE}, - {"is_reply", (cmd_function)w_is_reply, 0, 0, 0, ANY_ROUTE}, - {"is_gruu", (cmd_function)w_is_gruu, 0, 0, 0, ANY_ROUTE}, - {"is_gruu", (cmd_function)w_is_gruu, 1, fixup_spve_null, 0, ANY_ROUTE}, - {"is_supported", (cmd_function)w_is_supported, 1, fixup_option, 0, - ANY_ROUTE}, - {"is_first_hop", (cmd_function)w_is_first_hop, 0, 0, 0, ANY_ROUTE}, - {"is_first_hop", (cmd_function)w_is_first_hop, 1, fixup_igp_null, - fixup_free_igp_null, ANY_ROUTE}, - {"is_tel_number", (cmd_function)is_tel_number, 1, fixup_spve_null, 0, - ANY_ROUTE}, - {"is_numeric", (cmd_function)is_numeric, 1, fixup_spve_null, 0, - ANY_ROUTE}, - {"is_alphanum", (cmd_function)ksr_is_alphanum, 1, fixup_spve_null, 0, - ANY_ROUTE}, - {"is_alphanumex", (cmd_function)ksr_is_alphanumex, 2, fixup_spve_spve, - 0, ANY_ROUTE}, - {"sip_p_charging_vector", (cmd_function)sip_handle_pcv, 1, - fixup_spve_null, fixup_free_spve_null, ANY_ROUTE}, - {"contact_param_encode", (cmd_function)w_contact_param_encode, 2, - fixup_spve_spve, fixup_free_spve_spve, - REQUEST_ROUTE | ONREPLY_ROUTE}, - {"contact_param_decode", (cmd_function)w_contact_param_decode, 1, - fixup_spve_null, fixup_free_spve_null, - REQUEST_ROUTE | ONREPLY_ROUTE}, - {"contact_param_decode_ruri", (cmd_function)w_contact_param_decode_ruri, - 1, fixup_spve_null, fixup_free_spve_null, REQUEST_ROUTE}, - {"contact_param_rm", (cmd_function)w_contact_param_rm, 1, - fixup_spve_null, fixup_free_spve_null, - REQUEST_ROUTE | ONREPLY_ROUTE}, - {"hdr_date_check", (cmd_function)w_hdr_date_check, 1, fixup_igp_null, - fixup_free_igp_null, ANY_ROUTE}, - - {"bind_siputils", (cmd_function)bind_siputils, 1, 0, 0, 0}, - - {0, 0, 0, 0, 0, 0}}; - -static param_export_t params[] = {{"options_accept", PARAM_STR, &opt_accept}, - {"options_accept_encoding", PARAM_STR, &opt_accept_enc}, - {"options_accept_language", PARAM_STR, &opt_accept_lang}, - {"options_support", PARAM_STR, &opt_supported}, - {"contact_flds_separator", PARAM_STRING, &contact_flds_separator}, - {"rpid_prefix", PARAM_STR, &rpid_prefix}, - {"rpid_suffix", PARAM_STR, &rpid_suffix}, - {"rpid_avp", PARAM_STRING, &rpid_avp_param}, - {"e164_max_len", PARAM_INT, &e164_max_len}, {0, 0, 0}}; + {"options_reply", (cmd_function)opt_reply, 0, 0, 0, REQUEST_ROUTE}, + {"is_user", (cmd_function)is_user, 1, fixup_spve_null, 0, + REQUEST_ROUTE | LOCAL_ROUTE}, + {"has_totag", (cmd_function)w_has_totag, 0, 0, 0, ANY_ROUTE}, + {"uri_param", (cmd_function)uri_param_1, 1, fixup_spve_null, 0, + REQUEST_ROUTE | BRANCH_ROUTE | FAILURE_ROUTE}, + {"uri_param", (cmd_function)uri_param_2, 2, fixup_spve_spve, 0, + REQUEST_ROUTE | BRANCH_ROUTE | FAILURE_ROUTE}, + {"uri_param_any", (cmd_function)w_uri_param_any, 1, fixup_spve_null, 0, + REQUEST_ROUTE | BRANCH_ROUTE | FAILURE_ROUTE}, + {"add_uri_param", (cmd_function)add_uri_param, 1, fixup_str_null, 0, + REQUEST_ROUTE}, + {"get_uri_param", (cmd_function)get_uri_param, 2, fixup_get_uri_param, + free_fixup_get_uri_param, REQUEST_ROUTE | LOCAL_ROUTE}, + {"uri_param_rm", (cmd_function)w_uri_param_rm, 1, fixup_spve_null, 0, + REQUEST_ROUTE | BRANCH_ROUTE | FAILURE_ROUTE}, + {"tel2sip", (cmd_function)tel2sip, 3, fixup_tel2sip, 0, + REQUEST_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE | ONREPLY_ROUTE}, + {"tel2sip2", (cmd_function)tel2sip2, 3, fixup_tel2sip, 0, + REQUEST_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE | ONREPLY_ROUTE}, + {"is_uri", (cmd_function)is_uri, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"is_e164", (cmd_function)w_is_e164, 1, fixup_pvar_null, + fixup_free_pvar_null, + REQUEST_ROUTE | FAILURE_ROUTE | LOCAL_ROUTE}, + {"is_uri_user_e164", (cmd_function)w_is_uri_user_e164, 1, + fixup_pvar_null, fixup_free_pvar_null, ANY_ROUTE}, + {"encode_contact", (cmd_function)encode_contact, 2, 0, 0, + REQUEST_ROUTE | ONREPLY_ROUTE}, + {"decode_contact", (cmd_function)decode_contact, 0, 0, 0, + REQUEST_ROUTE}, + {"decode_contact_header", (cmd_function)decode_contact_header, 0, 0, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, + {"cmp_uri", (cmd_function)w_cmp_uri, 2, fixup_spve_spve, 0, ANY_ROUTE}, + {"cmp_aor", (cmd_function)w_cmp_aor, 2, fixup_spve_spve, 0, ANY_ROUTE}, + {"cmp_hdr_name", (cmd_function)w_cmp_hdr_name, 2, fixup_spve_spve, 0, + ANY_ROUTE}, + {"is_rpid_user_e164", (cmd_function)is_rpid_user_e164, 0, 0, 0, + REQUEST_ROUTE}, + {"append_rpid_hf", (cmd_function)append_rpid_hf, 0, 0, 0, + REQUEST_ROUTE | BRANCH_ROUTE | FAILURE_ROUTE}, + {"append_rpid_hf", (cmd_function)append_rpid_hf_p, 2, fixup_str_str, 0, + REQUEST_ROUTE | BRANCH_ROUTE | FAILURE_ROUTE}, + {"set_uri_user", (cmd_function)set_uri_user, 2, fixup_set_uri, + fixup_free_set_uri, ANY_ROUTE}, + {"set_uri_host", (cmd_function)set_uri_host, 2, fixup_set_uri, + fixup_free_set_uri, ANY_ROUTE}, + {"is_request", (cmd_function)w_is_request, 0, 0, 0, ANY_ROUTE}, + {"is_reply", (cmd_function)w_is_reply, 0, 0, 0, ANY_ROUTE}, + {"is_gruu", (cmd_function)w_is_gruu, 0, 0, 0, ANY_ROUTE}, + {"is_gruu", (cmd_function)w_is_gruu, 1, fixup_spve_null, 0, ANY_ROUTE}, + {"is_supported", (cmd_function)w_is_supported, 1, fixup_option, 0, + ANY_ROUTE}, + {"is_first_hop", (cmd_function)w_is_first_hop, 0, 0, 0, ANY_ROUTE}, + {"is_first_hop", (cmd_function)w_is_first_hop, 1, fixup_igp_null, + fixup_free_igp_null, ANY_ROUTE}, + {"is_tel_number", (cmd_function)is_tel_number, 1, fixup_spve_null, 0, + ANY_ROUTE}, + {"is_numeric", (cmd_function)is_numeric, 1, fixup_spve_null, 0, + ANY_ROUTE}, + {"is_alphanum", (cmd_function)ksr_is_alphanum, 1, fixup_spve_null, 0, + ANY_ROUTE}, + {"is_alphanumex", (cmd_function)ksr_is_alphanumex, 2, fixup_spve_spve, + 0, ANY_ROUTE}, + {"sip_p_charging_vector", (cmd_function)sip_handle_pcv, 1, + fixup_spve_null, fixup_free_spve_null, ANY_ROUTE}, + {"contact_param_encode", (cmd_function)w_contact_param_encode, 2, + fixup_spve_spve, fixup_free_spve_spve, + REQUEST_ROUTE | ONREPLY_ROUTE}, + {"contact_param_decode", (cmd_function)w_contact_param_decode, 1, + fixup_spve_null, fixup_free_spve_null, + REQUEST_ROUTE | ONREPLY_ROUTE}, + {"contact_param_decode_ruri", (cmd_function)w_contact_param_decode_ruri, + 1, fixup_spve_null, fixup_free_spve_null, REQUEST_ROUTE}, + {"contact_param_rm", (cmd_function)w_contact_param_rm, 1, + fixup_spve_null, fixup_free_spve_null, + REQUEST_ROUTE | ONREPLY_ROUTE}, + {"contact_param_check", (cmd_function)w_contact_param_check, 1, + fixup_spve_null, fixup_free_spve_null, ANY_ROUTE}, + {"hdr_date_check", (cmd_function)w_hdr_date_check, 1, fixup_igp_null, + fixup_free_igp_null, ANY_ROUTE}, + + {"bind_siputils", (cmd_function)bind_siputils, 1, 0, 0, 0}, + + {0, 0, 0, 0, 0, 0} +}; + +static param_export_t params[] = { + {"options_accept", PARAM_STR, &opt_accept}, + {"options_accept_encoding", PARAM_STR, &opt_accept_enc}, + {"options_accept_language", PARAM_STR, &opt_accept_lang}, + {"options_support", PARAM_STR, &opt_supported}, + {"contact_flds_separator", PARAM_STRING, &contact_flds_separator}, + {"rpid_prefix", PARAM_STR, &rpid_prefix}, + {"rpid_suffix", PARAM_STR, &rpid_suffix}, + {"rpid_avp", PARAM_STRING, &rpid_avp_param}, + {"e164_max_len", PARAM_INT, &e164_max_len}, + {0, 0, 0} +}; static pv_export_t mod_pvs[] = { - {{"pcv", (sizeof("pcv") - 1)}, PVT_OTHER, pv_get_charging_vector, 0, - pv_parse_charging_vector_name, 0, 0, 0}, + {{"pcv", (sizeof("pcv") - 1)}, PVT_OTHER, pv_get_charging_vector, 0, + pv_parse_charging_vector_name, 0, 0, 0}, - {{0, 0}, 0, 0, 0, 0, 0, 0, 0}}; + {{0, 0}, 0, 0, 0, 0, 0, 0, 0} +}; struct module_exports exports = { - "siputils", /* module name */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* exported functions */ - params, /* param exports */ - 0, /* exported RPC functions */ - mod_pvs, /* exported pseudo-variables */ - 0, /* response function */ - mod_init, /* initialization function */ - 0, /* child init function */ - mod_destroy /* destroy function */ + "siputils", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* exported functions */ + params, /* param exports */ + 0, /* exported RPC functions */ + mod_pvs, /* exported pseudo-variables */ + 0, /* response function */ + mod_init, /* initialization function */ + 0, /* child init function */ + mod_destroy /* destroy function */ }; +/* clang-format on */ static int mod_init(void) @@ -503,6 +515,18 @@ static int w_contact_param_rm(sip_msg_t *msg, char *pnparam, char *p2) return ki_contact_param_rm(msg, &nparam); } +static int w_contact_param_check(sip_msg_t *msg, char *pnparam, char *p2) +{ + str nparam = STR_NULL; + + if(fixup_get_svalue(msg, (gparam_t *)pnparam, &nparam) < 0) { + LM_ERR("failed to get p1\n"); + return -1; + } + + return ki_contact_param_check(msg, &nparam); +} + /* * Check if pseudo variable contains a valid uri */ @@ -699,6 +723,11 @@ static sr_kemi_t sr_kemi_siputils_exports[] = { { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, + { str_init("siputils"), str_init("contact_param_check"), + SR_KEMIP_INT, ki_contact_param_check, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, { str_init("siputils"), str_init("hdr_date_check"), SR_KEMIP_INT, ki_hdr_date_check, { SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, diff --git a/src/modules/sl/README b/src/modules/sl/README index 615e7a531..6433a1d7e 100644 --- a/src/modules/sl/README +++ b/src/modules/sl/README @@ -32,6 +32,7 @@ Daniel-Constantin Mierla 3.3. send_reply_mode(code, reason, mode) 3.4. sl_reply_error() 3.5. sl_forward_reply([ code, [ reason ] ]) + 3.6. send_reply_error() 4. Statistics @@ -78,6 +79,7 @@ Daniel-Constantin Mierla 1.9. send_reply_mode usage 1.10. sl_reply_error usage 1.11. send_reply usage + 1.12. send_reply_error usage Chapter 1. Admin Guide @@ -100,6 +102,7 @@ Chapter 1. Admin Guide 3.3. send_reply_mode(code, reason, mode) 3.4. sl_reply_error() 3.5. sl_forward_reply([ code, [ reason ] ]) + 3.6. send_reply_error() 4. Statistics @@ -252,6 +255,7 @@ modparam("sl", "event_callback_lres_sent", "ksr_event_sl_local_response") 3.3. send_reply_mode(code, reason, mode) 3.4. sl_reply_error() 3.5. sl_forward_reply([ code, [ reason ] ]) + 3.6. send_reply_error() 3.1. sl_send_reply(code, reason) @@ -350,6 +354,20 @@ if(status=="408") sl_forward_reply("404", "Not found"); ... +3.6. send_reply_error() + + For the current request, the internal error code reply is sent back + stateful or stateless, depending of the TM module: if a transaction + exists for the current request, then the reply is sent statefully, + otherwise stateless. + + It can be used from REQUEST_ROUTE, ONREPLY_ROUTE and FAILURE_ROUTE. + + Example 1.12. send_reply_error usage +... +send_reply_error(); +... + 4. Statistics 4.1. 1xx_replies diff --git a/src/modules/sl/doc/sl_functions.xml b/src/modules/sl/doc/sl_functions.xml index 11ef47067..8f2715b7a 100644 --- a/src/modules/sl/doc/sl_functions.xml +++ b/src/modules/sl/doc/sl_functions.xml @@ -130,7 +130,7 @@ send_reply_mode("403", "Invalid user - $fU", "3"); Sends back an error reply describing the nature of the last - internal error. Usually this function should be used after a + internal error. Usually this function should be used after a script function that returned an error code. @@ -174,6 +174,29 @@ sl_reply_error(); if(status=="408") sl_forward_reply("404", "Not found"); ... + + + + +
+ + <function moreinfo="none">send_reply_error()</function> + + + For the current request, the internal error code reply is sent back + stateful or stateless, depending of the TM module: + if a transaction exists for the current request, then the reply is sent + statefully, otherwise stateless. + + + It can be used from REQUEST_ROUTE, ONREPLY_ROUTE and FAILURE_ROUTE. + + + <function>send_reply_error</function> usage + +... +send_reply_error(); +...
diff --git a/src/modules/sl/sl.c b/src/modules/sl/sl.c index 0ee22efcc..945538a82 100644 --- a/src/modules/sl/sl.c +++ b/src/modules/sl/sl.c @@ -73,6 +73,7 @@ static int w_sl_send_reply(struct sip_msg *msg, char *str1, char *str2); static int w_send_reply(struct sip_msg *msg, char *str1, char *str2); static int w_send_reply_mode( struct sip_msg *msg, char *str1, char *str2, char *str3); +static int w_send_reply_error(sip_msg_t *msg, char *str1, char *str2); static int w_sl_reply_error(struct sip_msg *msg, char *str1, char *str2); static int w_sl_forward_reply0(sip_msg_t *msg, char *str1, char *str2); static int w_sl_forward_reply1(sip_msg_t *msg, char *str1, char *str2); @@ -88,40 +89,48 @@ static int pv_get_ltt(sip_msg_t *msg, pv_param_t *param, pv_value_t *res); static int pv_parse_ltt_name(pv_spec_p sp, str *in); +/* clang-format off */ static pv_export_t mod_pvs[] = { - {{"ltt", (sizeof("ltt") - 1)}, PVT_OTHER, pv_get_ltt, 0, + {{"ltt", (sizeof("ltt") - 1)}, PVT_OTHER, pv_get_ltt, 0, pv_parse_ltt_name, 0, 0, 0}, - {{0, 0}, 0, 0, 0, 0, 0, 0, 0}}; + {{0, 0}, 0, 0, 0, 0, 0, 0, 0} +}; static cmd_export_t cmds[] = { - {"sl_send_reply", w_sl_send_reply, 2, fixup_sl_reply, 0, REQUEST_ROUTE}, - {"sl_reply", w_sl_send_reply, 2, fixup_sl_reply, 0, REQUEST_ROUTE}, - {"send_reply", w_send_reply, 2, fixup_sl_reply, 0, - REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE}, - {"send_reply_mode", (cmd_function)w_send_reply_mode, 3, - fixup_sl_reply_mode, 0, - REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE}, - {"sl_reply_error", w_sl_reply_error, 0, 0, 0, REQUEST_ROUTE}, - {"sl_forward_reply", w_sl_forward_reply0, 0, 0, 0, ONREPLY_ROUTE}, - {"sl_forward_reply", w_sl_forward_reply1, 1, fixup_spve_all, 0, - ONREPLY_ROUTE}, - {"sl_forward_reply", w_sl_forward_reply2, 2, fixup_spve_all, 0, - ONREPLY_ROUTE}, - {"bind_sl", (cmd_function)bind_sl, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}}; + {"sl_send_reply", w_sl_send_reply, 2, fixup_sl_reply, 0, REQUEST_ROUTE}, + {"sl_reply", w_sl_send_reply, 2, fixup_sl_reply, 0, REQUEST_ROUTE}, + {"send_reply", w_send_reply, 2, fixup_sl_reply, 0, + REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE}, + {"send_reply_mode", (cmd_function)w_send_reply_mode, 3, + fixup_sl_reply_mode, 0, + REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE}, + {"send_reply_error", w_send_reply_error, 0, 0, 0, + REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE}, + {"sl_reply_error", w_sl_reply_error, 0, 0, 0, REQUEST_ROUTE}, + {"sl_forward_reply", w_sl_forward_reply0, 0, 0, 0, ONREPLY_ROUTE}, + {"sl_forward_reply", w_sl_forward_reply1, 1, fixup_spve_all, 0, + ONREPLY_ROUTE}, + {"sl_forward_reply", w_sl_forward_reply2, 2, fixup_spve_all, 0, + ONREPLY_ROUTE}, + {"bind_sl", (cmd_function)bind_sl, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} +}; /* * Exported parameters */ -static param_export_t params[] = {{"default_code", PARAM_INT, &default_code}, - {"default_reason", PARAM_STR, &default_reason}, - {"bind_tm", PARAM_INT, &sl_bind_tm}, - {"rich_redirect", PARAM_INT, &sl_rich_redirect}, - {"event_callback_fl_ack", PARAM_STR, &_sl_event_callback_fl_ack}, - {"event_callback_lres_sent", PARAM_STR, &_sl_event_callback_lres_sent}, - - {0, 0, 0}}; +static param_export_t params[] = { + {"default_code", PARAM_INT, &default_code}, + {"default_reason", PARAM_STR, &default_reason}, + {"bind_tm", PARAM_INT, &sl_bind_tm}, + {"rich_redirect", PARAM_INT, &sl_rich_redirect}, + {"event_callback_fl_ack", PARAM_STR, &_sl_event_callback_fl_ack}, + {"event_callback_lres_sent", PARAM_STR, &_sl_event_callback_lres_sent}, + + {0, 0, 0} +}; #ifdef STATIC_SL @@ -129,17 +138,18 @@ struct module_exports sl_exports = { #else struct module_exports exports = { #endif - "sl", /* module name */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* cmd (cfg function) exports */ - params, /* param exports */ - sl_rpc, /* RPC method exports */ - mod_pvs, /* pv exports */ - 0, /* response handling function */ - mod_init, /* module init function */ - child_init, /* per-child init function */ - mod_destroy /* module destroy function */ + "sl", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* cmd (cfg function) exports */ + params, /* param exports */ + sl_rpc, /* RPC method exports */ + mod_pvs, /* pv exports */ + 0, /* response handling function */ + mod_init, /* module init function */ + child_init, /* per-child init function */ + mod_destroy /* module destroy function */ }; +/* clang-format on */ static int mod_init(void) @@ -326,6 +336,39 @@ static int w_send_reply(struct sip_msg *msg, char *p1, char *p2) return send_reply(msg, code, &reason); } +/** + * + */ +static int ki_send_reply_error(sip_msg_t *msg) +{ + int ret; + + if(msg->msg_flags & FL_FINAL_REPLY) { + LM_INFO("message marked with final-reply flag\n"); + return -2; + } + if(msg->msg_flags & FL_DELAYED_REPLY) { + LM_INFO("message marked with delayed-reply flag\n"); + return -3; + } + + if(sl_bind_tm != 0 && tmb.t_reply_error != NULL) { + ret = tmb.t_reply_error(msg); + if(ret > 0) { + return ret; + } + } + return sl_reply_error(msg); +} + +/** + * + */ +static int w_send_reply_error(sip_msg_t *msg, char *p1, char *p2) +{ + return ki_send_reply_error(msg); +} + /** * @brief send stateful reply if transaction was created * @@ -672,6 +715,11 @@ static sr_kemi_t sl_kemi_exports[] = { { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, + { str_init("sl"), str_init("send_reply_error"), + SR_KEMIP_INT, ki_send_reply_error, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, { str_init("sl"), str_init("sl_forward_reply"), SR_KEMIP_INT, w_sl_forward_reply, { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, diff --git a/src/modules/sl/sl_funcs.c b/src/modules/sl/sl_funcs.c index 253686a4a..5f9ac4099 100644 --- a/src/modules/sl/sl_funcs.c +++ b/src/modules/sl/sl_funcs.c @@ -337,6 +337,10 @@ int sl_reply_helper(struct sip_msg *msg, int code, char *reason, str *tag) goto error; } + if(code >= 200) { + msg->msg_flags |= FL_FINAL_REPLY; + } + update_sl_stats(code); return 1; @@ -408,6 +412,15 @@ int sl_reply_error(struct sip_msg *msg) return -2; } + if(msg->msg_flags & FL_FINAL_REPLY) { + LM_INFO("message marked with final-reply flag\n"); + return -2; + } + if(msg->msg_flags & FL_DELAYED_REPLY) { + LM_INFO("message marked with delayed-reply flag\n"); + return -3; + } + ret = err2reason_phrase( prev_ser_error, &sip_error, err_buf, sizeof(err_buf), "SL"); if(ret > 0) { diff --git a/src/modules/sms/libsms_getsms.c b/src/modules/sms/libsms_getsms.c index 94f50f917..418156049 100644 --- a/src/modules/sms/libsms_getsms.c +++ b/src/modules/sms/libsms_getsms.c @@ -26,6 +26,7 @@ mailto:s.frings@mail.isis.de #include "libsms_sms.h" #include "sms_funcs.h" +#define SMS_BUF_SIZE 512 #define set_date(_date, _Pointer) \ { \ @@ -131,7 +132,7 @@ static int pdu2binary(char *pdu, char *binary) static int fetchsms(struct modem *mdm, int sim, char *pdu) { char command[16]; - char answer[512]; + char answer[SMS_BUF_SIZE]; char *position; char *beginning; char *end; @@ -160,7 +161,7 @@ static int fetchsms(struct modem *mdm, int sim, char *pdu) } } else { LM_DBG("Trying to get stored message %i\n", sim); - clen = sprintf(command, "AT+CMGR=%i\r", sim); + clen = snprintf(command, 16, "AT+CMGR=%i\r", sim); put_command(mdm, command, clen, answer, sizeof(answer), 50, 0); /* search for beginning of the answer */ position = strstr(answer, "+CMGR:"); @@ -186,7 +187,15 @@ static int fetchsms(struct modem *mdm, int sim, char *pdu) return 0; /* Now we have the end of the PDU or ASCII string */ *end = 0; - strcpy(pdu, beginning); + clen = strlen(beginning); + if(clen < SMS_BUF_SIZE) { + memcpy(pdu, beginning, clen); + pdu[clen] = '\0'; + } else { + /* truncate */ + memcpy(pdu, beginning, SMS_BUF_SIZE - 1); + pdu[SMS_BUF_SIZE - 1] = '\0'; + } return sim; } @@ -200,7 +209,7 @@ static void deletesms(struct modem *mdm, int sim) int clen; LM_DBG("Deleting message %i !\n", sim); - clen = sprintf(command, "AT+CMGD=%i\r", sim); + clen = snprintf(command, 32, "AT+CMGD=%i\r", sim); put_command(mdm, command, clen, answer, sizeof(answer), 50, 0); } @@ -270,6 +279,7 @@ static int splitascii(struct modem *mdm, char *source, struct incame_sms *sms) char *end; char tbuf[TIME_LEN + 1]; char dbuf[DATE_LEN + 1]; + int l1 = 0; /* the text is after the \r */ for(start = source; *start && *start != '\r'; start++) @@ -277,7 +287,13 @@ static int splitascii(struct modem *mdm, char *source, struct incame_sms *sms) if(!*start) return 1; start++; - strcpy(sms->ascii, start); + l1 = strlen(start); + if(l1 >= SMS_ASCII_LEN) { + /* truncate */ + l1 = SMS_ASCII_LEN - 1; + } + memcpy(sms->ascii, start, l1); + sms->ascii[l1] = '\0'; /* get the senders MSISDN */ start = strstr(source, "\",\""); if(start == 0) { @@ -291,7 +307,14 @@ static int splitascii(struct modem *mdm, char *source, struct incame_sms *sms) return 1; } *end = 0; - strcpy(sms->sender, start); + l1 = strlen(start); + if(l1 >= SMS_SENDER_LEN) { + /* truncate */ + l1 = SMS_SENDER_LEN - 1; + } + memcpy(sms->sender, start, l1); + sms->sender[l1] = '\0'; + /* Siemens M20 inserts the senders name between MSISDN and date */ start = end + 3; // Workaround for Thomas Stoeckel // @@ -304,17 +327,23 @@ static int splitascii(struct modem *mdm, char *source, struct incame_sms *sms) return 1; } *end = 0; - strcpy(sms->name, start); + l1 = strlen(start); + if(l1 >= SMS_NAME_LEN) { + /* truncate */ + l1 = SMS_NAME_LEN - 1; + } + memcpy(sms->name, start, l1); + sms->name[l1] = '\0'; } /* Get the date */ start = end + 3; - sprintf(dbuf, "%c%c-%c%c-%c%c", start[3], start[4], start[0], start[1], - start[6], start[7]); + snprintf(dbuf, DATE_LEN + 1, "%c%c-%c%c-%c%c", start[3], start[4], start[0], + start[1], start[6], start[7]); memcpy(sms->date, dbuf, DATE_LEN); /* Get the time */ start += 9; - sprintf(tbuf, "%c%c:%c%c:%c%c", start[0], start[1], start[3], start[4], - start[7], start[7]); + snprintf(tbuf, TIME_LEN + 1, "%c%c:%c%c:%c%c", start[0], start[1], start[3], + start[4], start[7], start[7]); memcpy(sms->time, tbuf, TIME_LEN); sms->userdatalength = strlen(sms->ascii); return 1; @@ -480,7 +509,7 @@ static inline int decode_pdu( int getsms(struct incame_sms *sms, struct modem *mdm, int sim) { - char pdu[512]; + char pdu[SMS_BUF_SIZE]; int found; int ret; diff --git a/src/modules/sms/libsms_modem.c b/src/modules/sms/libsms_modem.c index 1740b2ab4..7540b99ab 100644 --- a/src/modules/sms/libsms_modem.c +++ b/src/modules/sms/libsms_modem.c @@ -225,7 +225,8 @@ int initmodem(struct modem *mdm, cds_report cds_report_f) put_command(mdm, "AT+CPIN?\r", 9, answer, sizeof(answer), 50, 0); if(strstr(answer, "+CPIN: SIM PIN")) { LM_INFO("Modem needs PIN, entering PIN...\n"); - clen = sprintf(command, "AT+CPIN=\"%s\"\r", mdm->pin); + clen = snprintf( + command, MAX_CHAR_BUF + 12, "AT+CPIN=\"%s\"\r", mdm->pin); put_command(mdm, command, clen, answer, sizeof(answer), 100, 0); put_command(mdm, "AT+CPIN?\r", 9, answer, sizeof(answer), 50, 0); if(!strstr(answer, "+CPIN: READY")) { @@ -377,7 +378,7 @@ int setsmsc(struct modem *mdm, char *smsc) int clen; if(smsc && smsc[0]) { - clen = sprintf(command, "AT+CSCA=\"+%s\"\r", smsc); + clen = snprintf(command, 100, "AT+CSCA=\"+%s\"\r", smsc); put_command(mdm, command, clen, answer, sizeof(answer), 50, 0); } return 0; diff --git a/src/modules/sms/libsms_putsms.c b/src/modules/sms/libsms_putsms.c index 1622a1bb0..a130d4acf 100644 --- a/src/modules/sms/libsms_putsms.c +++ b/src/modules/sms/libsms_putsms.c @@ -101,7 +101,8 @@ int binary2pdu(char *binary, int length, char *pdu) /* make the PDU string. The destination variable pdu has to be big enough. */ -int make_pdu(struct sms_msg *msg, struct modem *mdm, char *pdu) +int make_pdu(struct sms_msg *msg, struct modem *mdm, char *pdu, + unsigned int pdu_size) { int coding; int flags; @@ -127,11 +128,11 @@ int make_pdu(struct sms_msg *msg, struct modem *mdm, char *pdu) flags += 16; // Validity field /* concatenate the first part of the PDU string */ if(mdm->mode == MODE_OLD) - pdu_len += sprintf(pdu, "%02X00%02X91%s00%02X%02X", flags, msg->to.len, - tmp, coding, msg->text.len); - else - pdu_len += sprintf(pdu, "00%02X00%02X91%s00%02XA7%02X", flags, + pdu_len += snprintf(pdu, pdu_size, "%02X00%02X91%s00%02X%02X", flags, msg->to.len, tmp, coding, msg->text.len); + else + pdu_len += snprintf(pdu, pdu_size, "00%02X00%02X91%s00%02XA7%02X", + flags, msg->to.len, tmp, coding, msg->text.len); /* Create the PDU string of the message */ /* pdu_len += binary2pdu(msg->text.s,msg->text.len,pdu+pdu_len); */ pdu_len += @@ -180,20 +181,20 @@ int putsms(struct sms_msg *sms_messg, struct modem *mdm) int pdu_len; int sms_id; - pdu_len = make_pdu(sms_messg, mdm, pdu); + pdu_len = make_pdu(sms_messg, mdm, pdu, 500); if(mdm->mode == MODE_OLD) - clen = sprintf(command, "AT+CMGS=%i\r", pdu_len / 2); + clen = snprintf(command, 500, "AT+CMGS=%i\r", pdu_len / 2); else if(mdm->mode == MODE_ASCII) - clen = sprintf(command, "AT+CMGS=\"+%.*s\"\r", sms_messg->to.len, + clen = snprintf(command, 500, "AT+CMGS=\"+%.*s\"\r", sms_messg->to.len, sms_messg->to.s); else - clen = sprintf(command, "AT+CMGS=%i\r", pdu_len / 2 - 1); + clen = snprintf(command, 500, "AT+CMGS=%i\r", pdu_len / 2 - 1); if(mdm->mode == MODE_ASCII) - clen2 = sprintf( - command2, "%.*s\x1A", sms_messg->text.len, sms_messg->text.s); + clen2 = snprintf(command2, 500, "%.*s\x1A", sms_messg->text.len, + sms_messg->text.s); else - clen2 = sprintf(command2, "%.*s\x1A", pdu_len, pdu); + clen2 = snprintf(command2, 500, "%.*s\x1A", pdu_len, pdu); sms_id = 0; for(err_code = 0, retries = 0; err_code < 2 && retries < mdm->retry; diff --git a/src/modules/sms/sms.c b/src/modules/sms/sms.c index 3c7522a31..10d8602a8 100644 --- a/src/modules/sms/sms.c +++ b/src/modules/sms/sms.c @@ -59,7 +59,7 @@ char *default_net_str = 0; /*global variables*/ int default_net = 0; int max_sms_parts = MAX_SMS_PARTS; -str domain = {0, 0}; +str _sms_domain = {0, 0}; int *queued_msgs = 0; int use_contact = 0; int sms_report_type = NO_REPORT; @@ -77,7 +77,7 @@ static param_export_t params[] = {{"networks", PARAM_STRING, &networks_config}, {"links", PARAM_STRING, &links_config}, {"default_net", PARAM_STRING, &default_net_str}, {"max_sms_parts", INT_PARAM, &max_sms_parts}, - {"domain", PARAM_STR, &domain}, + {"domain", PARAM_STR, &_sms_domain}, {"use_contact", INT_PARAM, &use_contact}, {"sms_report_type", INT_PARAM, &sms_report_type}, {0, 0, 0}}; @@ -515,11 +515,11 @@ int global_init(void) goto error; } /* let the auto-loading function load all TM stuff */ - if(load_tm(&tmb) == -1) + if(load_tm(&_sms_tmb) == -1) goto error; - /*fix domain*/ - if(!domain.s) { + /*discover domain*/ + if(!_sms_domain.s) { si = get_first_socket(); if(si == 0) { LM_CRIT("null listen socket list\n"); @@ -527,13 +527,13 @@ int global_init(void) } /*do I have to add port?*/ i = (si->port_no_str.len && si->port_no != 5060); - domain.len = si->name.len + i * (si->port_no_str.len + 1); - domain.s = (char *)pkg_malloc(domain.len); - if(!domain.s) { + _sms_domain.len = si->name.len + i * (si->port_no_str.len + 1); + _sms_domain.s = (char *)pkg_malloc(_sms_domain.len); + if(!_sms_domain.s) { PKG_MEM_ERROR; goto error; } - p = domain.s; + p = _sms_domain.s; memcpy(p, si->name.s, si->name.len); p += si->name.len; if(i) { diff --git a/src/modules/sms/sms_funcs.c b/src/modules/sms/sms_funcs.c index 7c45d8c59..89b756efa 100644 --- a/src/modules/sms/sms_funcs.c +++ b/src/modules/sms/sms_funcs.c @@ -45,7 +45,7 @@ struct network networks[MAX_NETWORKS]; int net_pipes_in[MAX_NETWORKS]; int nr_of_networks; int nr_of_modems; -struct tm_binds tmb; +struct tm_binds _sms_tmb; #define ERR_NUMBER_TEXT \ @@ -101,7 +101,7 @@ inline int add_contact(struct sip_msg* msg , str* user) int len; len = 9 /*"Contact: "*/ + user->len/*user*/ + 1 /*"@"*/ - + domain.len/*host*/ + 6/*""*/ + CRLF_LEN; + + _sms_domain.len/*host*/ + 6/*""*/ + CRLF_LEN; buf = pkg_malloc( len ); if(!buf) { @@ -114,7 +114,7 @@ inline int add_contact(struct sip_msg* msg , str* user) append_str( p, "s, user->len); *(p++) = '@'; - append_str( p, domain.s, domain.len); + append_str( p, _sms_domain.s, _sms_domain.len); *(p++) = '>'; append_str( p, CRLF, CRLF_LEN); @@ -288,7 +288,7 @@ int send_sip_msg_request(str *to, str *from_user, str *body) /* From header */ from.len = 6 /*"len /*user*/ + 1 /*"@"*/ - + domain.len /*host*/ + 1 /*">"*/; + + _sms_domain.len /*host*/ + 1 /*">"*/; from.s = (char *)pkg_malloc(from.len); if(!from.s) goto error; @@ -296,15 +296,16 @@ int send_sip_msg_request(str *to, str *from_user, str *body) append_str(p, "s, from_user->len); *(p++) = '@'; - append_str(p, domain.s, domain.len); + append_str(p, _sms_domain.s, _sms_domain.len); *(p++) = '>'; /* hdrs = Contact header + Content-type */ /* length */ hdrs.len = CONTENT_TYPE_HDR_LEN + CRLF_LEN; if(use_contact) - hdrs.len += 15 /*"Contact: len /*user*/ - + 1 /*"@"*/ + domain.len /*host*/ + 1 /*">"*/ + CRLF_LEN; + hdrs.len += + 15 /*"Contact: len /*user*/ + + 1 /*"@"*/ + _sms_domain.len /*host*/ + 1 /*">"*/ + CRLF_LEN; hdrs.s = (char *)pkg_malloc(hdrs.len); if(!hdrs.s) goto error; @@ -315,7 +316,7 @@ int send_sip_msg_request(str *to, str *from_user, str *body) append_str(p, "Contact: s, from_user->len); *(p++) = '@'; - append_str(p, domain.s, domain.len); + append_str(p, _sms_domain.s, _sms_domain.len); append_str(p, ">" CRLF, 1 + CRLF_LEN); } @@ -329,10 +330,10 @@ int send_sip_msg_request(str *to, str *from_user, str *body) 0 /* Callback parameter */ ); - foo = tmb.t_request(&uac_r, 0, /* Request-URI */ - to, /* To */ - &from, /* From */ - 0 /* next hop */ + foo = _sms_tmb.t_request(&uac_r, 0, /* Request-URI */ + to, /* To */ + &from, /* From */ + 0 /* next hop */ ); if(from.s) @@ -487,7 +488,7 @@ int send_as_sms(struct sms_msg *sms_messg, struct modem *mdm) goto error; if(sms_report_type != NO_REPORT) add_sms_into_report_queue(ret_code, sms_messg, - p - use_nice * (nr_chunks > 1) * SMS_EDGE_PART_LEN, + p - SMS_EDGE_PART_LEN * use_nice * (nr_chunks > 1), len_array[i]); } diff --git a/src/modules/sms/sms_funcs.h b/src/modules/sms/sms_funcs.h index e49427c91..559c3ea4c 100644 --- a/src/modules/sms/sms_funcs.h +++ b/src/modules/sms/sms_funcs.h @@ -91,14 +91,19 @@ struct sms_msg int ref; }; +#define SMS_NAME_LEN 64 +#define SMS_SENDER_LEN 32 +#define SMS_ASCII_LEN 500 +#define SMS_SMSC_LEN 32 + struct incame_sms { - char sender[31]; - char name[64]; + char sender[SMS_SENDER_LEN]; + char name[SMS_NAME_LEN]; char date[DATE_LEN]; char time[TIME_LEN]; - char ascii[500]; - char smsc[31]; + char ascii[SMS_ASCII_LEN]; + char smsc[SMS_SMSC_LEN]; int userdatalength; int is_statusreport; int sms_id; @@ -111,11 +116,11 @@ extern int net_pipes_in[MAX_NETWORKS]; extern int nr_of_networks; extern int nr_of_modems; extern int max_sms_parts; -extern str domain; +extern str _sms_domain; extern int *queued_msgs; extern int use_contact; extern int sms_report_type; -extern struct tm_binds tmb; +extern struct tm_binds _sms_tmb; void modem_process(struct modem *); int push_on_network(struct sip_msg *, int); diff --git a/src/modules/smsops/README b/src/modules/smsops/README index 65e410de6..0dc5edbd6 100644 --- a/src/modules/smsops/README +++ b/src/modules/smsops/README @@ -33,6 +33,8 @@ Carsten Bock 4.1. isRPDATA() 4.2. smsdump() + 5. Variables + List of Examples 1.1. isRPDATA() usage @@ -57,6 +59,8 @@ Chapter 1. Admin Guide 4.1. isRPDATA() 4.2. smsdump() + 5. Variables + 1. Overview This module collects the Transformations for 3GPP-SMS. @@ -115,3 +119,12 @@ if (isRPDATA()) ... smsdump(); ... + +5. Variables + + Several variables are exported by the module to access the attributes + of the SMS. + * $smsack + $smsbody + $rpdata(key) + $tpdu(key) diff --git a/src/modules/smsops/doc/smsops_admin.xml b/src/modules/smsops/doc/smsops_admin.xml index fa19ebfc7..da95e37c0 100644 --- a/src/modules/smsops/doc/smsops_admin.xml +++ b/src/modules/smsops/doc/smsops_admin.xml @@ -95,5 +95,19 @@ smsdump(); +
+ Variables + Several variables are exported by the module to access the + attributes of the SMS. + + + $smsack + $smsbody + $rpdata(key) + $tpdu(key) + + +
+ diff --git a/src/modules/smsops/smsops.c b/src/modules/smsops/smsops.c index 3e2cb88bc..d8354af23 100644 --- a/src/modules/smsops/smsops.c +++ b/src/modules/smsops/smsops.c @@ -30,31 +30,36 @@ MODULE_VERSION -static pv_export_t mod_pvs[] = {{{"smsack", sizeof("smsack") - 1}, PVT_OTHER, - pv_sms_ack, 0, 0, 0, 0, 0}, - {{"rpdata", sizeof("rpdata") - 1}, PVT_OTHER, pv_get_sms, pv_set_sms, - pv_parse_rpdata_name, 0, 0, 0}, - {{"tpdu", sizeof("tpdu") - 1}, PVT_OTHER, pv_get_sms, pv_set_sms, +/* clang-format off */ +static pv_export_t mod_pvs[] = { + {{"smsack", sizeof("smsack") - 1}, PVT_OTHER, pv_sms_ack, 0, 0, 0, 0, 0}, + {{"rpdata", sizeof("rpdata") - 1}, PVT_OTHER, pv_get_sms, pv_set_sms, + pv_parse_rpdata_name, 0, 0, 0}, + {{"tpdu", sizeof("tpdu") - 1}, PVT_OTHER, pv_get_sms, pv_set_sms, pv_parse_tpdu_name, 0, 0, 0}, - {{"smsbody", sizeof("smsbody") - 1}, PVT_OTHER, pv_sms_body, 0, 0, 0, 0, - 0}, - {{0, 0}, 0, 0, 0, 0, 0, 0, 0}}; + {{"smsbody", sizeof("smsbody") - 1}, PVT_OTHER, pv_sms_body, 0, 0, 0, 0, 0}, + + {{0, 0}, 0, 0, 0, 0, 0, 0, 0} +}; static cmd_export_t cmds[] = { - {"smsdump", (cmd_function)smsdump, 0, 0, 0, REQUEST_ROUTE}, - {"isRPDATA", (cmd_function)isRPDATA, 0, 0, 0, REQUEST_ROUTE}, - {0, 0, 0, 0, 0, 0}}; + {"smsdump", (cmd_function)smsdump, 0, 0, 0, REQUEST_ROUTE}, + {"isRPDATA", (cmd_function)isRPDATA, 0, 0, 0, REQUEST_ROUTE}, + + {0, 0, 0, 0, 0, 0} +}; /** module exports */ struct module_exports exports = { - "smsops", /* module name */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* exported functions */ - 0, /* exported parameters */ - 0, /* exported rpc functions */ - mod_pvs, /* exported pseudo-variables */ - 0, /* response handling function*/ - 0, /* module init function */ - 0, /* per-child init function */ - 0 /* module destroy function */ + "smsops", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* exported functions */ + 0, /* exported parameters */ + 0, /* exported rpc functions */ + mod_pvs, /* exported pseudo-variables */ + 0, /* response handling function*/ + 0, /* module init function */ + 0, /* per-child init function */ + 0 /* module destroy function */ }; +/* clang-format on */ diff --git a/src/modules/smsops/smsops_impl.c b/src/modules/smsops/smsops_impl.c index e015f5358..052a2568b 100644 --- a/src/modules/smsops/smsops_impl.c +++ b/src/modules/smsops/smsops_impl.c @@ -157,9 +157,9 @@ typedef struct _sms_rp_data } sms_rp_data_t; // Pointer to current parsed rp_data/tpdu -static sms_rp_data_t *rp_data = NULL; +static sms_rp_data_t *_smsops_rp_data = NULL; // Pointer to rp_data/tpdu used for sending -static sms_rp_data_t *rp_send_data = NULL; +static sms_rp_data_t *_smsops_rp_send_data = NULL; // ID of current message static unsigned int current_msg_id = 0; @@ -435,7 +435,7 @@ int gsm_to_ascii(char *buffer, int buffer_length, str sms, const int fill_bits) unsigned char cmask = ((1 << carry_on_bits) - 1) << (8 - carry_on_bits); //mask for the leftmost carry_on_bits. - //E.g. carry_on_bits=3 -> X X X _ _ _ _ _ + //E.g. carry_on_bits=3 -> X X X _ _ _ _ _ symbol = ((buffer[i] << carry_on_bits) | //shift left to make space for the carried bits @@ -505,60 +505,143 @@ int gsm_to_ascii(char *buffer, int buffer_length, str sms, const int fill_bits) } // Decode UCS2 message by splitting the buffer into utf8 characters -int ucs2_to_utf8(int ucs2, char *utf8) +int ucs2_to_utf8(char *ucs2, int ucs2_len, char *utf8) { - if(ucs2 < 0x80) { - utf8[0] = ucs2; - utf8[1] = 0; - return 1; - } - if(ucs2 >= 0x80 && ucs2 < 0x800) { - utf8[0] = (ucs2 >> 6) | 0xC0; - utf8[1] = (ucs2 & 0x3F) | 0x80; - return 2; - } - if(ucs2 >= 0x800 && ucs2 < 0xFFFF) { - if(ucs2 >= 0xD800 && ucs2 <= 0xDFFF) - return -1; - utf8[0] = ((ucs2 >> 12)) | 0xE0; - utf8[1] = ((ucs2 >> 6) & 0x3F) | 0x80; - utf8[2] = ((ucs2)&0x3F) | 0x80; - return 3; - } - if(ucs2 >= 0x10000 && ucs2 < 0x10FFFF) { - utf8[0] = 0xF0 | (ucs2 >> 18); - utf8[1] = 0x80 | ((ucs2 >> 12) & 0x3F); - utf8[2] = 0x80 | ((ucs2 >> 6) & 0x3F); - utf8[3] = 0x80 | ((ucs2 & 0x3F)); - return 4; + size_t utf8_index = 0; + uint16_t high_surrogate, low_surrogate; + uint32_t codepoint; + uint16_t ucs2_char; + size_t ucs2_index; + + for(ucs2_index = 0; ucs2_index < ucs2_len; ucs2_index += 2) { + ucs2_char = (unsigned char)ucs2[ucs2_index]; + ucs2_char = (ucs2_char << 8) | (unsigned char)ucs2[ucs2_index + 1]; + if(ucs2_char <= 0x7F) { + // Single-byte UTF-8 character + utf8[utf8_index++] = ucs2_char; + } else if(ucs2_char <= 0x7FF) { + // Two-byte UTF-8 character + utf8[utf8_index++] = 0xC0 | (ucs2_char >> 6); + utf8[utf8_index++] = 0x80 | (ucs2_char & 0x3F); + } else if(ucs2_char >= 0xD800 && ucs2_char <= 0xDBFF + && ucs2_index < ucs2_len - 2) { + // High surrogate of a surrogate pair + high_surrogate = ucs2_char; + low_surrogate = (unsigned char)ucs2[ucs2_index + 2]; + low_surrogate = + (low_surrogate << 8) | (unsigned char)ucs2[ucs2_index + 3]; + + if(low_surrogate >= 0xDC00 && low_surrogate <= 0xDFFF) { + // Valid low surrogate + codepoint = 0x10000 + ((high_surrogate & 0x3FF) << 10) + + (low_surrogate & 0x3FF); + + // Four-byte UTF-8 character + utf8[utf8_index++] = 0xF0 | (codepoint >> 18); + utf8[utf8_index++] = 0x80 | ((codepoint >> 12) & 0x3F); + utf8[utf8_index++] = 0x80 | ((codepoint >> 6) & 0x3F); + utf8[utf8_index++] = 0x80 | (codepoint & 0x3F); + + ucs2_index += 2; // Skip the low surrogate + } + } else if(ucs2_char >= 0xDC00 && ucs2_char <= 0xDFFF && ucs2_index > 0 + && ucs2_index < ucs2_len - 1) { + // Low surrogate of a surrogate pair + low_surrogate = ucs2_char; + high_surrogate = (unsigned char)ucs2[ucs2_index - 2]; + high_surrogate = + (high_surrogate << 8) | (unsigned char)ucs2[ucs2_index - 1]; + + if(high_surrogate >= 0xD800 && high_surrogate <= 0xDBFF) { + // Valid high surrogate + codepoint = 0x10000 + ((high_surrogate & 0x3FF) << 10) + + (low_surrogate & 0x3FF); + + // Four-byte UTF-8 character + utf8[utf8_index++] = 0xF0 | (codepoint >> 18); + utf8[utf8_index++] = 0x80 | ((codepoint >> 12) & 0x3F); + utf8[utf8_index++] = 0x80 | ((codepoint >> 6) & 0x3F); + utf8[utf8_index++] = 0x80 | (codepoint & 0x3F); + + ucs2_index += 2; // Skip the high surrogate + } + } else { + // Three-byte UTF-8 character for BMP characters + utf8[utf8_index++] = 0xE0 | (ucs2_char >> 12); + utf8[utf8_index++] = 0x80 | ((ucs2_char >> 6) & 0x3F); + utf8[utf8_index++] = 0x80 | (ucs2_char & 0x3F); + } } - return -1; + return utf8_index; } // Decode UTF8 to UCS2 -int utf8_to_ucs2(const unsigned char *input, const unsigned char **end_ptr) +int utf8_to_ucs2(char *utf8, int utf8_len, char *ucs2, int buffer_len) { - *end_ptr = input; - if(input[0] == 0) + // Allocate for worst case scenario + unsigned char *tmp_buff = (unsigned char *)pkg_malloc(utf8_len * 4); + size_t ucs2_index = 0, utf8_index = 0; + uint16_t codepoint, high_surrogate, low_surrogate; + unsigned char utf8_char; + + if(tmp_buff == NULL) { + LM_ERR("Error allocating memory to encode sms text\n"); return -1; - if(input[0] < 0x80) { - *end_ptr = input + 1; - return input[0]; } - if((input[0] & 0xE0) == 0xE0) { - if(input[1] == 0 || input[2] == 0) + memset(tmp_buff, 0, utf8_len * 4); + + while(utf8_index < utf8_len) { + utf8_char = (unsigned char)utf8[utf8_index++]; + + if((utf8_char & 0x80) == 0) { + // Single-byte UTF-8 character + tmp_buff[ucs2_index++] = 0x00; + tmp_buff[ucs2_index++] = utf8_char; + } else if((utf8_char & 0xE0) == 0xC0) { + // Two-byte UTF-8 character + codepoint = ((utf8_char & 0x1F) << 6) + | ((unsigned char)utf8[utf8_index++] & 0x3F); + tmp_buff[ucs2_index++] = (uint8_t)(codepoint >> 8); + tmp_buff[ucs2_index++] = (uint8_t)(codepoint & 0xFF); + } else if((utf8_char & 0xF0) == 0xE0) { + // Three-byte UTF-8 character + codepoint = ((utf8_char & 0x0F) << 12) + | (((unsigned char)utf8[utf8_index] & 0x3F) << 6) + | ((unsigned char)utf8[utf8_index + 1] & 0x3F); + utf8_index += 2; + tmp_buff[ucs2_index++] = (uint8_t)(codepoint >> 8); + tmp_buff[ucs2_index++] = (uint8_t)(codepoint & 0xFF); + } else if((utf8_char & 0xF8) == 0xF0) { + // Four-byte UTF-8 character + codepoint = ((utf8_char & 0x07) << 18) + | (((unsigned char)utf8[utf8_index] & 0x3F) << 12) + | (((unsigned char)utf8[utf8_index + 1] & 0x3F) << 6) + | ((unsigned char)utf8[utf8_index + 2] & 0x3F); + utf8_index += 3; + // Convert to UCS-2 surrogate pair + codepoint -= 0x10000; + high_surrogate = 0xD800 | (codepoint >> 10); + low_surrogate = 0xDC00 | (codepoint & 0x3FF); + tmp_buff[ucs2_index++] = (uint8_t)(high_surrogate >> 8); + tmp_buff[ucs2_index++] = (uint8_t)(high_surrogate & 0xFF); + tmp_buff[ucs2_index++] = (uint8_t)(low_surrogate >> 8); + tmp_buff[ucs2_index++] = (uint8_t)(low_surrogate & 0xFF); + } else { + // Unsupported UTF-8 format + LM_ERR("Unsupported UTF-8 format\n"); + pkg_free(tmp_buff); return -1; - *end_ptr = input + 3; - return (input[0] & 0x0F) << 12 | (input[1] & 0x3F) << 6 - | (input[2] & 0x3F); + } } - if((input[0] & 0xC0) == 0xC0) { - if(input[1] == 0) - return -1; - *end_ptr = input + 2; - return (input[0] & 0x1F) << 6 | (input[1] & 0x3F); + // Check for space in SMS buffer + if(ucs2_index > buffer_len) { + LM_ERR("Encoded SMS size exceed allocated buffer size\n"); + pkg_free(tmp_buff); + return -1; } - return -1; + memcpy(ucs2, tmp_buff, ucs2_index); + pkg_free(tmp_buff); + return ucs2_index; } // Encode a digit based phone number for SMS based format. @@ -723,113 +806,118 @@ int decode_3gpp_sms(struct sip_msg *msg) } // Get structure for RP-DATA: - if(!rp_data) { - rp_data = (sms_rp_data_t *)pkg_malloc(sizeof(struct _sms_rp_data)); - if(!rp_data) { - LM_ERR("Error allocating %lu bytes!\n", - (unsigned long)sizeof(struct _sms_rp_data)); - return -1; - } - } else { - freeRP_DATA(rp_data); + if(_smsops_rp_data) { + freeRP_DATA(_smsops_rp_data); + } + _smsops_rp_data = + (sms_rp_data_t *)pkg_malloc(sizeof(struct _sms_rp_data)); + if(!_smsops_rp_data) { + LM_ERR("Error allocating %lu bytes!\n", + (unsigned long)sizeof(struct _sms_rp_data)); + return -1; } // Initialize structure: - memset(rp_data, 0, sizeof(struct _sms_rp_data)); + memset(_smsops_rp_data, 0, sizeof(struct _sms_rp_data)); //////////////////////////////////////////////// // RP-Data //////////////////////////////////////////////// - rp_data->msg_type = (unsigned char)body.s[p++]; - rp_data->reference = (unsigned char)body.s[p++]; - if((rp_data->msg_type == RP_DATA_MS_TO_NETWORK) - || (rp_data->msg_type == RP_DATA_NETWORK_TO_MS)) { + _smsops_rp_data->msg_type = (unsigned char)body.s[p++]; + _smsops_rp_data->reference = (unsigned char)body.s[p++]; + if((_smsops_rp_data->msg_type == RP_DATA_MS_TO_NETWORK) + || (_smsops_rp_data->msg_type == RP_DATA_NETWORK_TO_MS)) { len = body.s[p++]; if(len > 0) { p++; // Type of Number, we assume E164, thus ignored len--; // Deduct the type of number from the len - rp_data->originator.s = pkg_malloc(len * 2); - rp_data->originator.len = DecodePhoneNumber( - &body.s[p], len * 2, rp_data->originator); + _smsops_rp_data->originator.s = pkg_malloc(len * 2); + _smsops_rp_data->originator.len = DecodePhoneNumber( + &body.s[p], len * 2, _smsops_rp_data->originator); p += len; } len = body.s[p++]; if(len > 0) { p++; // Type of Number, we assume E164, thus ignored len--; // Deduct the type of number from the len - rp_data->destination.s = pkg_malloc(len * 2); - rp_data->destination.len = DecodePhoneNumber( - &body.s[p], len * 2, rp_data->destination); + _smsops_rp_data->destination.s = pkg_malloc(len * 2); + _smsops_rp_data->destination.len = DecodePhoneNumber( + &body.s[p], len * 2, _smsops_rp_data->destination); p += len; } //////////////////////////////////////////////// // TPDU //////////////////////////////////////////////// - rp_data->pdu_len = body.s[p++]; - if(rp_data->pdu_len > 0) { - rp_data->pdu.flags = (unsigned char)body.s[p++]; - rp_data->pdu.msg_type = - (unsigned char)rp_data->pdu.flags & 0x03; - - if(rp_data->pdu.msg_type == SUBMIT - || rp_data->pdu.msg_type == COMMAND) { - rp_data->pdu.reference = (unsigned char)body.s[p++]; + _smsops_rp_data->pdu_len = body.s[p++]; + if(_smsops_rp_data->pdu_len > 0) { + _smsops_rp_data->pdu.flags = (unsigned char)body.s[p++]; + _smsops_rp_data->pdu.msg_type = + (unsigned char)_smsops_rp_data->pdu.flags & 0x03; + + if(_smsops_rp_data->pdu.msg_type == SUBMIT + || _smsops_rp_data->pdu.msg_type == COMMAND) { + _smsops_rp_data->pdu.reference = (unsigned char)body.s[p++]; } - if(rp_data->pdu.msg_type == SUBMIT) { + if(_smsops_rp_data->pdu.msg_type == SUBMIT) { // TP-DA - rp_data->pdu.destination.len = body.s[p++]; - if(rp_data->pdu.destination.len > 0) { - rp_data->pdu.destination_flags = + _smsops_rp_data->pdu.destination.len = body.s[p++]; + if(_smsops_rp_data->pdu.destination.len > 0) { + _smsops_rp_data->pdu.destination_flags = (unsigned char)body.s[p++]; - rp_data->pdu.destination.s = - pkg_malloc(rp_data->pdu.destination.len); + _smsops_rp_data->pdu.destination.s = pkg_malloc( + _smsops_rp_data->pdu.destination.len); DecodePhoneNumber(&body.s[p], - rp_data->pdu.destination.len, - rp_data->pdu.destination); - if(rp_data->pdu.destination.len % 2 == 0) { - p += rp_data->pdu.destination.len / 2; + _smsops_rp_data->pdu.destination.len, + _smsops_rp_data->pdu.destination); + if(_smsops_rp_data->pdu.destination.len % 2 == 0) { + p += _smsops_rp_data->pdu.destination.len / 2; } else { - p += (rp_data->pdu.destination.len / 2) + 1; + p += (_smsops_rp_data->pdu.destination.len / 2) + 1; } } - } else if(rp_data->pdu.msg_type == DELIVER) { + } else if(_smsops_rp_data->pdu.msg_type == DELIVER) { // TP-OA - rp_data->pdu.originating_address.len = body.s[p++]; - if(rp_data->pdu.originating_address.len > 0) { - rp_data->pdu.originating_address_flags = + _smsops_rp_data->pdu.originating_address.len = body.s[p++]; + if(_smsops_rp_data->pdu.originating_address.len > 0) { + _smsops_rp_data->pdu.originating_address_flags = (unsigned char)body.s[p++]; - rp_data->pdu.originating_address.s = pkg_malloc( - rp_data->pdu.originating_address.len); + _smsops_rp_data->pdu.originating_address.s = pkg_malloc( + _smsops_rp_data->pdu.originating_address.len); DecodePhoneNumber(&body.s[p], - rp_data->pdu.originating_address.len, - rp_data->pdu.originating_address); - if(rp_data->pdu.originating_address.len % 2 == 0) { - p += rp_data->pdu.originating_address.len / 2; + _smsops_rp_data->pdu.originating_address.len, + _smsops_rp_data->pdu.originating_address); + if(_smsops_rp_data->pdu.originating_address.len % 2 + == 0) { + p += _smsops_rp_data->pdu.originating_address.len + / 2; } else { - p += (rp_data->pdu.originating_address.len / 2) + 1; + p += (_smsops_rp_data->pdu.originating_address.len + / 2) + + 1; } } } - rp_data->pdu.pid = (unsigned char)body.s[p++]; + _smsops_rp_data->pdu.pid = (unsigned char)body.s[p++]; - if(rp_data->pdu.msg_type == SUBMIT - || rp_data->pdu.msg_type == DELIVER) { - rp_data->pdu.coding = (unsigned char)body.s[p++]; + if(_smsops_rp_data->pdu.msg_type == SUBMIT + || _smsops_rp_data->pdu.msg_type == DELIVER) { + _smsops_rp_data->pdu.coding = (unsigned char)body.s[p++]; } // 3GPP TS 03.40 9.2.2.2 SMS SUBMIT type // https://en.wikipedia.org/wiki/GSM_03.40 - if(rp_data->pdu.msg_type == SUBMIT) { + if(_smsops_rp_data->pdu.msg_type == SUBMIT) { // 3GPP TS 03.40 9.2.3.3 TP Validity Period Format (TP VPF) - switch(rp_data->pdu.flags & BITMASK_TP_VPF) { + switch(_smsops_rp_data->pdu.flags & BITMASK_TP_VPF) { case BITMASK_TP_VPF_RELATIVE: // 3GPP TS 03.40 9.2.3.12.1 TP-VP (Relative format) - rp_data->pdu.validity = (unsigned char)body.s[p++]; + _smsops_rp_data->pdu.validity = + (unsigned char)body.s[p++]; break; case BITMASK_TP_VPF_ABSOLUTE: // 3GPP TS 03.40 9.2.3.12.2 TP-VP (Absolute format) - DecodeTime(&body.s[p], &rp_data->pdu.time); + DecodeTime(&body.s[p], &_smsops_rp_data->pdu.time); p += 7; break; case BITMASK_TP_VPF_ENHANCED: // 3GPP TS 03.40 9.2.3.12.3 TP-VP (Enhanced format) @@ -840,24 +928,24 @@ int decode_3gpp_sms(struct sip_msg *msg) default: break; } - } else if(rp_data->pdu.msg_type == DELIVER) { + } else if(_smsops_rp_data->pdu.msg_type == DELIVER) { // TP-SCTS - DecodeTime(&body.s[p], &rp_data->pdu.time); + DecodeTime(&body.s[p], &_smsops_rp_data->pdu.time); p += 7; } - if(rp_data->pdu.msg_type == SUBMIT - || rp_data->pdu.msg_type == DELIVER) { + if(_smsops_rp_data->pdu.msg_type == SUBMIT + || _smsops_rp_data->pdu.msg_type == DELIVER) { //TP-User-Data-Length and TP-User-Data len = (unsigned char)body.s[p++]; int fill_bits = 0; if(len > 0) { - if((unsigned char)rp_data->pdu.flags + if((unsigned char)_smsops_rp_data->pdu.flags & BITMASK_TP_UDHI) { //TP-UDHI int udh_len = (unsigned char)body.s[p++]; int udh_read = 0; - if(rp_data->pdu.coding == 0) { + if(_smsops_rp_data->pdu.coding == 0) { //calcucate padding size for 7bit coding //udh_len + 1, because the length field itself should be included fill_bits = (7 - (udh_len + 1) % 7) @@ -929,7 +1017,7 @@ int decode_3gpp_sms(struct sip_msg *msg) } if(prev_ie == NULL) { - rp_data->pdu.payload.header = ie; + _smsops_rp_data->pdu.payload.header = ie; } else { prev_ie->next = ie; } @@ -941,7 +1029,7 @@ int decode_3gpp_sms(struct sip_msg *msg) // TS 23.040, Sec. 9.2.3.16 // Coding: 7 Bit - if(rp_data->pdu.coding == 0x00) { + if(_smsops_rp_data->pdu.coding == 0x00) { int udh_bit_len = (1 + udh_len) * 8; // add 1 octet for the udh length @@ -953,32 +1041,41 @@ int decode_3gpp_sms(struct sip_msg *msg) } } + // Check for malicious length + if(len <= 0) { + LM_ERR("Length of TP-User-Data payload is less " + "than or equal to zero!\n"); + return -1; + } + + // Check for maximum TP-User-Data payload length since SMS concatenation is not supported + if((_smsops_rp_data->pdu.coding == 0x00 && len > 160) + || (_smsops_rp_data->pdu.coding != 0x00 + && len > 70)) { + LM_ERR("Length of TP-User-Data payload exceeds " + "maximum length!\n"); + return -1; + } + blen = 2 + len * 4; - rp_data->pdu.payload.sm.s = pkg_malloc(blen); - if(rp_data->pdu.payload.sm.s == NULL) { + _smsops_rp_data->pdu.payload.sm.s = pkg_malloc(blen); + if(_smsops_rp_data->pdu.payload.sm.s == NULL) { LM_ERR("no more pkg\n"); return -1; } - memset(rp_data->pdu.payload.sm.s, 0, blen); + memset(_smsops_rp_data->pdu.payload.sm.s, 0, blen); // Coding: 7 Bit - if(rp_data->pdu.coding == 0x00) { + if(_smsops_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); + _smsops_rp_data->pdu.payload.sm.len = len; + _smsops_rp_data->pdu.payload.sm.len = gsm_to_ascii( + &body.s[p], len, + _smsops_rp_data->pdu.payload.sm, fill_bits); } else { // Length is worst-case 2 * len (UCS2 is 2 Bytes, UTF8 is worst-case 4 Bytes) - rp_data->pdu.payload.sm.len = 0; - while(len > 0) { - j = ((unsigned char)body.s[p] << 8) - + (unsigned char)body.s[p + 1]; - p += 2; - rp_data->pdu.payload.sm.len += ucs2_to_utf8(j, - &rp_data->pdu.payload.sm.s - [rp_data->pdu.payload.sm.len]); - len -= 2; - } + j = ucs2_to_utf8(&body.s[p], len, + &_smsops_rp_data->pdu.payload.sm.s[0]); + _smsops_rp_data->pdu.payload.sm.len = j < 0 ? 0 : j; } } } @@ -1071,7 +1168,7 @@ int pv_sms_ack(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) // Always ACK NETWORK to MS rp_data_ack.s[0] = RP_ACK_NETWORK_TO_MS; // Take the reference from request: - rp_data_ack.s[1] = rp_data->reference; + rp_data_ack.s[1] = _smsops_rp_data->reference; // RP-Data-Element-ID rp_data_ack.s[2] = 0x41; // Length @@ -1093,7 +1190,7 @@ int pv_sms_ack(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) */ int pv_sms_body(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { - dumpRPData(rp_send_data, L_DBG); + dumpRPData(_smsops_rp_send_data, L_DBG); str sms_body = {0, 0}; int buffer_size = 1024, lenpos = 0, i = 0, smstext_len_pos = 0; @@ -1108,26 +1205,26 @@ int pv_sms_body(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) } // Encode the data (RP-Data) - sms_body.s[sms_body.len++] = rp_send_data->msg_type; - sms_body.s[sms_body.len++] = rp_send_data->reference; + sms_body.s[sms_body.len++] = _smsops_rp_send_data->msg_type; + sms_body.s[sms_body.len++] = _smsops_rp_send_data->reference; lenpos = sms_body.len; sms_body.s[sms_body.len++] = 0x00; - if(rp_send_data->originator.len > 0) { + if(_smsops_rp_send_data->originator.len > 0) { sms_body.s[sms_body.len++] = - rp_send_data + _smsops_rp_send_data ->originator_flags; // Type of number: ISDN/Telephony Numbering (E164), no extension - i = EncodePhoneNumber(rp_send_data->originator, + i = EncodePhoneNumber(_smsops_rp_send_data->originator, &sms_body.s[sms_body.len], buffer_size - sms_body.len); sms_body.s[lenpos] = i + 1; sms_body.len += i; } lenpos = sms_body.len; sms_body.s[sms_body.len++] = 0x00; - if(rp_send_data->destination.len > 0) { + if(_smsops_rp_send_data->destination.len > 0) { sms_body.s[sms_body.len++] = - rp_send_data + _smsops_rp_send_data ->destination_flags; // Type of number: ISDN/Telephony Numbering (E164), no extension - i = EncodePhoneNumber(rp_send_data->destination, + i = EncodePhoneNumber(_smsops_rp_send_data->destination, &sms_body.s[sms_body.len], buffer_size - sms_body.len); sms_body.s[lenpos] = i + 1; sms_body.len += i; @@ -1140,25 +1237,32 @@ int pv_sms_body(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) // T-PDU /////////////////////////////////////////////////// sms_body.s[sms_body.len++] = - rp_send_data->pdu.msg_type | rp_send_data->pdu.flags + _smsops_rp_send_data->pdu.msg_type | _smsops_rp_send_data->pdu.flags | 0x4; // We've always got no more messages to send. // Originating Address: - sms_body.s[sms_body.len++] = rp_send_data->pdu.originating_address.len; - sms_body.s[sms_body.len++] = rp_send_data->pdu.originating_address_flags; - sms_body.len += EncodePhoneNumber(rp_send_data->pdu.originating_address, - &sms_body.s[sms_body.len], buffer_size - sms_body.len); + sms_body.s[sms_body.len++] = + _smsops_rp_send_data->pdu.originating_address.len; + sms_body.s[sms_body.len++] = + _smsops_rp_send_data->pdu.originating_address_flags; + sms_body.len += + EncodePhoneNumber(_smsops_rp_send_data->pdu.originating_address, + &sms_body.s[sms_body.len], buffer_size - sms_body.len); // Protocol ID - sms_body.s[sms_body.len++] = rp_send_data->pdu.pid; + sms_body.s[sms_body.len++] = _smsops_rp_send_data->pdu.pid; // Encoding (0 => default 7 Bit) - sms_body.s[sms_body.len++] = rp_send_data->pdu.coding; + sms_body.s[sms_body.len++] = _smsops_rp_send_data->pdu.coding; // Service-Center-Timestamp (always 7 octets) EncodeTime(&sms_body.s[sms_body.len]); sms_body.len += 7; smstext_len_pos = sms_body.len; - sms_body.s[sms_body.len++] = rp_send_data->pdu.payload.sm.len; + sms_body.s[sms_body.len++] = _smsops_rp_send_data->pdu.payload.sm.len; // Check for UDH - concat = GetConcatShortMsg8bitRefIE(rp_send_data); + concat = GetConcatShortMsg8bitRefIE(_smsops_rp_send_data); + if(concat == NULL) { + LM_ERR("message building failure\n"); + return -1; + } if(concat->max_num_sm && concat->seq) { sms_body.s[sms_body.len++] = 5; // always 5 for TP_UDH_IE_CONCAT_SM_8BIT_REF @@ -1172,40 +1276,30 @@ int pv_sms_body(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) } // Coding: 7 Bit - if(rp_send_data->pdu.coding == 0x00) { + if(_smsops_rp_send_data->pdu.coding == 0x00) { int actual_text_size = 0; unsigned char paddingBits = (udh_len * 8) % 7; if(paddingBits) { paddingBits = 7 - paddingBits; } - i = ascii_to_gsm(rp_send_data->pdu.payload.sm, + i = ascii_to_gsm(_smsops_rp_send_data->pdu.payload.sm, &sms_body.s[sms_body.len], buffer_size - sms_body.len, &actual_text_size, paddingBits); sms_body.len += i; sms_body.s[smstext_len_pos] = actual_text_size + udh_len; } else { // Coding: ucs2 - int i, ucs2, ucs2len = 0; - const unsigned char *p_input = - (unsigned char *)rp_send_data->pdu.payload.sm.s; - const unsigned char *p_end = p_input; - - for(i = 0; i < rp_send_data->pdu.payload.sm.len;) { - ucs2 = utf8_to_ucs2(p_input, &p_end); - if(ucs2 < 0) { - break; - } - - sms_body.s[sms_body.len++] = (ucs2 >> 8) & 0xFF; - sms_body.s[sms_body.len++] = ucs2 & 0xFF; - - ucs2len += 2; - - i += (p_end - p_input); - p_input = p_end; + int ucs2len = utf8_to_ucs2(&_smsops_rp_send_data->pdu.payload.sm.s[0], + _smsops_rp_send_data->pdu.payload.sm.len, + &sms_body.s[sms_body.len], buffer_size - sms_body.len); + if(ucs2len < 0) { + // Failed in coding UCS2. + LM_ERR("Error encoding SMS in UCS-2 format!\n"); + return -1; } + sms_body.len += ucs2len; // Update the sms text len sms_body.s[smstext_len_pos] = (unsigned char)ucs2len + udh_len; } @@ -1229,34 +1323,45 @@ int pv_get_sms(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) switch(param->pvn.u.isname.name.n) { case SMS_RPDATA_TYPE: - return pv_get_sintval(msg, param, res, (int)rp_data->msg_type); + return pv_get_sintval( + msg, param, res, (int)_smsops_rp_data->msg_type); case SMS_RPDATA_REFERENCE: - return pv_get_sintval(msg, param, res, (int)rp_data->reference); + return pv_get_sintval( + msg, param, res, (int)_smsops_rp_data->reference); case SMS_RPDATA_ORIGINATOR: - return pv_get_strval(msg, param, res, &rp_data->originator); + return pv_get_strval(msg, param, res, &_smsops_rp_data->originator); case SMS_RPDATA_DESTINATION: - return pv_get_strval(msg, param, res, &rp_data->destination); + return pv_get_strval( + msg, param, res, &_smsops_rp_data->destination); case SMS_TPDU_TYPE: - return pv_get_sintval(msg, param, res, (int)rp_data->pdu.msg_type); + return pv_get_sintval( + msg, param, res, (int)_smsops_rp_data->pdu.msg_type); case SMS_TPDU_FLAGS: - return pv_get_sintval(msg, param, res, (int)rp_data->pdu.flags); + return pv_get_sintval( + msg, param, res, (int)_smsops_rp_data->pdu.flags); case SMS_TPDU_CODING: - return pv_get_sintval(msg, param, res, (int)rp_data->pdu.coding); + return pv_get_sintval( + msg, param, res, (int)_smsops_rp_data->pdu.coding); case SMS_TPDU_PROTOCOL: - return pv_get_sintval(msg, param, res, (int)rp_data->pdu.pid); + return pv_get_sintval( + msg, param, res, (int)_smsops_rp_data->pdu.pid); case SMS_TPDU_VALIDITY: - return pv_get_sintval(msg, param, res, (int)rp_data->pdu.validity); + return pv_get_sintval( + msg, param, res, (int)_smsops_rp_data->pdu.validity); case SMS_TPDU_REFERENCE: - return pv_get_sintval(msg, param, res, (int)rp_data->pdu.reference); + return pv_get_sintval( + msg, param, res, (int)_smsops_rp_data->pdu.reference); case SMS_TPDU_PAYLOAD: - return pv_get_strval(msg, param, res, &rp_data->pdu.payload.sm); + return pv_get_strval( + msg, param, res, &_smsops_rp_data->pdu.payload.sm); case SMS_TPDU_DESTINATION: - return pv_get_strval(msg, param, res, &rp_data->pdu.destination); + return pv_get_strval( + msg, param, res, &_smsops_rp_data->pdu.destination); case SMS_TPDU_ORIGINATING_ADDRESS: return pv_get_strval( - msg, param, res, &rp_data->pdu.originating_address); + msg, param, res, &_smsops_rp_data->pdu.originating_address); case SMS_UDH_CONCATSM_REF: { - tp_udh_inf_element_t *ie = rp_data->pdu.payload.header; + tp_udh_inf_element_t *ie = _smsops_rp_data->pdu.payload.header; while(ie) { if(ie->identifier == TP_UDH_IE_CONCAT_SM_8BIT_REF) return pv_get_uintval(msg, param, res, @@ -1266,7 +1371,7 @@ int pv_get_sms(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) return -1; } case SMS_UDH_CONCATSM_MAX_NUM_SM: { - tp_udh_inf_element_t *ie = rp_data->pdu.payload.header; + tp_udh_inf_element_t *ie = _smsops_rp_data->pdu.payload.header; while(ie) { if(ie->identifier == TP_UDH_IE_CONCAT_SM_8BIT_REF) return pv_get_uintval(msg, param, res, @@ -1276,7 +1381,7 @@ int pv_get_sms(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) return -1; } case SMS_UDH_CONCATSM_SEQ: { - tp_udh_inf_element_t *ie = rp_data->pdu.payload.header; + tp_udh_inf_element_t *ie = _smsops_rp_data->pdu.payload.header; while(ie) { if(ie->identifier == TP_UDH_IE_CONCAT_SM_8BIT_REF) return pv_get_uintval(msg, param, res, @@ -1287,16 +1392,16 @@ int pv_get_sms(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) } case SMS_TPDU_ORIGINATING_ADDRESS_FLAGS: return pv_get_sintval(msg, param, res, - (int)rp_data->pdu.originating_address_flags); + (int)_smsops_rp_data->pdu.originating_address_flags); case SMS_TPDU_DESTINATION_FLAGS: - return pv_get_sintval( - msg, param, res, (int)rp_data->pdu.destination_flags); + return pv_get_sintval(msg, param, res, + (int)_smsops_rp_data->pdu.destination_flags); case SMS_RPDATA_ORIGINATOR_FLAGS: return pv_get_sintval( - msg, param, res, (int)rp_data->originator_flags); + msg, param, res, (int)_smsops_rp_data->originator_flags); case SMS_RPDATA_DESTINATION_FLAGS: return pv_get_sintval( - msg, param, res, (int)rp_data->destination_flags); + msg, param, res, (int)_smsops_rp_data->destination_flags); } return 0; } @@ -1306,60 +1411,61 @@ int pv_set_sms(struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val) if(param == NULL) return -1; - if(!rp_send_data) { - rp_send_data = (sms_rp_data_t *)pkg_malloc(sizeof(struct _sms_rp_data)); - if(!rp_send_data) { + if(!_smsops_rp_send_data) { + _smsops_rp_send_data = + (sms_rp_data_t *)pkg_malloc(sizeof(struct _sms_rp_data)); + if(!_smsops_rp_send_data) { LM_ERR("Error allocating %lu bytes!\n", (unsigned long)sizeof(struct _sms_rp_data)); return -1; } // Initialize structure: - memset(rp_send_data, 0, sizeof(struct _sms_rp_data)); - rp_send_data->pdu.originating_address_flags = + memset(_smsops_rp_send_data, 0, sizeof(struct _sms_rp_data)); + _smsops_rp_send_data->pdu.originating_address_flags = 0x91; // Type of number: ISDN/Telephony Numbering (E164), no extension - rp_send_data->pdu.destination_flags = 0x91; - rp_send_data->originator_flags = 0x91; - rp_send_data->destination_flags = 0x91; + _smsops_rp_send_data->pdu.destination_flags = 0x91; + _smsops_rp_send_data->originator_flags = 0x91; + _smsops_rp_send_data->destination_flags = 0x91; } switch(param->pvn.u.isname.name.n) { case SMS_ALL: - freeRP_DATA(rp_send_data); + freeRP_DATA(_smsops_rp_send_data); // Initialize structure: - memset(rp_send_data, 0, sizeof(struct _sms_rp_data)); - rp_send_data->pdu.originating_address_flags = + memset(_smsops_rp_send_data, 0, sizeof(struct _sms_rp_data)); + _smsops_rp_send_data->pdu.originating_address_flags = 0x91; // Type of number: ISDN/Telephony Numbering (E164), no extension - rp_send_data->pdu.destination_flags = 0x91; - rp_send_data->originator_flags = 0x91; - rp_send_data->destination_flags = 0x91; + _smsops_rp_send_data->pdu.destination_flags = 0x91; + _smsops_rp_send_data->originator_flags = 0x91; + _smsops_rp_send_data->destination_flags = 0x91; break; case SMS_RPDATA_TYPE: if(val == NULL) { - rp_send_data->msg_type = 0; + _smsops_rp_send_data->msg_type = 0; return 0; } if(!(val->flags & PV_VAL_INT)) { LM_ERR("Invalid value type\n"); return -1; } - rp_send_data->msg_type = (unsigned char)val->ri; + _smsops_rp_send_data->msg_type = (unsigned char)val->ri; break; case SMS_RPDATA_REFERENCE: if(val == NULL) { - rp_send_data->reference = 0; + _smsops_rp_send_data->reference = 0; return 0; } if(!(val->flags & PV_VAL_INT)) { LM_ERR("Invalid value type\n"); return -1; } - rp_send_data->reference = (unsigned char)val->ri; + _smsops_rp_send_data->reference = (unsigned char)val->ri; break; case SMS_RPDATA_ORIGINATOR: - if(rp_send_data->originator.s) { - pkg_free(rp_send_data->originator.s); - rp_send_data->originator.s = 0; - rp_send_data->originator.len = 0; + if(_smsops_rp_send_data->originator.s) { + pkg_free(_smsops_rp_send_data->originator.s); + _smsops_rp_send_data->originator.s = 0; + _smsops_rp_send_data->originator.len = 0; } if(val == NULL) return 0; @@ -1367,19 +1473,19 @@ int pv_set_sms(struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val) LM_ERR("Invalid type\n"); return -1; } - rp_send_data->originator.s = pkg_malloc(val->rs.len); - if(rp_send_data->originator.s == NULL) { + _smsops_rp_send_data->originator.s = pkg_malloc(val->rs.len); + if(_smsops_rp_send_data->originator.s == NULL) { LM_ERR("no more pkg\n"); return -1; } - rp_send_data->originator.len = val->rs.len; - memcpy(rp_send_data->originator.s, val->rs.s, val->rs.len); + _smsops_rp_send_data->originator.len = val->rs.len; + memcpy(_smsops_rp_send_data->originator.s, val->rs.s, val->rs.len); break; case SMS_RPDATA_DESTINATION: - if(rp_send_data->destination.s) { - pkg_free(rp_send_data->destination.s); - rp_send_data->destination.s = 0; - rp_send_data->destination.len = 0; + if(_smsops_rp_send_data->destination.s) { + pkg_free(_smsops_rp_send_data->destination.s); + _smsops_rp_send_data->destination.s = 0; + _smsops_rp_send_data->destination.len = 0; } if(val == NULL) return 0; @@ -1387,86 +1493,86 @@ int pv_set_sms(struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val) LM_ERR("Invalid type\n"); return -1; } - rp_send_data->destination.s = pkg_malloc(val->rs.len); - if(rp_send_data->destination.s == NULL) { + _smsops_rp_send_data->destination.s = pkg_malloc(val->rs.len); + if(_smsops_rp_send_data->destination.s == NULL) { LM_ERR("no more pkg\n"); return -1; } - rp_send_data->destination.len = val->rs.len; - memcpy(rp_send_data->destination.s, val->rs.s, val->rs.len); + _smsops_rp_send_data->destination.len = val->rs.len; + memcpy(_smsops_rp_send_data->destination.s, val->rs.s, val->rs.len); break; case SMS_TPDU_TYPE: if(val == NULL) { - rp_send_data->pdu.msg_type = 0; + _smsops_rp_send_data->pdu.msg_type = 0; return 0; } if(!(val->flags & PV_VAL_INT)) { LM_ERR("Invalid value type\n"); return -1; } - rp_send_data->pdu.msg_type = (unsigned char)val->ri; + _smsops_rp_send_data->pdu.msg_type = (unsigned char)val->ri; break; case SMS_TPDU_FLAGS: if(val == NULL) { - rp_send_data->pdu.flags = 0; + _smsops_rp_send_data->pdu.flags = 0; return 0; } if(!(val->flags & PV_VAL_INT)) { LM_ERR("Invalid value type\n"); return -1; } - rp_send_data->pdu.flags = (unsigned char)val->ri; + _smsops_rp_send_data->pdu.flags = (unsigned char)val->ri; break; case SMS_TPDU_CODING: if(val == NULL) { - rp_send_data->pdu.coding = 0; + _smsops_rp_send_data->pdu.coding = 0; return 0; } if(!(val->flags & PV_VAL_INT)) { LM_ERR("Invalid value type\n"); return -1; } - rp_send_data->pdu.coding = (unsigned char)val->ri; + _smsops_rp_send_data->pdu.coding = (unsigned char)val->ri; break; case SMS_TPDU_PROTOCOL: if(val == NULL) { - rp_send_data->pdu.pid = 0; + _smsops_rp_send_data->pdu.pid = 0; return 0; } if(!(val->flags & PV_VAL_INT)) { LM_ERR("Invalid value type\n"); return -1; } - rp_send_data->pdu.pid = (unsigned char)val->ri; + _smsops_rp_send_data->pdu.pid = (unsigned char)val->ri; break; case SMS_TPDU_REFERENCE: if(val == NULL) { - rp_send_data->pdu.reference = 0; + _smsops_rp_send_data->pdu.reference = 0; return 0; } if(!(val->flags & PV_VAL_INT)) { LM_ERR("Invalid value type\n"); return -1; } - rp_send_data->pdu.reference = (unsigned char)val->ri; + _smsops_rp_send_data->pdu.reference = (unsigned char)val->ri; break; case SMS_TPDU_VALIDITY: if(val == NULL) { - rp_send_data->pdu.validity = 0; + _smsops_rp_send_data->pdu.validity = 0; return 0; } if(!(val->flags & PV_VAL_INT)) { LM_ERR("Invalid value type\n"); return -1; } - rp_send_data->pdu.validity = (unsigned char)val->ri; + _smsops_rp_send_data->pdu.validity = (unsigned char)val->ri; break; case SMS_TPDU_PAYLOAD: - if(rp_send_data->pdu.payload.sm.s) { - pkg_free(rp_send_data->pdu.payload.sm.s); - rp_send_data->pdu.payload.sm.s = 0; - rp_send_data->pdu.payload.sm.len = 0; + if(_smsops_rp_send_data->pdu.payload.sm.s) { + pkg_free(_smsops_rp_send_data->pdu.payload.sm.s); + _smsops_rp_send_data->pdu.payload.sm.s = 0; + _smsops_rp_send_data->pdu.payload.sm.len = 0; } if(val == NULL) return 0; @@ -1474,19 +1580,20 @@ int pv_set_sms(struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val) LM_ERR("Invalid type\n"); return -1; } - rp_send_data->pdu.payload.sm.s = pkg_malloc(val->rs.len); - if(rp_send_data->pdu.payload.sm.s == NULL) { + _smsops_rp_send_data->pdu.payload.sm.s = pkg_malloc(val->rs.len); + if(_smsops_rp_send_data->pdu.payload.sm.s == NULL) { LM_ERR("no more pkg\n"); return -1; } - rp_send_data->pdu.payload.sm.len = val->rs.len; - memcpy(rp_send_data->pdu.payload.sm.s, val->rs.s, val->rs.len); + _smsops_rp_send_data->pdu.payload.sm.len = val->rs.len; + memcpy(_smsops_rp_send_data->pdu.payload.sm.s, val->rs.s, + val->rs.len); break; case SMS_TPDU_DESTINATION: - if(rp_send_data->pdu.destination.s) { - pkg_free(rp_send_data->pdu.destination.s); - rp_send_data->pdu.destination.s = 0; - rp_send_data->pdu.destination.len = 0; + if(_smsops_rp_send_data->pdu.destination.s) { + pkg_free(_smsops_rp_send_data->pdu.destination.s); + _smsops_rp_send_data->pdu.destination.s = 0; + _smsops_rp_send_data->pdu.destination.len = 0; } if(val == NULL) return 0; @@ -1494,19 +1601,20 @@ int pv_set_sms(struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val) LM_ERR("Invalid type\n"); return -1; } - rp_send_data->pdu.destination.s = pkg_malloc(val->rs.len); - if(rp_send_data->pdu.destination.s == NULL) { + _smsops_rp_send_data->pdu.destination.s = pkg_malloc(val->rs.len); + if(_smsops_rp_send_data->pdu.destination.s == NULL) { LM_ERR("no more pkg\n"); return -1; } - rp_send_data->pdu.destination.len = val->rs.len; - memcpy(rp_send_data->pdu.destination.s, val->rs.s, val->rs.len); + _smsops_rp_send_data->pdu.destination.len = val->rs.len; + memcpy(_smsops_rp_send_data->pdu.destination.s, val->rs.s, + val->rs.len); break; case SMS_TPDU_ORIGINATING_ADDRESS: - if(rp_send_data->pdu.originating_address.s) { - pkg_free(rp_send_data->pdu.originating_address.s); - rp_send_data->pdu.originating_address.s = 0; - rp_send_data->pdu.originating_address.len = 0; + if(_smsops_rp_send_data->pdu.originating_address.s) { + pkg_free(_smsops_rp_send_data->pdu.originating_address.s); + _smsops_rp_send_data->pdu.originating_address.s = 0; + _smsops_rp_send_data->pdu.originating_address.len = 0; } if(val == NULL) return 0; @@ -1514,13 +1622,14 @@ int pv_set_sms(struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val) LM_ERR("Invalid type\n"); return -1; } - rp_send_data->pdu.originating_address.s = pkg_malloc(val->rs.len); - if(rp_send_data->pdu.originating_address.s == NULL) { + _smsops_rp_send_data->pdu.originating_address.s = + pkg_malloc(val->rs.len); + if(_smsops_rp_send_data->pdu.originating_address.s == NULL) { LM_ERR("no more pkg\n"); return -1; } - rp_send_data->pdu.originating_address.len = val->rs.len; - memcpy(rp_send_data->pdu.originating_address.s, val->rs.s, + _smsops_rp_send_data->pdu.originating_address.len = val->rs.len; + memcpy(_smsops_rp_send_data->pdu.originating_address.s, val->rs.s, val->rs.len); break; case SMS_UDH_CONCATSM_REF: { @@ -1531,7 +1640,7 @@ int pv_set_sms(struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val) return -1; } struct ie_concat_sm_8bit_ref *concat = - GetConcatShortMsg8bitRefIE(rp_send_data); + GetConcatShortMsg8bitRefIE(_smsops_rp_send_data); if(concat == NULL) return -1; @@ -1546,7 +1655,7 @@ int pv_set_sms(struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val) return -1; } struct ie_concat_sm_8bit_ref *concat = - GetConcatShortMsg8bitRefIE(rp_send_data); + GetConcatShortMsg8bitRefIE(_smsops_rp_send_data); if(concat == NULL) return -1; @@ -1561,7 +1670,7 @@ int pv_set_sms(struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val) return -1; } struct ie_concat_sm_8bit_ref *concat = - GetConcatShortMsg8bitRefIE(rp_send_data); + GetConcatShortMsg8bitRefIE(_smsops_rp_send_data); if(concat == NULL) return -1; @@ -1570,51 +1679,52 @@ int pv_set_sms(struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val) } case SMS_TPDU_ORIGINATING_ADDRESS_FLAGS: { if(val == NULL) { - rp_send_data->pdu.originating_address_flags = 0; + _smsops_rp_send_data->pdu.originating_address_flags = 0; return 0; } if(!(val->flags & PV_VAL_INT)) { LM_ERR("Invalid value type\n"); return -1; } - rp_send_data->pdu.originating_address_flags = + _smsops_rp_send_data->pdu.originating_address_flags = (unsigned char)val->ri; break; } case SMS_TPDU_DESTINATION_FLAGS: { if(val == NULL) { - rp_send_data->pdu.destination_flags = 0; + _smsops_rp_send_data->pdu.destination_flags = 0; return 0; } if(!(val->flags & PV_VAL_INT)) { LM_ERR("Invalid value type\n"); return -1; } - rp_send_data->pdu.destination_flags = (unsigned char)val->ri; + _smsops_rp_send_data->pdu.destination_flags = + (unsigned char)val->ri; break; } case SMS_RPDATA_ORIGINATOR_FLAGS: { if(val == NULL) { - rp_send_data->originator_flags = 0; + _smsops_rp_send_data->originator_flags = 0; return 0; } if(!(val->flags & PV_VAL_INT)) { LM_ERR("Invalid value type\n"); return -1; } - rp_send_data->originator_flags = (unsigned char)val->ri; + _smsops_rp_send_data->originator_flags = (unsigned char)val->ri; break; } case SMS_RPDATA_DESTINATION_FLAGS: { if(val == NULL) { - rp_send_data->destination_flags = 0; + _smsops_rp_send_data->destination_flags = 0; return 0; } if(!(val->flags & PV_VAL_INT)) { LM_ERR("Invalid value type\n"); return -1; } - rp_send_data->destination_flags = (unsigned char)val->ri; + _smsops_rp_send_data->destination_flags = (unsigned char)val->ri; break; } } @@ -1783,7 +1893,7 @@ int smsdump(struct sip_msg *msg, char *str1, char *str2) return -1; } - return dumpRPData(rp_data, L_DBG); + return dumpRPData(_smsops_rp_data, L_DBG); } int isRPDATA(struct sip_msg *msg, char *str1, char *str2) @@ -1793,8 +1903,8 @@ int isRPDATA(struct sip_msg *msg, char *str1, char *str2) LM_ERR("Error getting/decoding RP-Data from request!\n"); return -1; } - if((rp_data->msg_type == RP_DATA_MS_TO_NETWORK) - || (rp_data->msg_type == RP_DATA_NETWORK_TO_MS)) + if((_smsops_rp_data->msg_type == RP_DATA_MS_TO_NETWORK) + || (_smsops_rp_data->msg_type == RP_DATA_NETWORK_TO_MS)) return 1; else return -1; diff --git a/src/modules/snmpstats/README b/src/modules/snmpstats/README index f121a8680..407b6def6 100644 --- a/src/modules/snmpstats/README +++ b/src/modules/snmpstats/README @@ -796,9 +796,11 @@ Name First at all check if your question was already answered on one of our mailing lists: * User Mailing List - - https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users + https://lists.kamailio.org/mailman3/postorius/lists/sr-users.lists. + kamailio.org/ * Developer Mailing List - - https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-dev + https://lists.kamailio.org/mailman3/postorius/lists/sr-dev.lists.ka + mailio.org/ E-mails regarding any stable Kamailio release should be sent to and e-mails regarding development diff --git a/src/modules/snmpstats/snmpObjects.c b/src/modules/snmpstats/snmpObjects.c index 7b81ebb36..a8ecafc18 100644 --- a/src/modules/snmpstats/snmpObjects.c +++ b/src/modules/snmpstats/snmpObjects.c @@ -214,7 +214,7 @@ void init_kamailioObjects(void) * The following are thresholds used by: * * - The alarm monitoring process, to decide when to send out traps. - * - All scalars involving alarm status's and thresholds. + * - All scalars involving alarm status' and thresholds. * * By default they are initialized to -1, which disables alarm checks. * These are set through the kamailio.cfg file with the following modparams to diff --git a/src/modules/snmpstats/snmpstats.c b/src/modules/snmpstats/snmpstats.c index fe77cbb1e..34b699bde 100644 --- a/src/modules/snmpstats/snmpstats.c +++ b/src/modules/snmpstats/snmpstats.c @@ -166,7 +166,7 @@ struct module_exports exports = { /*! * The module will fork off a child process to run an snmp command via execve(). * We need a customized handler to ignore the SIGCHLD when the execve() - * finishes. We keep around the child process's pid for the customized + * finishes. We keep around the child process' pid for the customized * handler. * * Specifically, If the process that generated the SIGCHLD doesn't match this diff --git a/src/modules/sqlops/sql_api.c b/src/modules/sqlops/sql_api.c index 93a9b3652..b76edbd48 100644 --- a/src/modules/sqlops/sql_api.c +++ b/src/modules/sqlops/sql_api.c @@ -357,17 +357,17 @@ int sql_do_query(sql_con_t *con, str *query, sql_result_t *res) case DB1_INT: res->vals[i][j].flags = PV_VAL_INT; res->vals[i][j].value.n = - (int)RES_ROWS(db_res)[i].values[j].val.int_val; + (long)RES_ROWS(db_res)[i].values[j].val.int_val; break; case DB1_DATETIME: res->vals[i][j].flags = PV_VAL_INT; res->vals[i][j].value.n = - (int)RES_ROWS(db_res)[i].values[j].val.time_val; + (long)RES_ROWS(db_res)[i].values[j].val.time_val; break; case DB1_BITMAP: res->vals[i][j].flags = PV_VAL_INT; res->vals[i][j].value.n = - (int)RES_ROWS(db_res)[i].values[j].val.bitmap_val; + (long)RES_ROWS(db_res)[i].values[j].val.bitmap_val; break; case DB1_BIGINT: res->vals[i][j].flags = PV_VAL_STR; diff --git a/src/modules/sqlops/sql_api.h b/src/modules/sqlops/sql_api.h index b11895610..0051a61a5 100644 --- a/src/modules/sqlops/sql_api.h +++ b/src/modules/sqlops/sql_api.h @@ -41,7 +41,7 @@ typedef struct _sql_col typedef struct _sql_val { int flags; - int_str value; + numstr_ut value; } sql_val_t; typedef struct _sql_result diff --git a/src/modules/ss7ops/isup_parsed.c b/src/modules/ss7ops/isup_parsed.c index 5ebc2d7f3..75a132435 100644 --- a/src/modules/ss7ops/isup_parsed.c +++ b/src/modules/ss7ops/isup_parsed.c @@ -1067,7 +1067,7 @@ static int do_parse( while(opt_left > 0) { uint8_t ie = opt_data[0]; - size_t len; + size_t len1; opt_data += 1; opt_left -= 1; @@ -1078,20 +1078,20 @@ static int do_parse( LM_ERR("ISUP no space for len %zu\n", opt_left); return -1; } - len = opt_data[0]; + len1 = opt_data[0]; opt_left -= 1; opt_data += 1; - if(opt_left < len) { + if(opt_left < len1) { LM_ERR("ISUP no space optional data %zu vs. %zu\n", opt_left, - len); + len1); return -1; } - visitor(ie, opt_data, len, ptr); + visitor(ie, opt_data, len1, ptr); - opt_data += len; - opt_left -= len; + opt_data += len1; + opt_left -= len1; } } diff --git a/src/modules/ss7ops/ss7ops_mod.c b/src/modules/ss7ops/ss7ops_mod.c index b0f846946..8772ff56b 100644 --- a/src/modules/ss7ops/ss7ops_mod.c +++ b/src/modules/ss7ops/ss7ops_mod.c @@ -221,9 +221,7 @@ static const uint8_t *extract_from_m2pa(const uint8_t *data, size_t *len) } data += 8; data_len -= 8; - if(data_len == 0) - return NULL; - else if(data_len < 1) { + if(data_len < 1) { LM_ERR("M2PA no space for prio %u\n", data_len); return NULL; } diff --git a/src/modules/statsd/README b/src/modules/statsd/README index 6bccb3145..ed29ed492 100644 --- a/src/modules/statsd/README +++ b/src/modules/statsd/README @@ -170,7 +170,7 @@ route [gauge_method]{ 3.4. statsd_start(key) statsd_start set an avp with the key name, and when statsd_stop(key) is - used, the module will send statsd the difference in milliseconds. this + used, the module will send statsd the difference in milliseconds. This is useful to know the time of a SQL query, or how much time your replies take. diff --git a/src/modules/statsd/doc/statsd_admin.xml b/src/modules/statsd/doc/statsd_admin.xml index 24410f1af..2be8355f4 100644 --- a/src/modules/statsd/doc/statsd_admin.xml +++ b/src/modules/statsd/doc/statsd_admin.xml @@ -156,7 +156,7 @@ route [gauge_method]{ statsd_start set an avp with the key name, and when statsd_stop(key) is used, the module will send statsd the difference in - milliseconds. this is useful to know the time of a SQL query, or how much time your replies take. + milliseconds. This is useful to know the time of a SQL query, or how much time your replies take. This function can be used in all routes. diff --git a/src/modules/statsd/lib_statsd.c b/src/modules/statsd/lib_statsd.c index d73f77fd3..195f1f657 100644 --- a/src/modules/statsd/lib_statsd.c +++ b/src/modules/statsd/lib_statsd.c @@ -11,8 +11,26 @@ #include "../../core/sr_module.h" #include "lib_statsd.h" +bool isNumber(char *str); + static StatsConnection statsd_connection = {"127.0.0.1", "8125", -1}; +enum actions +{ + GAUGE = 0, + COUNTER, + SET, + HISTOGRAM, + TIMMING +}; + +static const char *const actions_val[] = {[GAUGE] = "g", + [COUNTER] = "c", + [SET] = "s", + [HISTOGRAM] = "h", + [TIMMING] = "ms"}; + + bool statsd_connect(void) { @@ -69,55 +87,66 @@ bool send_command(char *command) return true; } -bool statsd_set(char *key, char *value) +bool statsd_send_command( + char *key, char *value, enum actions action, char *labels) { - char *end = 0; - char command[254]; - int val; - val = strtol(value, &end, 0); - if(*end) { - LM_ERR("statsd_count could not use the provide value(%s)\n", value); - return false; + size_t labels_len = 0; + if(labels != NULL) { + labels_len = strlen(labels); + } + const char *action_str = actions_val[action]; + size_t command_len = + strlen(key) + strlen(value) + labels_len + strlen(action_str) + 6; + char command[command_len]; + + if(labels_len == 0) { + snprintf(command, command_len, "%s:%s|%s\n", key, value, action_str); + } else { + snprintf(command, sizeof command, "%s:%s|%s|#%s\n", key, value, + action_str, labels); } - snprintf(command, sizeof command, "%s:%i|s\n", key, val); return send_command(command); } -bool statsd_gauge(char *key, char *value) +bool statsd_set(char *key, char *value, char *labels) { - char command[254]; - snprintf(command, sizeof command, "%s:%s|g\n", key, value); - return send_command(command); + if(!isNumber(value)) { + LM_ERR("statsd_set could not use the provide value(%s)\n", value); + return false; + } + return statsd_send_command(key, value, SET, labels); } -bool statsd_histogram(char *key, char *value) + +bool statsd_gauge(char *key, char *value, char *labels) { - char command[254]; - snprintf(command, sizeof command, "%s:%s|h\n", key, value); - return send_command(command); + return statsd_send_command(key, value, GAUGE, labels); } -bool statsd_count(char *key, char *value) +bool statsd_histogram(char *key, char *value, char *labels) { - char *end = 0; - char command[254]; - int val; + return statsd_send_command(key, value, HISTOGRAM, labels); +} - val = strtol(value, &end, 0); - if(*end) { +bool statsd_count(char *key, char *value, char *labels) +{ + if(!isNumber(value)) { LM_ERR("statsd_count could not use the provide value(%s)\n", value); return false; } - snprintf(command, sizeof command, "%s:%i|c\n", key, val); - return send_command(command); + return statsd_send_command(key, value, COUNTER, labels); } -bool statsd_timing(char *key, int value) +bool statsd_timing(char *key, int value, char *labels) { - char command[254]; - snprintf(command, sizeof command, "%s:%i|ms\n", key, value); - return send_command(command); + int value_len = 1; + if(value > 0) { + value_len = (int)((ceil(log10(value)) + 1) * sizeof(char)); + } + char val[value_len]; + sprintf(val, "%i", value); + return statsd_send_command(key, val, TIMMING, labels); } bool statsd_init(char *ip, char *port) @@ -137,3 +166,10 @@ bool statsd_destroy(void) statsd_connection.sock = 0; return true; } + +bool isNumber(char *s) +{ + char *e = NULL; + (void)strtol(s, &e, 0); + return e != NULL && *e == (char)0; +} diff --git a/src/modules/statsd/lib_statsd.h b/src/modules/statsd/lib_statsd.h index 308e67a7a..d4b85b96d 100644 --- a/src/modules/statsd/lib_statsd.h +++ b/src/modules/statsd/lib_statsd.h @@ -11,10 +11,10 @@ typedef struct StatsConnection bool statsd_connect(void); bool send_command(char *command); -bool statsd_set(char *key, char *value); -bool statsd_gauge(char *key, char *value); -bool statsd_histogram(char *key, char *value); -bool statsd_count(char *key, char *value); -bool statsd_timing(char *key, int value); +bool statsd_set(char *key, char *value, char *labels); +bool statsd_gauge(char *key, char *value, char *labels); +bool statsd_histogram(char *key, char *value, char *labels); +bool statsd_count(char *key, char *value, char *labels); +bool statsd_timing(char *key, int value, char *labels); bool statsd_init(char *ip, char *port); bool statsd_destroy(void); diff --git a/src/modules/statsd/statsd.c b/src/modules/statsd/statsd.c index 889534c62..e9d3682bb 100644 --- a/src/modules/statsd/statsd.c +++ b/src/modules/statsd/statsd.c @@ -34,12 +34,22 @@ MODULE_VERSION static int mod_init(void); void mod_destroy(void); static int func_gauge(struct sip_msg *msg, char *key, char *val); +static int func_gauge_with_labels( + struct sip_msg *msg, char *key, char *val, char *labels); static int func_histogram(struct sip_msg *msg, char *key, char *val); +static int func_histogram_with_labels( + struct sip_msg *msg, char *key, char *val, char *labels); static int func_set(struct sip_msg *msg, char *key, char *val); +static int func_set_with_labels( + struct sip_msg *msg, char *key, char *val, char *labels); static int func_time_start(struct sip_msg *msg, char *key); static int func_time_end(struct sip_msg *msg, char *key); +static int func_time_end_with_labels( + struct sip_msg *msg, char *key, char *labels); static int func_incr(struct sip_msg *msg, char *key); +static int func_incr_with_labels(struct sip_msg *msg, char *key, char *labels); static int func_decr(struct sip_msg *msg, char *key); +static int func_decr_with_labels(struct sip_msg *msg, char *key, char *labels); static char *get_milliseconds(char *dst); typedef struct StatsdParams @@ -52,12 +62,18 @@ static StatsdParams statsd_params = {}; /* clang-format off */ static cmd_export_t commands[] = { {"statsd_gauge", (cmd_function)func_gauge, 2, 0, 0, ANY_ROUTE}, + {"statsd_gauge", (cmd_function)func_gauge_with_labels, 3, 0, 0, ANY_ROUTE}, {"statsd_histogram", (cmd_function)func_histogram, 2, 0, 0, ANY_ROUTE}, + {"statsd_histogram", (cmd_function)func_histogram_with_labels, 3, 0, 0, ANY_ROUTE}, {"statsd_start", (cmd_function)func_time_start, 1, 0, 0, ANY_ROUTE}, {"statsd_stop", (cmd_function)func_time_end, 1, 0, 0, ANY_ROUTE}, + {"statsd_stop", (cmd_function)func_time_end_with_labels, 2, 0, 0, ANY_ROUTE}, {"statsd_incr", (cmd_function)func_incr, 1, 0, 0, ANY_ROUTE}, + {"statsd_incr", (cmd_function)func_incr_with_labels, 2, 0, 0, ANY_ROUTE}, {"statsd_decr", (cmd_function)func_decr, 1, 0, 0, ANY_ROUTE}, + {"statsd_decr", (cmd_function)func_decr_with_labels, 2, 0, 0, ANY_ROUTE}, {"statsd_set", (cmd_function)func_set, 2, 0, 0, ANY_ROUTE}, + {"statsd_set", (cmd_function)func_set_with_labels, 3, 0, 0, ANY_ROUTE}, {0, 0, 0, 0, 0, 0} }; @@ -117,32 +133,69 @@ void mod_destroy(void) static int func_gauge(struct sip_msg *msg, char *key, char *val) { - return statsd_gauge(key, val); + return statsd_gauge(key, val, NULL); } -static int func_histogram(struct sip_msg *msg, char *key, char *val) +static int func_gauge_with_labels( + struct sip_msg *msg, char *key, char *val, char *labels) { - return statsd_histogram(key, val); + return statsd_gauge(key, val, labels); } static int ki_statsd_gauge(sip_msg_t *msg, str *key, str *val) { - return statsd_gauge(key->s, val->s); + return statsd_gauge(key->s, val->s, NULL); +} + +static int ki_statsd_gauge_with_labels( + sip_msg_t *msg, str *key, str *val, str *labels) +{ + return statsd_gauge(key->s, val->s, labels->s); } +static int func_histogram(struct sip_msg *msg, char *key, char *val) +{ + return statsd_histogram(key, val, NULL); +} + +static int func_histogram_with_labels( + struct sip_msg *msg, char *key, char *val, char *labels) +{ + return statsd_histogram(key, val, labels); +} + + static int ki_statsd_histogram(sip_msg_t *msg, str *key, str *val) { - return statsd_histogram(key->s, val->s); + return statsd_histogram(key->s, val->s, NULL); +} + +static int ki_statsd_histogram_with_labels( + sip_msg_t *msg, str *key, str *val, str *labels) +{ + return statsd_histogram(key->s, val->s, labels->s); } static int func_set(struct sip_msg *msg, char *key, char *val) { - return statsd_set(key, val); + return statsd_set(key, val, NULL); +} + +static int func_set_with_labels( + struct sip_msg *msg, char *key, char *val, char *labels) +{ + return statsd_set(key, val, labels); } static int ki_statsd_set(sip_msg_t *msg, str *key, str *val) { - return statsd_set(key->s, val->s); + return statsd_set(key->s, val->s, NULL); +} + +static int ki_statsd_set_with_labels( + sip_msg_t *msg, str *key, str *val, str *labels) +{ + return statsd_set(key->s, val->s, labels->s); } static int func_time_start(struct sip_msg *msg, char *key) @@ -168,7 +221,13 @@ static int ki_statsd_start(sip_msg_t *msg, str *key) return func_time_start(msg, key->s); } + static int func_time_end(struct sip_msg *msg, char *key) +{ + return func_time_end_with_labels(msg, key, NULL); +} + +int func_time_end_with_labels(struct sip_msg *msg, char *key, char *labels) { char unix_time[24]; char *endptr; @@ -204,7 +263,7 @@ static int func_time_end(struct sip_msg *msg, char *key) LM_DBG("Statsd: statsd_stop Start_time=%ld unix_time=%ld (%i)\n", start_time, atol(unix_time), result); destroy_avp(prev_avp); - return statsd_timing(key, result); + return statsd_timing(key, result, labels); } static int ki_statsd_stop(sip_msg_t *msg, str *key) @@ -212,24 +271,49 @@ static int ki_statsd_stop(sip_msg_t *msg, str *key) return func_time_end(msg, key->s); } +static int ki_statsd_stop_with_labels(sip_msg_t *msg, str *key, str *labels) +{ + return func_time_end_with_labels(msg, key->s, labels->s); +} + static int func_incr(struct sip_msg *msg, char *key) { - return statsd_count(key, "+1"); + return statsd_count(key, "+1", NULL); +} + +static int func_incr_with_labels(struct sip_msg *msg, char *key, char *labels) +{ + return statsd_count(key, "+1", labels); } static int ki_statsd_incr(sip_msg_t *msg, str *key) { - return statsd_count(key->s, "+1"); + return statsd_count(key->s, "+1", NULL); +} + +static int ki_statsd_incr_with_labels(sip_msg_t *msg, str *key, str *labels) +{ + return statsd_count(key->s, "+1", labels->s); } static int func_decr(struct sip_msg *msg, char *key) { - return statsd_count(key, "-1"); + return statsd_count(key, "-1", NULL); +} + +static int func_decr_with_labels(struct sip_msg *msg, char *key, char *labels) +{ + return statsd_count(key, "-1", labels); } static int ki_statsd_decr(sip_msg_t *msg, str *key) { - return statsd_count(key->s, "-1"); + return statsd_count(key->s, "-1", NULL); +} + +static int ki_statsd_decr_with_labels(sip_msg_t *msg, str *key, str *labels) +{ + return statsd_count(key->s, "-1", labels->s); } char *get_milliseconds(char *dst) @@ -253,11 +337,21 @@ static sr_kemi_t sr_kemi_statsd_exports[] = { { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, + { str_init("statsd"), str_init("statsd_labels_gauge"), + SR_KEMIP_INT, ki_statsd_gauge_with_labels, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, { str_init("statsd"), str_init("statsd_histogram"), SR_KEMIP_INT, ki_statsd_histogram, { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, + { str_init("statsd"), str_init("statsd_labels_histogram"), + SR_KEMIP_INT, ki_statsd_histogram_with_labels, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, { str_init("statsd"), str_init("statsd_start"), SR_KEMIP_INT, ki_statsd_start, { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, @@ -268,21 +362,41 @@ static sr_kemi_t sr_kemi_statsd_exports[] = { { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, + { str_init("statsd"), str_init("statsd_labels_stop"), + SR_KEMIP_INT, ki_statsd_stop_with_labels, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_STR, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, { str_init("statsd"), str_init("statsd_incr"), SR_KEMIP_INT, ki_statsd_incr, { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, + { str_init("statsd"), str_init("statsd_labels_incr"), + SR_KEMIP_INT, ki_statsd_incr_with_labels, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_STR, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, { str_init("statsd"), str_init("statsd_decr"), SR_KEMIP_INT, ki_statsd_decr, { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, + { str_init("statsd"), str_init("statsd_labels_decr"), + SR_KEMIP_INT, ki_statsd_decr_with_labels, + { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_STR, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, { str_init("statsd"), str_init("statsd_set"), SR_KEMIP_INT, ki_statsd_set, { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, + { str_init("statsd"), str_init("statsd_labels_set"), + SR_KEMIP_INT, ki_statsd_set_with_labels, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, + 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/tcpops/README b/src/modules/tcpops/README index 5bbd68344..bbebe20ff 100644 --- a/src/modules/tcpops/README +++ b/src/modules/tcpops/README @@ -90,9 +90,8 @@ Chapter 1. Admin Guide 1. Overview - This modules allows Kamailio to control the TCP connection options - (such as the keepalive mechanism), on demand, and on a per-socket - basis. + This module allows Kamailio to control the TCP connection options (such + as the keepalive mechanism), on demand, and on a per-socket basis. Note: the keepalive functions only work on systems with the HAVE_TCP_KEEPIDLE, HAVE_TCP_KEEPCNT and HAVE_TCP_KEEPINTVL macros @@ -139,7 +138,7 @@ modparam("tcpops", "event_callback", "ksr_tcpops_event") ... -- event callback function implemented in Lua function ksr_tcpops_event(evname) - KSR.info("===== evapi module triggered event: " .. evname .. "\n"); + KSR.info("===== tcpops module triggered event: " .. evname .. "\n"); return 1; end ... diff --git a/src/modules/tcpops/doc/params.xml b/src/modules/tcpops/doc/params.xml index 1f7aaa507..db29f86fa 100644 --- a/src/modules/tcpops/doc/params.xml +++ b/src/modules/tcpops/doc/params.xml @@ -66,7 +66,7 @@ modparam("tcpops", "event_callback", "ksr_tcpops_event") ... -- event callback function implemented in Lua function ksr_tcpops_event(evname) - KSR.info("===== evapi module triggered event: " .. evname .. "\n"); + KSR.info("===== tcpops module triggered event: " .. evname .. "\n"); return 1; end ... diff --git a/src/modules/tcpops/doc/tcpops.xml b/src/modules/tcpops/doc/tcpops.xml index 6f17462a5..00e4bf8cd 100644 --- a/src/modules/tcpops/doc/tcpops.xml +++ b/src/modules/tcpops/doc/tcpops.xml @@ -45,7 +45,7 @@
Overview - This modules allows Kamailio to control the TCP connection options (such as the keepalive + This module allows Kamailio to control the TCP connection options (such as the keepalive mechanism), on demand, and on a per-socket basis. diff --git a/src/modules/tcpops/tcpops_mod.c b/src/modules/tcpops/tcpops_mod.c index d8953c434..aad29665d 100644 --- a/src/modules/tcpops/tcpops_mod.c +++ b/src/modules/tcpops/tcpops_mod.c @@ -762,24 +762,51 @@ static int pv_get_tcp(sip_msg_t *msg, pv_param_t *param, pv_value_t *res) return -1; } - if((con = tcpconn_get(msg->rcv.proto_reserved1, 0, 0, 0, 0)) == NULL) { - return pv_get_null(msg, param, res); - } + con = tcpconn_get(msg->rcv.proto_reserved1, 0, 0, 0, 0); switch(param->pvn.u.isname.name.n) { - case 1: + case 1: /* c_si */ + if(con == NULL) { + sval.s = ip_addr2a(&msg->rcv.src_ip); + sval.len = strlen(sval.s); + return pv_get_strval(msg, param, res, &sval); + } sval.s = ip_addr2a(&con->cinfo.src_ip); tcpconn_put(con); sval.len = strlen(sval.s); return pv_get_strval(msg, param, res, &sval); - case 2: + case 2: /* c_sp */ + if(con == NULL) { + ival = msg->rcv.src_port; + return pv_get_sintval(msg, param, res, ival); + } ival = con->cinfo.src_port; tcpconn_put(con); return pv_get_sintval(msg, param, res, ival); - default: + case 3: /* ac_si */ + if(con == NULL) { + return pv_get_null(msg, param, res); + } + sval.s = ip_addr2a(&con->cinfo.src_ip); + tcpconn_put(con); + sval.len = strlen(sval.s); + return pv_get_strval(msg, param, res, &sval); + case 4: /* ac_sp */ + if(con == NULL) { + return pv_get_null(msg, param, res); + } + ival = con->cinfo.src_port; + tcpconn_put(con); + return pv_get_sintval(msg, param, res, ival); + case 5: /* aconid */ + if(con == NULL) { + return pv_get_null(msg, param, res); + } ival = con->id; tcpconn_put(con); return pv_get_sintval(msg, param, res, ival); + default: /* conid */ + return pv_get_sintval(msg, param, res, msg->rcv.proto_reserved1); } } @@ -805,6 +832,17 @@ static int pv_parse_tcp_name(pv_spec_p sp, str *in) case 5: if(strncmp(in->s, "conid", 5) == 0) { sp->pvp.pvn.u.isname.name.n = 0; + } else if(strncmp(in->s, "ac_si", 5) == 0) { + sp->pvp.pvn.u.isname.name.n = 3; + } else if(strncmp(in->s, "ac_sp", 5) == 0) { + sp->pvp.pvn.u.isname.name.n = 4; + } else { + goto error; + } + break; + case 6: + if(strncmp(in->s, "aconid", 6) == 0) { + sp->pvp.pvn.u.isname.name.n = 5; } else { goto error; } diff --git a/src/modules/textops/README b/src/modules/textops/README index 9c3399470..3979dfdf1 100644 --- a/src/modules/textops/README +++ b/src/modules/textops/README @@ -104,6 +104,7 @@ Ovidiu Sas 4.59. get_body_part_raw(content_type, opv) 4.60. remove_body_part(content_type) 4.61. regex_substring(itext, regexp, mindex, mcount, dpv) + 4.62. via_param_rm(name, idx) 2. Developer Guide @@ -175,6 +176,7 @@ Ovidiu Sas 1.60. get_body_part_raw usage 1.61. remove_body_part usage 1.62. _regex_substring usage + 1.63. via_param_rm usage Chapter 1. Admin Guide @@ -252,6 +254,7 @@ Chapter 1. Admin Guide 4.59. get_body_part_raw(content_type, opv) 4.60. remove_body_part(content_type) 4.61. regex_substring(itext, regexp, mindex, mcount, dpv) + 4.62. via_param_rm(name, idx) 1. Overview @@ -355,6 +358,7 @@ From: medabeda 4.59. get_body_part_raw(content_type, opv) 4.60. remove_body_part(content_type) 4.61. regex_substring(itext, regexp, mindex, mcount, dpv) + 4.62. via_param_rm(name, idx) 4.1. search(re) @@ -876,8 +880,8 @@ append_urihf("CC-Diversion: ", "\r\n"); Note - The function is also able to distinguish the compact names. For exmaple - “From” will match with “f” + The function is also able to distinguish the compact names. For example + “From” will match with “f”. Meaning of the parameters is as follows: * hf_name - Header field name (long or compact form). It can be only @@ -1621,6 +1625,25 @@ msg_apply_changes(); ---- ... +4.62. via_param_rm(name, idx) + + Remove parameter matching by name from Via body at the specified index. + The index starts from 0 (first Via body). Negative index counts from + the end of the list for Via header bodies (-1 is the last Via body). + + Meaning of the parameters is as follows: + * name - name of the parameter + * idx - index of the Via body. + + The parameters can also be variables. + + This function can be used from ANY_ROUTE. + + Example 1.63. via_param_rm usage +... +via_param_rm("p1", "0"); +... + Chapter 2. Developer Guide Table of Contents diff --git a/src/modules/textops/api.h b/src/modules/textops/api.h index fc77e2355..bf1686f76 100644 --- a/src/modules/textops/api.h +++ b/src/modules/textops/api.h @@ -66,7 +66,7 @@ typedef int (*bind_textops_f)(textops_api_t *); int bind_textops(textops_api_t *); /* - * Function to be called direclty from other modules to load + * Function to be called directly from other modules to load * the textops API. */ inline static int load_textops_api(textops_api_t *tob) diff --git a/src/modules/textops/doc/textops_admin.xml b/src/modules/textops/doc/textops_admin.xml index e30bc39d3..9c121e51c 100644 --- a/src/modules/textops/doc/textops_admin.xml +++ b/src/modules/textops/doc/textops_admin.xml @@ -1068,7 +1068,7 @@ append_urihf("CC-Diversion: ", "\r\n"); The function is also able to distinguish the compact names. For - exmaple From will match with f + example From will match with f. Meaning of the parameters is as follows: @@ -2303,5 +2303,40 @@ msg_apply_changes();
+
+ + <function moreinfo="none">via_param_rm(name, idx)</function> + + + Remove parameter matching by name from Via body at the specified index. + The index starts from 0 (first Via body). Negative index counts from the + end of the list for Via header bodies (-1 is the last Via body). + + Meaning of the parameters is as follows: + + + name - name of the parameter + + + + idx - index of the Via body. + + + + The parameters can also be variables. + + This function can be used from ANY_ROUTE. + + + + <function>via_param_rm</function> usage + +... +via_param_rm("p1", "0"); +... + + +
+ diff --git a/src/modules/textops/textops.c b/src/modules/textops/textops.c index f551c596a..6baf40de6 100644 --- a/src/modules/textops/textops.c +++ b/src/modules/textops/textops.c @@ -169,6 +169,8 @@ static int fixup_search_hf(void **param, int param_no); static int fixup_subst_hf(void **param, int param_no); static int fixup_regex_substring(void **param, int param_no); +static int w_via_param_rm(sip_msg_t *msg, char *pname, char *pidx); + static int mod_init(void); static tr_export_t mod_trans[] = {{{"re", sizeof("re") - 1}, /* regexp class */ @@ -287,6 +289,8 @@ static cmd_export_t cmds[] = { ANY_ROUTE}, {"append_time_to_request", (cmd_function)append_time_request_f, 0, 0, 0, ANY_ROUTE}, + {"via_param_rm", (cmd_function)w_via_param_rm, 2, fixup_spve_igp, + fixup_free_spve_igp, ANY_ROUTE}, {"set_body_multipart", (cmd_function)set_multibody_0, 0, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, @@ -4869,6 +4873,118 @@ static int fixup_subst_hf(void **param, int param_no) return 0; } +/** + * + */ +static int ki_via_param_rm(sip_msg_t *msg, str *name, int idx) +{ + via_body_t *vb; + hdr_field_t *hf = NULL; + int n = 0; + int ret = 0; + via_param_t *vp; + sr_lump_t *l; + char *p; + + if(parse_headers(msg, HDR_EOH_F, 0) < 0) { + LM_DBG("failed to parse sip headers\n"); + return -1; + } + if(msg->h_via1 == NULL) { + LM_WARN("no Via header\n"); + return -1; + } + + if(idx < 0) { + n = 1; + /* count Via header bodies */ + for(hf = msg->h_via1; hf != NULL; hf = hf->next) { + if(hf->type == HDR_VIA_T) { + for(vb = (via_body_t *)hf->parsed; vb != NULL; vb = vb->next) { + n++; + } + } + } + + idx = -idx; + if(idx > n) { + LM_DBG("index out of range\n"); + return -1; + } + idx = n - idx; + } + n = 0; + for(hf = msg->h_via1; hf != NULL; hf = hf->next) { + if(hf->type == HDR_VIA_T) { + for(vb = (via_body_t *)hf->parsed; vb != NULL; vb = vb->next) { + if(n == idx) { + for(vp = vb->param_lst; vp != NULL; vp = vp->next) { + if(vp->name.len == name->len + && strncasecmp(vp->name.s, name->s, name->len) + == 0) { + p = vp->name.s - 1; + while(p >= vb->host.s + vb->host.len && *p != ';') { + p--; + } + if(*p != ';') { + LM_ERR("missing start of via parameters\n"); + return -1; + } + if(vp->value.len > 0) { + if(vp->flags & VIA_PARAM_F_QUOTED) { + l = del_lump(msg, p - msg->buf, + vp->value.s + vp->value.len - p + 1, + 0); + } else { + l = del_lump(msg, p - msg->buf, + vp->value.s + vp->value.len - p, 0); + } + } else { + l = del_lump(msg, p - msg->buf, + vp->name.s + vp->name.len - p, 0); + } + if(l == 0) { + LM_ERR("no memory for delete operation\n"); + return -1; + } + if(ret < 0) { + ret = 1; + } else { + ret++; + } + } + } + if(ret > 0) { + return ret; + } + } + n++; + } + } + } + return ret; +} + +/** + * + */ +static int w_via_param_rm(sip_msg_t *msg, char *pname, char *pidx) +{ + str name = STR_NULL; + int idx = 0; + + if(fixup_get_svalue(msg, (gparam_t *)pname, &name) != 0) { + LM_ERR("cannot get name parameter\n"); + return -2; + } + if(fixup_get_ivalue(msg, (gparam_t *)pidx, &idx) != 0) { + LM_ERR("cannot get name parameter\n"); + return -2; + } + + return ki_via_param_rm(msg, &name, idx); +} + /** * */ diff --git a/src/modules/textopsx/README b/src/modules/textopsx/README index fa03fdf7b..1759870cb 100644 --- a/src/modules/textopsx/README +++ b/src/modules/textopsx/README @@ -320,7 +320,7 @@ if(fnmatch("$rU", "123*")) Meaning of the parameters is as follows: * hf - Header field to be appended. Format: HFNAME [ [IDX] ]. If index is not specified new header is inserted at the end of - message. The index 1 correxponds to the first header. + message. The index 1 corresponds to the first header. * hvalue - Value to be added, config var formatting supported. Example 1.8. append_hf_value usage @@ -341,7 +341,7 @@ ot exists add new header Meaning of the parameters is as follows: * hf - Header field to be appended. Format: HFNAME [ [IDX] ]. If index is not specified new header is inserted at the top of - message. The index 1 correxponds to the first header. + message. The index 1 corresponds to the first header. * hvalue - Value to be added, config var formatting supported. Example 1.9. insert_hf_value usage @@ -359,7 +359,7 @@ insert_hf_value("foo[1]", "gogo") # try add to the first header Meaning of the parameters is as follows: * hf_par - Header field/param to be removed. Format: HFNAME [ [IDX] ] [. PARAM ] If asterisk is specified as index then all values are - affected. The index 1 correxponds to the first header. + affected. The index 1 corresponds to the first header. Example 1.10. remove_hf_value usage ... @@ -379,7 +379,7 @@ remove_hf_value("foo[*].bar") # for each foo delete bar parameters Meaning of the parameters is as follows: * hf_par - Header/param to be removed. Format: HFNAME [ [IDX] ] [. PARAM ] If asterisk is specified as index then all values are - affected. The index 1 correxponds to the first header. + affected. The index 1 corresponds to the first header. Example 1.11. remove_hf_value2 usage ... @@ -398,7 +398,7 @@ remove_hf_value2("foo[*].bar") # for each foo delete bar parameters Meaning of the parameters is as follows: * hf_para - Header field value / param to be appended. Format: HFNAME [ [IDX] ] [. PARAM] If asterisk is specified as index then all - values are affected. The index 1 correxponds to the first header. + values are affected. The index 1 corresponds to the first header. * hvalue - Value to be assigned, config var formatting supported. If value is empty then no equal sign appears in param. @@ -422,7 +422,7 @@ assign_hf_value("foo[*].bar", "") # set empty value (ex. lr) Meaning of the parameters is as follows: * hf_para - Header field value / param to be appended. Format: HFNAME [ [IDX] ] [. PARAM] If asterisk is specified as index then all - values are affected. The index 1 correxponds to the first header. + values are affected. The index 1 corresponds to the first header. * hvalue - Value to be assigned, config var formatting supported. If value is empty then no equal sign appears in param. diff --git a/src/modules/textopsx/api.h b/src/modules/textopsx/api.h index b56e25b70..5d7e3740e 100644 --- a/src/modules/textopsx/api.h +++ b/src/modules/textopsx/api.h @@ -34,7 +34,7 @@ typedef struct textopsx_binds typedef int (*bind_textopsx_f)(textopsx_api_t *); /* - * Function to be called direclty from other modules to load + * Function to be called directly from other modules to load * the textops API. */ inline static int load_textopsx_api(textopsx_api_t *tob) diff --git a/src/modules/textopsx/doc/functions.xml b/src/modules/textopsx/doc/functions.xml index f45252744..b6b509160 100644 --- a/src/modules/textopsx/doc/functions.xml +++ b/src/modules/textopsx/doc/functions.xml @@ -234,7 +234,7 @@ if(fnmatch("$rU", "123*")) hf - Header field to be appended. Format: HFNAME [ [IDX] ]. If index is not specified new header is inserted at the end of message. The index 1 - correxponds to the first header. + corresponds to the first header. @@ -268,7 +268,7 @@ append_hf_value("foo[-1]", "$var(Bar)") # try add value to the last header, if n hf - Header field to be appended. Format: HFNAME [ [IDX] ]. If index is not specified new header is inserted at the top of message. The index 1 - correxponds to the first header. + corresponds to the first header. @@ -300,7 +300,7 @@ insert_hf_value("foo[1]", "gogo") # try add to the first header hf_par - Header field/param to be removed. Format: HFNAME [ [IDX] ] [. PARAM ] If asterisk is specified as index then all values are affected. The index 1 - correxponds to the first header. + corresponds to the first header. @@ -331,7 +331,7 @@ remove_hf_value("foo[*].bar") # for each foo delete bar parameters hf_par - Header/param to be removed. Format: HFNAME [ [IDX] ] [. PARAM ] If asterisk is specified as index then all values are affected. The index 1 - correxponds to the first header. + corresponds to the first header. @@ -362,7 +362,7 @@ remove_hf_value2("foo[*].bar") # for each foo delete bar parameters hf_para - Header field value / param to be appended. Format: HFNAME [ [IDX] ] [. PARAM] If asterisk is specified as index then all values are affected. The index 1 - correxponds to the first header. + corresponds to the first header. @@ -399,7 +399,7 @@ assign_hf_value("foo[*].bar", "") # set empty value (ex. lr) hf_para - Header field value / param to be appended. Format: HFNAME [ [IDX] ] [. PARAM] If asterisk is specified as index then all values are affected. The index 1 - correxponds to the first header. + corresponds to the first header. diff --git a/src/modules/textopsx/textopsx.c b/src/modules/textopsx/textopsx.c index 66fc28441..5710cfeb8 100644 --- a/src/modules/textopsx/textopsx.c +++ b/src/modules/textopsx/textopsx.c @@ -107,96 +107,94 @@ static int pv_parse_bl_iterator_name(pv_spec_t *sp, str *in); static int pv_get_bl_iterator_value( sip_msg_t *msg, pv_param_t *param, pv_value_t *res); -static pv_export_t mod_pvs[] = {{{"hfitname", sizeof("hfitname") - 1}, - PVT_OTHER, pv_get_hf_iterator_hname, 0, - pv_parse_hf_iterator_name, 0, 0, 0}, - {{"hfitbody", sizeof("hfitbody") - 1}, PVT_OTHER, - pv_get_hf_iterator_hbody, 0, pv_parse_hf_iterator_name, 0, 0, - 0}, - {{"blitval", sizeof("blitval") - 1}, PVT_OTHER, - pv_get_bl_iterator_value, 0, pv_parse_bl_iterator_name, 0, 0, - 0}, - {{0, 0}, 0, 0, 0, 0, 0, 0, 0}}; +/* clang-format off */ +static pv_export_t mod_pvs[] = { + {{"hfitname", sizeof("hfitname") - 1}, PVT_OTHER, + pv_get_hf_iterator_hname, 0, pv_parse_hf_iterator_name, 0, 0, 0}, + {{"hfitbody", sizeof("hfitbody") - 1}, PVT_OTHER, + pv_get_hf_iterator_hbody, 0, pv_parse_hf_iterator_name, 0, 0, 0}, + {{"blitval", sizeof("blitval") - 1}, PVT_OTHER, + pv_get_bl_iterator_value, 0, pv_parse_bl_iterator_name, 0, 0, 0}, + {{0, 0}, 0, 0, 0, 0, 0, 0, 0} +}; /* cfg functions */ -/* clag-format off */ static cmd_export_t cmds[] = { - {"msg_apply_changes", (cmd_function)msg_apply_changes_f, 0, 0, 0, - REQUEST_ROUTE | ONREPLY_ROUTE}, - {"msg_set_buffer", (cmd_function)msg_set_buffer_f, 1, fixup_spve_null, - fixup_free_spve_null, REQUEST_ROUTE | ONREPLY_ROUTE}, - {"change_reply_status", change_reply_status_f, 2, - change_reply_status_fixup, 0, ONREPLY_ROUTE}, - {"change_reply_status_code", change_reply_status_code_f, 1, - fixup_igp_null, 0, ONREPLY_ROUTE}, - {"remove_body", (cmd_function)w_remove_body_f, 0, 0, 0, ANY_ROUTE}, - {"keep_hf", (cmd_function)w_keep_hf_f, 0, fixup_regexp_null, 0, - ANY_ROUTE}, - {"keep_hf", (cmd_function)w_keep_hf_f, 1, fixup_regexp_null, 0, - ANY_ROUTE}, - {"fnmatch", (cmd_function)w_fnmatch2_f, 2, fixup_fnmatch, 0, ANY_ROUTE}, - {"fnmatch", (cmd_function)w_fnmatch3_f, 3, fixup_fnmatch, 0, ANY_ROUTE}, - {"append_hf_value", insupddel_hf_value_f, 2, append_hf_value_fixup, 0, - REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, - {"insert_hf_value", insupddel_hf_value_f, 2, insert_hf_value_fixup, 0, - REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, - {"remove_hf_value", insupddel_hf_value_f, 1, remove_hf_value_fixup, 0, - REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, - {"assign_hf_value", insupddel_hf_value_f, 2, assign_hf_value_fixup, 0, - REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, - {"remove_hf_value2", insupddel_hf_value_f, 1, remove_hf_value2_fixup, 0, - REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, - {"assign_hf_value2", insupddel_hf_value_f, 2, assign_hf_value2_fixup, 0, - REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, - {"include_hf_value", incexc_hf_value_f, 2, include_hf_value_fixup, 0, - REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, - {"exclude_hf_value", incexc_hf_value_f, 2, exclude_hf_value_fixup, 0, - REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, - {"hf_value_exists", incexc_hf_value_f, 2, hf_value_exists_fixup, 0, - REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, - {"hf_iterator_start", w_hf_iterator_start, 1, fixup_spve_null, - fixup_free_spve_null, ANY_ROUTE}, - {"hf_iterator_next", w_hf_iterator_next, 1, fixup_spve_null, - fixup_free_spve_null, ANY_ROUTE}, - {"hf_iterator_prev", w_hf_iterator_prev, 1, fixup_spve_null, - fixup_free_spve_null, ANY_ROUTE}, - {"hf_iterator_end", w_hf_iterator_end, 1, fixup_spve_null, - fixup_free_spve_null, ANY_ROUTE}, - {"hf_iterator_rm", w_hf_iterator_rm, 1, fixup_spve_null, - fixup_free_spve_null, ANY_ROUTE}, - {"hf_iterator_append", w_hf_iterator_append, 2, fixup_spve_spve, - fixup_free_spve_spve, ANY_ROUTE}, - {"hf_iterator_insert", w_hf_iterator_insert, 2, fixup_spve_spve, - fixup_free_spve_spve, ANY_ROUTE}, - {"bl_iterator_start", w_bl_iterator_start, 1, fixup_spve_null, - fixup_free_spve_null, ANY_ROUTE}, - {"bl_iterator_next", w_bl_iterator_next, 1, fixup_spve_null, - fixup_free_spve_null, ANY_ROUTE}, - {"bl_iterator_end", w_bl_iterator_end, 1, fixup_spve_null, - fixup_free_spve_null, ANY_ROUTE}, - {"bl_iterator_rm", w_bl_iterator_rm, 1, fixup_spve_null, - fixup_free_spve_null, ANY_ROUTE}, - {"bl_iterator_append", w_bl_iterator_append, 2, fixup_spve_spve, - fixup_free_spve_spve, ANY_ROUTE}, - {"bl_iterator_insert", w_bl_iterator_insert, 2, fixup_spve_spve, - fixup_free_spve_spve, ANY_ROUTE}, - - {"bind_textopsx", (cmd_function)bind_textopsx, 1, 0, 0, ANY_ROUTE}, - - {0, 0, 0, 0, 0, 0}}; + {"msg_apply_changes", (cmd_function)msg_apply_changes_f, 0, 0, 0, + REQUEST_ROUTE | ONREPLY_ROUTE}, + {"msg_set_buffer", (cmd_function)msg_set_buffer_f, 1, fixup_spve_null, + fixup_free_spve_null, REQUEST_ROUTE | ONREPLY_ROUTE}, + {"change_reply_status", change_reply_status_f, 2, + change_reply_status_fixup, 0, ONREPLY_ROUTE}, + {"change_reply_status_code", change_reply_status_code_f, 1, + fixup_igp_null, 0, ONREPLY_ROUTE}, + {"remove_body", (cmd_function)w_remove_body_f, 0, 0, 0, ANY_ROUTE}, + {"keep_hf", (cmd_function)w_keep_hf_f, 0, fixup_regexp_null, 0, ANY_ROUTE}, + {"keep_hf", (cmd_function)w_keep_hf_f, 1, fixup_regexp_null, 0, ANY_ROUTE}, + {"fnmatch", (cmd_function)w_fnmatch2_f, 2, fixup_fnmatch, 0, ANY_ROUTE}, + {"fnmatch", (cmd_function)w_fnmatch3_f, 3, fixup_fnmatch, 0, ANY_ROUTE}, + {"append_hf_value", insupddel_hf_value_f, 2, append_hf_value_fixup, 0, + REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, + {"insert_hf_value", insupddel_hf_value_f, 2, insert_hf_value_fixup, 0, + REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, + {"remove_hf_value", insupddel_hf_value_f, 1, remove_hf_value_fixup, 0, + REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, + {"assign_hf_value", insupddel_hf_value_f, 2, assign_hf_value_fixup, 0, + REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, + {"remove_hf_value2", insupddel_hf_value_f, 1, remove_hf_value2_fixup, 0, + REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, + {"assign_hf_value2", insupddel_hf_value_f, 2, assign_hf_value2_fixup, 0, + REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, + {"include_hf_value", incexc_hf_value_f, 2, include_hf_value_fixup, 0, + REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, + {"exclude_hf_value", incexc_hf_value_f, 2, exclude_hf_value_fixup, 0, + REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, + {"hf_value_exists", incexc_hf_value_f, 2, hf_value_exists_fixup, 0, + REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, + {"hf_iterator_start", w_hf_iterator_start, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"hf_iterator_next", w_hf_iterator_next, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"hf_iterator_prev", w_hf_iterator_prev, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"hf_iterator_end", w_hf_iterator_end, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"hf_iterator_rm", w_hf_iterator_rm, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"hf_iterator_append", w_hf_iterator_append, 2, fixup_spve_spve, + fixup_free_spve_spve, ANY_ROUTE}, + {"hf_iterator_insert", w_hf_iterator_insert, 2, fixup_spve_spve, + fixup_free_spve_spve, ANY_ROUTE}, + {"bl_iterator_start", w_bl_iterator_start, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"bl_iterator_next", w_bl_iterator_next, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"bl_iterator_end", w_bl_iterator_end, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"bl_iterator_rm", w_bl_iterator_rm, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + {"bl_iterator_append", w_bl_iterator_append, 2, fixup_spve_spve, + fixup_free_spve_spve, ANY_ROUTE}, + {"bl_iterator_insert", w_bl_iterator_insert, 2, fixup_spve_spve, + fixup_free_spve_spve, ANY_ROUTE}, + + {"bind_textopsx", (cmd_function)bind_textopsx, 1, 0, 0, ANY_ROUTE}, + + {0, 0, 0, 0, 0, 0} +}; /* module exports structure */ struct module_exports exports = { - "textopsx", /* module name */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* exported cfg functions */ - 0, /* exported cfg parameters */ - 0, /* exported RPC methods */ - mod_pvs, /* exported pseudo-variables */ - 0, /* response handling function */ - mod_init, /* module init function */ - 0, /* per-child init function */ - 0, /* destroy function */ + "textopsx", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* exported cfg functions */ + 0, /* exported cfg parameters */ + 0, /* exported RPC methods */ + mod_pvs, /* exported pseudo-variables */ + 0, /* response handling function */ + mod_init, /* module init function */ + 0, /* per-child init function */ + 0, /* destroy function */ }; /* clag-format on */ @@ -1213,7 +1211,7 @@ static int delete_value_lump( struct lump *l; /* TODO: check already existing lumps */ if(hf && val->s == hf->body.s - && val->len == hf->body.len) /* check if remove whole haeder? */ + && val->len == hf->body.len) /* check if remove whole header? */ l = del_lump(msg, hf->name.s - msg->buf, hf->len, 0); else l = del_lump(msg, val->s - msg->buf, val->len, 0); @@ -2443,7 +2441,7 @@ static int pv_get_hf_iterator_hbody( typedef struct bl_iterator { str name; - char bname[HF_ITERATOR_NAME_SIZE]; + char bname[BL_ITERATOR_NAME_SIZE]; str body; str it; int eob; diff --git a/src/modules/timer/timer.c b/src/modules/timer/timer.c index a77414966..2f3f1b1bf 100644 --- a/src/modules/timer/timer.c +++ b/src/modules/timer/timer.c @@ -88,12 +88,12 @@ static timer_action_t *timer_executed = 0; } static timer_action_t *find_action_by_name( - timer_action_t *timer_actions, char *name, int len) + timer_action_t *timer_actions_list, char *name, int len) { timer_action_t *a; if(len == -1) len = strlen(name); - for(a = timer_actions; a; a = a->next) { + for(a = timer_actions_list; a; a = a->next) { if(a->timer_name && strlen(a->timer_name) == len && strncmp(name, a->timer_name, len) == 0) return a; diff --git a/src/modules/tls/Makefile b/src/modules/tls/Makefile index 9112150b8..3f1df2e8c 100644 --- a/src/modules/tls/Makefile +++ b/src/modules/tls/Makefile @@ -72,8 +72,6 @@ LIBS+= $(TLS_EXTRA_LIBS) -lpthread # dcm: tls.cfg installed via local 'install-cfg' to update paths #MOD_INSTALL_CFGS=tls.cfg -MOD_INSTALL_UTILS=utils/openssl_mutex_shared - include ../../Makefile.modules install-tls-cert: $(cfg_prefix)/$(cfg_dir) diff --git a/src/modules/tls/README b/src/modules/tls/README index a5897da4f..d98f94eb8 100644 --- a/src/modules/tls/README +++ b/src/modules/tls/README @@ -81,7 +81,8 @@ Olle E. Johansson 12.1. tls.info 12.2. tls.list 12.3. tls.options - 12.4. tls.reload + 12.4. tls.kill + 12.5. tls.reload 13. Status @@ -213,7 +214,8 @@ Chapter 1. Admin Guide 12.1. tls.info 12.2. tls.list 12.3. tls.options - 12.4. tls.reload + 12.4. tls.kill + 12.5. tls.reload 13. Status @@ -261,8 +263,9 @@ Chapter 1. Admin Guide profiles of tls.cfg file. When installing tls module of kamailio, a sample 'tls.cfg' file is - deployed in the same folder with 'kamailio.cfg', along with freshly - generated self signed certificates. + deployed in the same folder with 'kamailio.cfg'. For freshly generated + self signed certificates make must be called from tls folder +make install-tls-cert HINT: be sure you have enable_tls=yes to your kamailio.cfg. @@ -297,10 +300,6 @@ request_route { options, run kamailio -V and look for USE_TLS and TLS_HOOKS among the flags. - For OpenSSL (libssl) v1.1.x, it is required to preload - 'openssl_mutex_shared' library shipped by Kamailio. For more details - see 'src/modules/tls/utils/openssl_mutex_shared/README.md'. - This module includes several workarounds for various Openssl bugs (like compression and Kerberos using the wrong memory allocations functions, low memory problems a.s.o). On startup it will try to enable the needed @@ -404,9 +403,6 @@ make -C modules/tls extra_defs="-DTLS_WR_DEBUG -DTLS_RD_DEBUG" standard conforming (the verification should happen during TLS connection establishment and not after). - TLS specific config reloading is not safe, so for now better don't use - it, especially under heavy traffic. - This documentation is incomplete. The provided selects are not documented in this file. A list with all the ones implemented by the TLS module can be found in the Cookbook @@ -678,11 +674,12 @@ Place holder If RFC 3261 conformance is desired, at least TLSv1 must be used. For compatibility with older clients SSLv23 is the option, but again, be - aware of security concerns, SSLv2/3 being considered very insecure by - 2014. For current information about what's considered secure, please - consult, IETF BCP 195, currently RFC 7525 - "Recommendations for Secure - Use of Transport Layer Security (TLS) and Datagram Transport Layer - Security (DTLS)" + aware of security concerns, SSLv2/3 as well as TLS v1.0 and v1.1 are + being considered very insecure and are therefore deprecated since March + 2021 (RFC 8996). For current information about what's considered + secure, please consult, IETF BCP 195, currently RFC 9325 - + "Recommendations for Secure Use of Transport Layer Security (TLS) and + Datagram Transport Layer Security (DTLS)" Example 1.3. Set tls_method parameter ... @@ -1645,7 +1642,8 @@ verify_client = optional_no_ca 12.1. tls.info 12.2. tls.list 12.3. tls.options - 12.4. tls.reload + 12.4. tls.kill + 12.5. tls.reload 12.1. tls.info @@ -1669,13 +1667,24 @@ verify_client = optional_no_ca Parameters: * None. -12.4. tls.reload +12.4. tls.kill + + Kill a TLS session by id. + + Parameters: + * None. + +12.5. tls.reload Reload the external TLS configuration file (aka tls.cfg). It does not reload modparam() parameters. Note that existing active TLS connections are not terminated and they continue to use the old certificates. The new configuration will be used for new connections. + Reload is generally safe and usable in production environments. If + possible should be done in a time where the service has lower + usage/connections. + This RPC command is exported with "RPC_EXEC_DELTA" flag, therefore its execution rate can be restricted to specific time intervals by setting the "rpc_exec_delta" core parameter. diff --git a/src/modules/tls/doc/params.xml b/src/modules/tls/doc/params.xml index 1c7eb768a..fa14216a4 100644 --- a/src/modules/tls/doc/params.xml +++ b/src/modules/tls/doc/params.xml @@ -105,9 +105,10 @@ If RFC 3261 conformance is desired, at least TLSv1 must be used. For compatibility with older clients SSLv23 is the option, but again, be aware - of security concerns, SSLv2/3 being considered very insecure by 2014. + of security concerns, SSLv2/3 as well as TLS v1.0 and v1.1 are being considered very insecure + and are therefore deprecated since March 2021 (RFC 8996). For current information about what's considered secure, please consult, - IETF BCP 195, currently RFC 7525 - "Recommendations for Secure Use of + IETF BCP 195, currently RFC 9325 - "Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS)" diff --git a/src/modules/tls/doc/rpc.xml b/src/modules/tls/doc/rpc.xml index 30c67d5c8..d9e75b014 100644 --- a/src/modules/tls/doc/rpc.xml +++ b/src/modules/tls/doc/rpc.xml @@ -50,6 +50,18 @@
+
+ <function>tls.kill</function> + + Kill a TLS session by id. + + Parameters: + + + None. + + +
<function>tls.reload</function> @@ -58,6 +70,10 @@ terminated and they continue to use the old certificates. The new configuration will be used for new connections. + + Reload is generally safe and usable in production environments. If possible should + be done in a time where the service has lower usage/connections. + This RPC command is exported with "RPC_EXEC_DELTA" flag, therefore its execution rate can be restricted to specific time intervals by setting diff --git a/src/modules/tls/doc/tls.xml b/src/modules/tls/doc/tls.xml index a8d5dca02..569779265 100644 --- a/src/modules/tls/doc/tls.xml +++ b/src/modules/tls/doc/tls.xml @@ -93,7 +93,10 @@ When installing tls module of kamailio, a sample 'tls.cfg' file is deployed in the same - folder with 'kamailio.cfg', along with freshly generated self signed certificates. + folder with 'kamailio.cfg'. For freshly generated self signed certificates make must be called from tls folder + +make install-tls-cert + HINT: be sure you have enable_tls=yes to your kamailio.cfg. @@ -135,11 +138,6 @@ request_route { To quickly check if your Kamailio version was compiled with these options, run kamailio -V and look for USE_TLS and TLS_HOOKS among the flags. - - For OpenSSL (libssl) v1.1.x, it is required to preload - 'openssl_mutex_shared' library shipped by &kamailio;. For more details - see 'src/modules/tls/utils/openssl_mutex_shared/README.md'. - This module includes several workarounds for various Openssl bugs (like compression and Kerberos using the wrong memory allocations @@ -289,10 +287,6 @@ make -C modules/tls extra_defs="-DTLS_WR_DEBUG -DTLS_RD_DEBUG" but also not exactly standard conforming (the verification should happen during TLS connection establishment and not after). - - TLS specific config reloading is not safe, so for now better don't use it, - especially under heavy traffic. - This documentation is incomplete. The provided selects are not documented in this file. A list with all the @@ -369,4 +363,3 @@ event_route[tls:connection-out] {
- diff --git a/src/modules/tls/tls_domain.c b/src/modules/tls/tls_domain.c index 4e35f91f8..e056a70b5 100644 --- a/src/modules/tls/tls_domain.c +++ b/src/modules/tls/tls_domain.c @@ -30,13 +30,21 @@ #include #include -#if OPENSSL_VERSION_NUMBER >= 0x030000000L -#define OPENSSL_NO_ENGINE +/* only OpenSSL <= 1.1.1 */ +#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_VERSION_NUMBER < 0x030000000L +#define KSR_SSL_COMMON +#define KSR_SSL_ENGINE +#define KEY_PREFIX "/engine:" +#define KEY_PREFIX_LEN (strlen(KEY_PREFIX)) +#include +extern EVP_PKEY *tls_engine_private_key(const char *key_id); #endif -#ifndef OPENSSL_NO_ENGINE -#include -#include "tls_map.h" +#if !defined(OPENSSL_NO_PROVIDER) && OPENSSL_VERSION_NUMBER >= 0x030000000L +#define KSR_SSL_COMMON +#define KSR_SSL_PROVIDER +#define KEY_PREFIX "/uri:" +#define KEY_PREFIX_LEN (strlen(KEY_PREFIX)) extern EVP_PKEY *tls_engine_private_key(const char *key_id); #endif @@ -1227,32 +1235,7 @@ err: #endif } -#ifndef OPENSSL_NO_ENGINE -/* - * Implement a hash map from SSL_CTX to private key - * as HSM keys need to be process local - */ -static map_void_t private_key_map; - -/** - * @brief Return a private key from the lookup table - * @param p SSL_CTX* - * @return EVP_PKEY on success, NULL on error - */ -EVP_PKEY *tls_lookup_private_key(SSL_CTX *ctx) -{ - void *pkey; - char ctx_str[64]; - snprintf(ctx_str, 64, "SSL_CTX-%p", ctx); - pkey = map_get(&private_key_map, ctx_str); - LM_DBG("Private key lookup for %s: %p\n", ctx_str, pkey); - if(pkey) - return *(EVP_PKEY **)pkey; - else - return NULL; -} - - +#ifdef KSR_SSL_COMMON /** * @brief Load a private key from an OpenSSL engine * @param d TLS domain @@ -1262,7 +1245,7 @@ EVP_PKEY *tls_lookup_private_key(SSL_CTX *ctx) * to be fork() safe * * private_key setting which starts with /engine: is assumed to be - * an HSM key and not a file-based key + * an HSM key and not a file-based key (/uri: for OpenSSL 3 key URIs) * * We store the private key in a local memory hash table as * HSM keys must be process-local. We use the SSL_CTX* address @@ -1273,31 +1256,22 @@ static int load_engine_private_key(tls_domain_t *d) { int idx, ret_pwd, i; EVP_PKEY *pkey = 0; - int procs_no; - char ctx_str[64]; if(!d->pkey_file.s || !d->pkey_file.len) { DBG("%s: No private key specified\n", tls_domain_str(d)); return 0; } - if(strncmp(d->pkey_file.s, "/engine:", 8) != 0) + if(strncmp(d->pkey_file.s, KEY_PREFIX, KEY_PREFIX_LEN) != 0) return 0; - procs_no = get_max_procs(); - for(i = 0; i < procs_no; i++) { - snprintf(ctx_str, 64, "SSL_CTX-%p", d->ctx[i]); + + do { + i = process_no; for(idx = 0, ret_pwd = 0; idx < 3; idx++) { - if(i) { - map_set(&private_key_map, ctx_str, pkey); - ret_pwd = 1; + pkey = tls_engine_private_key(d->pkey_file.s + KEY_PREFIX_LEN); + if(pkey) { + ret_pwd = SSL_CTX_use_PrivateKey(d->ctx[i], pkey); } else { - pkey = tls_engine_private_key(d->pkey_file.s + 8); - if(pkey) { - map_set(&private_key_map, ctx_str, pkey); - // store the key for i = 0 to perform certificate sanity check - ret_pwd = SSL_CTX_use_PrivateKey(d->ctx[i], pkey); - } else { - ret_pwd = 0; - } + ret_pwd = 0; } if(ret_pwd) { break; @@ -1315,21 +1289,21 @@ static int load_engine_private_key(tls_domain_t *d) TLS_ERR("load_private_key:"); return -1; } - if(i == 0 && !SSL_CTX_check_private_key(d->ctx[i])) { + if(!SSL_CTX_check_private_key(d->ctx[i])) { ERR("%s: Key '%s' does not match the public key of the" " certificate\n", tls_domain_str(d), d->pkey_file.s); TLS_ERR("load_engine_private_key:"); return -1; } - } + } while(0); LM_INFO("%s: Key '%s' successfully loaded\n", tls_domain_str(d), d->pkey_file.s); return 0; } -#endif +#endif /* KSR_SSL_COMMON */ /** * @brief Load a private key from a file * @param d TLS domain @@ -1353,10 +1327,10 @@ static int load_private_key(tls_domain_t *d) SSL_CTX_set_default_passwd_cb_userdata(d->ctx[i], d->pkey_file.s); for(idx = 0, ret_pwd = 0; idx < 3; idx++) { -#ifndef OPENSSL_NO_ENGINE +#ifdef KSR_SSL_COMMON // in PROC_INIT skip loading HSM keys due to // fork() issues with PKCS#11 libraries - if(strncmp(d->pkey_file.s, "/engine:", 8) != 0) { + if(strncmp(d->pkey_file.s, KEY_PREFIX, KEY_PREFIX_LEN) != 0) { ret_pwd = SSL_CTX_use_PrivateKey_file( d->ctx[i], d->pkey_file.s, SSL_FILETYPE_PEM); } else { @@ -1365,7 +1339,7 @@ static int load_private_key(tls_domain_t *d) #else ret_pwd = SSL_CTX_use_PrivateKey_file( d->ctx[i], d->pkey_file.s, SSL_FILETYPE_PEM); -#endif +#endif /* KSR_SSL_COMMON */ if(ret_pwd) { break; } else { @@ -1382,12 +1356,12 @@ static int load_private_key(tls_domain_t *d) TLS_ERR("load_private_key:"); return -1; } -#ifndef OPENSSL_NO_ENGINE - if(strncmp(d->pkey_file.s, "/engine:", 8) == 0) { +#ifdef KSR_SSL_COMMON + if(strncmp(d->pkey_file.s, KEY_PREFIX, KEY_PREFIX_LEN) == 0) { // skip private key validity check for HSM keys continue; } -#endif +#endif /* KSR_SSL_COMMON */ if(!SSL_CTX_check_private_key(d->ctx[i])) { ERR("%s: Key '%s' does not match the public key of the" " certificate\n", @@ -1403,7 +1377,7 @@ static int load_private_key(tls_domain_t *d) } -#ifndef OPENSSL_NO_ENGINE +#ifdef KSR_SSL_COMMON /** * @brief Initialize engine private keys * @@ -1435,7 +1409,7 @@ int tls_fix_engine_keys(tls_domains_cfg_t *cfg, tls_domain_t *srv_defaults, return 0; } -#endif +#endif /* KSR_SSL_COMMON */ /** * @brief Initialize attributes of all domains from default domains if necessary * diff --git a/src/modules/tls/tls_init.c b/src/modules/tls/tls_init.c index 1c6b19f56..6992d4a65 100644 --- a/src/modules/tls/tls_init.c +++ b/src/modules/tls/tls_init.c @@ -269,14 +269,13 @@ static void *ser_malloc(size_t size, const char *file, int line) #endif s = backtrace2str(bt_buf, sizeof(bt_buf)); /* ugly hack: keep the bt inside the alloc'ed fragment */ - p = _shm_malloc(size + s, file, "via ser_malloc", line); + p = shm_mallocxp(size + s, file, "ser_malloc", line, "tls"); if(p == 0) { - LM_CRIT("tls - ser_malloc(%d)[%s:%d]==null, bt: %s\n", size, file, + LM_CRIT("tls - ser_malloc(%lu)[%s:%d]==null, bt: %s\n", size, file, line, bt_buf); } else { memcpy(p + size, bt_buf, s); - ((struct qm_frag *)((char *)p - sizeof(struct qm_frag)))->func = - p + size; + shm_setfunc(p, p + size); } #ifdef RAND_NULL_MALLOC } else { @@ -308,14 +307,13 @@ static void *ser_realloc(void *ptr, size_t size, const char *file, int line) || (random() % RAND_NULL_MALLOC)) { #endif s = backtrace2str(bt_buf, sizeof(bt_buf)); - p = _shm_realloc(ptr, size + s, file, "via ser_realloc", line); + p = shm_reallocxp(ptr, size + s, file, "ser_realloc", line, "tls"); if(p == 0) { - LM_CRIT("tls - ser_realloc(%p, %d)[%s:%d]==null, bt: %s\n", ptr, + LM_CRIT("tls - ser_realloc(%p, %lu)[%s:%d]==null, bt: %s\n", ptr, size, file, line, bt_buf); } else { memcpy(p + size, bt_buf, s); - ((struct qm_frag *)((char *)p - sizeof(struct qm_frag)))->func = - p + size; + shm_setfunc(p, p + size); } #ifdef RAND_NULL_MALLOC } else { @@ -700,7 +698,11 @@ int tls_pre_init(void) rf = NULL; ff = NULL; #ifdef TLS_MALLOC_DBG +#if OPENSSL_VERSION_NUMBER < 0x010100000L if(!CRYPTO_set_mem_ex_functions(ser_malloc, ser_realloc, ser_free)) { +#else + if(!CRYPTO_set_mem_functions(ser_malloc, ser_realloc, ser_free)) { +#endif #else if(!CRYPTO_set_mem_functions(ser_malloc, ser_realloc, ser_free)) { #endif diff --git a/src/modules/tls/tls_map.c b/src/modules/tls/tls_map.c deleted file mode 100644 index 70c275d31..000000000 --- a/src/modules/tls/tls_map.c +++ /dev/null @@ -1,213 +0,0 @@ -/** - * Copyright (c) 2014 rxi - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MIT license. See LICENSE for details. - */ - -#include -#include - -#include "../../core/mem/mem.h" -#include "tls_map.h" - -struct map_node_t -{ - unsigned hash; - void *value; - map_node_t *next; - /* char key[]; */ - /* char value[]; */ -}; - - -static unsigned map_hash(const char *str) -{ - unsigned hash = 5381; - while(*str) { - hash = ((hash << 5) + hash) ^ *str++; - } - return hash; -} - - -static map_node_t *map_newnode(const char *key, void *value, int vsize) -{ - map_node_t *node; - int ksize = strlen(key) + 1; - int voffset = ksize + ((sizeof(void *) - ksize) % sizeof(void *)); - node = pkg_malloc(sizeof(*node) + voffset + vsize); - if(!node) - return NULL; - memcpy(node + 1, key, ksize); - node->hash = map_hash(key); - node->value = ((char *)(node + 1)) + voffset; - memcpy(node->value, value, vsize); - return node; -} - - -static int map_bucketidx(map_base_t *m, unsigned hash) -{ - /* If the implementation is changed to allow a non-power-of-2 bucket count, - * the line below should be changed to use mod instead of AND */ - return hash & (m->nbuckets - 1); -} - - -static void map_addnode(map_base_t *m, map_node_t *node) -{ - int n = map_bucketidx(m, node->hash); - node->next = m->buckets[n]; - m->buckets[n] = node; -} - - -static int map_resize(map_base_t *m, int nbuckets) -{ - map_node_t *nodes, *node, *next; - map_node_t **buckets; - int i; - /* Chain all nodes together */ - nodes = NULL; - i = m->nbuckets; - while(i--) { - node = (m->buckets)[i]; - while(node) { - next = node->next; - node->next = nodes; - nodes = node; - node = next; - } - } - /* Reset buckets */ - buckets = realloc(m->buckets, sizeof(*m->buckets) * nbuckets); - if(buckets != NULL) { - m->buckets = buckets; - m->nbuckets = nbuckets; - } - if(m->buckets) { - memset(m->buckets, 0, sizeof(*m->buckets) * m->nbuckets); - /* Re-add nodes to buckets */ - node = nodes; - while(node) { - next = node->next; - map_addnode(m, node); - node = next; - } - } - /* Return error code if realloc() failed */ - return (buckets == NULL) ? -1 : 0; -} - - -static map_node_t **map_getref(map_base_t *m, const char *key) -{ - unsigned hash = map_hash(key); - map_node_t **next; - if(m->nbuckets > 0) { - next = &m->buckets[map_bucketidx(m, hash)]; - while(*next) { - if((*next)->hash == hash && !strcmp((char *)(*next + 1), key)) { - return next; - } - next = &(*next)->next; - } - } - return NULL; -} - - -void map_deinit_(map_base_t *m) -{ - map_node_t *next, *node; - int i; - i = m->nbuckets; - while(i--) { - node = m->buckets[i]; - while(node) { - next = node->next; - pkg_free(node); - node = next; - } - } - pkg_free(m->buckets); -} - - -void *map_get_(map_base_t *m, const char *key) -{ - map_node_t **next = map_getref(m, key); - return next ? (*next)->value : NULL; -} - - -int map_set_(map_base_t *m, const char *key, void *value, int vsize) -{ - int n, err; - map_node_t **next, *node; - /* Find & replace existing node */ - next = map_getref(m, key); - if(next) { - memcpy((*next)->value, value, vsize); - return 0; - } - /* Add new node */ - node = map_newnode(key, value, vsize); - if(node == NULL) - goto fail; - if(m->nnodes >= m->nbuckets) { - n = (m->nbuckets > 0) ? (m->nbuckets << 1) : 1; - err = map_resize(m, n); - if(err) - goto fail; - } - map_addnode(m, node); - m->nnodes++; - return 0; -fail: - if(node) - pkg_free(node); - return -1; -} - - -void map_remove_(map_base_t *m, const char *key) -{ - map_node_t *node; - map_node_t **next = map_getref(m, key); - if(next) { - node = *next; - *next = (*next)->next; - pkg_free(node); - m->nnodes--; - } -} - - -map_iter_t map_iter_(void) -{ - map_iter_t iter; - iter.bucketidx = -1; - iter.node = NULL; - return iter; -} - - -const char *map_next_(map_base_t *m, map_iter_t *iter) -{ - if(iter->node) { - iter->node = iter->node->next; - if(iter->node == NULL) - goto nextBucket; - } else { - nextBucket: - do { - if(++iter->bucketidx >= m->nbuckets) { - return NULL; - } - iter->node = m->buckets[iter->bucketidx]; - } while(iter->node == NULL); - } - return (char *)(iter->node + 1); -} diff --git a/src/modules/tls/tls_map.h b/src/modules/tls/tls_map.h deleted file mode 100644 index e4028a302..000000000 --- a/src/modules/tls/tls_map.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Copyright (c) 2014 rxi - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MIT license. See LICENSE for details. - */ - -#ifndef _TLS_MAP_H -#define _TLS_MAP_H - -#include - -#define MAP_VERSION "0.1.0" - -struct map_node_t; -typedef struct map_node_t map_node_t; - -typedef struct -{ - map_node_t **buckets; - unsigned nbuckets, nnodes; -} map_base_t; - -typedef struct -{ - unsigned bucketidx; - map_node_t *node; -} map_iter_t; - - -#define map_t(T) \ - struct \ - { \ - map_base_t base; \ - T *ref; \ - T tmp; \ - } - - -#define map_init(m) memset(m, 0, sizeof(*(m))) - - -#define map_deinit(m) map_deinit_(&(m)->base) - - -#define map_get(m, key) ((m)->ref = map_get_(&(m)->base, key)) - - -#define map_set(m, key, value) \ - ((m)->tmp = (value), map_set_(&(m)->base, key, &(m)->tmp, sizeof((m)->tmp))) - - -#define map_remove(m, key) map_remove_(&(m)->base, key) - - -#define map_iter(m) map_iter_() - - -#define map_next(m, iter) map_next_(&(m)->base, iter) - - -void map_deinit_(map_base_t *m); -void *map_get_(map_base_t *m, const char *key); -int map_set_(map_base_t *m, const char *key, void *value, int vsize); -void map_remove_(map_base_t *m, const char *key); -map_iter_t map_iter_(void); -const char *map_next_(map_base_t *m, map_iter_t *iter); - - -typedef map_t(void *) map_void_t; -typedef map_t(char *) map_str_t; -typedef map_t(int) map_int_t; -typedef map_t(char) map_char_t; -typedef map_t(float) map_float_t; -typedef map_t(double) map_double_t; - -#endif /* _TLS_MAP_H */ diff --git a/src/modules/tls/tls_mod.c b/src/modules/tls/tls_mod.c index beaf1b7b7..83b86d99d 100644 --- a/src/modules/tls/tls_mod.c +++ b/src/modules/tls/tls_mod.c @@ -42,6 +42,10 @@ #include "../../core/dprint.h" #include "../../core/mod_fix.h" #include "../../core/kemi.h" + +#define KSR_RTHREAD_SKIP_P +#define KSR_RTHREAD_NEED_4PP +#include "../../core/rthreads.h" #include "tls_init.h" #include "tls_server.h" #include "tls_domain.h" @@ -87,10 +91,23 @@ int ksr_rand_engine_param(modparam_t type, void *val); MODULE_VERSION -#if OPENSSL_VERSION_NUMBER >= 0x030000000L -#define OPENSSL_NO_ENGINE +/* Engine is deprecated in OpenSSL 3 */ +#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_VERSION_NUMBER < 0x030000000L +#define KSR_SSL_COMMON +#define KSR_SSL_ENGINE +#define KEY_PREFIX "/engine:" +#define KEY_PREFIX_LEN (strlen(KEY_PREFIX)) +#endif + +#if !defined(OPENSSL_NO_PROVIDER) && OPENSSL_VERSION_NUMBER >= 0x030000000L +#define KSR_SSL_COMMON +#define KSR_SSL_PROVIDER +#include +#define KEY_PREFIX "/uri:" +#define KEY_PREFIX_LEN (strlen(KEY_PREFIX)) #endif + extern str sr_tls_event_callback; str sr_tls_xavp_cfg = {0, 0}; /* @@ -145,24 +162,29 @@ tls_domain_t srv_defaults = { }; -#ifndef OPENSSL_NO_ENGINE - +#ifdef KSR_SSL_ENGINE typedef struct tls_engine { str engine; str engine_config; str engine_algorithms; } tls_engine_t; -#include -#include - -static ENGINE *ksr_tls_engine; static tls_engine_t tls_engine_settings = { STR_STATIC_INIT("NONE"), STR_STATIC_INIT("NONE"), STR_STATIC_INIT("ALL"), }; -#endif /* OPENSSL_NO_ENGINE */ + +#include +#include + +static ENGINE *ksr_tls_engine; +#endif + +#ifdef KSR_SSL_PROVIDER +static int tls_provider_quirks; +#endif + /* * Default settings for client domains when using external config file */ @@ -227,12 +249,16 @@ static param_export_t params[] = { {"crl", PARAM_STR, &default_tls_cfg.crl}, {"cipher_list", PARAM_STR, &default_tls_cfg.cipher_list}, {"connection_timeout", PARAM_INT, &default_tls_cfg.con_lifetime}, -#ifndef OPENSSL_NO_ENGINE +#ifdef KSR_SSL_ENGINE {"engine", PARAM_STR, &tls_engine_settings.engine}, {"engine_config", PARAM_STR, &tls_engine_settings.engine_config}, {"engine_algorithms", PARAM_STR, &tls_engine_settings.engine_algorithms}, -#endif /* OPENSSL_NO_ENGINE */ +#endif /* KSR_SSL_ENGINE */ +#ifdef KSR_SSL_PROVIDER + {"provider_quirks", PARAM_INT, + &tls_provider_quirks}, /* OpenSSL 3 provider that needs new OSSL_LIB_CTX in child */ +#endif /* KSR_SSL_PROVIDER */ {"tls_log", PARAM_INT, &default_tls_cfg.log}, {"tls_debug", PARAM_INT, &default_tls_cfg.debug}, {"session_cache", PARAM_INT, &default_tls_cfg.session_cache}, @@ -311,6 +337,20 @@ static tls_domains_cfg_t* tls_use_modparams(void) } #endif +/* global config tls_threads_mode = 2 + * - force all thread-locals to be 0x0 after fork() + * - with OpenSSL loaded the largest value observed + * is < 10 + * + */ +static void fork_child(void) +{ + int k = 0; + for(k = 0; k < 16; k++) { + if(pthread_getspecific(k) != 0) + pthread_setspecific(k, 0x0); + } +} static int mod_init(void) { @@ -421,6 +461,9 @@ static int mod_init(void) ksr_module_set_flag(KSRMOD_FLAG_POSTCHILDINIT); } #endif + if(ksr_tls_threads_mode == 2) { + pthread_atfork(NULL, NULL, &fork_child); + } return 0; error: tls_h_mod_destroy_f(); @@ -428,10 +471,10 @@ error: } -#ifndef OPENSSL_NO_ENGINE +#ifdef KSR_SSL_COMMON static int tls_engine_init(); int tls_fix_engine_keys(tls_domains_cfg_t *, tls_domain_t *, tls_domain_t *); -#endif +#endif /* KSR_SSL_COMMON */ /* * OpenSSL 1.1.1+: SSL_CTX is repeated in each worker @@ -443,50 +486,66 @@ int tls_fix_engine_keys(tls_domains_cfg_t *, tls_domain_t *, tls_domain_t *); * * EC operations do not use pthread_self(), so could use shared SSL_CTX */ +static int mod_child_hook(int *rank, void *dummy) +{ + LM_INFO("Loading SSL_CTX in process_no=%d rank=%d " + "ksr_tls_threads_mode=%d\n", + process_no, *rank, ksr_tls_threads_mode); + + if(cfg_get(tls, tls_cfg, config_file).s) { + if(tls_fix_domains_cfg(*tls_domains_cfg, &srv_defaults, &cli_defaults) + < 0) + return -1; + } else { + if(tls_fix_domains_cfg(*tls_domains_cfg, &mod_params, &mod_params) < 0) + return -1; + } + return 0; +} + +#ifdef KSR_SSL_PROVIDER +static OSSL_LIB_CTX *orig_ctx; +static OSSL_LIB_CTX *new_ctx; +#endif static int mod_child(int rank) { if(tls_disable || (tls_domains_cfg == 0)) return 0; -#if OPENSSL_VERSION_NUMBER >= 0x010101000L - /* - * OpenSSL 3.x/1.1.1: create shared SSL_CTX* in worker to avoid init of - * libssl in rank 0(thread#1) + /* + * OpenSSL 3.x/1.1.1: create shared SSL_CTX* in thread executor + * to avoid init of libssl in thread#1: ksr_tls_threads_mode = 1 */ - if(rank == PROC_SIPINIT) { -#else - if(rank == PROC_INIT) { -#endif - if(cfg_get(tls, tls_cfg, config_file).s) { - if(tls_fix_domains_cfg( - *tls_domains_cfg, &srv_defaults, &cli_defaults) - < 0) - return -1; - } else { - if(tls_fix_domains_cfg(*tls_domains_cfg, &mod_params, &mod_params) - < 0) - return -1; - } - return 0; + if(rank == PROC_INIT) { + return run_thread4PP((_thread_proto4PP)mod_child_hook, &rank, NULL); } -#ifndef OPENSSL_NO_ENGINE +#ifdef KSR_SSL_COMMON /* * after the child is fork()ed we go through the TLS domains * and fix up private keys from engine */ +#ifdef KSR_SSL_ENGINE if(!strncmp(tls_engine_settings.engine.s, "NONE", 4)) return 0; +#endif /* KSR_SSL_ENGINE */ if(rank > 0) { +#ifdef KSR_SSL_PROVIDER + if(tls_provider_quirks & 1) { + new_ctx = OSSL_LIB_CTX_new(); + orig_ctx = OSSL_LIB_CTX_set0_default(new_ctx); + CONF_modules_load_file(CONF_get1_default_config_file(), NULL, 0L); + } +#endif /* KSR_SSL_PROVIDER */ if(tls_engine_init() < 0) return -1; if(tls_fix_engine_keys(*tls_domains_cfg, &srv_defaults, &cli_defaults) < 0) return -1; - LM_INFO("OpenSSL Engine loaded private keys in child: %d\n", rank); + LM_INFO("OpenSSL loaded private keys in child: %d\n", rank); } -#endif +#endif /* KSR_SSL_PROVIDER */ return 0; } @@ -678,17 +737,25 @@ int mod_register(char *path, int *dlflags, void *p1, void *p2) register_tls_hooks(&tls_h); - /* + /* * GH #3695: OpenSSL 1.1.1 historical note: it is no longer * needed to replace RAND with cryptorand */ +#if OPENSSL_VERSION_NUMBER >= 0x10100000L \ + && OPENSSL_VERSION_NUMBER < 0x030000000L + if(ksr_tls_threads_mode == 0) { + LM_WARN("OpenSSL 1.1.1 setting cryptorand random engine\n"); + RAND_set_rand_method(RAND_ksr_cryptorand_method()); + } +#endif + sr_kemi_modules_add(sr_kemi_tls_exports); return 0; } -#ifndef OPENSSL_NO_ENGINE +#ifdef KSR_SSL_ENGINE /* * initialize OpenSSL engine in child process * PKCS#11 libraries are not guaranteed to be fork() safe @@ -714,6 +781,7 @@ static int tls_engine_init() * We are in the child process and the global engine linked-list * is initialized in the parent. */ + ENGINE_load_builtin_engines(); e = ENGINE_by_id("dynamic"); if(!e) { err = "Error loading dynamic engine"; @@ -781,4 +849,53 @@ EVP_PKEY *tls_engine_private_key(const char *key_id) { return ENGINE_load_private_key(ksr_tls_engine, key_id, NULL, NULL); } +#endif /* KSR_SSL_ENGINE */ + +#ifdef KSR_SSL_PROVIDER +#include +static int tls_engine_init() +{ + return 0; +} +EVP_PKEY *tls_engine_private_key(const char *key_id) +{ + OSSL_STORE_CTX *ctx; + EVP_PKEY *pkey = NULL; + + ctx = OSSL_STORE_open_ex(key_id, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + if(!ctx) { + LM_ERR("[ERR] could not load URI %s\n", key_id); + goto error; + } + + OSSL_STORE_expect(ctx, OSSL_STORE_INFO_PKEY); + + while(!(OSSL_STORE_eof(ctx))) { + OSSL_STORE_INFO *info = OSSL_STORE_load(ctx); + if(info == NULL) + continue; + + int type; + type = OSSL_STORE_INFO_get_type(info); + + switch(type) { + case OSSL_STORE_INFO_PKEY: + pkey = OSSL_STORE_INFO_get1_PKEY(info); + break; + default: + continue; + break; + } + OSSL_STORE_INFO_free(info); + if(pkey) + break; + } + + LM_INFO("Loaded private key = %p\n", pkey); + +error: + OSSL_STORE_close(ctx); + + return pkey; +} #endif diff --git a/src/modules/tls/tls_rpc.c b/src/modules/tls/tls_rpc.c index 5d24b6cbe..171a833c4 100644 --- a/src/modules/tls/tls_rpc.c +++ b/src/modules/tls/tls_rpc.c @@ -256,9 +256,46 @@ static void tls_options(rpc_t *rpc, void *c) cfg_get(tls, tls_cfg, ct_wq_blk_size)); } +static const char *tls_kill_doc[2] = { + "Kills a tls session, identified via id.", 0}; + +static void tls_kill(rpc_t *rpc, void *c) +{ + struct tcp_connection *con; + int i, kill_id = 0; + + if(rpc->scan(c, "d", &kill_id) < 0) { + /* Reply is set automatically by scan upon failure, + * no need to do anything here + */ + return; + } + + TCPCONN_LOCK; + for(i = 0; i < TCP_ID_HASH_SIZE; i++) { + for(con = tcpconn_id_hash[i]; con; con = con->id_next) { + if(con->rcv.proto != PROTO_TLS) + continue; + if(con->id == kill_id) { + con->state = -2; + con->timeout = get_ticks_raw(); + + TCPCONN_UNLOCK; + + rpc->add(c, "s", "OK"); + return; + } + } + } + TCPCONN_UNLOCK; + + rpc->add(c, "s", "TLS connection id not found"); +} + rpc_export_t tls_rpc[] = { {"tls.reload", tls_reload, tls_reload_doc, RPC_EXEC_DELTA}, {"tls.list", tls_list, tls_list_doc, RET_ARRAY}, {"tls.info", tls_info, tls_info_doc, 0}, - {"tls.options", tls_options, tls_options_doc, 0}, {0, 0, 0, 0}}; + {"tls.options", tls_options, tls_options_doc, 0}, + {"tls.kill", tls_kill, tls_kill_doc, 0}, {0, 0, 0, 0}}; diff --git a/src/modules/tls/tls_server.c b/src/modules/tls/tls_server.c index 420fd5a86..3bfea131c 100644 --- a/src/modules/tls/tls_server.c +++ b/src/modules/tls/tls_server.c @@ -128,10 +128,6 @@ int tls_run_event_routes(struct tcp_connection *c); #endif /* __SUNPRO_c */ #endif /* TLS_RD_DEBUG */ -#if OPENSSL_VERSION_NUMBER >= 0x030000000L -#define OPENSSL_NO_ENGINE -#endif - extern str sr_tls_xavp_cfg; static str _ksr_tls_connect_server_id = STR_NULL; @@ -426,11 +422,6 @@ static void tls_dump_cert_info(char *s, X509 *cert) } } - -#ifndef OPENSSL_NO_ENGINE -// lookup HSM keys in process-local memory -EVP_PKEY *tls_lookup_private_key(SSL_CTX *); -#endif /** wrapper around SSL_accept, usin SSL return convention. * It will also log critical errors and certificate debugging info. * @param c - tcp connection with tls (extra_data must be a filled @@ -461,12 +452,7 @@ int tls_accept(struct tcp_connection *c, int *error) BUG("Invalid connection state %d (bug in TLS code)\n", tls_c->state); goto err; } -#ifndef OPENSSL_NO_ENGINE - /* check if we have a HSM key */ - EVP_PKEY *pkey = tls_lookup_private_key(SSL_get_SSL_CTX(ssl)); - if(pkey) - SSL_use_PrivateKey(ssl, pkey); -#endif + tls_openssl_clear_errors(); ret = SSL_accept(ssl); if(unlikely(ret == 1)) { @@ -531,13 +517,7 @@ int tls_connect(struct tcp_connection *c, int *error) BUG("Invalid connection state %d (bug in TLS code)\n", tls_c->state); goto err; } -#ifndef OPENSSL_NO_ENGINE - // lookup HSM private key in process-local memory - EVP_PKEY *pkey = tls_lookup_private_key(SSL_get_SSL_CTX(ssl)); - if(pkey) { - SSL_use_PrivateKey(ssl, pkey); - } -#endif + tls_openssl_clear_errors(); ret = SSL_connect(ssl); if(unlikely(ret == 1)) { diff --git a/src/modules/tls/tls_util.c b/src/modules/tls/tls_util.c index 037739720..40d2bf07d 100644 --- a/src/modules/tls/tls_util.c +++ b/src/modules/tls/tls_util.c @@ -106,9 +106,9 @@ void collect_garbage(void) void tls_openssl_clear_errors(void) { int i; - char err[160]; + char err[256]; while((i = ERR_get_error())) { ERR_error_string(i, err); - INFO("clearing leftover error before SSL_* calls: %s", err); + INFO("clearing leftover error before SSL_* calls: %s\n", err); } } diff --git a/src/modules/tls/utils/openssl_mutex_shared/Makefile b/src/modules/tls/utils/openssl_mutex_shared/Makefile deleted file mode 100644 index 8edfe13a6..000000000 --- a/src/modules/tls/utils/openssl_mutex_shared/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -COREPATH=../../../../../src -include $(COREPATH)/Makefile.defs -include $(COREPATH)/Makefile.targets - - -.PHONY: all -all: openssl_mutex_shared.so - -.PHONY: install-if-newer -install-if-newer: install - -.PHONY: install -install: install-modules - -.PHONY: install-modules -install-modules: openssl_mutex_shared.so - mkdir -p $(modules_prefix)/$(lib_dir)/openssl_mutex_shared - $(INSTALL_TOUCH) $(modules_prefix)/$(lib_dir)/openssl_mutex_shared/openssl_mutex_shared.so - $(INSTALL_BIN) openssl_mutex_shared.so $(modules_prefix)/$(lib_dir)/openssl_mutex_shared - -openssl_mutex_shared.so: openssl_mutex_shared.c - $(CC) -g -D_GNU_SOURCE -std=c99 -fvisibility=hidden -pthread -o $@ -O3 -Wall -shared -fPIC -ldl $< - -.PHONY: clean -clean: - rm -f openssl_mutex_shared.so diff --git a/src/modules/tls/utils/openssl_mutex_shared/README.md b/src/modules/tls/utils/openssl_mutex_shared/README.md deleted file mode 100644 index d5002b333..000000000 --- a/src/modules/tls/utils/openssl_mutex_shared/README.md +++ /dev/null @@ -1,63 +0,0 @@ -# OpenSSL Shared Mutex # - -**IMPORTANT: the workaround of using this preloaded shared library is no longer -needed starting with Kamailio v5.3.0-pre1 (git master branch after September 14, 2019). -The code of this shared library has been included in the core of Kamailio and the -same behaviour is now achieved by default.** - -This is a shared library required as a short term workaround for using Kamailio -with OpenSSL (libssl) v1.1. It has to be pre-loaded before starting Kamailio. - -In v1.1, libssl does not allow setting custom locking functions, using internally -pthread mutexes and rwlocks, but they are not initialized with process shared -option (PTHREAD_PROCESS_SHARED), which can result in blocking Kamailio worker -processes. - -## Installation ## - -By default, it is installed when the tls module is installed. - -It can be installed manually, in this folder execute: - -``` -make -make install -``` - -It is installed at the same place where Kamailio deploys the directory with -modules. - -For example, when installing from sources on a 64b system, the location is: - -``` -/usr/local/lib64/kamailio/openssl_mutex_shared/openssl_mutex_shared.so -``` - -For Debian packing, the location is like: - -``` -/usr/lib/x86_64-linux-gnu/kamailio/openssl_mutex_shared/openssl_mutex_shared.so -``` - -Note: there is no dependency on Kamailio source code, this shared object can -be compiled and used ouside of Kamailio source tree. It uses only Kamailio's -Makefile system to install in the same directory like the other shared objects -installed by Kamailio. - -## Usage ## - -Use LD_PRELOAD to tell the linker to preload this shared object before starting -Kamailio. - -Example, when Kamailio was installed from sources: - -``` -LD_PRELOAD=/usr/local/lib64/kamailio/openssl_mutex_shared/openssl_mutex_shared.so \ - /usr/local/sbin/kamailio -f /usr/local/etc/kamailio/kamailio.cfg -``` - -If using systemd, add to service file: - -``` -Environment='LD_PRELOAD=/usr/local/lib64/kamailio/openssl_mutex_shared/openssl_mutex_shared.so' -``` diff --git a/src/modules/tls/utils/openssl_mutex_shared/openssl_mutex_shared.c b/src/modules/tls/utils/openssl_mutex_shared/openssl_mutex_shared.c deleted file mode 100644 index 7f284515c..000000000 --- a/src/modules/tls/utils/openssl_mutex_shared/openssl_mutex_shared.c +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include - -#define SYMBOL_EXPORT __attribute__((visibility("default"))) - -int SYMBOL_EXPORT pthread_mutex_init( - pthread_mutex_t *__mutex, const pthread_mutexattr_t *__mutexattr) -{ - static int (*real_pthread_mutex_init)( - pthread_mutex_t * __mutex, const pthread_mutexattr_t *__mutexattr); - if(!real_pthread_mutex_init) - real_pthread_mutex_init = dlsym(RTLD_NEXT, "pthread_mutex_init"); - - if(__mutexattr) { - pthread_mutexattr_t attr = *__mutexattr; - pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); - return real_pthread_mutex_init(__mutex, &attr); - } - - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); - int ret = real_pthread_mutex_init(__mutex, &attr); - pthread_mutexattr_destroy(&attr); - return ret; -} - -int SYMBOL_EXPORT pthread_rwlock_init(pthread_rwlock_t *__restrict __rwlock, - const pthread_rwlockattr_t *__restrict __attr) -{ - static int (*real_pthread_rwlock_init)( - pthread_rwlock_t *__restrict __rwlock, - const pthread_rwlockattr_t *__restrict __attr); - if(!real_pthread_rwlock_init) - real_pthread_rwlock_init = dlsym(RTLD_NEXT, "pthread_rwlock_init"); - - if(__attr) { - pthread_rwlockattr_t attr = *__attr; - pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); - return real_pthread_rwlock_init(__rwlock, &attr); - } - - pthread_rwlockattr_t attr; - pthread_rwlockattr_init(&attr); - pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); - int ret = real_pthread_rwlock_init(__rwlock, &attr); - pthread_rwlockattr_destroy(&attr); - return ret; -} diff --git a/src/modules/tls_wolfssl/Makefile b/src/modules/tls_wolfssl/Makefile index 5ef95d697..dda5ad477 100644 --- a/src/modules/tls_wolfssl/Makefile +++ b/src/modules/tls_wolfssl/Makefile @@ -8,6 +8,13 @@ include ../../Makefile.defs auto_gen= NAME=tls_wolfssl.so +# make WOLFSSL_INTERNAL=yes... for internal submodule +# make WOLFSSL_INTERNAL=no... for system package +# default: yes + +WOLFSSL_INTERNAL ?= yes + +ifeq ($(WOLFSSL_INTERNAL),yes) WOLFSSL_PREFIX = ../../../misc/external/wolfssl/build WOLFSSL_SRC = ../../../misc/external/wolfssl/wolfssl @@ -25,7 +32,7 @@ $(WOLFSSL_PREFIX)/include/wolfssl/options.h $(WOLFSSL_PREFIX)/lib/libwolfssl.a: if [ ! -f "Makefile" ]; then \ env -u DEFS -u CFLAGS -u LDFLAGS -u LIBS EXTRA_CFLAGS="-g -O2 -fPIC" ./configure \ --enable-all --enable-pkcs11 --enable-static --enable-writedup \ - --disable-aligndata --disable-shared --disable-examples \ + --disable-shared --disable-examples \ --disable-jni --disable-crl-monitor \ --prefix=$(CURDIR)/$(WOLFSSL_PREFIX) \ --exec-prefix=$(CURDIR)/$(WOLFSSL_PREFIX); \ @@ -34,6 +41,15 @@ $(WOLFSSL_PREFIX)/include/wolfssl/options.h $(WOLFSSL_PREFIX)/lib/libwolfssl.a: $(NAME): $(WOLFSSL_PREFIX)/lib/libwolfssl.a +else +WOLFSSL_LIBS ?= $(shell pkg-config wolfssl --libs) +WOLFSSL_INCLUDES ?= $(shell pkg-config wolfssl --cflags) + +LIBS += $(WOLFSSL_LIBS) +INCLUDES += $(WOLFSSL_INCLUDES) +include ../../Makefile.modules +endif + clean-wolfssl: @rm -rf $(WOLFSSL_PREFIX)/{bin,include,share,lib}; \ (cd $(WOLFSSL_SRC); make distclean) || /bin/true diff --git a/src/modules/tls_wolfssl/README b/src/modules/tls_wolfssl/README index bffec53ba..29db26c23 100644 --- a/src/modules/tls_wolfssl/README +++ b/src/modules/tls_wolfssl/README @@ -64,6 +64,10 @@ loadmodule "tls_wolfssl.so" The wolfSSL TLS module is intended to be compiled with a recent version of wolfSSL (5.2.0+). + Default compilations of the library will not work with Kamailio's own + memory allocation. See https://github.com/wolfSSL/wolfssl/issues/5264 + for more details. + 4. Compiling the wolfSSL TLS Module The development package for wolfSSL is required (libwolfssl-dev or diff --git a/src/modules/tls_wolfssl/doc/tls_wolfssl.xml b/src/modules/tls_wolfssl/doc/tls_wolfssl.xml index 199679b9a..cf7770a77 100644 --- a/src/modules/tls_wolfssl/doc/tls_wolfssl.xml +++ b/src/modules/tls_wolfssl/doc/tls_wolfssl.xml @@ -77,6 +77,11 @@ loadmodule "tls_wolfssl.so" The wolfSSL TLS module is intended to be compiled with a recent version of wolfSSL (5.2.0+). + + Default compilations of the library will not work with Kamailio's + own memory allocation. See https://github.com/wolfSSL/wolfssl/issues/5264 + for more details. + diff --git a/src/modules/tls_wolfssl/tls_bio.c b/src/modules/tls_wolfssl/tls_bio.c deleted file mode 100644 index 1d2e2a39c..000000000 --- a/src/modules/tls_wolfssl/tls_bio.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Kamailio TLS module - * - * Copyright (C) 2010 iptelorg GmbH - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/** - * openssl BIOs for reading/writing via a fixed memory buffer. - * @file - * @ingroup tls - */ - -#include "tls_bio.h" -#include "../../core/compiler_opt.h" -#include "../../core/dprint.h" -#include "../../core/ut.h" -#include "tls_cfg.h" - -/* 0xf2 should be unused (as of openssl 1.0.0 max. - internal defined BIO is 23) */ -#define BIO_TYPE_TLS_MBUF 0x4f2 - -/* debugging */ -#ifdef NO_TLS_BIO_DEBUG -#undef TLS_BIO_DEBUG -#endif -#ifdef TLS_BIO_DEBUG -#ifdef __SUNPRO_C -#define TLS_BIO_DBG(...) \ - LOG_FP(DEFAULT_FACILITY, cfg_get(tls, tls_cfg, debug), \ - "tls_BIO: " LOC_INFO, __VA_ARGS__) -#else -#define TLS_BIO_DBG(args...) \ - LOG_FP(DEFAULT_FACILITY, cfg_get(tls, tls_cfg, debug), \ - "tls_BIO: " LOC_INFO, ##args) -#endif /* __SUNPRO_c */ -#else /* TLS_BIO_DEBUG */ -#ifdef __SUNPRO_C -#define TLS_BIO_DBG(...) -#else -#define TLS_BIO_DBG(fmt, args...) -#endif /* __SUNPRO_c */ -#endif /* TLS_BIO_DEBUG */ - - -static int tls_bio_mbuf_new(WOLFSSL_BIO *b); -static int tls_bio_mbuf_free(WOLFSSL_BIO *b); -static int tls_bio_mbuf_write(WOLFSSL_BIO *b, const char *buf, int num); -static int tls_bio_mbuf_read(WOLFSSL_BIO *b, char *buf, int num); -static int tls_bio_mbuf_puts(WOLFSSL_BIO *b, const char *s); -static long tls_bio_mbuf_ctrl(WOLFSSL_BIO *b, int cmd, long arg1, void *arg2); - - -static WOLFSSL_BIO_METHOD *tls_mbuf_method = NULL; - - -/** returns a custom tls_mbuf BIO. */ -WOLFSSL_BIO_METHOD *tls_BIO_mbuf(void) -{ - if(tls_mbuf_method != NULL) { - return tls_mbuf_method; - } - tls_mbuf_method = wolfSSL_BIO_meth_new(BIO_TYPE_TLS_MBUF, "sr_tls_mbuf"); - if(tls_mbuf_method == NULL) { - LM_ERR("cannot get a new bio method structure\n"); - return NULL; - } - wolfSSL_BIO_meth_set_write(tls_mbuf_method, tls_bio_mbuf_write); - wolfSSL_BIO_meth_set_read(tls_mbuf_method, tls_bio_mbuf_read); - wolfSSL_BIO_meth_set_puts(tls_mbuf_method, tls_bio_mbuf_puts); - wolfSSL_BIO_meth_set_gets(tls_mbuf_method, NULL); - wolfSSL_BIO_meth_set_ctrl(tls_mbuf_method, tls_bio_mbuf_ctrl); - wolfSSL_BIO_meth_set_create(tls_mbuf_method, tls_bio_mbuf_new); - wolfSSL_BIO_meth_set_destroy(tls_mbuf_method, tls_bio_mbuf_free); - return tls_mbuf_method; -} - - -/** create an initialize a new tls_BIO_mbuf. - * @return new BIO on success (!=0), 0 on error. - */ -WOLFSSL_BIO *tls_BIO_new_mbuf(struct tls_mbuf *rd, struct tls_mbuf *wr) -{ - WOLFSSL_BIO *ret; - - TLS_BIO_DBG("tls_BIO_new_mbuf called (%p, %p)\n", rd, wr); - ret = wolfSSL_BIO_new(tls_BIO_mbuf()); - if(unlikely(ret == 0)) - return 0; - if(unlikely(tls_BIO_mbuf_set(ret, rd, wr) == 0)) { - wolfSSL_BIO_free(ret); - return 0; - } - return ret; -} - - -/** sets the read and write mbuf for an mbuf BIO. - * @return 1 on success, 0 on error (openssl BIO convention). - */ -int tls_BIO_mbuf_set(WOLFSSL_BIO *b, struct tls_mbuf *rd, struct tls_mbuf *wr) -{ - struct tls_bio_mbuf_data *d; - - TLS_BIO_DBG("tls_BIO_mbuf_set called (%p => %p, %p)\n", b, rd, wr); - d = wolfSSL_BIO_get_data(b); - if(unlikely(d == 0)) { - BUG("null BIO ptr data\n"); - return 0; - } - d->rd = rd; - d->wr = wr; - wolfSSL_BIO_set_init(b, 1); - return 1; -} - - -/** create a new BIO. - * (internal openssl use via the tls_mbuf method) - * @return 1 on success, 0 on error. - */ -static int tls_bio_mbuf_new(WOLFSSL_BIO *b) -{ - struct tls_bio_mbuf_data *d; - - TLS_BIO_DBG("tls_bio_mbuf_new called (%p)\n", b); - wolfSSL_BIO_set_init(b, 0); - wolfSSL_BIO_set_data(b, NULL); - d = wolfSSL_Malloc(sizeof(*d)); - memset(d, 0, sizeof(*d)); - if(unlikely(d == 0)) - return 0; - wolfSSL_BIO_set_data(b, d); - return 1; -} - - -/** destroy a tls mbuf BIO. - * (internal openssl use via the tls_mbuf method) - * @return 1 on success, 0 on error. - */ -static int tls_bio_mbuf_free(WOLFSSL_BIO *b) -{ - TLS_BIO_DBG("tls_bio_mbuf_free called (%p)\n", b); - if(unlikely(b == 0)) - return 0; - do { - struct tls_bio_mbuf_data *d; - d = wolfSSL_BIO_get_data(b); - if(likely(d)) { - wolfSSL_OPENSSL_free(d); - wolfSSL_BIO_set_data(b, NULL); - wolfSSL_BIO_set_init(b, 0); - } - } while(0); - return 1; -} - - -/** read from a mbuf. - * (internal openssl use via the tls_mbuf method) - * @return bytes read on success (0< ret <=dst_len), -1 on empty buffer & sets - * should_retry_read, -1 on some other errors (w/o should_retry_read set). - */ -static int tls_bio_mbuf_read(WOLFSSL_BIO *b, char *dst, int dst_len) -{ - struct tls_bio_mbuf_data *d; - struct tls_mbuf *rd; - int ret; - - ret = 0; - if(likely(dst)) { - d = wolfSSL_BIO_get_data(b); - wolfSSL_BIO_clear_retry_flags(b); - if(unlikely(d == 0 || d->rd->buf == 0)) { - if(d == 0) - BUG("tls_BIO_mbuf %p: read called with null b->ptr\n", b); - else { - /* this form of calling read with a null buffer is used - as a shortcut when no data is available => - simulate EAGIAN/WANT_READ */ - TLS_BIO_DBG("read (%p, %p, %d) called with null read buffer" - "(%p->%p) => simulating EAGAIN/WANT_READ\n", - b, dst, dst_len, d, d->rd); - BIO_set_retry_read(b); - } - return -1; - } - rd = d->rd; - if(unlikely(rd->used == rd->pos && dst_len)) { - /* mimic non-blocking read behaviour */ - TLS_BIO_DBG("read (%p, %p, %d) called with full rd (%d)" - " => simulating EAGAIN/WANT_READ\n", - b, dst, dst_len, rd->used); - BIO_set_retry_read(b); - return -1; - } - ret = MIN_int(rd->used - rd->pos, dst_len); - /* copy data from rd.buf into dst */ - memcpy(dst, rd->buf + rd->pos, ret); - TLS_BIO_DBG("read(%p, %p, %d) called with rd=%p pos=%d => %d bytes\n", - b, dst, dst_len, rd->buf, rd->pos, ret); - rd->pos += ret; - /* if (unlikely(rd->pos < rd->used)) - wolfSSL_BIO_set_retry_read(b); -*/ - } - return ret; -} - - -/** write to a mbuf. - * (internal openssl use via the tls_mbuf method) - * @return bytes written on success (0<= ret <=src_len), -1 on error or buffer - * full (in this case sets should_retry_write). - */ -static int tls_bio_mbuf_write(WOLFSSL_BIO *b, const char *src, int src_len) -{ - struct tls_bio_mbuf_data *d; - struct tls_mbuf *wr; - int ret; - - ret = 0; - d = wolfSSL_BIO_get_data(b); - wolfSSL_BIO_clear_retry_flags(b); - if(unlikely(d == 0 || d->wr->buf == 0)) { - if(d == 0) - BUG("tls_BIO_mbuf %p: write called with null b->ptr\n", b); - else { - /* this form of calling write with a null buffer is used - as a shortcut when no data is available => - simulate EAGAIN/WANT_WRITE */ - TLS_BIO_DBG("write (%p, %p, %d) called with null buffer" - " => simulating WANT_WRITE\n", - b, src, src_len); - BIO_set_retry_write(b); - } - return -1; - } - wr = d->wr; - if(unlikely(wr->size == wr->used && src_len)) { - /* mimic non-blocking socket behaviour */ - TLS_BIO_DBG("write (%p, %p, %d) called with full wr buffer (%d)" - " => simulating WANT_WRITE\n", - b, src, src_len, wr->used); - BIO_set_retry_write(b); - return -1; - } - ret = MIN_int(wr->size - wr->used, src_len); - memcpy(wr->buf + wr->used, src, ret); - wr->used += ret; - /* if (unlikely(ret < src_len)) - wolfSSL_BIO_set_retry_write(); -*/ - TLS_BIO_DBG("write called (%p, %p, %d) => %d\n", b, src, src_len, ret); - return ret; -} - - -static long tls_bio_mbuf_ctrl(WOLFSSL_BIO *b, int cmd, long arg1, void *arg2) -{ - long ret; - ret = 0; - switch(cmd) { - case BIO_CTRL_GET_CLOSE: - case BIO_CTRL_SET_CLOSE: - ret = 0; - break; - case BIO_CTRL_DUP: - case BIO_CTRL_FLUSH: - ret = 1; - break; - case BIO_CTRL_RESET: - case BIO_CTRL_INFO: - case BIO_CTRL_PENDING: - case BIO_CTRL_WPENDING: - default: - ret = 0; - break; - } - TLS_BIO_DBG( - "ctrl called (%p, %d, %ld, %p) => %ld\n", b, cmd, arg1, arg2, ret); - return ret; -} - - -static int tls_bio_mbuf_puts(WOLFSSL_BIO *b, const char *s) -{ - int len; - - TLS_BIO_DBG("puts called (%p, %s)\n", b, s); - len = strlen(s); - return tls_bio_mbuf_write(b, s, len); -} - -/* vi: set ts=4 sw=4 tw=79:ai:cindent: */ diff --git a/src/modules/tls_wolfssl/tls_bio.h b/src/modules/tls_wolfssl/tls_bio.h deleted file mode 100644 index 986aebab5..000000000 --- a/src/modules/tls_wolfssl/tls_bio.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Kamailio TLS module - * - * Copyright (C) 2010 iptelorg GmbH - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/** openssl BIOs for reading/writing via a fixed memory buffer. - * @file modules/tls/tls_bio.h - * @ingroup tls - */ - -#ifndef __tls_bio_h -#define __tls_bio_h - -#include -#include - -/* memory buffer used for tls I/O */ -struct tls_mbuf -{ - unsigned char *buf; - int pos; /**< current position in the buffer while reading or writing*/ - int used; /**< how much it's used (read or write)*/ - int size; /**< total buffer size (fixed) */ -}; - -struct tls_bio_mbuf_data -{ - struct tls_mbuf *rd; - struct tls_mbuf *wr; -}; - - -WOLFSSL_BIO_METHOD *tls_BIO_mbuf(void); -WOLFSSL_BIO *tls_BIO_new_mbuf(struct tls_mbuf *rd, struct tls_mbuf *wr); -int tls_BIO_mbuf_set(WOLFSSL_BIO *b, struct tls_mbuf *rd, struct tls_mbuf *wr); - - -/** initialize an mbuf structure. - * @param mb - struct tls_mbuf pointer that will be initialized. - * @param b - buffer (unsigned char*). - * @param sz - suze of the buffer (int). - * WARNING: the buffer will not be copied, but referenced. - */ -#define tls_mbuf_init(mb, b, sz) \ - do { \ - (mb)->buf = (b); \ - (mb)->size = (sz); \ - (mb)->pos = 0; \ - (mb)->used = 0; \ - } while(0) - - -#endif /*__tls_bio_h*/ - -/* vi: set ts=4 sw=4 tw=79:ai:cindent: */ diff --git a/src/modules/tls_wolfssl/tls_cfg.c b/src/modules/tls_wolfssl/tls_cfg.c index 9c362704d..f2ef60f0e 100644 --- a/src/modules/tls_wolfssl/tls_cfg.c +++ b/src/modules/tls_wolfssl/tls_cfg.c @@ -60,8 +60,6 @@ struct cfg_group_tls default_tls_cfg = { -1, /* ssl_max_send_fragment (use the default: 16k), requires openssl > 0.9.9 */ 0, /* ssl_read_ahead (off, not needed, we have our own buffering BIO)*/ - -1, /* low_mem_threshold1 */ - -1, /* low_mem_threshold2 */ 10 * 1024 * 1024, /* ct_wq_max: 10 Mb by default */ 64 * 1024, /* con_ct_wq_max: 64Kb by default */ 4096, /* ct_wq_blk_size */ @@ -200,12 +198,6 @@ cfg_def_t tls_cfg_def[] = {{"force_run", CFG_VAR_INT | CFG_READONLY, 0, 1, 0, 0, " module versions it is better to have read ahead disabled, " "since" " everything it is buffered in memory anyway"}, - {"low_mem_threshold1", CFG_VAR_INT | CFG_ATOMIC, -1, 1 << 30, 0, 0, - "sets the minimum amount of free memory for accepting new TLS" - " connections (KB)"}, - {"low_mem_threshold2", CFG_VAR_INT | CFG_ATOMIC, -1, 1 << 30, 0, 0, - "sets the minimum amount of free memory after which no more TLS" - " operations will be attempted (even on existing connections)"}, {"ct_wq_max", CFG_VAR_INT | CFG_ATOMIC, 0, 1 << 30, 0, 0, "maximum bytes queued globally for write when write has to " "wait due" diff --git a/src/modules/tls_wolfssl/tls_cfg.h b/src/modules/tls_wolfssl/tls_cfg.h index 9b51b6aa4..9682fb2f4 100644 --- a/src/modules/tls_wolfssl/tls_cfg.h +++ b/src/modules/tls_wolfssl/tls_cfg.h @@ -90,8 +90,6 @@ struct cfg_group_tls * now) */ int ssl_read_ahead; - int low_mem_threshold1; - int low_mem_threshold2; int ct_wq_max; /* maximum overall tls write clear text queued bytes */ int con_ct_wq_max; /* maximum clear text write queued bytes per con */ int ct_wq_blk_size; /* minimum block size for the clear text write queue */ diff --git a/src/modules/tls_wolfssl/tls_config.h b/src/modules/tls_wolfssl/tls_config.h index 3284fd601..653465178 100644 --- a/src/modules/tls_wolfssl/tls_config.h +++ b/src/modules/tls_wolfssl/tls_config.h @@ -29,9 +29,6 @@ #include "../../core/str.h" #include "tls_domain.h" -#include -#include - tls_domains_cfg_t *tls_load_config(str *filename); /* diff --git a/src/modules/tls_wolfssl/tls_ct_wrq.h b/src/modules/tls_wolfssl/tls_ct_wrq.h index 7ac8ce460..79bc36490 100644 --- a/src/modules/tls_wolfssl/tls_ct_wrq.h +++ b/src/modules/tls_wolfssl/tls_ct_wrq.h @@ -29,7 +29,6 @@ #define __tls_ct_wrq_h #include "tls_ct_q.h" -#include "tls_server.h" #include "../../core/tcp_conn.h" diff --git a/src/modules/tls_wolfssl/tls_domain.c b/src/modules/tls_wolfssl/tls_domain.c index 32ea09c96..aae5c01c6 100644 --- a/src/modules/tls_wolfssl/tls_domain.c +++ b/src/modules/tls_wolfssl/tls_domain.c @@ -26,10 +26,6 @@ #include -#include -#include - -// # include #include "../../core/ut.h" #include "../../core/mem/shm_mem.h" #include "../../core/pt.h" @@ -157,17 +153,13 @@ tls_domain_t *tls_new_domain(int type, struct ip_addr *ip, unsigned short port) */ void tls_free_domain(tls_domain_t *d) { - int i; - int procs_no; - if(!d) return; if(d->ctx) { - procs_no = get_max_procs(); - for(i = 0; i < procs_no; i++) { - if(d->ctx[i]) - wolfSSL_CTX_free(d->ctx[i]); - } + do { + if(d->ctx[0]) + wolfSSL_CTX_free(d->ctx[0]); + } while(0); shm_free(d->ctx); } @@ -378,14 +370,12 @@ typedef int (*per_ctx_cbk_f)(WOLFSSL_CTX *ctx, long larg, void *parg); static int tls_domain_foreach_CTX( tls_domain_t *d, per_ctx_cbk_f ctx_cbk, long l1, void *p2) { - int i, ret; - int procs_no; + int ret; - procs_no = get_max_procs(); - for(i = 0; i < procs_no; i++) { - if((ret = ctx_cbk(d->ctx[i], l1, p2)) < 0) + do { + if((ret = ctx_cbk(d->ctx[0], l1, p2)) < 0) return ret; - } + } while(0); return 0; } @@ -519,24 +509,21 @@ int fix_shm_pathname(str *path) */ static int load_cert(tls_domain_t *d) { - int i; - int procs_no; - if(!d->cert_file.s || !d->cert_file.len) { DBG("%s: No certificate configured\n", tls_domain_str(d)); return 0; } if(fix_shm_pathname(&d->cert_file) < 0) return -1; - procs_no = get_max_procs(); - for(i = 0; i < procs_no; i++) { - if(!wolfSSL_CTX_use_certificate_chain_file(d->ctx[i], d->cert_file.s)) { + + do { + if(!wolfSSL_CTX_use_certificate_chain_file(d->ctx[0], d->cert_file.s)) { ERR("%s: Unable to load certificate file '%s'\n", tls_domain_str(d), d->cert_file.s); TLS_ERR("load_cert:"); return -1; } - } + } while(0); return 0; } @@ -548,9 +535,6 @@ static int load_cert(tls_domain_t *d) */ static int load_ca_list(tls_domain_t *d) { - int i; - int procs_no; - if((!d->ca_file.s || !d->ca_file.len) && (!d->ca_path.s || !d->ca_path.len)) { DBG("%s: No CA list configured\n", tls_domain_str(d)); @@ -560,10 +544,10 @@ static int load_ca_list(tls_domain_t *d) return -1; if(d->ca_path.s && d->ca_path.len > 0 && fix_shm_pathname(&d->ca_path) < 0) return -1; - procs_no = get_max_procs(); - for(i = 0; i < procs_no; i++) { + + do { if(wolfSSL_CTX_load_verify_locations( - d->ctx[i], d->ca_file.s, d->ca_path.s) + d->ctx[0], d->ca_file.s, d->ca_path.s) != 1) { ERR("%s: Unable to load CA list file '%s' dir '%s'\n", tls_domain_str(d), (d->ca_file.s) ? d->ca_file.s : "", @@ -573,8 +557,8 @@ static int load_ca_list(tls_domain_t *d) } if(d->ca_file.s && d->ca_file.len > 0) { wolfSSL_CTX_set_client_CA_list( - d->ctx[i], wolfSSL_load_client_CA_file(d->ca_file.s)); - if(wolfSSL_CTX_get_client_CA_list(d->ctx[i]) == 0) { + d->ctx[0], wolfSSL_load_client_CA_file(d->ca_file.s)); + if(wolfSSL_CTX_get_client_CA_list(d->ctx[0]) == 0) { ERR("%s: Error while setting client CA list file [%.*s/%d]\n", tls_domain_str(d), (d->ca_file.s) ? d->ca_file.len : 0, (d->ca_file.s) ? d->ca_file.s : "", d->ca_file.len); @@ -582,7 +566,7 @@ static int load_ca_list(tls_domain_t *d) return -1; } } - } + } while(0); return 0; } @@ -594,9 +578,7 @@ static int load_ca_list(tls_domain_t *d) */ static int load_crl(tls_domain_t *d) { - int i; - int procs_no; - X509_STORE *store; + WOLFSSL_X509_STORE *store; if(!d->crl_file.s) { DBG("%s: No CRL configured\n", tls_domain_str(d)); @@ -606,19 +588,19 @@ static int load_crl(tls_domain_t *d) return -1; LOG(L_INFO, "%s: Certificate revocation lists will be checked (%.*s)\n", tls_domain_str(d), d->crl_file.len, d->crl_file.s); - procs_no = get_max_procs(); - for(i = 0; i < procs_no; i++) { - if(wolfSSL_CTX_load_verify_locations(d->ctx[i], d->crl_file.s, 0) + + do { + if(wolfSSL_CTX_load_verify_locations(d->ctx[0], d->crl_file.s, 0) != 1) { ERR("%s: Unable to load certificate revocation list '%s'\n", tls_domain_str(d), d->crl_file.s); TLS_ERR("load_crl:"); return -1; } - store = wolfSSL_CTX_get_cert_store(d->ctx[i]); - X509_STORE_set_flags( - store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); - } + store = wolfSSL_CTX_get_cert_store(d->ctx[0]); + wolfSSL_X509_STORE_set_flags( + store, WOLFSSL_CRL_CHECK | WOLFSSL_CRL_CHECKALL); + } while(0); return 0; } @@ -636,43 +618,20 @@ static int load_crl(tls_domain_t *d) static int set_cipher_list(tls_domain_t *) __attribute__((unused)); static int set_cipher_list(tls_domain_t *d) { - int i; - int procs_no; char *cipher_list; cipher_list = d->cipher_list.s; -#ifdef TLS_KSSL_WORKAROUND - if(openssl_kssl_malloc_bug) { /* is openssl bug #1467 present ? */ - if(d->cipher_list.s == 0) { - /* use "DEFAULT:!KRB5" */ - cipher_list = "DEFAULT:!KRB5"; - } else { - /* append ":!KRB5" */ - cipher_list = - shm_malloc(d->cipher_list.len + C_NO_KRB5_SUFFIX_LEN + 1); - if(cipher_list) { - memcpy(cipher_list, d->cipher_list.s, d->cipher_list.len); - memcpy(cipher_list + d->cipher_list.len, C_NO_KRB5_SUFFIX, - C_NO_KRB5_SUFFIX_LEN); - cipher_list[d->cipher_list.len + C_NO_KRB5_SUFFIX_LEN] = 0; - shm_free(d->cipher_list.s); - d->cipher_list.s = cipher_list; - d->cipher_list.len += C_NO_KRB5_SUFFIX_LEN; - } - } - } -#endif /* TLS_KSSL_WORKAROUND */ if(!cipher_list) return 0; - procs_no = get_max_procs(); - for(i = 0; i < procs_no; i++) { - if(wolfSSL_CTX_set_cipher_list(d->ctx[i], cipher_list) == 0) { + + do { + if(wolfSSL_CTX_set_cipher_list(d->ctx[0], cipher_list) == 0) { ERR("%s: Failure to set SSL context cipher list \"%s\"\n", tls_domain_str(d), cipher_list); return -1; } - setup_dh(d->ctx[i]); - } + setup_dh(d->ctx[0]); + } while(0); return 0; } @@ -684,8 +643,7 @@ static int set_cipher_list(tls_domain_t *d) */ static int set_verification(tls_domain_t *d) { - int verify_mode, i; - int procs_no; + int verify_mode; if(d->require_cert || d->verify_client == TLS_VERIFY_CLIENT_ON) { verify_mode = WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT; @@ -718,17 +676,16 @@ static int set_verification(tls_domain_t *d) } } - procs_no = get_max_procs(); - for(i = 0; i < procs_no; i++) { + do { if(d->verify_client >= TLS_VERIFY_CLIENT_OPTIONAL_NO_CA) { /* Note that actual verification result is available in $tls_peer_verified */ - wolfSSL_CTX_set_verify(d->ctx[i], verify_mode, + wolfSSL_CTX_set_verify(d->ctx[0], verify_mode, verify_callback_unconditional_success); } else { - wolfSSL_CTX_set_verify(d->ctx[i], verify_mode, 0); + wolfSSL_CTX_set_verify(d->ctx[0], verify_mode, 0); } - wolfSSL_CTX_set_verify_depth(d->ctx[i], d->verify_depth); - } + wolfSSL_CTX_set_verify_depth(d->ctx[0], d->verify_depth); + } while(0); return 0; } @@ -769,21 +726,17 @@ static void sr_ssl_ctx_info_callback(const SSL *ssl, int event, int ret) */ static int set_ssl_options(tls_domain_t *d) { - int i; - int procs_no; long options; - - procs_no = get_max_procs(); options = SSL_OP_ALL; /* all the bug workarounds by default */ options |= SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION - | SSL_OP_CIPHER_SERVER_PREFERENCE; + | WOLFSSL_OP_CIPHER_SERVER_PREFERENCE; - for(i = 0; i < procs_no; i++) { - wolfSSL_CTX_set_options(d->ctx[i], options); + do { + wolfSSL_CTX_set_options(d->ctx[0], options); if(sr_tls_renegotiation == 0) - wolfSSL_CTX_set_info_callback(d->ctx[i], sr_ssl_ctx_info_callback); - } + wolfSSL_CTX_set_info_callback(d->ctx[0], sr_ssl_ctx_info_callback); + } while(0); return 0; } @@ -795,24 +748,21 @@ static int set_ssl_options(tls_domain_t *d) */ static int set_session_cache(tls_domain_t *d) { - int i; - int procs_no; str tls_session_id; - procs_no = get_max_procs(); tls_session_id = cfg_get(tls, tls_cfg, session_id); - for(i = 0; i < procs_no; i++) { + do { /* janakj: I am not sure if session cache makes sense in ser, session * cache is stored in SSL_CTX and we have one SSL_CTX per process, * thus sessions among processes will not be reused */ - wolfSSL_CTX_set_session_cache_mode(d->ctx[i], - cfg_get(tls, tls_cfg, session_cache) ? SSL_SESS_CACHE_SERVER - : SSL_SESS_CACHE_OFF); + wolfSSL_CTX_set_session_cache_mode(d->ctx[0], + cfg_get(tls, tls_cfg, session_cache) ? WOLFSSL_SESS_CACHE_SERVER + : WOLFSSL_SESS_CACHE_OFF); /* not really needed is SSL_SESS_CACHE_OFF */ - wolfSSL_CTX_set_session_id_context(d->ctx[i], + wolfSSL_CTX_set_session_id_context(d->ctx[0], (unsigned char *)tls_session_id.s, tls_session_id.len); - } + } while(0); return 0; } @@ -844,6 +794,7 @@ static int tls_ssl_ctx_mode(WOLFSSL_CTX *ctx, long mode, void *clear) */ static int tls_ssl_ctx_set_freelist(WOLFSSL_CTX *ctx, long val, void *unused) { + /* NOOP */ return 0; } @@ -857,10 +808,7 @@ static int tls_ssl_ctx_set_freelist(WOLFSSL_CTX *ctx, long val, void *unused) static int tls_ssl_ctx_set_max_send_fragment( WOLFSSL_CTX *ctx, long val, void *unused) { - /* WOLFFIX if (val >= 0) - return SSL_CTX_set_max_send_fragment(ctx, val) -1; - */ - + /* NOOP */ return 0; } @@ -891,8 +839,7 @@ static int tls_server_name_cb(SSL *ssl, int *ad, void *private) str server_name; orig_domain = (tls_domain_t *)private; - server_name.s = - (char *)wolfSSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); + server_name.s = (char *)wolfSSL_get_servername(ssl, WOLFSSL_SNI_HOST_NAME); if(server_name.s) { LM_DBG("received server_name (TLS extension): '%s'\n", server_name.s); } else { @@ -918,10 +865,9 @@ static int tls_server_name_cb(SSL *ssl, int *ad, void *private) " socket [%s:%d] server name='%s' -" " switching SSL CTX to %p dom %p%s\n", server_name.s, ip_addr2a(&new_domain->ip), new_domain->port, - ZSW(new_domain->server_name.s), new_domain->ctx[process_no], - new_domain, + ZSW(new_domain->server_name.s), new_domain->ctx[0], new_domain, (new_domain->type & TLS_DOMAIN_DEF) ? " (default)" : ""); - wolfSSL_set_SSL_CTX(ssl, new_domain->ctx[process_no]); + wolfSSL_set_SSL_CTX(ssl, new_domain->ctx[0]); /* SSL_set_SSL_CTX only sets the correct certificate parameters, but does set the proper verify options. Thus this will be done manually! */ @@ -952,9 +898,6 @@ static int tls_server_name_cb(SSL *ssl, int *ad, void *private) */ static int ksr_tls_fix_domain(tls_domain_t *d, tls_domain_t *def) { - int i; - int procs_no; - if(ksr_tls_fill_missing(d, def) < 0) return -1; @@ -966,8 +909,7 @@ static int ksr_tls_fix_domain(tls_domain_t *d, tls_domain_t *def) } } - procs_no = get_max_procs(); - d->ctx = (WOLFSSL_CTX **)shm_malloc(sizeof(WOLFSSL_CTX *) * procs_no); + d->ctx = (WOLFSSL_CTX **)shm_malloc(sizeof(WOLFSSL_CTX *) * 1); if(!d->ctx) { ERR("%s: Cannot allocate shared memory\n", tls_domain_str(d)); return -1; @@ -977,38 +919,21 @@ static int ksr_tls_fix_domain(tls_domain_t *d, tls_domain_t *def) } else { LM_DBG("using one tls method version: %d\n", d->method); } - memset(d->ctx, 0, sizeof(WOLFSSL_CTX *) * procs_no); - for(i = 0; i < procs_no; i++) { + memset(d->ctx, 0, sizeof(WOLFSSL_CTX *) * 1); + do { /* libssl >= 1.1.0 */ //d->ctx[i] = SSL_CTX_new(sr_tls_methods[d->method - 1].TLSMethod); - d->ctx[i] = wolfSSL_CTX_new(wolfSSLv23_method()); - if(d->ctx[i] == NULL) { + d->ctx[0] = wolfSSL_CTX_new(wolfSSLv23_method()); + if(d->ctx[0] == NULL) { unsigned long e = 0; e = ERR_peek_last_error(); ERR("%s: Cannot create SSL context [%d] (%lu: %s / %s)\n", - tls_domain_str(d), i, e, ERR_error_string(e, NULL), + tls_domain_str(d), 0, e, ERR_error_string(e, NULL), ERR_reason_error_string(e)); return -1; } - wolfSSL_CTX_set_min_proto_version(d->ctx[i], TLS1_2_VERSION); -#if 0 - if(d->method>TLS_USE_TLSvRANGE) { - if(sr_tls_methods[d->method - 1].TLSMethodMin) { - SSL_CTX_set_min_proto_version(d->ctx[i], - sr_tls_methods[d->method - 1].TLSMethodMin); - } - } else { - if(sr_tls_methods[d->method - 1].TLSMethodMin) { - SSL_CTX_set_min_proto_version(d->ctx[i], - sr_tls_methods[d->method - 1].TLSMethodMin); - } - if(sr_tls_methods[d->method - 1].TLSMethodMax) { - SSL_CTX_set_max_proto_version(d->ctx[i], - sr_tls_methods[d->method - 1].TLSMethodMax); - } - } -#endif + wolfSSL_CTX_set_min_proto_version(d->ctx[0], TLS1_2_VERSION); /* * check server domains for server_name extension and register @@ -1017,22 +942,22 @@ static int ksr_tls_fix_domain(tls_domain_t *d, tls_domain_t *def) if((d->type & TLS_DOMAIN_SRV) && (d->server_name.len > 0 || (d->type & TLS_DOMAIN_DEF))) { if(!wolfSSL_CTX_set_tlsext_servername_callback( - d->ctx[i], tls_server_name_cb)) { + d->ctx[0], tls_server_name_cb)) { LM_ERR("register server_name callback handler for socket " "[%s:%d], server_name='%s' failed for proc %d\n", ip_addr2a(&d->ip), d->port, - (d->server_name.s) ? d->server_name.s : "", i); + (d->server_name.s) ? d->server_name.s : "", 0); return -1; } - if(!wolfSSL_CTX_set_servername_arg(d->ctx[i], d)) { + if(!wolfSSL_CTX_set_servername_arg(d->ctx[0], d)) { LM_ERR("register server_name callback handler data for socket " "[%s:%d], server_name='%s' failed for proc %d\n", ip_addr2a(&d->ip), d->port, - (d->server_name.s) ? d->server_name.s : "", i); + (d->server_name.s) ? d->server_name.s : "", 0); return -1; } } - } + } while(0); if((d->type & TLS_DOMAIN_SRV) && (d->server_name.len > 0 || (d->type & TLS_DOMAIN_DEF))) { @@ -1065,8 +990,7 @@ static int ksr_tls_fix_domain(tls_domain_t *d, tls_domain_t *def) */ static int load_private_key(tls_domain_t *d) { - int idx, ret_pwd, i; - int procs_no; + int idx, ret_pwd; if(!d->pkey_file.s || !d->pkey_file.len) { DBG("%s: No private key specified\n", tls_domain_str(d)); @@ -1075,12 +999,11 @@ static int load_private_key(tls_domain_t *d) if(fix_shm_pathname(&d->pkey_file) < 0) return -1; - procs_no = get_max_procs(); - for(i = 0; i < procs_no; i++) { + do { for(idx = 0, ret_pwd = 0; idx < 3; idx++) { ret_pwd = wolfSSL_CTX_use_PrivateKey_file( - d->ctx[i], d->pkey_file.s, SSL_FILETYPE_PEM); + d->ctx[0], d->pkey_file.s, SSL_FILETYPE_PEM); if(ret_pwd) { break; } else { @@ -1097,14 +1020,14 @@ static int load_private_key(tls_domain_t *d) TLS_ERR("load_private_key:"); return -1; } - if(!wolfSSL_CTX_check_private_key(d->ctx[i])) { + if(!wolfSSL_CTX_check_private_key(d->ctx[0])) { ERR("%s: Key '%s' does not match the public key of the" " certificate\n", tls_domain_str(d), d->pkey_file.s); TLS_ERR("load_private_key:"); return -1; } - } + } while(0); DBG("%s: Key '%s' successfully loaded\n", tls_domain_str(d), d->pkey_file.s); diff --git a/src/modules/tls_wolfssl/tls_dump_vf.c b/src/modules/tls_wolfssl/tls_dump_vf.c deleted file mode 100644 index c8fcd88c7..000000000 --- a/src/modules/tls_wolfssl/tls_dump_vf.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * TLS module - * - * Copyright (C) 2006 enum.at - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Exception: permission to copy, modify, propagate, and distribute a work - * formed by combining OpenSSL toolkit software and the code in this file, - * such as linking with software components and libraries released under - * OpenSSL project license. - */ - -/** log the verification failure reason. - * @file tls_dump_vf.c - * @ingroup: tls - * Module: @ref tls - */ - -#include "tls_dump_vf.h" - -#include -#include -#include "../../core/dprint.h" -#include "tls_wolfssl_mod.h" -#include "tls_cfg.h" - -/** log the verification failure reason. - */ -void tls_dump_verification_failure(long verification_result) -{ - int tls_log; - - tls_log = cfg_get(tls, tls_cfg, log); - switch(verification_result) { - case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: - LOG(tls_log, - "verification failure: unable to get issuer certificate\n"); - break; - case X509_V_ERR_UNABLE_TO_GET_CRL: - LOG(tls_log, - "verification failure: unable to get certificate CRL\n"); - break; - case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: - LOG(tls_log, "verification failure: unable to decrypt " - "certificate's signature\n"); - break; - case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: - LOG(tls_log, "verification failure: unable to decrypt CRL's " - "signature\n"); - break; - case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: - LOG(tls_log, "verification failure: unable to decode issuer public " - "key\n"); - break; - case X509_V_ERR_CERT_SIGNATURE_FAILURE: - LOG(tls_log, - "verification failure: certificate signature failure\n"); - break; - case X509_V_ERR_CRL_SIGNATURE_FAILURE: - LOG(tls_log, "verification failure: CRL signature failure\n"); - break; - case X509_V_ERR_CERT_NOT_YET_VALID: - LOG(tls_log, - "verification failure: certificate is not yet valid\n"); - break; - case X509_V_ERR_CERT_HAS_EXPIRED: - LOG(tls_log, "verification failure: certificate has expired\n"); - break; - case X509_V_ERR_CRL_NOT_YET_VALID: - LOG(tls_log, "verification failure: CRL is not yet valid\n"); - break; - case X509_V_ERR_CRL_HAS_EXPIRED: - LOG(tls_log, "verification failure: CRL has expired\n"); - break; - case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: - LOG(tls_log, "verification failure: format error in certificate's " - "notBefore field\n"); - break; - case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: - LOG(tls_log, "verification failure: format error in certificate's " - "notAfter field\n"); - break; - case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: - LOG(tls_log, "verification failure: format error in CRL's " - "lastUpdate field\n"); - break; - case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: - LOG(tls_log, "verification failure: format error in CRL's " - "nextUpdate field\n"); - break; - case X509_V_ERR_OUT_OF_MEM: - LOG(tls_log, "verification failure: out of memory\n"); - break; - case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: - LOG(tls_log, "verification failure: self signed certificate\n"); - break; - case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: - LOG(tls_log, "verification failure: self signed certificate in " - "certificate chain\n"); - break; - case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: - LOG(tls_log, "verification failure: unable to get local issuer " - "certificate\n"); - break; - case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: - LOG(tls_log, "verification failure: unable to verify the first " - "certificate\n"); - break; - case X509_V_ERR_CERT_CHAIN_TOO_LONG: - LOG(tls_log, "verification failure: certificate chain too long\n"); - break; - case X509_V_ERR_CERT_REVOKED: - LOG(tls_log, "verification failure: certificate revoked\n"); - break; - case X509_V_ERR_INVALID_CA: - LOG(tls_log, "verification failure: invalid CA certificate\n"); - break; - case X509_V_ERR_PATH_LENGTH_EXCEEDED: - LOG(tls_log, - "verification failure: path length constraint exceeded\n"); - break; - case X509_V_ERR_INVALID_PURPOSE: - LOG(tls_log, - "verification failure: unsupported certificate purpose\n"); - break; - case X509_V_ERR_CERT_UNTRUSTED: - LOG(tls_log, "verification failure: certificate not trusted\n"); - break; - case X509_V_ERR_CERT_REJECTED: - LOG(tls_log, "verification failure: certificate rejected\n"); - break; - case X509_V_ERR_SUBJECT_ISSUER_MISMATCH: - LOG(tls_log, "verification failure: subject issuer mismatch\n"); - break; - case X509_V_ERR_AKID_SKID_MISMATCH: - LOG(tls_log, "verification failure: authority and subject key " - "identifier mismatch\n"); - break; - case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: - LOG(tls_log, "verification failure: authority and issuer serial " - "number mismatch\n"); - break; - case X509_V_ERR_KEYUSAGE_NO_CERTSIGN: - LOG(tls_log, "verification failure: key usage does not include " - "certificate signing\n"); - break; - case X509_V_ERR_APPLICATION_VERIFICATION: - LOG(tls_log, - "verification failure: application verification failure\n"); - break; - } -} - - -/* vi: set ts=4 sw=4 tw=79:ai:cindent: */ diff --git a/src/modules/tls_wolfssl/tls_init.c b/src/modules/tls_wolfssl/tls_init.c index 9675ef432..2c8c4a496 100644 --- a/src/modules/tls_wolfssl/tls_init.c +++ b/src/modules/tls_wolfssl/tls_init.c @@ -318,73 +318,61 @@ static void init_ssl_methods(void) memset(sr_tls_methods, 0, sizeof(sr_tls_methods)); /* any SSL/TLS version */ - sr_tls_methods[TLS_USE_SSLv23_cli - 1].TLSMethod = TLS_client_method(); - sr_tls_methods[TLS_USE_SSLv23_srv - 1].TLSMethod = TLS_server_method(); - sr_tls_methods[TLS_USE_SSLv23 - 1].TLSMethod = TLS_method(); - -#ifndef OPENSSL_NO_SSL3_METHOD - sr_tls_methods[TLS_USE_SSLv3_cli - 1].TLSMethod = TLS_client_method(); - sr_tls_methods[TLS_USE_SSLv3_cli - 1].TLSMethodMin = SSL3_VERSION; - sr_tls_methods[TLS_USE_SSLv3_cli - 1].TLSMethodMax = SSL3_VERSION; - sr_tls_methods[TLS_USE_SSLv3_srv - 1].TLSMethod = TLS_server_method(); - sr_tls_methods[TLS_USE_SSLv3_srv - 1].TLSMethodMin = SSL3_VERSION; - sr_tls_methods[TLS_USE_SSLv3_srv - 1].TLSMethodMax = SSL3_VERSION; - sr_tls_methods[TLS_USE_SSLv3 - 1].TLSMethod = TLS_method(); - sr_tls_methods[TLS_USE_SSLv3 - 1].TLSMethodMin = SSL3_VERSION; - sr_tls_methods[TLS_USE_SSLv3 - 1].TLSMethodMax = SSL3_VERSION; -#endif + sr_tls_methods[TLS_USE_SSLv23_cli - 1].TLSMethod = wolfTLS_client_method(); + sr_tls_methods[TLS_USE_SSLv23_srv - 1].TLSMethod = wolfTLS_server_method(); + sr_tls_methods[TLS_USE_SSLv23 - 1].TLSMethod = wolfSSLv23_method(); - sr_tls_methods[TLS_USE_TLSv1_cli - 1].TLSMethod = TLS_client_method(); + sr_tls_methods[TLS_USE_TLSv1_cli - 1].TLSMethod = wolfTLS_client_method(); sr_tls_methods[TLS_USE_TLSv1_cli - 1].TLSMethodMin = TLS1_VERSION; sr_tls_methods[TLS_USE_TLSv1_cli - 1].TLSMethodMax = TLS1_VERSION; - sr_tls_methods[TLS_USE_TLSv1_srv - 1].TLSMethod = TLS_server_method(); + sr_tls_methods[TLS_USE_TLSv1_srv - 1].TLSMethod = wolfTLS_server_method(); sr_tls_methods[TLS_USE_TLSv1_srv - 1].TLSMethodMin = TLS1_VERSION; sr_tls_methods[TLS_USE_TLSv1_srv - 1].TLSMethodMax = TLS1_VERSION; - sr_tls_methods[TLS_USE_TLSv1 - 1].TLSMethod = TLS_method(); + sr_tls_methods[TLS_USE_TLSv1 - 1].TLSMethod = wolfSSLv23_method(); sr_tls_methods[TLS_USE_TLSv1 - 1].TLSMethodMin = TLS1_VERSION; sr_tls_methods[TLS_USE_TLSv1 - 1].TLSMethodMax = TLS1_VERSION; - sr_tls_methods[TLS_USE_TLSv1_1_cli - 1].TLSMethod = TLS_client_method(); + sr_tls_methods[TLS_USE_TLSv1_1_cli - 1].TLSMethod = wolfTLS_client_method(); sr_tls_methods[TLS_USE_TLSv1_1_cli - 1].TLSMethodMin = TLS1_1_VERSION; sr_tls_methods[TLS_USE_TLSv1_1_cli - 1].TLSMethodMax = TLS1_1_VERSION; - sr_tls_methods[TLS_USE_TLSv1_1_srv - 1].TLSMethod = TLS_server_method(); + sr_tls_methods[TLS_USE_TLSv1_1_srv - 1].TLSMethod = wolfTLS_server_method(); sr_tls_methods[TLS_USE_TLSv1_1_srv - 1].TLSMethodMin = TLS1_1_VERSION; sr_tls_methods[TLS_USE_TLSv1_1_srv - 1].TLSMethodMax = TLS1_1_VERSION; - sr_tls_methods[TLS_USE_TLSv1_1 - 1].TLSMethod = TLS_method(); + sr_tls_methods[TLS_USE_TLSv1_1 - 1].TLSMethod = wolfSSLv23_method(); sr_tls_methods[TLS_USE_TLSv1_1 - 1].TLSMethodMin = TLS1_1_VERSION; sr_tls_methods[TLS_USE_TLSv1_1 - 1].TLSMethodMax = TLS1_1_VERSION; - sr_tls_methods[TLS_USE_TLSv1_2_cli - 1].TLSMethod = TLS_client_method(); + sr_tls_methods[TLS_USE_TLSv1_2_cli - 1].TLSMethod = wolfTLS_client_method(); sr_tls_methods[TLS_USE_TLSv1_2_cli - 1].TLSMethodMin = TLS1_2_VERSION; sr_tls_methods[TLS_USE_TLSv1_2_cli - 1].TLSMethodMax = TLS1_2_VERSION; - sr_tls_methods[TLS_USE_TLSv1_2_srv - 1].TLSMethod = TLS_server_method(); + sr_tls_methods[TLS_USE_TLSv1_2_srv - 1].TLSMethod = wolfTLS_server_method(); sr_tls_methods[TLS_USE_TLSv1_2_srv - 1].TLSMethodMin = TLS1_2_VERSION; sr_tls_methods[TLS_USE_TLSv1_2_srv - 1].TLSMethodMax = TLS1_2_VERSION; - sr_tls_methods[TLS_USE_TLSv1_2 - 1].TLSMethod = TLS_method(); + sr_tls_methods[TLS_USE_TLSv1_2 - 1].TLSMethod = wolfSSLv23_method(); sr_tls_methods[TLS_USE_TLSv1_2 - 1].TLSMethodMin = TLS1_2_VERSION; sr_tls_methods[TLS_USE_TLSv1_2 - 1].TLSMethodMax = TLS1_2_VERSION; - sr_tls_methods[TLS_USE_TLSv1_3_cli - 1].TLSMethod = TLS_client_method(); + sr_tls_methods[TLS_USE_TLSv1_3_cli - 1].TLSMethod = wolfTLS_client_method(); sr_tls_methods[TLS_USE_TLSv1_3_cli - 1].TLSMethodMin = TLS1_3_VERSION; sr_tls_methods[TLS_USE_TLSv1_3_cli - 1].TLSMethodMax = TLS1_3_VERSION; - sr_tls_methods[TLS_USE_TLSv1_3_srv - 1].TLSMethod = TLS_server_method(); + sr_tls_methods[TLS_USE_TLSv1_3_srv - 1].TLSMethod = wolfTLS_server_method(); sr_tls_methods[TLS_USE_TLSv1_3_srv - 1].TLSMethodMin = TLS1_3_VERSION; sr_tls_methods[TLS_USE_TLSv1_3_srv - 1].TLSMethodMax = TLS1_3_VERSION; - sr_tls_methods[TLS_USE_TLSv1_3 - 1].TLSMethod = TLS_method(); + sr_tls_methods[TLS_USE_TLSv1_3 - 1].TLSMethod = wolfSSLv23_method(); sr_tls_methods[TLS_USE_TLSv1_3 - 1].TLSMethodMin = TLS1_3_VERSION; sr_tls_methods[TLS_USE_TLSv1_3 - 1].TLSMethodMax = TLS1_3_VERSION; /* ranges of TLS versions (require a minimum TLS version) */ - sr_tls_methods[TLS_USE_TLSv1_PLUS - 1].TLSMethod = TLS_method(); + sr_tls_methods[TLS_USE_TLSv1_PLUS - 1].TLSMethod = wolfSSLv23_method(); sr_tls_methods[TLS_USE_TLSv1_PLUS - 1].TLSMethodMin = TLS1_VERSION; - sr_tls_methods[TLS_USE_TLSv1_1_PLUS - 1].TLSMethod = TLS_method(); + sr_tls_methods[TLS_USE_TLSv1_1_PLUS - 1].TLSMethod = wolfSSLv23_method(); sr_tls_methods[TLS_USE_TLSv1_1_PLUS - 1].TLSMethodMin = TLS1_1_VERSION; - sr_tls_methods[TLS_USE_TLSv1_2_PLUS - 1].TLSMethod = TLS_method(); + sr_tls_methods[TLS_USE_TLSv1_2_PLUS - 1].TLSMethod = wolfSSLv23_method(); sr_tls_methods[TLS_USE_TLSv1_2_PLUS - 1].TLSMethodMin = TLS1_2_VERSION; - sr_tls_methods[TLS_USE_TLSv1_3_PLUS - 1].TLSMethod = TLS_method(); + sr_tls_methods[TLS_USE_TLSv1_3_PLUS - 1].TLSMethod = wolfSSLv23_method(); sr_tls_methods[TLS_USE_TLSv1_3_PLUS - 1].TLSMethodMin = TLS1_3_VERSION; } diff --git a/src/modules/tls_wolfssl/tls_init.h b/src/modules/tls_wolfssl/tls_init.h index 8c9fd567f..cf24854ff 100644 --- a/src/modules/tls_wolfssl/tls_init.h +++ b/src/modules/tls_wolfssl/tls_init.h @@ -27,14 +27,12 @@ #ifndef _TLS_INIT_H #define _TLS_INIT_H -#include -#include #include "../../core/ip_addr.h" #include "tls_domain.h" typedef struct sr_tls_methods_s { - const SSL_METHOD *TLSMethod; + const WOLFSSL_METHOD *TLSMethod; int TLSMethodMin; int TLSMethodMax; } sr_tls_methods_t; diff --git a/src/modules/tls_wolfssl/tls_map.c b/src/modules/tls_wolfssl/tls_map.c deleted file mode 100644 index 70c275d31..000000000 --- a/src/modules/tls_wolfssl/tls_map.c +++ /dev/null @@ -1,213 +0,0 @@ -/** - * Copyright (c) 2014 rxi - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MIT license. See LICENSE for details. - */ - -#include -#include - -#include "../../core/mem/mem.h" -#include "tls_map.h" - -struct map_node_t -{ - unsigned hash; - void *value; - map_node_t *next; - /* char key[]; */ - /* char value[]; */ -}; - - -static unsigned map_hash(const char *str) -{ - unsigned hash = 5381; - while(*str) { - hash = ((hash << 5) + hash) ^ *str++; - } - return hash; -} - - -static map_node_t *map_newnode(const char *key, void *value, int vsize) -{ - map_node_t *node; - int ksize = strlen(key) + 1; - int voffset = ksize + ((sizeof(void *) - ksize) % sizeof(void *)); - node = pkg_malloc(sizeof(*node) + voffset + vsize); - if(!node) - return NULL; - memcpy(node + 1, key, ksize); - node->hash = map_hash(key); - node->value = ((char *)(node + 1)) + voffset; - memcpy(node->value, value, vsize); - return node; -} - - -static int map_bucketidx(map_base_t *m, unsigned hash) -{ - /* If the implementation is changed to allow a non-power-of-2 bucket count, - * the line below should be changed to use mod instead of AND */ - return hash & (m->nbuckets - 1); -} - - -static void map_addnode(map_base_t *m, map_node_t *node) -{ - int n = map_bucketidx(m, node->hash); - node->next = m->buckets[n]; - m->buckets[n] = node; -} - - -static int map_resize(map_base_t *m, int nbuckets) -{ - map_node_t *nodes, *node, *next; - map_node_t **buckets; - int i; - /* Chain all nodes together */ - nodes = NULL; - i = m->nbuckets; - while(i--) { - node = (m->buckets)[i]; - while(node) { - next = node->next; - node->next = nodes; - nodes = node; - node = next; - } - } - /* Reset buckets */ - buckets = realloc(m->buckets, sizeof(*m->buckets) * nbuckets); - if(buckets != NULL) { - m->buckets = buckets; - m->nbuckets = nbuckets; - } - if(m->buckets) { - memset(m->buckets, 0, sizeof(*m->buckets) * m->nbuckets); - /* Re-add nodes to buckets */ - node = nodes; - while(node) { - next = node->next; - map_addnode(m, node); - node = next; - } - } - /* Return error code if realloc() failed */ - return (buckets == NULL) ? -1 : 0; -} - - -static map_node_t **map_getref(map_base_t *m, const char *key) -{ - unsigned hash = map_hash(key); - map_node_t **next; - if(m->nbuckets > 0) { - next = &m->buckets[map_bucketidx(m, hash)]; - while(*next) { - if((*next)->hash == hash && !strcmp((char *)(*next + 1), key)) { - return next; - } - next = &(*next)->next; - } - } - return NULL; -} - - -void map_deinit_(map_base_t *m) -{ - map_node_t *next, *node; - int i; - i = m->nbuckets; - while(i--) { - node = m->buckets[i]; - while(node) { - next = node->next; - pkg_free(node); - node = next; - } - } - pkg_free(m->buckets); -} - - -void *map_get_(map_base_t *m, const char *key) -{ - map_node_t **next = map_getref(m, key); - return next ? (*next)->value : NULL; -} - - -int map_set_(map_base_t *m, const char *key, void *value, int vsize) -{ - int n, err; - map_node_t **next, *node; - /* Find & replace existing node */ - next = map_getref(m, key); - if(next) { - memcpy((*next)->value, value, vsize); - return 0; - } - /* Add new node */ - node = map_newnode(key, value, vsize); - if(node == NULL) - goto fail; - if(m->nnodes >= m->nbuckets) { - n = (m->nbuckets > 0) ? (m->nbuckets << 1) : 1; - err = map_resize(m, n); - if(err) - goto fail; - } - map_addnode(m, node); - m->nnodes++; - return 0; -fail: - if(node) - pkg_free(node); - return -1; -} - - -void map_remove_(map_base_t *m, const char *key) -{ - map_node_t *node; - map_node_t **next = map_getref(m, key); - if(next) { - node = *next; - *next = (*next)->next; - pkg_free(node); - m->nnodes--; - } -} - - -map_iter_t map_iter_(void) -{ - map_iter_t iter; - iter.bucketidx = -1; - iter.node = NULL; - return iter; -} - - -const char *map_next_(map_base_t *m, map_iter_t *iter) -{ - if(iter->node) { - iter->node = iter->node->next; - if(iter->node == NULL) - goto nextBucket; - } else { - nextBucket: - do { - if(++iter->bucketidx >= m->nbuckets) { - return NULL; - } - iter->node = m->buckets[iter->bucketidx]; - } while(iter->node == NULL); - } - return (char *)(iter->node + 1); -} diff --git a/src/modules/tls_wolfssl/tls_map.h b/src/modules/tls_wolfssl/tls_map.h deleted file mode 100644 index e4028a302..000000000 --- a/src/modules/tls_wolfssl/tls_map.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Copyright (c) 2014 rxi - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MIT license. See LICENSE for details. - */ - -#ifndef _TLS_MAP_H -#define _TLS_MAP_H - -#include - -#define MAP_VERSION "0.1.0" - -struct map_node_t; -typedef struct map_node_t map_node_t; - -typedef struct -{ - map_node_t **buckets; - unsigned nbuckets, nnodes; -} map_base_t; - -typedef struct -{ - unsigned bucketidx; - map_node_t *node; -} map_iter_t; - - -#define map_t(T) \ - struct \ - { \ - map_base_t base; \ - T *ref; \ - T tmp; \ - } - - -#define map_init(m) memset(m, 0, sizeof(*(m))) - - -#define map_deinit(m) map_deinit_(&(m)->base) - - -#define map_get(m, key) ((m)->ref = map_get_(&(m)->base, key)) - - -#define map_set(m, key, value) \ - ((m)->tmp = (value), map_set_(&(m)->base, key, &(m)->tmp, sizeof((m)->tmp))) - - -#define map_remove(m, key) map_remove_(&(m)->base, key) - - -#define map_iter(m) map_iter_() - - -#define map_next(m, iter) map_next_(&(m)->base, iter) - - -void map_deinit_(map_base_t *m); -void *map_get_(map_base_t *m, const char *key); -int map_set_(map_base_t *m, const char *key, void *value, int vsize); -void map_remove_(map_base_t *m, const char *key); -map_iter_t map_iter_(void); -const char *map_next_(map_base_t *m, map_iter_t *iter); - - -typedef map_t(void *) map_void_t; -typedef map_t(char *) map_str_t; -typedef map_t(int) map_int_t; -typedef map_t(char) map_char_t; -typedef map_t(float) map_float_t; -typedef map_t(double) map_double_t; - -#endif /* _TLS_MAP_H */ diff --git a/src/modules/tls_wolfssl/tls_rand.c b/src/modules/tls_wolfssl/tls_rand.c deleted file mode 100644 index 87ab83c48..000000000 --- a/src/modules/tls_wolfssl/tls_rand.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * TLS module - * - * Copyright (C) 2019 Asipto GmbH - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * OpenSSL docs: - * https://www.openssl.org/docs/man1.1.1/man7/RAND.html - * https://www.openssl.org/docs/man1.1.1/man3/RAND_set_rand_method.html - */ - -#include -#include -#include -#include - -#include "tls_rand.h" - - -#include "../../core/dprint.h" -#include "../../core/locking.h" -#include "../../core/mem/shm.h" -#include "../../core/rand/kam_rand.h" -#include "../../core/rand/fastrand.h" -#include "../../core/rand/fortuna/random.h" - -/* - * Implementation for tests with system library PNRG, - * do not use this in production. - */ -static int ksr_krand_bytes(unsigned char *outdata, int size) -{ - int r; - - if(size < 0) { - return 0; - } else if(size == 0) { - return 1; - } - - while(size >= sizeof(int)) { - r = kam_rand(); - memcpy(outdata, &r, sizeof(int)); - size -= sizeof(int); - outdata += sizeof(int); - } - if(size > 0) { - r = kam_rand(); - memcpy(outdata, &r, size); - } - return 1; -} - -static int ksr_krand_pseudorand(unsigned char *outdata, int size) -{ - return ksr_krand_bytes(outdata, size); -} - -static int ksr_krand_status(void) -{ - return 1; -} - -const WOLFSSL_RAND_METHOD _ksr_krand_method = {NULL, ksr_krand_bytes, NULL, - NULL, ksr_krand_pseudorand, ksr_krand_status}; - -const WOLFSSL_RAND_METHOD *RAND_ksr_krand_method(void) -{ - return &_ksr_krand_method; -} - -/* - * Implementation for tests with fastrand implementation, - * better as system library but still not secure enough. - * Do not use this in production.y - */ -static int ksr_fastrand_bytes(unsigned char *outdata, int size) -{ - int r; - - if(size < 0) { - return 0; - } else if(size == 0) { - return 1; - } - - while(size >= sizeof(int)) { - r = fastrand(); - memcpy(outdata, &r, sizeof(int)); - size -= sizeof(int); - outdata += sizeof(int); - } - if(size > 0) { - r = fastrand(); - memcpy(outdata, &r, size); - } - return 1; -} - -static int ksr_fastrand_pseudorand(unsigned char *outdata, int size) -{ - return ksr_fastrand_bytes(outdata, size); -} - -static int ksr_fastrand_status(void) -{ - return 1; -} - -const WOLFSSL_RAND_METHOD _ksr_fastrand_method = {NULL, ksr_fastrand_bytes, - NULL, NULL, ksr_fastrand_pseudorand, ksr_fastrand_status}; - -const WOLFSSL_RAND_METHOD *RAND_ksr_fastrand_method(void) -{ - return &_ksr_fastrand_method; -} - -/* - * Implementation with Fortuna cryptographic PRNG. - * We are not strictly implementing the OpenSSL API here - we will - * not return an error if the PRNG has not been seeded with enough - * randomness to ensure an unpredictable byte sequence. - */ -static int ksr_cryptorand_bytes(unsigned char *outdata, int size) -{ - if(size < 0) { - return 0; - } else if(size == 0) { - return 1; - } - - sr_get_pseudo_random_bytes(outdata, size); - return 1; -} - -static int ksr_cryptorand_status(void) -{ - return 1; -} - -/* - * We don't have a dedicated function for pseudo-random - * bytes, just use the secure version as well for it. - */ -const WOLFSSL_RAND_METHOD _ksr_cryptorand_method = {NULL, ksr_cryptorand_bytes, - NULL, NULL, ksr_cryptorand_bytes, ksr_cryptorand_status}; - -const WOLFSSL_RAND_METHOD *RAND_ksr_cryptorand_method(void) -{ - return &_ksr_cryptorand_method; -} - -/** - * PRNG by using default libssl random engine protected by lock - */ -// WOLFFIX no libssl rand method diff --git a/src/modules/tls_wolfssl/tls_rand.h b/src/modules/tls_wolfssl/tls_rand.h deleted file mode 100644 index b9d97f4b4..000000000 --- a/src/modules/tls_wolfssl/tls_rand.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * TLS module - * - * Copyright (C) 2019 Asipto GmbH - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - - -#ifndef _TLS_RAND_H_ -#define _TLS_RAND_H_ -#include -#include - -const WOLFSSL_RAND_METHOD *RAND_ksr_krand_method(void); -const WOLFSSL_RAND_METHOD *RAND_ksr_fastrand_method(void); -const WOLFSSL_RAND_METHOD *RAND_ksr_cryptorand_method(void); -// WOLFFIX const WOLFSSL_RAND_METHOD *RAND_ksr_kxlibssl_method(void); - -#endif diff --git a/src/modules/tls_wolfssl/tls_rpc.c b/src/modules/tls_wolfssl/tls_rpc.c index 40a53c354..ece8b77ff 100644 --- a/src/modules/tls_wolfssl/tls_rpc.c +++ b/src/modules/tls_wolfssl/tls_rpc.c @@ -186,16 +186,13 @@ static void tls_list(rpc_t *rpc, void *c) state = "established"; break; } - rpc->struct_add(handle, "sddds", "cipher", tls_info, + rpc->struct_add(handle, "sdds", "cipher", tls_info, "ct_wq_size", tls_d->ct_wq ? tls_d->ct_wq->queued : 0, - "enc_rd_buf", - tls_d->enc_rd_buf ? tls_d->enc_rd_buf->size : 0, "flags", tls_d->flags, "state", state); lock_release(&con->write_lock); } else { - rpc->struct_add(handle, "sddds", "cipher", "unknown", - "ct_wq_size", 0, "enc_rd_buf", 0, "flags", 0, "state", - "pre-init"); + rpc->struct_add(handle, "sdds", "cipher", "unknown", + "ct_wq_size", 0, "flags", 0, "state", "pre-init"); } } } @@ -225,15 +222,14 @@ static void tls_options(rpc_t *rpc, void *c) { void *handle; rpc->add(c, "{", &handle); - rpc->struct_add(handle, "dSdddSSSSSdSSdddddddddddddd", "force_run", + rpc->struct_add(handle, "dSdddSSSSSdSSdddddddddddd", "force_run", cfg_get(tls, tls_cfg, force_run), "method", &cfg_get(tls, tls_cfg, method), "verify_certificate", - cfg_get(tls, tls_cfg, verify_cert), - - "verify_depth", cfg_get(tls, tls_cfg, verify_depth), - "require_certificate", cfg_get(tls, tls_cfg, require_cert), - "verify_client", &cfg_get(tls, tls_cfg, verify_client), - "private_key", &cfg_get(tls, tls_cfg, private_key), "ca_list", + cfg_get(tls, tls_cfg, verify_cert), "verify_depth", + cfg_get(tls, tls_cfg, verify_depth), "require_certificate", + cfg_get(tls, tls_cfg, require_cert), "verify_client", + &cfg_get(tls, tls_cfg, verify_client), "private_key", + &cfg_get(tls, tls_cfg, private_key), "ca_list", &cfg_get(tls, tls_cfg, ca_list), "certificate", &cfg_get(tls, tls_cfg, certificate), "cipher_list", &cfg_get(tls, tls_cfg, cipher_list), "session_cache", @@ -249,9 +245,7 @@ static void tls_options(rpc_t *rpc, void *c) "ssl_max_send_fragment", cfg_get(tls, tls_cfg, ssl_max_send_fragment), "ssl_read_ahead", cfg_get(tls, tls_cfg, ssl_read_ahead), "send_close_notify", - cfg_get(tls, tls_cfg, send_close_notify), "low_mem_threshold1", - cfg_get(tls, tls_cfg, low_mem_threshold1), "low_mem_threshold2", - cfg_get(tls, tls_cfg, low_mem_threshold2), "ct_wq_max", + cfg_get(tls, tls_cfg, send_close_notify), "ct_wq_max", cfg_get(tls, tls_cfg, ct_wq_max), "con_ct_wq_max", cfg_get(tls, tls_cfg, con_ct_wq_max), "ct_wq_blk_size", cfg_get(tls, tls_cfg, ct_wq_blk_size)); diff --git a/src/modules/tls_wolfssl/tls_select.c b/src/modules/tls_wolfssl/tls_select.c index 662d4b71a..fc83eec89 100644 --- a/src/modules/tls_wolfssl/tls_select.c +++ b/src/modules/tls_wolfssl/tls_select.c @@ -158,10 +158,10 @@ static SSL *get_ssl(struct tcp_connection *c) } -static int get_cert( - X509 **cert, struct tcp_connection **c, struct sip_msg *msg, int my) +static int get_cert(WOLFSSL_X509 **cert, struct tcp_connection **c, + struct sip_msg *msg, int my) { - SSL *ssl; + WOLFSSL *ssl; *cert = 0; *c = get_cur_connection(msg); @@ -197,7 +197,7 @@ static int get_cipher(str *res, sip_msg_t *msg) static char buf[1024]; struct tcp_connection *c; - SSL *ssl; + WOLFSSL *ssl; c = get_cur_connection(msg); if(!c) { @@ -253,7 +253,7 @@ static int get_bits(str *res, long *i, sip_msg_t *msg) static char buf[1024]; struct tcp_connection *c; - SSL *ssl; + WOLFSSL *ssl; c = get_cur_connection(msg); if(!c) { @@ -404,17 +404,17 @@ static int pv_desc(sip_msg_t *msg, pv_param_t *param, pv_value_t *res) static int get_cert_version(str *res, int local, sip_msg_t *msg) { static char buf[INT2STR_MAX_LEN]; - X509 *cert; + WOLFSSL_X509 *cert; struct tcp_connection *c; char *version; if(get_cert(&cert, &c, msg, local) < 0) return -1; - version = int2str(X509_get_version(cert), &res->len); + version = int2str(wolfSSL_X509_get_version(cert), &res->len); memcpy(buf, version, res->len); res->s = buf; if(!local) - X509_free(cert); + wolfSSL_X509_free(cert); tcpconn_put(c); return 0; } @@ -470,7 +470,7 @@ static int check_cert(str *res, long *ires, int local, int err, sip_msg_t *msg) struct tcp_connection *c; SSL *ssl; - X509 *cert = 0; + WOLFSSL_X509 *cert = 0; c = get_cur_connection(msg); if(!c) @@ -485,7 +485,7 @@ static int check_cert(str *res, long *ires, int local, int err, sip_msg_t *msg) goto error; } else { if((cert = wolfSSL_get_peer_certificate(ssl)) - && SSL_get_verify_result(ssl) == err) { + && wolfSSL_get_verify_result(ssl) == err) { *res = succ; if(ires) *ires = 1; @@ -497,7 +497,7 @@ static int check_cert(str *res, long *ires, int local, int err, sip_msg_t *msg) } if(cert) - X509_free(cert); + wolfSSL_X509_free(cert); tcpconn_put(c); return 0; @@ -583,21 +583,21 @@ static int get_validity(str *res, int local, int bound, sip_msg_t *msg) #define NOT_BEFORE 0 #define NOT_AFTER 1 static char buf[1024]; - X509 *cert; + WOLFSSL_X509 *cert; struct tcp_connection *c; - BUF_MEM *p; - BIO *mem = 0; - ASN1_TIME *date; + WOLFSSL_BUF_MEM *p; + WOLFSSL_BIO *mem = 0; + WOLFSSL_ASN1_TIME *date; if(get_cert(&cert, &c, msg, local) < 0) return -1; switch(bound) { case NOT_BEFORE: - date = X509_get_notBefore(cert); + date = wolfSSL_X509_get_notBefore(cert); break; case NOT_AFTER: - date = X509_get_notAfter(cert); + date = wolfSSL_X509_get_notAfter(cert); break; default: BUG("Unexpected parameter value \"%d\"\n", bound); @@ -610,12 +610,12 @@ static int get_validity(str *res, int local, int bound, sip_msg_t *msg) goto err; } - if(!ASN1_TIME_print(mem, date)) { + if(!wolfSSL_ASN1_TIME_print(mem, date)) { ERR("Error while printing certificate date/time\n"); goto err; } - BIO_get_mem_ptr(mem, &p); + wolfSSL_BIO_get_mem_ptr(mem, &p); if(p->length >= 1024) { ERR("Date/time too long\n"); goto err; @@ -624,16 +624,16 @@ static int get_validity(str *res, int local, int bound, sip_msg_t *msg) res->s = buf; res->len = p->length; - BIO_free(mem); + wolfSSL_BIO_free(mem); if(!local) - X509_free(cert); + wolfSSL_X509_free(cert); tcpconn_put(c); return 0; err: if(mem) - BIO_free(mem); + wolfSSL_BIO_free(mem); if(!local) - X509_free(cert); + wolfSSL_X509_free(cert); tcpconn_put(c); return -1; } @@ -699,7 +699,7 @@ static int pv_validity(sip_msg_t *msg, pv_param_t *param, pv_value_t *res) static int get_sn(str *res, int local, sip_msg_t *msg) { static char buf[80]; // > log(2^256,10) - X509 *cert; + WOLFSSL_X509 *cert; struct tcp_connection *c; char *sn = NULL; WOLFSSL_BIGNUM *bn = NULL; @@ -718,7 +718,7 @@ static int get_sn(str *res, int local, sip_msg_t *msg) res->s = buf; if(!local) - X509_free(cert); + wolfSSL_X509_free(cert); tcpconn_put(c); wolfSSL_OPENSSL_free(sn); wolfSSL_BN_free(bn); @@ -777,7 +777,7 @@ static int cert_to_buf(X509 *cert, char **bufptr, size_t *len) { #define MAX_CERT_SIZE 16384 static char buf[MAX_CERT_SIZE]; - BIO *mem = NULL; + WOLFSSL_BIO *mem = NULL; mem = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()); if(!mem) { @@ -786,29 +786,29 @@ static int cert_to_buf(X509 *cert, char **bufptr, size_t *len) } /* Write a certificate to a BIO */ - if(!PEM_write_bio_X509(mem, cert)) { + if(!wolfSSL_PEM_write_bio_X509(mem, cert)) { goto err; } - *len = BIO_pending(mem); + *len = wolfSSL_BIO_pending(mem); if(*len > MAX_CERT_SIZE) { ERR("certificate is too long\n"); goto err; } - if(BIO_read(mem, buf, *len) <= 0) { + if(wolfSSL_BIO_read(mem, buf, *len) <= 0) { ERR("problem reading data out of BIO"); goto err; } *bufptr = buf; - BIO_free(mem); + wolfSSL_BIO_free(mem); return 0; err: if(mem) - BIO_free(mem); + wolfSSL_BIO_free(mem); return -1; } @@ -818,7 +818,7 @@ static int get_ssl_cert(str *res, int local, int urlencoded, sip_msg_t *msg) char *buf = NULL; /* buf2 holds the urlencoded version of buf, which can be up to 3 times its size */ static char buf2[MAX_CERT_SIZE * 3 + 1]; - X509 *cert; + WOLFSSL_X509 *cert; struct tcp_connection *c; size_t len; str temp_str; @@ -847,13 +847,13 @@ static int get_ssl_cert(str *res, int local, int urlencoded, sip_msg_t *msg) } if(!local) - X509_free(cert); + wolfSSL_X509_free(cert); tcpconn_put(c); return 0; err: if(!local) - X509_free(cert); + wolfSSL_X509_free(cert); tcpconn_put(c); return -1; } @@ -918,8 +918,8 @@ static int pv_ssl_cert(sip_msg_t *msg, pv_param_t *param, pv_value_t *res) /* NB: SSL_get0_verified_chain() was introduced in OpenSSL 1.1.0 */ -static int get_verified_cert_chain( - STACK_OF(X509) * *chain, struct tcp_connection **c, struct sip_msg *msg) +static int get_verified_cert_chain(WOLF_STACK_OF(WOLFSSL_X509) * *chain, + struct tcp_connection **c, struct sip_msg *msg) { SSL *ssl; @@ -950,8 +950,8 @@ static int sel_ssl_verified_cert_chain(str *res, select_t *s, sip_msg_t *msg) char *buf = NULL; struct tcp_connection *c; size_t len; - STACK_OF(X509) * chain; - X509 *cert; + WOLF_STACK_OF(WOLFSSL_X509) * chain; + WOLFSSL_X509 *cert; int i; if(get_verified_cert_chain(&chain, &c, msg) < 0) @@ -962,10 +962,10 @@ static int sel_ssl_verified_cert_chain(str *res, select_t *s, sip_msg_t *msg) } else return -1; - if(i < 0 || i >= sk_X509_num(chain)) + if(i < 0 || i >= wolfSSL_sk_X509_num(chain)) return -1; - cert = sk_X509_value(chain, i); + cert = wolfSSL_sk_X509_value(chain, i); if(!cert) return -1; @@ -989,11 +989,11 @@ err: static int get_comp(str *res, int local, int issuer, int nid, sip_msg_t *msg) { static char buf[1024]; - X509 *cert; + WOLFSSL_X509 *cert; struct tcp_connection *c; - X509_NAME *name; - X509_NAME_ENTRY *e; - ASN1_STRING *asn1; + WOLFSSL_X509_NAME *name; + WOLFSSL_X509_NAME_ENTRY *e; + WOLFSSL_ASN1_STRING *asn1; int index, text_len; char *elem; unsigned char *text_s; @@ -1003,13 +1003,14 @@ static int get_comp(str *res, int local, int issuer, int nid, sip_msg_t *msg) if(get_cert(&cert, &c, msg, local) < 0) return -1; - name = issuer ? X509_get_issuer_name(cert) : X509_get_subject_name(cert); + name = issuer ? wolfSSL_X509_get_issuer_name(cert) + : wolfSSL_X509_get_subject_name(cert); if(!name) { ERR("Cannot extract subject or issuer name from peer certificate\n"); goto err; } - index = X509_NAME_get_index_by_NID(name, nid, -1); + index = wolfSSL_X509_NAME_get_index_by_NID(name, nid, -1); if(index == -1) { switch(nid) { case NID_commonName: @@ -1041,9 +1042,9 @@ static int get_comp(str *res, int local, int issuer, int nid, sip_msg_t *msg) goto err; } - e = X509_NAME_get_entry(name, index); - asn1 = X509_NAME_ENTRY_get_data(e); - text_len = ASN1_STRING_to_UTF8(&text_s, asn1); + e = wolfSSL_X509_NAME_get_entry(name, index); + asn1 = wolfSSL_X509_NAME_ENTRY_get_data(e); + text_len = wolfSSL_ASN1_STRING_to_UTF8(&text_s, asn1); if(text_len < 0 || text_len >= 1024) { ERR("Error converting ASN1 string\n"); goto err; @@ -1054,7 +1055,7 @@ static int get_comp(str *res, int local, int issuer, int nid, sip_msg_t *msg) wolfSSL_OPENSSL_free(text_s); if(!local) - X509_free(cert); + wolfSSL_X509_free(cert); tcpconn_put(c); return 0; @@ -1187,9 +1188,9 @@ static int get_alt(str *res, int local, int type, sip_msg_t *msg) { static char buf[1024]; int n, found = 0; - STACK_OF(GENERAL_NAME) *names = 0; - GENERAL_NAME *nm; - X509 *cert; + WOLF_STACK_OF(WOLF_GENERAL_NAME) *names = 0; + WOLFSSL_GENERAL_NAME *nm; + WOLFSSL_X509 *cert; struct tcp_connection *c; str text; struct ip_addr ip; @@ -1197,14 +1198,14 @@ static int get_alt(str *res, int local, int type, sip_msg_t *msg) if(get_cert(&cert, &c, msg, local) < 0) return -1; - names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); + names = wolfSSL_X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); if(!names) { DBG("Cannot get certificate alternative subject\n"); goto err; } - for(n = 0; n < sk_GENERAL_NAME_num(names); n++) { - nm = sk_GENERAL_NAME_value(names, n); + for(n = 0; n < wolfSSL_sk_GENERAL_NAME_num(names); n++) { + nm = wolfSSL_sk_GENERAL_NAME_value(names, n); if(nm->type != type) continue; switch(type) { @@ -1241,16 +1242,16 @@ static int get_alt(str *res, int local, int type, sip_msg_t *msg) goto err; if(names) - sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free); + wolfSSL_sk_GENERAL_NAME_pop_free(names, wolfSSL_GENERAL_NAME_free); if(!local) - X509_free(cert); + wolfSSL_X509_free(cert); tcpconn_put(c); return 0; err: if(names) - sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free); + wolfSSL_sk_GENERAL_NAME_pop_free(names, wolfSSL_GENERAL_NAME_free); if(!local) - X509_free(cert); + wolfSSL_X509_free(cert); tcpconn_put(c); return -1; } @@ -1467,7 +1468,7 @@ int pv_get_tls(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { SSL *ssl = NULL; tcp_connection_t *c = NULL; - X509 *cert = NULL; + WOLFSSL_X509 *cert = NULL; str sv = STR_NULL; if(msg == NULL || param == NULL) { diff --git a/src/modules/tls_wolfssl/tls_server.c b/src/modules/tls_wolfssl/tls_server.c index 6abbb4481..f3c69839e 100644 --- a/src/modules/tls_wolfssl/tls_server.c +++ b/src/modules/tls_wolfssl/tls_server.c @@ -57,8 +57,7 @@ #include "tls_wolfssl_mod.h" #include "tls_server.h" #include "tls_select.h" -#include "tls_bio.h" -#include "tls_dump_vf.h" + #include "tls_cfg.h" int tls_run_event_routes(struct tcp_connection *c); @@ -225,6 +224,9 @@ static int tls_complete_init(struct tcp_connection *c) str *sname = NULL; str *srvid = NULL; + WOLFSSL_BIO *internal_bio, *rw_bio; + + /* Get current TLS configuration and increase reference * count immediately. */ @@ -258,8 +260,7 @@ static int tls_complete_init(struct tcp_connection *c) goto error; } DBG("Using initial TLS domain %s (dom %p ctx %p sn [%s])\n", - tls_domain_str(dom), dom, dom->ctx[process_no], - ZSW(dom->server_name.s)); + tls_domain_str(dom), dom, dom->ctx[0], ZSW(dom->server_name.s)); data = (struct tls_extra_data *)shm_malloc(sizeof(struct tls_extra_data)); if(!data) { @@ -267,8 +268,10 @@ static int tls_complete_init(struct tcp_connection *c) goto error; } memset(data, '\0', sizeof(struct tls_extra_data)); - data->ssl = wolfSSL_new(dom->ctx[process_no]); - data->rwbio = tls_BIO_new_mbuf(0, 0); + data->ssl = wolfSSL_new(dom->ctx[0]); + wolfSSL_BIO_new_bio_pair( + &internal_bio, TLS_WR_MBUF_SZ, &rw_bio, TLS_RD_MBUF_SZ); + data->rwbio = rw_bio; data->cfg = cfg; data->state = state; @@ -277,7 +280,7 @@ static int tls_complete_init(struct tcp_connection *c) if(data->ssl) wolfSSL_free(data->ssl); if(data->rwbio) - BIO_free(data->rwbio); + wolfSSL_BIO_free(data->rwbio); goto error; } @@ -287,14 +290,14 @@ static int tls_complete_init(struct tcp_connection *c) if(data->ssl) wolfSSL_free(data->ssl); if(data->rwbio) - BIO_free(data->rwbio); + wolfSSL_BIO_free(data->rwbio); goto error; } LM_DBG("outbound TLS server name set to: %s\n", sname->s); } #endif - wolfSSL_set_bio(data->ssl, data->rwbio, data->rwbio); + wolfSSL_set_bio(data->ssl, internal_bio, internal_bio); c->extra_data = data; /* link the extra data struct inside ssl connection*/ @@ -351,33 +354,15 @@ static int tls_fix_connection(struct tcp_connection *c) } -/** sets an mbuf pair for the bio used by the tls connection. - * WARNING: must be called with c->write_lock held. - * @return 0 on success, -1 on error. - */ -static int tls_set_mbufs( - struct tcp_connection *c, struct tls_mbuf *rd, struct tls_mbuf *wr) -{ - BIO *rwbio; - - rwbio = ((struct tls_extra_data *)c->extra_data)->rwbio; - if(unlikely(tls_BIO_mbuf_set(rwbio, rd, wr) <= 0)) { - /* it should be always 1 */ - ERR("failed to set mbufs"); - return -1; - } - return 0; -} - - -static void tls_dump_cert_info(char *s, X509 *cert) +static void tls_dump_cert_info(char *s, WOLFSSL_X509 *cert) { char *subj; char *issuer; subj = issuer = 0; - subj = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); - issuer = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); + subj = wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_subject_name(cert), 0, 0); + issuer = + wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_issuer_name(cert), 0, 0); if(subj) { LOG(cfg_get(tls, tls_cfg, log), "%s subject:%s\n", s ? s : "", subj); @@ -407,12 +392,12 @@ static void tls_dump_cert_info(char *s, X509 *cert) int tls_accept(struct tcp_connection *c, int *error) { int ret; - SSL *ssl = NULL; - X509 *cert; + WOLFSSL *ssl = NULL; + WOLFSSL_X509 *cert; struct tls_extra_data *tls_c; int tls_log; - *error = SSL_ERROR_NONE; + *error = WOLFSSL_ERROR_NONE; tls_c = (struct tls_extra_data *)c->extra_data; ssl = tls_c->ssl; @@ -439,7 +424,7 @@ int tls_accept(struct tcp_connection *c, int *error) "verification failed!!!\n"); tls_dump_verification_failure(wolfSSL_get_verify_result(ssl)); } - X509_free(cert); + wolfSSL_X509_free(cert); } else { LOG(tls_log, "tls_accept: client did not present a certificate\n"); } @@ -469,13 +454,13 @@ err: */ int tls_connect(struct tcp_connection *c, int *error) { - SSL *ssl; + WOLFSSL *ssl; int ret; - X509 *cert; + WOLFSSL_X509 *cert; struct tls_extra_data *tls_c; int tls_log; - *error = SSL_ERROR_NONE; + *error = WOLFSSL_ERROR_NONE; tls_c = (struct tls_extra_data *)c->extra_data; ssl = tls_c->ssl; @@ -502,7 +487,7 @@ int tls_connect(struct tcp_connection *c, int *error) "verification failed!!!\n"); tls_dump_verification_failure(wolfSSL_get_verify_result(ssl)); } - X509_free(cert); + wolfSSL_X509_free(cert); } else { /* this should not happen, servers always present a cert */ LOG(tls_log, "tls_connect: server did not " @@ -526,7 +511,7 @@ static int tls_shutdown(struct tcp_connection *c) { int ret, err, ssl_err; struct tls_extra_data *tls_c; - SSL *ssl; + WOLFSSL *ssl; tls_c = (struct tls_extra_data *)c->extra_data; if(unlikely(tls_c == 0 || tls_c->ssl == 0)) { @@ -549,31 +534,31 @@ static int tls_shutdown(struct tcp_connection *c) } else { err = wolfSSL_get_error(ssl, ret); switch(err) { - case SSL_ERROR_ZERO_RETURN: + case WOLFSSL_ERROR_ZERO_RETURN: DBG("TLS shutdown failed cleanly\n"); goto err; - case SSL_ERROR_WANT_READ: + case WOLFSSL_ERROR_WANT_READ: DBG("Need to get more data to finish TLS shutdown\n"); break; - case SSL_ERROR_WANT_WRITE: + case WOLFSSL_ERROR_WANT_WRITE: DBG("Need to send more data to finish TLS shutdown\n"); break; - case SSL_ERROR_WANT_CONNECT: + case WOLFSSL_ERROR_WANT_CONNECT: DBG("Need to retry connect\n"); break; - case SSL_ERROR_WANT_ACCEPT: + case WOLFSSL_ERROR_WANT_ACCEPT: DBG("Need to retry accept\n"); break; - case SSL_ERROR_WANT_X509_LOOKUP: + case WOLFSSL_ERROR_WANT_X509_LOOKUP: DBG("Application callback asked to be called again\n"); break; - case SSL_ERROR_SYSCALL: + case WOLFSSL_ERROR_SYSCALL: TLS_ERR_RET(ssl_err, "TLS shutdown"); if(!ssl_err) { if(ret == 0) { @@ -585,7 +570,7 @@ static int tls_shutdown(struct tcp_connection *c) } goto err; - case SSL_ERROR_SSL: + case WOLFSSL_ERROR_SSL: default: TLS_ERR("SSL error:"); goto err; @@ -627,8 +612,8 @@ void tls_h_tcpconn_clean_f(struct tcp_connection *c) { struct tls_extra_data *extra; /* - * runs within global tcp lock - */ + * runs within global tcp lock + */ if((c->type != PROTO_TLS) && (c->type != PROTO_WSS)) { BUG("Bad connection structure\n"); abort(); @@ -636,13 +621,10 @@ void tls_h_tcpconn_clean_f(struct tcp_connection *c) if(c->extra_data) { extra = (struct tls_extra_data *)c->extra_data; wolfSSL_free(extra->ssl); + wolfSSL_BIO_free_all(extra->rwbio); atomic_dec(&extra->cfg->ref_count); if(extra->ct_wq) tls_ct_wq_free(&extra->ct_wq); - if(extra->enc_rd_buf) { - shm_free(extra->enc_rd_buf); - extra->enc_rd_buf = 0; - } shm_free(c->extra_data); c->extra_data = 0; } @@ -651,10 +633,20 @@ void tls_h_tcpconn_clean_f(struct tcp_connection *c) /** perform one-way shutdown, do not wait for notify from the remote peer. */ + +/* + * wolfSSL implementation detail: BIO pair uses a ring buffer - + * wolfSSL_BIO_read does not do wrap-around; you may need a 2-pass read + * 1st read - front of buffer, 2nd read - wrap-around + * fixed in 4f1d777090 post-v5.6.6-stable + */ + void tls_h_tcpconn_close_f(struct tcp_connection *c, int fd) { unsigned char wr_buf[TLS_WR_MBUF_SZ]; - struct tls_mbuf rd, wr; + WOLFSSL_BIO *rwbio; + size_t wr_used, nr, npos; + /* * runs either within global tcp lock or after the connection has @@ -671,19 +663,27 @@ void tls_h_tcpconn_close_f(struct tcp_connection *c, int fd) lock_release(&c->write_lock); return; } - tls_mbuf_init(&rd, 0, 0); /* no read */ - tls_mbuf_init(&wr, wr_buf, sizeof(wr_buf)); - if(tls_set_mbufs(c, &rd, &wr) == 0) { - tls_shutdown(c); /* shutdown only on successful set fd */ - /* write as much as possible and update wr. - * Since this is a close, we don't want to queue the write - * (if it can't write immediately, just fail silently) - */ - if(wr.used) - _tcpconn_write_nb(fd, c, (char *)wr.buf, wr.used); - /* we don't bother reading anything (we don't want to wait - on close) */ + rwbio = ((struct tls_extra_data *)c->extra_data)->rwbio; + tls_shutdown(c); /* shutdown only on successful set fd */ + /* write as much as possible and update wr. + * Since this is a close, we don't want to queue the write + * (if it can't write immediately, just fail silently) + */ + /* use 2-pass read for wolfSSL ring buffer */ + wr_used = wolfSSL_BIO_pending(rwbio); + if(wr_used) { + for(nr = 0; nr < wr_used;) { + npos = wolfSSL_BIO_read(rwbio, wr_buf + nr, wr_used - nr); + if(npos <= 0) + break; + nr += npos; + } + assert(nr == wr_used); + _tcpconn_write_nb(fd, c, (char *)wr_buf, wr_used); } + /* we don't bother reading anything (we don't want to wait + on close) */ + lock_release(&c->write_lock); } } @@ -724,10 +724,12 @@ int tls_h_encode_f(struct tcp_connection *c, const char **pbuf, snd_flags_t *send_flags) { int n, offs; - SSL *ssl = NULL; + WOLFSSL *ssl = NULL; + WOLFSSL_BIO *rwbio; struct tls_extra_data *tls_c; static unsigned char wr_buf[TLS_WR_MBUF_SZ]; - struct tls_mbuf rd, wr; + size_t wr_used = 0, nr, npos; + int ssl_error; char *err_src; char ip_buf[64]; @@ -744,7 +746,7 @@ int tls_h_encode_f(struct tcp_connection *c, const char **pbuf, su2a(&c->rcv.src_su, sizeof(c->rcv.src_su))); n = 0; offs = 0; - ssl_error = SSL_ERROR_NONE; + ssl_error = WOLFSSL_ERROR_NONE; err_src = "TLS write:"; if(unlikely(tls_fix_connection_unsafe(c) < 0)) { /* c->extra_data might be null => exit immediately */ @@ -755,8 +757,7 @@ int tls_h_encode_f(struct tcp_connection *c, const char **pbuf, } tls_c = (struct tls_extra_data *)c->extra_data; ssl = tls_c->ssl; - tls_mbuf_init(&rd, 0, 0); /* no read */ - tls_mbuf_init(&wr, wr_buf, sizeof(wr_buf)); + rwbio = tls_c->rwbio; /* clear text already queued (WANTS_READ) queue directly*/ if(unlikely(tls_write_wants_read(tls_c))) { TLS_WR_TRACE("(%p) WANTS_READ queue present => queueing" @@ -773,10 +774,7 @@ int tls_h_encode_f(struct tcp_connection *c, const char **pbuf, send_flags->f &= ~SND_F_CON_CLOSE; goto end; } - if(unlikely(tls_set_mbufs(c, &rd, &wr) < 0)) { - ERR("tls_set_mbufs failed\n"); - goto error; - } + redo_wr: if(unlikely(tls_c->state == S_TLS_CONNECTING)) { n = tls_connect(c, &ssl_error); @@ -787,7 +785,7 @@ redo_wr: ssl_error = wolfSSL_get_error(ssl, n); } else { /* tls_connect failed/needs more IO */ - if(unlikely(n < 0 && ssl_error == SSL_ERROR_NONE)) + if(unlikely(n < 0 && ssl_error == WOLFSSL_ERROR_NONE)) goto error; err_src = "TLS connect:"; } @@ -800,29 +798,31 @@ redo_wr: ssl_error = wolfSSL_get_error(ssl, n); } else { /* tls_accept failed/needs more IO */ - if(unlikely(n < 0 && ssl_error == SSL_ERROR_NONE)) + if(unlikely(n < 0 && ssl_error == WOLFSSL_ERROR_NONE)) goto error; err_src = "TLS accept:"; } } else { - n = SSL_write(ssl, buf + offs, len - offs); + n = wolfSSL_write(ssl, buf + offs, len - offs); if(unlikely(n <= 0)) - ssl_error = SSL_get_error(ssl, n); + ssl_error = wolfSSL_get_error(ssl, n); } - TLS_WR_TRACE("(%p) SSL_write(%p + %d, %d) => %d (err=%d)\n", c, buf, offs, - len - offs, n, ssl_error); + TLS_WR_TRACE("(%p) wolfSSL_write(%p + %d, %d) => %d (err=%d)\n", c, buf, + offs, len - offs, n, ssl_error); /* check for possible ssl errors */ + wr_used = wolfSSL_BIO_pending(rwbio); + if(unlikely(n <= 0)) { switch(ssl_error) { - case SSL_ERROR_NONE: + case WOLFSSL_ERROR_NONE: BUG("unexpected SSL_ERROR_NONE for n=%d\n", n); goto error; break; - case SSL_ERROR_ZERO_RETURN: + case WOLFSSL_ERROR_ZERO_RETURN: /* SSL EOF */ ERR("ssl level EOF\n"); goto ssl_eof; - case SSL_ERROR_WANT_READ: + case WOLFSSL_ERROR_WANT_READ: /* queue write buffer */ TLS_WR_TRACE("(%p) SSL_ERROR_WANT_READ => queueing for read" " (%p + %d, %d)\n", @@ -835,24 +835,24 @@ redo_wr: } tls_c->flags |= F_TLS_CON_WR_WANTS_RD; /* buffer queued for a future send attempt, after first - * reading some data (key exchange) => don't allow immediate - * closing of the connection */ + * reading some data (key exchange) => don't allow immediate + * closing of the connection */ send_flags->f &= ~SND_F_CON_CLOSE; break; /* or goto end */ - case SSL_ERROR_WANT_WRITE: + case WOLFSSL_ERROR_WANT_WRITE: if(unlikely(offs == 0)) { /* error, no record fits in the buffer or - * no partial write enabled and buffer to small to fit - * all the records */ - BUG("write buffer too small (%d/%d bytes)\n", wr.used, - wr.size); + * no partial write enabled and buffer to small to fit + * all the records */ + BUG("write buffer too small (%d/%d bytes)\n", (int)wr_used, + TLS_WR_MBUF_SZ); goto bug; } else { /* offs != 0 => something was "written" */ *rest_buf = buf + offs; *rest_len = len - offs; /* this function should be called again => disallow - * immediate closing of the connection */ + * immediate closing of the connection */ send_flags->f &= ~SND_F_CON_CLOSE; TLS_WR_TRACE("(%p) SSL_ERROR_WANT_WRITE partial write" " (written %p , %d, rest_buf=%p" @@ -860,7 +860,7 @@ redo_wr: c, buf, offs, *rest_buf, *rest_len); } break; /* or goto end */ - case SSL_ERROR_SSL: + case WOLFSSL_ERROR_SSL: /* protocol level error */ ERR("protocol level error\n"); TLS_ERR_SSL(err_src, ssl); @@ -873,27 +873,27 @@ redo_wr: goto error; - case SSL_ERROR_WANT_CONNECT: + case WOLFSSL_ERROR_WANT_CONNECT: /* only if the underlying BIO is not yet connected - * and the call would block in connect(). - * (not possible in our case) */ + * and the call would block in connect(). + * (not possible in our case) */ BUG("unexpected SSL_ERROR_WANT_CONNECT\n"); break; - case SSL_ERROR_WANT_ACCEPT: + case WOLFSSL_ERROR_WANT_ACCEPT: /* only if the underlying BIO is not yet connected - * and call would block in accept() - * (not possible in our case) */ + * and call would block in accept() + * (not possible in our case) */ BUG("unexpected SSL_ERROR_WANT_ACCEPT\n"); break; - case SSL_ERROR_WANT_X509_LOOKUP: + case WOLFSSL_ERROR_WANT_X509_LOOKUP: /* can only appear on client application and it indicates that - * an installed client cert. callback should be called again - * (it returned < 0 indicated that it wants to be called - * later). Not possible in our case */ + * an installed client cert. callback should be called again + * (it returned < 0 indicated that it wants to be called + * later). Not possible in our case */ BUG("unsupported SSL_ERROR_WANT_X509_LOOKUP"); goto bug; - case SSL_ERROR_SYSCALL: + case WOLFSSL_ERROR_SYSCALL: TLS_ERR_RET(x, err_src); if(!x) { if(n == 0) { @@ -916,26 +916,42 @@ redo_wr: offs += n; goto redo_wr; } - tls_set_mbufs(c, 0, 0); end: - *pbuf = (const char *)wr.buf; - *plen = wr.used; + /* use 2-pass read for wolfSSL ring buffer */ + wr_used = wolfSSL_BIO_pending(rwbio); + for(nr = 0; nr < wr_used;) { + npos = wolfSSL_BIO_read(rwbio, wr_buf + nr, wr_used - nr); + if(npos <= 0) + break; + nr += npos; + } + assert(nr == wr_used); + *plen = wr_used; + *pbuf = (const char *)wr_buf; TLS_WR_TRACE("(%p) end (offs %d, rest_buf=%p rest_len=%d 0x%0x) => %d \n", c, offs, *rest_buf, *rest_len, send_flags->f, *plen); return *plen; error: -/*error_send:*/ + /*error_send:*/ error_wq_full: bug: - tls_set_mbufs(c, 0, 0); TLS_WR_TRACE( - "(%p) end error (offs %d, %d encoded) => -1\n", c, offs, wr.used); + "(%p) end error (offs %d, %d encoded) => -1\n", c, offs, wr_used); return -1; ssl_eof: c->state = S_CONN_EOF; c->flags |= F_CONN_FORCE_EOF; - *pbuf = (const char *)wr.buf; - *plen = wr.used; + /* use 2-pass read for wolfSSL ring buffer */ + wr_used = wolfSSL_BIO_pending(rwbio); + for(nr = 0; nr < wr_used;) { + npos = wolfSSL_BIO_read(rwbio, wr_buf + nr, wr_used - nr); + if(npos <= 0) + break; + nr += npos; + } + assert(nr == wr_used); + *plen = wr_used; + *pbuf = (const char *)wr_buf; DBG("TLS connection has been closed\n"); TLS_WR_TRACE("(%p) end EOF (offs %d) => (%d\n", c, offs, *plen); return *plen; @@ -973,12 +989,13 @@ int tls_h_read_f(struct tcp_connection *c, rd_conn_flags_t *flags) { struct tcp_req *r; int bytes_free, bytes_read, read_size, ssl_error, ssl_read; - SSL *ssl; + WOLFSSL *ssl; + WOLFSSL_BIO *rwbio; unsigned char rd_buf[TLS_RD_MBUF_SZ]; unsigned char wr_buf[TLS_WR_MBUF_SZ]; - struct tls_mbuf rd, wr; + size_t wr_used, rd_unused; + size_t nr, npos, nw; struct tls_extra_data *tls_c; - struct tls_rd_buf *enc_rd_buf; int n, flush_flags; char *err_src; char ip_buf[64]; @@ -991,7 +1008,7 @@ int tls_h_read_f(struct tcp_connection *c, rd_conn_flags_t *flags) ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port); ssl_read = 0; r = &c->req; - enc_rd_buf = 0; + *flags &= ~RD_CONN_REPEAT_READ; if(unlikely(tls_fix_connection(c) < 0)) { TLS_RD_TRACE("(%p, %p) end: tls_fix_connection failed =>" @@ -1003,6 +1020,7 @@ int tls_h_read_f(struct tcp_connection *c, rd_conn_flags_t *flags) * If it's != 0 is changed only on destroy. It's not possible to have * parallel reads.*/ tls_c = c->extra_data; + rwbio = tls_c->rwbio; bytes_free = c->req.b_size - (unsigned int)(r->pos - r->buf); if(unlikely(bytes_free <= 0)) { ERR("Buffer overrun, dropping\n"); @@ -1010,53 +1028,35 @@ int tls_h_read_f(struct tcp_connection *c, rd_conn_flags_t *flags) return -1; } redo_read: - /* if data queued from a previous read(), use it (don't perform - * a real read()). - */ - if(unlikely(tls_c->enc_rd_buf)) { - /* use queued data */ - /* safe to use without locks, because only read changes it and - * there can't be parallel reads on the same connection */ - enc_rd_buf = tls_c->enc_rd_buf; - tls_c->enc_rd_buf = 0; - TLS_RD_TRACE("(%p, %p) using queued data (%p: %p %d bytes)\n", c, flags, - enc_rd_buf, enc_rd_buf->buf + enc_rd_buf->pos, - enc_rd_buf->size - enc_rd_buf->pos); - tls_mbuf_init(&rd, enc_rd_buf->buf + enc_rd_buf->pos, - enc_rd_buf->size - enc_rd_buf->pos); - rd.used = enc_rd_buf->size - enc_rd_buf->pos; - } else { - /* if we were using using queued data before, free & reset the - the queued read data before performing the real read() */ - if(unlikely(enc_rd_buf)) { - TLS_RD_TRACE("(%p, %p) reset prev. used enc_rd_buf (%p)\n", c, - flags, enc_rd_buf); - shm_free(enc_rd_buf); - enc_rd_buf = 0; + /* real read() */ + /* read() only if no previously detected EOF, or previous + * short read (which means the socket buffer was emptied) */ + if(likely(!(*flags & (RD_CONN_EOF | RD_CONN_SHORT_READ)))) { + /* don't read more than the free bytes in the tcp req buffer */ + read_size = MIN_unsigned(TLS_RD_MBUF_SZ, bytes_free); + bytes_read = tcp_read_data(c->fd, c, (char *)rd_buf, read_size, flags); + TLS_RD_TRACE("(%p, %p) tcp_read_data(..., %d, *%d) => %d bytes\n", c, + flags, read_size, *flags, bytes_read); + /* try SSL_read even on 0 bytes read, it might have + * internally buffered data */ + if(unlikely(bytes_read < 0)) { + goto error; } - /* real read() */ - tls_mbuf_init(&rd, rd_buf, sizeof(rd_buf)); - /* read() only if no previously detected EOF, or previous - * short read (which means the socket buffer was emptied) */ - if(likely(!(*flags & (RD_CONN_EOF | RD_CONN_SHORT_READ)))) { - /* don't read more than the free bytes in the tcp req buffer */ - read_size = MIN_unsigned(rd.size, bytes_free); - bytes_read = - tcp_read_data(c->fd, c, (char *)rd.buf, read_size, flags); - TLS_RD_TRACE("(%p, %p) tcp_read_data(..., %d, *%d) => %d bytes\n", - c, flags, read_size, *flags, bytes_read); - /* try SSL_read even on 0 bytes read, it might have - * internally buffered data */ - if(unlikely(bytes_read < 0)) { - goto error; - } - rd.used = bytes_read; + + /* + * use 2-pass write for wolfSSL ring buffer + * fixed in 4f1d777090, post-v5.6.6-stable + */ + for(nw = 0; nw < bytes_read;) { + npos = wolfSSL_BIO_write(rwbio, rd_buf + nw, bytes_read - nw); + if(npos <= 0) + break; + nw += npos; } + assert(nw == bytes_read); } - continue_ssl_read: - tls_mbuf_init(&wr, wr_buf, sizeof(wr_buf)); - ssl_error = SSL_ERROR_NONE; + ssl_error = WOLFSSL_ERROR_NONE; err_src = "TLS read:"; /* we have to avoid to run in the same time * with a tls_write because of the @@ -1064,7 +1064,6 @@ continue_ssl_read: * stealing the wbio or rbio under us or vice versa) * => lock on con->write_lock (ugly hack) */ lock_get(&c->write_lock); - tls_set_mbufs(c, &rd, &wr); ssl = tls_c->ssl; n = 0; if(unlikely(tls_write_wants_read(tls_c) && !(*flags & RD_CONN_EOF))) { @@ -1073,7 +1072,6 @@ continue_ssl_read: " ct_wq_flush()=> %d (ff=%d ssl_error=%d))\n", c, flags, n, flush_flags, ssl_error); if(unlikely(n < 0)) { - tls_set_mbufs(c, 0, 0); lock_release(&c->write_lock); ERR("write flush error (%d)\n", n); goto error; @@ -1083,7 +1081,7 @@ continue_ssl_read: if(unlikely(flush_flags & F_BUFQ_ERROR_FLUSH)) err_src = "TLS write:"; } - if(likely(ssl_error == SSL_ERROR_NONE)) { + if(likely(ssl_error == WOLFSSL_ERROR_NONE)) { if(unlikely(tls_c->state == S_TLS_CONNECTING)) { n = tls_connect(c, &ssl_error); TLS_RD_TRACE("(%p, %p) tls_connect() => %d (err=%d)\n", c, flags, n, @@ -1092,7 +1090,7 @@ continue_ssl_read: n = wolfSSL_read(ssl, r->pos, bytes_free); } else { /* tls_connect failed/needs more IO */ - if(unlikely(n < 0 && ssl_error == SSL_ERROR_NONE)) { + if(unlikely(n < 0 && ssl_error == WOLFSSL_ERROR_NONE)) { lock_release(&c->write_lock); goto error; } @@ -1107,7 +1105,7 @@ continue_ssl_read: n = wolfSSL_read(ssl, r->pos, bytes_free); } else { /* tls_accept failed/needs more IO */ - if(unlikely(n < 0 && ssl_error == SSL_ERROR_NONE)) { + if(unlikely(n < 0 && ssl_error == WOLFSSL_ERROR_NONE)) { lock_release(&c->write_lock); goto error; } @@ -1116,74 +1114,74 @@ continue_ssl_read: } } else { /* if bytes in then decrypt read buffer into tcpconn req. - * buffer */ + * buffer */ n = wolfSSL_read(ssl, r->pos, bytes_free); } /** handle SSL_read() return. - * There are 3 main cases, each with several sub-cases, depending - * on whether or not the output buffer was filled, if there - * is still unconsumed input data in the input buffer (rd) - * and if there is "cached" data in the internal openssl - * buffers. - * 0. error (n<=0): - * SSL_ERROR_WANT_READ - input data fully - * consumed, no more returnable cached data inside openssl - * => exit. - * SSL_ERROR_WANT_WRITE - should never happen (the write - * buffer is big enough to handle any re-negociation). - * SSL_ERROR_ZERO_RETURN - ssl level shutdown => exit. - * other errors are unexpected. - * 1. output buffer filled (n == bytes_free): - * 1i. - still unconsumed input, nothing buffered by openssl - * 1ip. - unconsumed input + buffered data by openssl (pending - * on the next SSL_read). - * 1p. - completely consumed input, buffered data internally - * by openssl (pending). - * Likely to happen, about the only case when - * SSL_pending() could be used (but only if readahead=0). - * 1f. - consumed input, no buffered data. - * 2. output buffer not fully filled (n < bytes_free): - * 2i. - still unconsumed input, nothing buffered by openssl. - * This can appear if SSL readahead is 0 (SSL_read() - * tries to get only 1 record from the input). - * 2ip. - unconsumed input and buffered data by openssl. - * Unlikely to happen (e.g. readahead is 1, more - * records are buffered internally by openssl, but - * there was not enough space for buffering the whole - * input). - * 2p - consumed input, but buffered data by openssl. - * It happens especially when readahead is 1. - * 2f. - consumed input, no buffered data. - * - * One should repeat SSL_read() until and error is detected - * (0*) or the input and internal ssl buffers are fully consumed - * (1f or 2f). However in general is not possible to see if - * SSL_read() could return more data. SSL_pending() has very - * limited usability (basically it would return !=0 only if there - * was no enough space in the output buffer and only if this did - * not happen at a record boundary). - * The solution is to repeat SSL_read() until error or until - * the output buffer is filled (0* or 1*). - * In the later case, this whole function should be called again - * once there is more output space (set RD_CONN_REPEAT_READ). - */ + * There are 3 main cases, each with several sub-cases, depending + * on whether or not the output buffer was filled, if there + * is still unconsumed input data in the input buffer (rd) + * and if there is "cached" data in the internal openssl + * buffers. + * 0. error (n<=0): + * SSL_ERROR_WANT_READ - input data fully + * consumed, no more returnable cached data inside openssl + * => exit. + * SSL_ERROR_WANT_WRITE - should never happen (the write + * buffer is big enough to handle any re-negociation). + * SSL_ERROR_ZERO_RETURN - ssl level shutdown => exit. + * other errors are unexpected. + * 1. output buffer filled (n == bytes_free): + * 1i. - still unconsumed input, nothing buffered by openssl + * 1ip. - unconsumed input + buffered data by openssl (pending + * on the next SSL_read). + * 1p. - completely consumed input, buffered data internally + * by openssl (pending). + * Likely to happen, about the only case when + * SSL_pending() could be used (but only if readahead=0). + * 1f. - consumed input, no buffered data. + * 2. output buffer not fully filled (n < bytes_free): + * 2i. - still unconsumed input, nothing buffered by openssl. + * This can appear if SSL readahead is 0 (SSL_read() + * tries to get only 1 record from the input). + * 2ip. - unconsumed input and buffered data by openssl. + * Unlikely to happen (e.g. readahead is 1, more + * records are buffered internally by openssl, but + * there was not enough space for buffering the whole + * input). + * 2p - consumed input, but buffered data by openssl. + * It happens especially when readahead is 1. + * 2f. - consumed input, no buffered data. + * + * One should repeat SSL_read() until and error is detected + * (0*) or the input and internal ssl buffers are fully consumed + * (1f or 2f). However in general is not possible to see if + * SSL_read() could return more data. SSL_pending() has very + * limited usability (basically it would return !=0 only if there + * was no enough space in the output buffer and only if this did + * not happen at a record boundary). + * The solution is to repeat SSL_read() until error or until + * the output buffer is filled (0* or 1*). + * In the later case, this whole function should be called again + * once there is more output space (set RD_CONN_REPEAT_READ). + */ if(unlikely(tls_c->flags & F_TLS_CON_RENEGOTIATION)) { /* Fix CVE-2009-3555 - disable renegotiation if started by client - * - simulate SSL EOF to force close connection*/ + * - simulate SSL EOF to force close connection*/ tls_dbg = cfg_get(tls, tls_cfg, debug); LOG(tls_dbg, "Reading on a renegotiation of connection (n:%d) (%d)\n", n, wolfSSL_get_error(ssl, n)); err_src = "TLS R-N read:"; - ssl_error = SSL_ERROR_ZERO_RETURN; + ssl_error = WOLFSSL_ERROR_ZERO_RETURN; } else { if(unlikely(n <= 0)) { ssl_error = wolfSSL_get_error(ssl, n); err_src = "TLS read:"; /* errors handled below, outside the lock */ } else { - ssl_error = SSL_ERROR_NONE; + ssl_error = WOLFSSL_ERROR_NONE; r->pos += n; ssl_read += n; bytes_free -= n; @@ -1194,68 +1192,76 @@ continue_ssl_read: c, flags, n, ssl_error, ssl_read, *flags, tls_c->flags); ssl_read_skipped:; } - if(unlikely(wr.used != 0 && ssl_error != SSL_ERROR_ZERO_RETURN)) { + wr_used = wolfSSL_BIO_pending(rwbio); + if(unlikely(wr_used != 0 && ssl_error != WOLFSSL_ERROR_ZERO_RETURN)) { TLS_RD_TRACE( - "(%p, %p) tcpconn_send_unsafe %d bytes\n", c, flags, wr.used); + "(%p, %p) tcpconn_send_unsafe %d bytes\n", c, flags, wr_used); /* something was written and it's not ssl EOF*/ + /* use 2-pass read for wolfSSL ring buffer */ + for(nr = 0; nr < wr_used;) { + npos = wolfSSL_BIO_read(rwbio, wr_buf + nr, wr_used - nr); + if(npos <= 0) + break; + nr += npos; + } + assert(nr == wr_used); if(unlikely(tcpconn_send_unsafe( - c->fd, c, (char *)wr.buf, wr.used, c->send_flags) + c->fd, c, (char *)wr_buf, wr_used, c->send_flags) < 0)) { - tls_set_mbufs(c, 0, 0); lock_release(&c->write_lock); TLS_RD_TRACE("(%p, %p) tcpconn_send_unsafe error\n", c, flags); goto error_send; } } /* quickly catch bugs: segfault if accessed and not set */ - tls_set_mbufs(c, 0, 0); lock_release(&c->write_lock); switch(ssl_error) { - case SSL_ERROR_NONE: + case WOLFSSL_ERROR_NONE: if(unlikely(n < 0)) { BUG("unexpected SSL_ERROR_NONE for n=%d\n", n); goto error; } break; - case SSL_ERROR_ZERO_RETURN: + case WOLFSSL_ERROR_ZERO_RETURN: /* SSL EOF */ TLS_RD_TRACE("(%p, %p) SSL EOF (fd=%d)\n", c, flags, c->fd); goto ssl_eof; - case SSL_ERROR_WANT_READ: + case WOLFSSL_ERROR_WANT_READ: TLS_RD_TRACE("(%p, %p) SSL_ERROR_WANT_READ *flags=%d\n", c, flags, *flags); /* needs to read more data */ - if(unlikely(rd.pos != rd.used)) { + if(unlikely((rd_unused = wolfSSL_BIO_wpending(rwbio)))) { /* data still in the read buffer */ BUG("SSL_ERROR_WANT_READ but data still in" - " the rbio (%p, %d bytes at %d)\n", - rd.buf, rd.used - rd.pos, rd.pos); + " the rbio (%d bytes)\n", + (int)rd_unused); goto bug; } if(unlikely((*flags & (RD_CONN_EOF | RD_CONN_SHORT_READ)) == 0) && bytes_free) { /* there might still be data to read and there is space - * to decrypt it in tcp_req (no byte has been written into - * tcp_req in this case) */ + * to decrypt it in tcp_req (no byte has been written into + * tcp_req in this case) */ TLS_RD_TRACE("(%p, %p) redo read *flags=%d bytes_free=%d\n", c, flags, *flags, bytes_free); goto redo_read; } goto end; /* no more data to read */ - case SSL_ERROR_WANT_WRITE: - if(wr.used) { + case WOLFSSL_ERROR_WANT_WRITE: + if(wr_used) { /* something was written => buffer not big enough to hold - * everything => reset buffer & retry (the tcp_write already - * happened if we are here) */ + * everything => reset buffer & retry (the tcp_write already + * happened if we are here) */ TLS_RD_TRACE("(%p) SSL_ERROR_WANT_WRITE partial write" " (written %d), retrying\n", - c, wr.used); + c, wr_used); goto continue_ssl_read; } /* else write buffer too small, nothing written */ - BUG("write buffer too small (%d/%d bytes)\n", wr.used, wr.size); + BUG("write buffer too small (%d/%d bytes)\n", (int)wr_used, + TLS_WR_MBUF_SZ); goto bug; - case SSL_ERROR_SSL: + case WOLFSSL_ERROR_SSL: /* protocol level error */ ERR("protocol level error\n"); TLS_ERR_SSL(err_src, ssl); @@ -1268,27 +1274,27 @@ continue_ssl_read: goto error; - case SSL_ERROR_WANT_CONNECT: + case WOLFSSL_ERROR_WANT_CONNECT: /* only if the underlying BIO is not yet connected - * and the call would block in connect(). - * (not possible in our case) */ + * and the call would block in connect(). + * (not possible in our case) */ BUG("unexpected SSL_ERROR_WANT_CONNECT\n"); goto bug; - case SSL_ERROR_WANT_ACCEPT: + case WOLFSSL_ERROR_WANT_ACCEPT: /* only if the underlying BIO is not yet connected - * and call would block in accept() - * (not possible in our case) */ + * and call would block in accept() + * (not possible in our case) */ BUG("unexpected SSL_ERROR_WANT_ACCEPT\n"); goto bug; - case SSL_ERROR_WANT_X509_LOOKUP: + case WOLFSSL_ERROR_WANT_X509_LOOKUP: /* can only appear on client application and it indicates that - * an installed client cert. callback should be called again - * (it returned < 0 indicated that it wants to be called - * later). Not possible in our case */ + * an installed client cert. callback should be called again + * (it returned < 0 indicated that it wants to be called + * later). Not possible in our case */ BUG("unsupported SSL_ERROR_WANT_X509_LOOKUP"); goto bug; - case SSL_ERROR_SYSCALL: + case WOLFSSL_ERROR_SYSCALL: TLS_ERR_RET(x, err_src); if(!x) { if(n == 0) { @@ -1308,65 +1314,8 @@ continue_ssl_read: BUG("unexpected value (n = %d)\n", n); goto bug; } - if(unlikely(rd.pos != rd.used)) { - /* encrypted data still in the read buffer (SSL_read() did not - * consume all of it) */ - if(unlikely(n < 0)) - /* here n should always be >= 0 */ - BUG("unexpected value (n = %d)\n", n); - else { - if(unlikely(bytes_free != 0)) { - /* 2i or 2ip: unconsumed input and output buffer not filled => - * retry ssl read (SSL_read() will read will stop at - * record boundaries, unless readahead==1). - * No tcp_read() is attempted, since that would reset the - * current no-yet-consumed input data. - */ - TLS_RD_TRACE("(%p, %p) input not fully consumed =>" - " retry SSL_read" - " (pos: %d, remaining %d, output free %d)\n", - c, flags, rd.pos, rd.used - rd.pos, bytes_free); - goto continue_ssl_read; - } - /* 1i or 1ip: bytes_free == 0 - * (unconsumed input, but filled output buffer) => - * queue read data, and exit asking for repeating the call - * once there is some space in the output buffer. - */ - if(likely(!enc_rd_buf)) { - TLS_RD_TRACE("(%p, %p) creating enc_rd_buf (for %d bytes)\n", c, - flags, rd.used - rd.pos); - enc_rd_buf = - shm_malloc(sizeof(*enc_rd_buf) - sizeof(enc_rd_buf->buf) - + rd.used - rd.pos); - if(unlikely(enc_rd_buf == 0)) { - ERR("memory allocation error (%d bytes requested)\n", - (int)(sizeof(*enc_rd_buf) + sizeof(enc_rd_buf->buf) - + rd.used - rd.pos)); - goto error; - } - enc_rd_buf->pos = 0; - enc_rd_buf->size = rd.used - rd.pos; - memcpy(enc_rd_buf->buf, rd.buf + rd.pos, enc_rd_buf->size); - } else if((enc_rd_buf->buf + enc_rd_buf->pos) == rd.buf) { - TLS_RD_TRACE("(%p, %p) enc_rd_buf already in use," - " updating pos %d\n", - c, flags, enc_rd_buf->pos); - enc_rd_buf->pos += rd.pos; - } else { - BUG("enc_rd_buf->buf = %p, pos = %d, rd_buf.buf = %p\n", - enc_rd_buf->buf, enc_rd_buf->pos, rd.buf); - goto bug; - } - if(unlikely(tls_c->enc_rd_buf)) - BUG("tls_c->enc_rd_buf!=0 (%p)\n", tls_c->enc_rd_buf); - /* there can't be 2 reads in parallel, so no locking is needed - * here */ - tls_c->enc_rd_buf = enc_rd_buf; - enc_rd_buf = 0; - *flags |= RD_CONN_REPEAT_READ; - } - } else if(bytes_free != 0) { + + if(bytes_free != 0) { /* 2f or 2p: input fully consumed (rd.pos == rd.used), * output buffer not filled, still possible to have pending * data buffered by openssl */ @@ -1402,15 +1351,11 @@ continue_ssl_read: } end: - if(enc_rd_buf) - shm_free(enc_rd_buf); TLS_RD_TRACE( "(%p, %p) end => %d (*flags=%d)\n", c, flags, ssl_read, *flags); return ssl_read; ssl_eof: /* behave as an EOF would have been received at the tcp level */ - if(enc_rd_buf) - shm_free(enc_rd_buf); c->state = S_CONN_EOF; *flags |= RD_CONN_EOF; TLS_RD_TRACE( @@ -1419,8 +1364,6 @@ ssl_eof: error_send: error: bug: - if(enc_rd_buf) - shm_free(enc_rd_buf); r->error = TCP_READ_ERROR; TLS_RD_TRACE("(%p, %p) end error => %d (*flags=%d)\n", c, flags, ssl_read, *flags); diff --git a/src/modules/tls_wolfssl/tls_server.h b/src/modules/tls_wolfssl/tls_server.h index d6f6168f1..a277f46a2 100644 --- a/src/modules/tls_wolfssl/tls_server.h +++ b/src/modules/tls_wolfssl/tls_server.h @@ -62,7 +62,7 @@ typedef struct tls_extra_data * (openssl code might add buffering BIOs so * it's better to remember our original BIO) */ tls_ct_q *ct_wq; - struct tls_rd_buf *enc_rd_buf; + unsigned int flags; enum tls_conn_states state; } tls_extra_data_t; diff --git a/src/modules/tls_wolfssl/tls_util.c b/src/modules/tls_wolfssl/tls_util.c index 952fd308c..a03eb4e3f 100644 --- a/src/modules/tls_wolfssl/tls_util.c +++ b/src/modules/tls_wolfssl/tls_util.c @@ -96,3 +96,19 @@ void collect_garbage(void) lock_release(tls_domains_cfg_lock); } + + +/** log the verification failure reason. + * wolfSSL has a different set of return values + * than OpenSSL + */ +void tls_dump_verification_failure(long verification_result) +{ + int tls_log; + + tls_log = cfg_get(tls, tls_cfg, log); + LOG(tls_log, "%s\n", wolfSSL_ERR_reason_error_string(verification_result)); +} + + +/* vi: set ts=4 sw=4 tw=79:ai:cindent: */ diff --git a/src/modules/tls_wolfssl/tls_util.h b/src/modules/tls_wolfssl/tls_util.h index 162294710..b8d0b3b5b 100644 --- a/src/modules/tls_wolfssl/tls_util.h +++ b/src/modules/tls_wolfssl/tls_util.h @@ -26,11 +26,9 @@ #ifndef _TLS_UTIL_H #define _TLS_UTIL_H -#include -#include - #include "../../core/dprint.h" #include "../../core/str.h" +#include "tls_cfg.h" #include "tls_domain.h" static inline int tls_err_ret( @@ -47,8 +45,8 @@ static inline int tls_err_ret( } while((err = ERR_get_error())) { ret = 1; - ERR("%s%s (sni: %s)\n", s ? s : "", wolfSSL_ERR_error_string(err, 0), - (sn) ? sn : "unknown"); + ERR("%s%s (sni: %s)\n", s ? s : "", + wolfSSL_ERR_error_string(err, 0), (sn) ? sn : "unknown"); } } return ret; @@ -83,4 +81,6 @@ int shm_asciiz_dup(char **dest, char *val); */ void collect_garbage(void); +void tls_dump_verification_failure(long verification_result); + #endif /* _TLS_UTIL_H */ diff --git a/src/modules/tls_wolfssl/tls_verify.c b/src/modules/tls_wolfssl/tls_verify.c index ef458ba25..a17c6242b 100644 --- a/src/modules/tls_wolfssl/tls_verify.c +++ b/src/modules/tls_wolfssl/tls_verify.c @@ -30,107 +30,8 @@ /* FIXME: remove this and use the value in domains instead */ #define VERIFY_DEPTH_S 3 -/* This callback is called during each verification process, - at each step during the chain of certificates (this function - is not the certificate_verification one!). */ -int verify_callback(int pre_verify_ok, X509_STORE_CTX *ctx) -{ - char buf[256]; - X509 *err_cert; - int err, depth; - - depth = X509_STORE_CTX_get_error_depth(ctx); - LM_DBG("tls init - depth = %d\n", depth); - if(depth > VERIFY_DEPTH_S) { - LM_NOTICE("tls init - cert chain too long ( depth > VERIFY_DEPTH_S)\n"); - pre_verify_ok = 0; - } - - if(pre_verify_ok) { - LM_NOTICE("tls init - preverify is good: verify return: %d\n", - pre_verify_ok); - return pre_verify_ok; - } - - err_cert = X509_STORE_CTX_get_current_cert(ctx); - err = X509_STORE_CTX_get_error(ctx); - X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof buf); - - LM_NOTICE("tls init - subject = %s\n", buf); - LM_NOTICE("tls init - verify error - num=%d:%s\n", err, - X509_verify_cert_error_string(err)); - LM_NOTICE("tls init - error code is %d (depth: %d)\n", err, depth); - - switch(err) { - case X509_V_OK: - LM_NOTICE("tls init - all ok\n"); - break; - case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: - X509_NAME_oneline(X509_get_issuer_name(err_cert), buf, sizeof buf); - LM_NOTICE("tls init - issuer= %s\n", buf); - break; - - case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: - case X509_V_ERR_CERT_NOT_YET_VALID: - LM_NOTICE("tls init - notBefore\n"); - break; - - case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: - case X509_V_ERR_CERT_HAS_EXPIRED: - LM_NOTICE("tls init - notAfter\n"); - break; - - case X509_V_ERR_CERT_SIGNATURE_FAILURE: - case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: - LM_NOTICE("tls init - unable to decrypt cert signature\n"); - break; - - case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: - LM_NOTICE("tls init - unable to decode issuer public key\n"); - break; - - case X509_V_ERR_OUT_OF_MEM: - LM_ERR("tls init - Out of memory \n"); - break; - - case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: - case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: - LM_NOTICE("tls init - Self signed certificate issue\n"); - break; - - case X509_V_ERR_CERT_CHAIN_TOO_LONG: - LM_NOTICE("tls init - certificate chain too long\n"); - break; - case X509_V_ERR_INVALID_CA: - LM_NOTICE("tls init - invalid CA\n"); - break; - case X509_V_ERR_PATH_LENGTH_EXCEEDED: - LM_NOTICE("tls init - path length exceeded\n"); - break; - case X509_V_ERR_INVALID_PURPOSE: - LM_NOTICE("tls init - invalid purpose\n"); - break; - case X509_V_ERR_CERT_UNTRUSTED: - LM_NOTICE("tls init - certificate untrusted\n"); - break; - case X509_V_ERR_CERT_REJECTED: - LM_NOTICE("tls init - certificate rejected\n"); - break; - - default: - LM_NOTICE("tls init - something wrong with the" - " cert ... error code is %d (check x509_vfy.h)\n", - err); - break; - } - - LM_NOTICE("tls init - verify return: %d\n", pre_verify_ok); - return (pre_verify_ok); -} - - int verify_callback_unconditional_success( - int pre_verify_ok, X509_STORE_CTX *ctx) + int pre_verify_ok, WOLFSSL_X509_STORE_CTX *ctx) { LM_NOTICE("Post-verification callback: unconditional success\n"); return 1; diff --git a/src/modules/tls_wolfssl/tls_verify.h b/src/modules/tls_wolfssl/tls_verify.h index a392da4c6..5c29f955c 100644 --- a/src/modules/tls_wolfssl/tls_verify.h +++ b/src/modules/tls_wolfssl/tls_verify.h @@ -29,15 +29,10 @@ #include #include -/* This callback is called during each verification process, -at each step during the chain of certificates (this function -is not the certificate_verification one!). */ -int verify_callback(int pre_verify_ok, X509_STORE_CTX *ctx); - /* Post-verification callback handler which unconditionally returns 1 (success) Note that actual verification result can be retrieved through TLS PVs after-the-fact */ int verify_callback_unconditional_success( - int pre_verify_ok, X509_STORE_CTX *ctx); + int pre_verify_ok, WOLFSSL_X509_STORE_CTX *ctx); #endif /* _TLS_VERIFY_H */ diff --git a/src/modules/tls_wolfssl/tls_wolfssl_mod.c b/src/modules/tls_wolfssl/tls_wolfssl_mod.c index 2c2eb8d84..e95cecb7b 100644 --- a/src/modules/tls_wolfssl/tls_wolfssl_mod.c +++ b/src/modules/tls_wolfssl/tls_wolfssl_mod.c @@ -53,7 +53,6 @@ #include "tls_util.h" #include "tls_wolfssl_mod.h" #include "tls_cfg.h" -#include "tls_rand.h" #ifndef TLS_HOOKS #error "TLS_HOOKS must be defined, or the tls module won't work" @@ -85,8 +84,6 @@ static void destroy(void); static int w_is_peer_verified(struct sip_msg *msg, char *p1, char *p2); static int w_tls_set_connect_server_id(sip_msg_t *msg, char *psrvid, char *p2); -int ksr_rand_engine_param(modparam_t type, void *val); - MODULE_VERSION @@ -225,13 +222,9 @@ static param_export_t params[] = { {"ct_wq_max", PARAM_INT, &default_tls_cfg.ct_wq_max}, {"ct_wq_blk_size", PARAM_INT, &default_tls_cfg.ct_wq_blk_size}, {"tls_force_run", PARAM_INT, &default_tls_cfg.force_run}, - {"low_mem_threshold1", PARAM_INT, &default_tls_cfg.low_mem_threshold1}, - {"low_mem_threshold2", PARAM_INT, &default_tls_cfg.low_mem_threshold2}, {"renegotiation", PARAM_INT, &sr_tls_renegotiation}, {"xavp_cfg", PARAM_STR, &sr_tls_xavp_cfg}, {"event_callback", PARAM_STR, &sr_tls_event_callback}, - {"rand_engine", PARAM_STR | USE_FUNC_PARAM, - (void *)ksr_rand_engine_param}, {0, 0, 0}}; @@ -422,40 +415,12 @@ static void destroy(void) } -int ksr_rand_engine_param(modparam_t type, void *val) -{ - str *reng; - - if(val == NULL) { - return -1; - } - reng = (str *)val; - LM_DBG("random engine: %.*s\n", reng->len, reng->s); - if(reng->len == 5 && strncasecmp(reng->s, "krand", 5) == 0) { - LM_DBG("setting krand random engine\n"); - wolfSSL_RAND_set_rand_method(RAND_ksr_krand_method()); - } else if(reng->len == 8 && strncasecmp(reng->s, "fastrand", 8) == 0) { - LM_DBG("setting fastrand random engine\n"); - wolfSSL_RAND_set_rand_method(RAND_ksr_fastrand_method()); - } else if(reng->len == 10 && strncasecmp(reng->s, "cryptorand", 10) == 0) { - LM_DBG("setting cryptorand random engine\n"); - wolfSSL_RAND_set_rand_method(RAND_ksr_cryptorand_method()); - } - - /* WOLFFIX else if (reng->len == 8 && strncasecmp(reng->s, "kxlibssl", 8) == 0) { - LM_DBG("setting kxlibssl random engine\n"); - wolfSSL_RAND_set_rand_method(RAND_ksr_kxlibssl_method()); - } */ - - return 0; -} - static int ki_is_peer_verified(sip_msg_t *msg) { struct tcp_connection *c; SSL *ssl; long ssl_verify; - X509 *x509_cert; + WOLFSSL_X509 *x509_cert; LM_DBG("started...\n"); if(msg->rcv.proto != PROTO_TLS) { @@ -488,7 +453,8 @@ static int ki_is_peer_verified(sip_msg_t *msg) ssl = ((struct tls_extra_data *)c->extra_data)->ssl; ssl_verify = wolfSSL_get_verify_result(ssl); - if(ssl_verify != X509_V_OK) { + // WOLFSSL_X509_V_OK / X509_V_OK + if(ssl_verify != 0) { LM_WARN("verification of presented certificate failed... return -1\n"); tcpconn_put(c); return -1; @@ -505,7 +471,7 @@ static int ki_is_peer_verified(sip_msg_t *msg) return -1; } - X509_free(x509_cert); + wolfSSL_X509_free(x509_cert); tcpconn_put(c); @@ -593,9 +559,6 @@ int mod_register(char *path, int *dlflags, void *p1, void *p2) register_tls_hooks(&tls_h); - LM_DBG("setting cryptorand random engine\n"); - wolfSSL_RAND_set_rand_method(RAND_ksr_cryptorand_method()); - sr_kemi_modules_add(sr_kemi_tls_exports); return 0; diff --git a/src/modules/tlsa/tls_map.c b/src/modules/tlsa/tls_map.c deleted file mode 100644 index ad799b5cd..000000000 --- a/src/modules/tlsa/tls_map.c +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (C) 2021 Daniel-Constantin Mierla (asipto.com) - * - * This file is part of Kamailio, a free SIP server. - * - * This file 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 - * - * - * This file 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 - * - */ - -/** - * THIS FILE IS GENERATED - DO NOT MODIFY IT - */ - -#include "../tls/tls_map.c" diff --git a/src/modules/tlsa/tls_map.h b/src/modules/tlsa/tls_map.h deleted file mode 100644 index 96705a7f7..000000000 --- a/src/modules/tlsa/tls_map.h +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (C) 2021 Daniel-Constantin Mierla (asipto.com) - * - * This file is part of Kamailio, a free SIP server. - * - * This file 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 - * - * - * This file 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 - * - */ - -/** - * THIS FILE IS GENERATED - DO NOT MODIFY IT - */ - -#include "../tls/tls_map.h" diff --git a/src/modules/tm/README b/src/modules/tm/README index 98e3b9d6f..18a3efe55 100644 --- a/src/modules/tm/README +++ b/src/modules/tm/README @@ -95,53 +95,54 @@ Daniel-Constantin Mierla 4.9. t_on_branch(branch_route) 4.10. t_newtran() 4.11. t_reply(code, reason_phrase) - 4.12. t_send_reply(code, reason) - 4.13. t_lookup_request() - 4.14. t_retransmit_reply() - 4.15. t_release() - 4.16. t_forward_nonack([ip, port]) - 4.17. t_forward_nonack_udp(ip, port) - 4.18. t_forward_nonack_tcp(ip, port) - 4.19. t_forward_nonack_tls(ip, port) - 4.20. t_forward_nonack_sctp(ip, port) - 4.21. t_set_fr(fr_inv_timeout [, fr_timeout]) - 4.22. t_reset_fr() - 4.23. t_set_max_lifetime(inv_lifetime, noninv_lifetime) - 4.24. t_reset_max_lifetime() - 4.25. t_set_retr(retr_t1_interval, retr_t2_interval) - 4.26. t_reset_retr() - 4.27. t_set_auto_inv_100(0|1) - 4.28. t_branch_timeout() - 4.29. t_branch_replied() - 4.30. t_any_timeout() - 4.31. t_any_replied() - 4.32. t_grep_status("code") - 4.33. t_is_canceled() - 4.34. t_is_expired() - 4.35. t_relay_cancel() - 4.36. t_lookup_cancel([1]) - 4.37. t_drop_replies([mode]) - 4.38. t_save_lumps() - 4.39. t_load_contacts([mode]) - 4.40. t_next_contacts() - 4.41. t_next_contact_flow() - 4.42. t_check_status(re) - 4.43. t_check_trans() - 4.44. t_set_disable_6xx(0|1) - 4.45. t_set_disable_failover(0|1) - 4.46. t_set_disable_internal_reply(0|1) - 4.47. t_replicate([params]) - 4.48. t_relay_to(proxy, flags) - 4.49. t_set_no_e2e_cancel_reason(0|1) - 4.50. t_is_set(target) - 4.51. t_use_uac_headers() - 4.52. t_is_retr_async_reply() - 4.53. t_uac_send(method, ruri, nexthop, socket, headers, + 4.12. t_reply_error() + 4.13. t_send_reply(code, reason) + 4.14. t_lookup_request() + 4.15. t_retransmit_reply() + 4.16. t_release() + 4.17. t_forward_nonack([ip, port]) + 4.18. t_forward_nonack_udp(ip, port) + 4.19. t_forward_nonack_tcp(ip, port) + 4.20. t_forward_nonack_tls(ip, port) + 4.21. t_forward_nonack_sctp(ip, port) + 4.22. t_set_fr(fr_inv_timeout [, fr_timeout]) + 4.23. t_reset_fr() + 4.24. t_set_max_lifetime(inv_lifetime, noninv_lifetime) + 4.25. t_reset_max_lifetime() + 4.26. t_set_retr(retr_t1_interval, retr_t2_interval) + 4.27. t_reset_retr() + 4.28. t_set_auto_inv_100(0|1) + 4.29. t_branch_timeout() + 4.30. t_branch_replied() + 4.31. t_any_timeout() + 4.32. t_any_replied() + 4.33. t_grep_status("code") + 4.34. t_is_canceled() + 4.35. t_is_expired() + 4.36. t_relay_cancel() + 4.37. t_lookup_cancel([1]) + 4.38. t_drop_replies([mode]) + 4.39. t_save_lumps() + 4.40. t_load_contacts([mode]) + 4.41. t_next_contacts() + 4.42. t_next_contact_flow() + 4.43. t_check_status(re) + 4.44. t_check_trans() + 4.45. t_set_disable_6xx(0|1) + 4.46. t_set_disable_failover(0|1) + 4.47. t_set_disable_internal_reply(0|1) + 4.48. t_replicate([params]) + 4.49. t_relay_to(proxy, flags) + 4.50. t_set_no_e2e_cancel_reason(0|1) + 4.51. t_is_set(target) + 4.52. t_use_uac_headers() + 4.53. t_is_retr_async_reply() + 4.54. t_uac_send(method, ruri, nexthop, socket, headers, body) - 4.54. t_get_status_code() - 4.55. t_clean() - 4.56. t_exists() + 4.55. t_get_status_code() + 4.56. t_clean() + 4.57. t_exists() 5. RPC Commands @@ -245,50 +246,51 @@ Daniel-Constantin Mierla 1.61. t_on_branch usage 1.62. t_newtran usage 1.63. t_reply usage - 1.64. t_send_reply usage - 1.65. t_lookup_request usage - 1.66. t_retransmit_reply usage - 1.67. t_release usage - 1.68. t_forward_nonack usage - 1.69. t_set_fr usage - 1.70. t_reset_fr usage - 1.71. t_set_max_lifetime usage - 1.72. t_reset_max_lifetime usage - 1.73. t_set_retr usage - 1.74. t_reset_retr usage - 1.75. t_set_auto_inv_100 usage - 1.76. t_branch_timeout usage - 1.77. t_branch_replied usage - 1.78. t_any_timeout usage - 1.79. t_any_replied usage - 1.80. t_grep_status usage - 1.81. t_is_canceled usage - 1.82. t_is_expired usage - 1.83. t_relay_cancel usage - 1.84. t_lookup_cancel usage - 1.85. t_drop_replies() usage - 1.86. t_save_lumps() usage - 1.87. t_load_contacts usage - 1.88. t_next_contacts usage - 1.89. t_next_contact_flow usage - 1.90. t_check_status usage - 1.91. t_check_trans usage - 1.92. t_set_disable_6xx usage - 1.93. t_set_disable_failover usage - 1.94. t_set_disable_internal_reply usage - 1.95. t_replicate usage - 1.96. t_relay_to usage - 1.97. t_set_no_e2e_cancel_reason usage - 1.98. t_replicate usage - 1.99. t_use_uac_headers usage - 1.100. t_is_retr_async_reply usage - 1.101. t_uac_send usage - 1.102. t_get_status_code usage - 1.103. t_clean usage - 1.104. t_exists usage - 1.105. event_route[tm:branch-failure:id] usage - 1.106. event_route[tm:local-request] usage - 1.107. event_route[tm:local-response] usage + 1.64. t_reply_error usage + 1.65. t_send_reply usage + 1.66. t_lookup_request usage + 1.67. t_retransmit_reply usage + 1.68. t_release usage + 1.69. t_forward_nonack usage + 1.70. t_set_fr usage + 1.71. t_reset_fr usage + 1.72. t_set_max_lifetime usage + 1.73. t_reset_max_lifetime usage + 1.74. t_set_retr usage + 1.75. t_reset_retr usage + 1.76. t_set_auto_inv_100 usage + 1.77. t_branch_timeout usage + 1.78. t_branch_replied usage + 1.79. t_any_timeout usage + 1.80. t_any_replied usage + 1.81. t_grep_status usage + 1.82. t_is_canceled usage + 1.83. t_is_expired usage + 1.84. t_relay_cancel usage + 1.85. t_lookup_cancel usage + 1.86. t_drop_replies() usage + 1.87. t_save_lumps() usage + 1.88. t_load_contacts usage + 1.89. t_next_contacts usage + 1.90. t_next_contact_flow usage + 1.91. t_check_status usage + 1.92. t_check_trans usage + 1.93. t_set_disable_6xx usage + 1.94. t_set_disable_failover usage + 1.95. t_set_disable_internal_reply usage + 1.96. t_replicate usage + 1.97. t_relay_to usage + 1.98. t_set_no_e2e_cancel_reason usage + 1.99. t_replicate usage + 1.100. t_use_uac_headers usage + 1.101. t_is_retr_async_reply usage + 1.102. t_uac_send usage + 1.103. t_get_status_code usage + 1.104. t_clean usage + 1.105. t_exists usage + 1.106. event_route[tm:branch-failure:id] usage + 1.107. event_route[tm:local-request] usage + 1.108. event_route[tm:local-response] usage Chapter 1. Admin Guide @@ -366,51 +368,52 @@ Chapter 1. Admin Guide 4.9. t_on_branch(branch_route) 4.10. t_newtran() 4.11. t_reply(code, reason_phrase) - 4.12. t_send_reply(code, reason) - 4.13. t_lookup_request() - 4.14. t_retransmit_reply() - 4.15. t_release() - 4.16. t_forward_nonack([ip, port]) - 4.17. t_forward_nonack_udp(ip, port) - 4.18. t_forward_nonack_tcp(ip, port) - 4.19. t_forward_nonack_tls(ip, port) - 4.20. t_forward_nonack_sctp(ip, port) - 4.21. t_set_fr(fr_inv_timeout [, fr_timeout]) - 4.22. t_reset_fr() - 4.23. t_set_max_lifetime(inv_lifetime, noninv_lifetime) - 4.24. t_reset_max_lifetime() - 4.25. t_set_retr(retr_t1_interval, retr_t2_interval) - 4.26. t_reset_retr() - 4.27. t_set_auto_inv_100(0|1) - 4.28. t_branch_timeout() - 4.29. t_branch_replied() - 4.30. t_any_timeout() - 4.31. t_any_replied() - 4.32. t_grep_status("code") - 4.33. t_is_canceled() - 4.34. t_is_expired() - 4.35. t_relay_cancel() - 4.36. t_lookup_cancel([1]) - 4.37. t_drop_replies([mode]) - 4.38. t_save_lumps() - 4.39. t_load_contacts([mode]) - 4.40. t_next_contacts() - 4.41. t_next_contact_flow() - 4.42. t_check_status(re) - 4.43. t_check_trans() - 4.44. t_set_disable_6xx(0|1) - 4.45. t_set_disable_failover(0|1) - 4.46. t_set_disable_internal_reply(0|1) - 4.47. t_replicate([params]) - 4.48. t_relay_to(proxy, flags) - 4.49. t_set_no_e2e_cancel_reason(0|1) - 4.50. t_is_set(target) - 4.51. t_use_uac_headers() - 4.52. t_is_retr_async_reply() - 4.53. t_uac_send(method, ruri, nexthop, socket, headers, body) - 4.54. t_get_status_code() - 4.55. t_clean() - 4.56. t_exists() + 4.12. t_reply_error() + 4.13. t_send_reply(code, reason) + 4.14. t_lookup_request() + 4.15. t_retransmit_reply() + 4.16. t_release() + 4.17. t_forward_nonack([ip, port]) + 4.18. t_forward_nonack_udp(ip, port) + 4.19. t_forward_nonack_tcp(ip, port) + 4.20. t_forward_nonack_tls(ip, port) + 4.21. t_forward_nonack_sctp(ip, port) + 4.22. t_set_fr(fr_inv_timeout [, fr_timeout]) + 4.23. t_reset_fr() + 4.24. t_set_max_lifetime(inv_lifetime, noninv_lifetime) + 4.25. t_reset_max_lifetime() + 4.26. t_set_retr(retr_t1_interval, retr_t2_interval) + 4.27. t_reset_retr() + 4.28. t_set_auto_inv_100(0|1) + 4.29. t_branch_timeout() + 4.30. t_branch_replied() + 4.31. t_any_timeout() + 4.32. t_any_replied() + 4.33. t_grep_status("code") + 4.34. t_is_canceled() + 4.35. t_is_expired() + 4.36. t_relay_cancel() + 4.37. t_lookup_cancel([1]) + 4.38. t_drop_replies([mode]) + 4.39. t_save_lumps() + 4.40. t_load_contacts([mode]) + 4.41. t_next_contacts() + 4.42. t_next_contact_flow() + 4.43. t_check_status(re) + 4.44. t_check_trans() + 4.45. t_set_disable_6xx(0|1) + 4.46. t_set_disable_failover(0|1) + 4.47. t_set_disable_internal_reply(0|1) + 4.48. t_replicate([params]) + 4.49. t_relay_to(proxy, flags) + 4.50. t_set_no_e2e_cancel_reason(0|1) + 4.51. t_is_set(target) + 4.52. t_use_uac_headers() + 4.53. t_is_retr_async_reply() + 4.54. t_uac_send(method, ruri, nexthop, socket, headers, body) + 4.55. t_get_status_code() + 4.56. t_clean() + 4.57. t_exists() 5. RPC Commands @@ -613,8 +616,8 @@ request_route { configured before with seturi() and append_branch(). Function t_next_contacts() takes the AVP created by the previous - function and extract the branches with highest q values from it. In our - example it is branch D. That branch is then put back into the + function and extracts the branches with highest q values from it. In + our example it is branch D. That branch is then put back into the destination set and when the script finally reaches t_relay(), the destination set only contains branch D and the request will be forwarded there. @@ -660,7 +663,7 @@ failure_route["serial"] If t_next_contact() returns a positive value then we have more new branches to try and we need to setup the failure_route again and call t_relay(). In our example the request will now be forwarded to branches - B and C in paralell, because they were both added to the destination + B and C in parallel, because they were both added to the destination set by t_next_contacts() at the same time. When branches B and C finish, the failure_route block is executed @@ -815,7 +818,7 @@ modparam("tm", "max_inv_lifetime", 150000) The main difference between this timer and fr_timer is that the fr_timer is per branch, while max_noninv_lifetime is per the whole transaction. An example when a transaction can live substantially more - then its fr_timer and where max_noninv_lifetime will help is when DNS + than its fr_timer and where max_noninv_lifetime will help is when DNS failover is used (each failed DNS SRV destination can introduce a new branch). @@ -961,7 +964,7 @@ modparam("tm", "unix_tx_timeout", 250) 3.13. aggregate_challenges (integer) - If set (default) and the final response is a 401 or a 407 and more than + If set (default), the final response is a 401 or a 407 and more than one branch received a 401 or 407, then all the WWW-Authenticate and Proxy-Authenticate headers from all the 401 and 407 replies will be aggregated in a new final response. If only one branch received the @@ -1253,7 +1256,7 @@ modparam("tm", "contact_flows_avp", "tm_contact_flows") 3.27. fr_timer_avp (string) - The value of fr_timer timer can be overriden on per-transaction basis. + The value of fr_timer timer can be overridden on per-transaction basis. The administrator can provide a value to be used for a particular transaction in an AVP. This parameter contains the name of the AVP that will be checked. If the AVP exists then its value will be used for the @@ -1286,7 +1289,7 @@ modparam("tm", "fr_timer_avp", "i:708") 3.28. fr_inv_timer_avp (string) - The value of fr_inv_timer timer can be overriden on per-transaction + The value of fr_inv_timer timer can be overridden on per-transaction basis. The administrator can provide a value to be used for a particular transaction in an AVP. This parameter contains the name of the AVP that will be checked. If the AVP exists, is non-empty and @@ -1497,7 +1500,7 @@ modparam("tm", "disable_6xx_block", 1) Note - Mode 1 and 2 does not follow RFC 3261, but are useful to deal with some + Modes 1 and 2 do not follow RFC 3261, but are useful to deal with some simple UAs behind a NAT (no different routing for the ACK and the contact contains an address behind the NAT). @@ -1558,8 +1561,8 @@ modparam("tm", "failure_reply_mode", 0) can be adjusted. * 0 - disabled (default) * < 0 - priority is increased by given amount. - * > 0 - priority is decreased by given amount. Do not make it higer - than 10000 or faked replies will even loose from 1xx clsss replies. + * > 0 - priority is decreased by given amount. Do not make it higher + than 10000 or faked replies will even loose from 1xx class replies. The default value is 0. @@ -1757,10 +1760,10 @@ modparam("tm", "exec_time_check", 0) 3.52. reply_relay_mode (int) - If set to 1, a received 200 OK response that was suspeneded is no - longer forwarded in the transactional context if another final response - was forward while 200 OK was suspended. Forwarding the 200 OK, even it - was received first, results in overwritting the transaction response + If set to 1, a received 200 OK response that was suspended is no longer + forwarded in the transactional context if another final response was + forwarded while 200 OK was suspended. Forwarding the 200 OK, even it + was received first, results in overwriting 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 @@ -1777,7 +1780,8 @@ modparam("tm", "reply_relay_mode", 0) 3.53. enable_uac_fr (int) Enable failure route trigger, for uac. This will copy the tm uac into - uas. Thus, failure route can be triggered even for uac messages. + uas. Thus, failure route can be triggered even for uac messages. The + default is 0 (disabled). Example 1.54. enable_uac_fr example ... @@ -1815,58 +1819,61 @@ modparam("tm", "failover_reply_codes", "code=403;code=488;class=5") 4.9. t_on_branch(branch_route) 4.10. t_newtran() 4.11. t_reply(code, reason_phrase) - 4.12. t_send_reply(code, reason) - 4.13. t_lookup_request() - 4.14. t_retransmit_reply() - 4.15. t_release() - 4.16. t_forward_nonack([ip, port]) - 4.17. t_forward_nonack_udp(ip, port) - 4.18. t_forward_nonack_tcp(ip, port) - 4.19. t_forward_nonack_tls(ip, port) - 4.20. t_forward_nonack_sctp(ip, port) - 4.21. t_set_fr(fr_inv_timeout [, fr_timeout]) - 4.22. t_reset_fr() - 4.23. t_set_max_lifetime(inv_lifetime, noninv_lifetime) - 4.24. t_reset_max_lifetime() - 4.25. t_set_retr(retr_t1_interval, retr_t2_interval) - 4.26. t_reset_retr() - 4.27. t_set_auto_inv_100(0|1) - 4.28. t_branch_timeout() - 4.29. t_branch_replied() - 4.30. t_any_timeout() - 4.31. t_any_replied() - 4.32. t_grep_status("code") - 4.33. t_is_canceled() - 4.34. t_is_expired() - 4.35. t_relay_cancel() - 4.36. t_lookup_cancel([1]) - 4.37. t_drop_replies([mode]) - 4.38. t_save_lumps() - 4.39. t_load_contacts([mode]) - 4.40. t_next_contacts() - 4.41. t_next_contact_flow() - 4.42. t_check_status(re) - 4.43. t_check_trans() - 4.44. t_set_disable_6xx(0|1) - 4.45. t_set_disable_failover(0|1) - 4.46. t_set_disable_internal_reply(0|1) - 4.47. t_replicate([params]) - 4.48. t_relay_to(proxy, flags) - 4.49. t_set_no_e2e_cancel_reason(0|1) - 4.50. t_is_set(target) - 4.51. t_use_uac_headers() - 4.52. t_is_retr_async_reply() - 4.53. t_uac_send(method, ruri, nexthop, socket, headers, body) - 4.54. t_get_status_code() - 4.55. t_clean() - 4.56. t_exists() + 4.12. t_reply_error() + 4.13. t_send_reply(code, reason) + 4.14. t_lookup_request() + 4.15. t_retransmit_reply() + 4.16. t_release() + 4.17. t_forward_nonack([ip, port]) + 4.18. t_forward_nonack_udp(ip, port) + 4.19. t_forward_nonack_tcp(ip, port) + 4.20. t_forward_nonack_tls(ip, port) + 4.21. t_forward_nonack_sctp(ip, port) + 4.22. t_set_fr(fr_inv_timeout [, fr_timeout]) + 4.23. t_reset_fr() + 4.24. t_set_max_lifetime(inv_lifetime, noninv_lifetime) + 4.25. t_reset_max_lifetime() + 4.26. t_set_retr(retr_t1_interval, retr_t2_interval) + 4.27. t_reset_retr() + 4.28. t_set_auto_inv_100(0|1) + 4.29. t_branch_timeout() + 4.30. t_branch_replied() + 4.31. t_any_timeout() + 4.32. t_any_replied() + 4.33. t_grep_status("code") + 4.34. t_is_canceled() + 4.35. t_is_expired() + 4.36. t_relay_cancel() + 4.37. t_lookup_cancel([1]) + 4.38. t_drop_replies([mode]) + 4.39. t_save_lumps() + 4.40. t_load_contacts([mode]) + 4.41. t_next_contacts() + 4.42. t_next_contact_flow() + 4.43. t_check_status(re) + 4.44. t_check_trans() + 4.45. t_set_disable_6xx(0|1) + 4.46. t_set_disable_failover(0|1) + 4.47. t_set_disable_internal_reply(0|1) + 4.48. t_replicate([params]) + 4.49. t_relay_to(proxy, flags) + 4.50. t_set_no_e2e_cancel_reason(0|1) + 4.51. t_is_set(target) + 4.52. t_use_uac_headers() + 4.53. t_is_retr_async_reply() + 4.54. t_uac_send(method, ruri, nexthop, socket, headers, body) + 4.55. t_get_status_code() + 4.56. t_clean() + 4.57. t_exists() 4.1. t_relay([host, port]) - Relay a message statefully either to the destination indicated in the - current URI (if called without any parameters) or to the specified host - and port. In the later case (host and port specified) the protocol used - is the same protocol on which the message was received. + Relay a SIP request statefully either to the destination indicated in + the current URI (if called without any parameters) or to the specified + host and port. In the later case (host and port specified) the protocol + used is the same protocol on which the message was received. It creates + the SIP transaction, if none was created before (e.g., with + t_newtran()). t_relay() is the stateful version for forward() while t_relay(host, port) is similar to forward(host, port). @@ -1884,7 +1891,7 @@ modparam("tm", "failover_reply_codes", "code=403;code=488;class=5") ... if (!t_relay()) { - sl_reply_error(); + send_reply_error(); break; }; ... @@ -2053,12 +2060,11 @@ branch_route[1] { 4.10. t_newtran() - Creates a new transaction, returns a negative value on error. This is - the only way a script can add a new transaction in an atomic way. + Creates a new transaction, returns a negative value on error. Typically, it is used to deploy a UAS. Note: once the t_newtran() is executed, the new message flag operations - (i.e., setflag() and resetflag()) are not syncronized to the + (i.e., setflag() and resetflag()) are not synchronized to the transaction, being stored only in the private memory SIP message structure. Use the tmx module function t_flush_flags() to synchronize the modified message flags to the already created transaction. @@ -2095,12 +2101,28 @@ if (t_newtran()) { * code - Reply code number. * reason_phrase - Reason string. + This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, + ONREPLY_ROUTE. + Example 1.63. t_reply usage ... t_reply("404", "Not found"); ... -4.12. t_send_reply(code, reason) +4.12. t_reply_error() + + Sends a stateful reply based in internal error code, similar to + sl_send_error() from sl module. + + This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, + ONREPLY_ROUTE. + + Example 1.64. t_reply_error usage +... +t_reply_error(); +... + +4.13. t_send_reply(code, reason) Creates the transaction if it does not exist (executing internally t_newtran()) and sends a stateful reply (executing internally @@ -2113,12 +2135,12 @@ t_reply("404", "Not found"); * code - Reply code number. * reason - Reason string. - Example 1.64. t_send_reply usage + Example 1.65. t_send_reply usage ... t_send_reply("404", "Not found"); ... -4.13. t_lookup_request() +4.14. t_lookup_request() Checks if a transaction exists. Returns a positive value if so, negative otherwise. Most likely you will not want to use it, as a @@ -2126,33 +2148,33 @@ t_send_reply("404", "Not found"); none was found. However this is safely (atomically) done using t_newtran. - Example 1.65. t_lookup_request usage + Example 1.66. t_lookup_request usage ... if (t_lookup_request()) { ... }; ... -4.14. t_retransmit_reply() +4.15. t_retransmit_reply() Retransmits a reply sent previously by UAS transaction. - Example 1.66. t_retransmit_reply usage + Example 1.67. t_retransmit_reply usage ... t_retransmit_reply(); ... -4.15. t_release() +4.16. t_release() Remove transaction from memory (it will be first put on a wait timer to absorb delayed messages). - Example 1.67. t_release usage + Example 1.68. t_release usage ... t_release(); ... -4.16. t_forward_nonack([ip, port]) +4.17. t_forward_nonack([ip, port]) Mainly for internal usage -- forward a non-ACK request statefully. Variants of this functions can enforce a specific transport protocol. @@ -2161,28 +2183,28 @@ t_release(); * ip - IP address where the message should be sent. * port - Port number. - Example 1.68. t_forward_nonack usage + Example 1.69. t_forward_nonack usage ... t_forward_nonack("1.2.3.4", "5060"); ... -4.17. t_forward_nonack_udp(ip, port) +4.18. t_forward_nonack_udp(ip, port) See function t_forward_nonack([ip, port]). -4.18. t_forward_nonack_tcp(ip, port) +4.19. t_forward_nonack_tcp(ip, port) See function t_forward_nonack([ip, port]). -4.19. t_forward_nonack_tls(ip, port) +4.20. t_forward_nonack_tls(ip, port) See function t_forward_nonack([ip, port]). -4.20. t_forward_nonack_sctp(ip, port) +4.21. t_forward_nonack_sctp(ip, port) See function t_forward_nonack([ip, port]). -4.21. t_set_fr(fr_inv_timeout [, fr_timeout]) +4.22. t_set_fr(fr_inv_timeout [, fr_timeout]) Sets the fr_inv_timeout and optionally fr_timeout for the current transaction or for transactions created during the same script @@ -2194,13 +2216,13 @@ t_forward_nonack("1.2.3.4", "5060"); Meaning of the parameters is as follows: * fr_inv_timeout - new final response timeout (in milliseconds) for INVITEs. See also fr_inv_timer. - fr_timeout - new final response timeout (in milliseconds) for + * fr_timeout - new final response timeout (in milliseconds) for non-INVITE transaction, or INVITEs which haven't received yet a provisional response. See also fr_timer. See also: fr_timer, fr_inv_timer, t_reset_fr(). - Example 1.69. t_set_fr usage + Example 1.70. t_set_fr usage ... route { t_set_fr(10000); # set only fr invite timeout to 10s @@ -2216,7 +2238,7 @@ branch_route[1] { } } -4.22. t_reset_fr() +4.23. t_reset_fr() Resets the fr_inv_timer and fr_timer for the current transaction to the default values (set using the tm module parameters fr_inv_timer and @@ -2227,7 +2249,7 @@ branch_route[1] { See also: fr_timer, fr_inv_timer, t_set_fr. - Example 1.70. t_reset_fr usage + Example 1.71. t_reset_fr usage ... route { ... @@ -2235,7 +2257,7 @@ route { ... } -4.23. t_set_max_lifetime(inv_lifetime, noninv_lifetime) +4.24. t_set_max_lifetime(inv_lifetime, noninv_lifetime) Sets the maximum lifetime for the current INVITE or non-INVITE transaction, or for transactions created during the same script @@ -2248,12 +2270,12 @@ route { Meaning of the parameters is as follows: * inv_lifetime - maximum INVITE transaction lifetime (in milliseconds). See also max_inv_lifetime. - noninv_lifetime - maximum non-INVITE transaction lifetime (in + * noninv_lifetime - maximum non-INVITE transaction lifetime (in milliseconds). See also max_noninv_lifetime. See also: max_inv_lifetime, max_noninv_lifetime, t_reset_max_lifetime. - Example 1.71. t_set_max_lifetime usage + Example 1.72. t_set_max_lifetime usage ... route { if (src_ip=1.2.3.4) @@ -2264,7 +2286,7 @@ route { # INVITE and to 15s if not } -4.24. t_reset_max_lifetime() +4.25. t_reset_max_lifetime() Resets the maximum lifetime for the current INVITE or non-INVITE transaction to the default value (set using the tm module parameter @@ -2275,7 +2297,7 @@ route { See also: max_inv_lifetime, max_noninv_lifetime, t_set_max_lifetime. - Example 1.72. t_reset_max_lifetime usage + Example 1.73. t_reset_max_lifetime usage ... route { ... @@ -2283,12 +2305,12 @@ route { ... } -4.25. t_set_retr(retr_t1_interval, retr_t2_interval) +4.26. t_set_retr(retr_t1_interval, retr_t2_interval) Sets the retr_t1_interval and retr_t2_interval for the current transaction or for transactions created during the same script invocation, after calling this function. If one of the parameters is 0, - it's value won't be changed. If the transaction is already created (e.g + its value won't be changed. If the transaction is already created (e.g called after t_relay() or in an onreply_route) all the existing branches will have their retransmissions intervals updated on-the-fly: if the retransmission interval for the branch has not yet reached T2 @@ -2305,12 +2327,12 @@ route { Meaning of the parameters is as follows: * retr_t1_interval - new T1 retransmission interval (in milliseconds). See also retr_t1_timeout. - retr_t2_interval - new T2 (or maximum) retransmission interval (in + * retr_t2_interval - new T2 (or maximum) retransmission interval (in milliseconds). See also retr_t2_timeout. See also: retr_timer1, retr_timer2, t_reset_retr(). - Example 1.73. t_set_retr usage + Example 1.74. t_set_retr usage ... route { t_set_retr(250, 0); # set only T1 to 250 ms @@ -2326,7 +2348,7 @@ branch_route[1] { } } -4.26. t_reset_retr() +4.27. t_reset_retr() Resets the retr_timer1 and retr_timer2 for the current transaction to the default values (set using the tm module parameters retr_timer1 and @@ -2337,7 +2359,7 @@ branch_route[1] { See also: retr_timer1, retr_timer2, t_set_retr. - Example 1.74. t_reset_retr usage + Example 1.75. t_reset_retr usage ... route { ... @@ -2345,7 +2367,7 @@ route { ... } -4.27. t_set_auto_inv_100(0|1) +4.28. t_set_auto_inv_100(0|1) Switch automatically sending 100 replies to INVITEs on/off on a per transaction basis. It overrides the auto_inv_100 value for the current @@ -2353,7 +2375,7 @@ route { See also: auto_inv_100. - Example 1.75. t_set_auto_inv_100 usage + Example 1.76. t_set_auto_inv_100 usage ... route { ... @@ -2362,13 +2384,13 @@ route { ... } -4.28. t_branch_timeout() +4.29. t_branch_timeout() Returns true if the failure route is executed for a branch that did timeout. It can be used from FAILURE_ROUTE and BRANCH_FAILURE_ROUTE event route. - Example 1.76. t_branch_timeout usage + Example 1.77. t_branch_timeout usage ... failure_route[0]{ if (t_branch_timeout()){ @@ -2377,14 +2399,14 @@ failure_route[0]{ } } -4.29. t_branch_replied() +4.30. t_branch_replied() Returns true if the failure route is executed for a branch that did receive at least one reply in the past (the "current" reply is not taken into account). It can be used from failure_route and branch-failure event route. - Example 1.77. t_branch_replied usage + Example 1.78. t_branch_replied usage ... failure_route[0]{ if (t_branch_timeout()){ @@ -2396,12 +2418,12 @@ failure_route[0]{ } } -4.30. t_any_timeout() +4.31. t_any_timeout() Returns true if at least one of the current transactions branches did timeout. - Example 1.78. t_any_timeout usage + Example 1.79. t_any_timeout usage ... failure_route[0]{ if (!t_branch_timeout()){ @@ -2412,13 +2434,13 @@ failure_route[0]{ } } -4.31. t_any_replied() +4.32. t_any_replied() Returns true if at least one of the current transactions branches did receive some reply in the past. If called from a failure or onreply route, the "current" reply is not taken into account. - Example 1.79. t_any_replied usage + Example 1.80. t_any_replied usage ... onreply_route[0]{ if (!t_any_replied()){ @@ -2427,12 +2449,12 @@ onreply_route[0]{ } } -4.32. t_grep_status("code") +4.33. t_grep_status("code") Returns true if "code" is the final reply received (or locally generated) in at least one of the current transactions branches. - Example 1.80. t_grep_status usage + Example 1.81. t_grep_status usage ... onreply_route[0]{ if (t_grep_status("486")){ @@ -2441,11 +2463,11 @@ onreply_route[0]{ } } -4.33. t_is_canceled() +4.34. t_is_canceled() Returns true if the current transaction was canceled. - Example 1.81. t_is_canceled usage + Example 1.82. t_is_canceled usage ... failure_route[0]{ if (t_is_canceled()){ @@ -2454,12 +2476,12 @@ failure_route[0]{ } } -4.34. t_is_expired() +4.35. t_is_expired() - Returns true if the current transaction has already been expired, i.e. - the max_inv_lifetime/max_noninv_lifetime interval has already elapsed. + Returns true if the current transaction has already expired, i.e. the + max_inv_lifetime/max_noninv_lifetime interval has already elapsed. - Example 1.82. t_is_expired usage + Example 1.83. t_is_expired usage ... failure_route[0]{ if (t_is_expired()){ @@ -2468,7 +2490,7 @@ failure_route[0]{ } } -4.35. t_relay_cancel() +4.36. t_relay_cancel() Forwards the CANCEL if the corresponding INVITE transaction exists. The function is supposed to be used at the very beginning of the script, @@ -2480,7 +2502,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.83. t_relay_cancel usage + Example 1.84. t_relay_cancel usage if (method == CANCEL) { if (!t_relay_cancel()) { # implicit drop if relaying was successful, # nothing to do @@ -2493,7 +2515,7 @@ if (method == CANCEL) { # do the same as for INVITEs } -4.36. t_lookup_cancel([1]) +4.37. t_lookup_cancel([1]) Returns true if the corresponding INVITE transaction exists for a CANCEL request. The function can be called at the beginning of the @@ -2507,7 +2529,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.84. t_lookup_cancel usage + Example 1.85. t_lookup_cancel usage if (method == CANCEL) { if (t_lookup_cancel()) { log("INVITE transaction exists"); @@ -2525,7 +2547,7 @@ if (method == CANCEL) { # do the same as for INVITEs } -4.37. t_drop_replies([mode]) +4.38. t_drop_replies([mode]) Drops all the previously received replies in failure_route block to make sure that none of them is picked up again. @@ -2537,7 +2559,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.85. t_drop_replies() usage + Example 1.86. t_drop_replies() usage ... failure_route[0]{ if (t_check_status("5[0-9][0-9]")){ @@ -2553,7 +2575,7 @@ failure_route[0]{ } } -4.38. t_save_lumps() +4.39. t_save_lumps() Forces the modifications of the processed SIP message to be saved in shared memory before t_relay() is called. The new branches which are @@ -2568,7 +2590,7 @@ failure_route[0]{ The transaction must be created by t_newtran() before calling t_save_lumps(). - Example 1.86. t_save_lumps() usage + Example 1.87. t_save_lumps() usage route { ... t_newtran(); @@ -2593,7 +2615,7 @@ failure_route[1] { t_relay(); } -4.39. t_load_contacts([mode]) +4.40. t_load_contacts([mode]) This is the first of the three functions that can be used to implement serial/parallel forking based on q and +sip.instance values of @@ -2610,7 +2632,7 @@ failure_route[1] { If the current destination set contains more than one branch, the function sorts them according to the algorithm selected with the 'mode' - paramenter and then stores the branches in reverse order into the XAVP. + parameter and then stores the branches in reverse order into the XAVP. The q parameter of a branch contains a value from range 0-1.0 and it expresses relative preference of the branch among all branches in the @@ -2642,7 +2664,7 @@ failure_route[1] { This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - Example 1.87. t_load_contacts usage + Example 1.88. t_load_contacts usage ... if (!t_load_contacts()) { sl_send_reply("500", "Server Internal Error - Cannot load contacts"); @@ -2650,7 +2672,7 @@ if (!t_load_contacts()) { }; ... -4.40. t_next_contacts() +4.41. t_next_contacts() Function t_next_contacts() is the second of the three functions that can be used to implement serial/parallel forking based on the q value @@ -2683,7 +2705,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.88. t_next_contacts usage + Example 1.89. t_next_contacts usage ... # First call after t_load_contacts() when transaction does not exist yet # and contacts should be available @@ -2702,7 +2724,7 @@ if (!t_next_contacts()) { }; ... -4.41. t_next_contact_flow() +4.42. t_next_contact_flow() Function t_next_contact_flow() is the last of the three functions that can be used to implement serial/parallel forking based on the q value @@ -2721,7 +2743,7 @@ if (!t_next_contacts()) { syslog). This function can be used from a BRANCH_FAILURE_ROUTE event route. - Example 1.89. t_next_contact_flow usage + Example 1.90. t_next_contact_flow usage ... event_route[tm:branch-failure:outbound] { @@ -2733,7 +2755,7 @@ event_route[tm:branch-failure:outbound] } ... -4.42. t_check_status(re) +4.43. t_check_status(re) Returns true if the regular expression “re” match the reply code of the response message as follows: @@ -2744,14 +2766,14 @@ event_route[tm:branch-failure:outbound] This function can be used from ANY_ROUTE . - Example 1.90. t_check_status usage + Example 1.91. t_check_status usage ... if (t_check_status("(487)|(408)")) { log("487 or 408 negative reply\n"); } ... -4.43. t_check_trans() +4.44. t_check_trans() t_check_trans() can be used to quickly check if a message belongs or is related to a transaction. It behaves differently for different types of @@ -2798,12 +2820,12 @@ Note See also: t_lookup_request(), t_lookup_cancel(). - Example 1.91. t_check_trans usage + Example 1.92. 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() -4.44. t_set_disable_6xx(0|1) +4.45. t_set_disable_6xx(0|1) Turn off/on 6xx replies special rfc conforming handling on a per transaction basis. If turned off (t_set_disable_6xx("1")) 6XXs will be @@ -2813,7 +2835,7 @@ if ( method == "CANCEL" && !t_check_trans()) See also: disable_6xx_block. - Example 1.92. t_set_disable_6xx usage + Example 1.93. t_set_disable_6xx usage ... route { ... @@ -2822,13 +2844,13 @@ route { ... } -4.45. t_set_disable_failover(0|1) +4.46. t_set_disable_failover(0|1) Turn off/on dns failover on a per transaction basis. See also: use_dns_failover. - Example 1.93. t_set_disable_failover usage + Example 1.94. t_set_disable_failover usage ... route { ... @@ -2837,11 +2859,11 @@ route { ... } -4.46. t_set_disable_internal_reply(0|1) +4.47. t_set_disable_internal_reply(0|1) Turn off/on sending internally a SIP reply in case of relay errors. - Example 1.94. t_set_disable_internal_reply usage + Example 1.95. t_set_disable_internal_reply usage ... t_set_disable_internal_reply(1); # turn off sending internal reply on error if(!t_relay()) { @@ -2849,7 +2871,7 @@ if(!t_relay()) { } ... -4.47. t_replicate([params]) +4.48. t_replicate([params]) Replicate the SIP request to a specific address. Return values are the same as for t_relay(). Note that responses to the replicated request @@ -2874,7 +2896,7 @@ if(!t_relay()) { * hostport - address in "host:port" format. It can be given via an AVP. - Example 1.95. t_replicate usage + Example 1.96. t_replicate usage ... # sent to 1.2.3.4:5060 over tcp t_replicate("sip:1.2.3.4:5060;transport=tcp"); @@ -2887,7 +2909,7 @@ t_replicate("sip:$var(h);transport=tls"); t_replicate_to_udp("1.2.3.4", "5060"); ... -4.48. t_relay_to(proxy, flags) +4.49. t_relay_to(proxy, flags) Forward the SIP request to a specific address, controlling internal behavior via flags. @@ -2908,7 +2930,7 @@ t_replicate_to_udp("1.2.3.4", "5060"); + 0x02 - do not generate reply on internal error. + 0x04 - disable dns failover. - Example 1.96. t_relay_to usage + Example 1.97. t_relay_to usage ... # sent to 1.2.3.4:5060 over tcp t_relay_to("tcp:1.2.3.4:5060"); @@ -2920,7 +2942,7 @@ t_relay_to("tls:1.2.3.4"); t_relay_to("0x01"); ... -4.49. t_set_no_e2e_cancel_reason(0|1) +4.50. t_set_no_e2e_cancel_reason(0|1) Enables/disables reason header (RFC 3326) copying from the triggering received CANCEL to the generated hop-by-hop CANCEL. 0 enables and 1 @@ -2934,7 +2956,7 @@ t_relay_to("0x01"); See also: e2e_cancel_reason. - Example 1.97. t_set_no_e2e_cancel_reason usage + Example 1.98. t_set_no_e2e_cancel_reason usage ... route { ... @@ -2944,7 +2966,7 @@ opying ... } -4.50. t_is_set(target) +4.51. t_is_set(target) Return true if the attribute specified by 'target' is set for transaction. @@ -2957,13 +2979,13 @@ opying * onreply_route - the function returns true if an onreply route is set to be executed. - Example 1.98. t_replicate usage + Example 1.99. t_replicate usage ... if(!t_is_set("failure_route")) LM_DBG("no failure route will be executed for current transaction\n"); ... -4.51. t_use_uac_headers() +4.52. t_use_uac_headers() Set internal flags to tell tm to use UAC side for building headers for local generated requests (ACK, CANCEL) - useful when changing From/To @@ -2971,12 +2993,12 @@ if(!t_is_set("failure_route")) It returns true. - Example 1.99. t_use_uac_headers usage + Example 1.100. t_use_uac_headers usage ... t_use_uac_headers(); ... -4.52. t_is_retr_async_reply() +4.53. t_is_retr_async_reply() Check to see if the reply is a retransmitted reply on a transaction that is currently suspended asynchronously (suspended during reply @@ -2990,7 +3012,7 @@ t_use_uac_headers(); returns true if the transaction is currently reply suspended or false if not. - Example 1.100. t_is_retr_async_reply usage + Example 1.101. t_is_retr_async_reply usage ... if (t_is_retr_async_reply()) { xlog("L_DBG", "Dropping retransmitted reply which is still currently sus @@ -2999,7 +3021,7 @@ pended\n"); } ... -4.53. t_uac_send(method, ruri, nexthop, socket, headers, body) +4.54. t_uac_send(method, ruri, nexthop, socket, headers, body) Send a UAC request. @@ -3015,39 +3037,39 @@ pended\n"); Content-Type header must exist. * body - SIP message body (can be empty). - Example 1.101. t_uac_send usage + Example 1.102. t_uac_send usage ... t_uac_send("OPTIONS", "sip:alice@kamailio.org", "", "", "From: bob@kamailio.org;tag=2w3e\r\nTo: bob@kamailio.org", ""); ... -4.54. t_get_status_code() +4.55. t_get_status_code() 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.102. t_get_status_code usage + Example 1.103. t_get_status_code usage ... $var(ts) = t_get_status_code(); if($var(ts) == 500) { ... } ... -4.55. t_clean() +4.56. t_clean() Cleans active but very old transactions. Returns true (1). Can be called from any route. - Example 1.103. t_clean usage + Example 1.104. t_clean usage ... t_clean(); ... -4.56. t_exists() +4.57. t_exists() - Return true of the transaction for current message exists, without + Return true if a transaction for the current message exists, without setting the global references. - Example 1.104. t_exists usage + Example 1.105. t_exists usage ... reply_route { if (!t_exists()) { @@ -3169,7 +3191,7 @@ reply_route { 6.1. event_route[tm:branch-failure:id] - Named branch failure routes can be defined to run when when a failure + Named branch failure routes can be defined to run when a failure response is received. This allows handling failures on individual branches, for example, retrying an alternative outbound flow. @@ -3177,7 +3199,7 @@ reply_route { enabled with the t_on_branch_failure function. This event_route uses the BRANCH_FAILURE_ROUTE route type. - Example 1.105. event_route[tm:branch-failure:id] usage + Example 1.106. event_route[tm:branch-failure:id] usage ... request_route { ... @@ -3203,7 +3225,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.106. event_route[tm:local-request] usage + Example 1.107. event_route[tm:local-request] usage ... event_route [tm:local-request] { xlog("L_INFO", "Routing locally generated $rm to $ru\n"); @@ -3216,7 +3238,7 @@ event_route [tm:local-request] { Executed after the tm module sent a local generated, transaction stateful response. - Example 1.107. event_route[tm:local-response] usage + Example 1.108. event_route[tm:local-response] usage ... event_route[tm:local-response] { xlog("tm:local-response replied locally\n"); diff --git a/src/modules/tm/config.h b/src/modules/tm/config.h index b0fedbbfb..2c215d2ab 100644 --- a/src/modules/tm/config.h +++ b/src/modules/tm/config.h @@ -39,7 +39,7 @@ #include "../../core/cfg/cfg.h" #include "../../core/str.h" -/* maximum length of localy generated acknowledgment */ +/* maximum length of locally generated acknowledgment */ #define MAX_ACK_LEN 1024 /* FINAL_RESPONSE_TIMER ... tells how long should the transaction engine diff --git a/src/modules/tm/dlg.c b/src/modules/tm/dlg.c index 6d131b53c..8120a061e 100644 --- a/src/modules/tm/dlg.c +++ b/src/modules/tm/dlg.c @@ -333,17 +333,25 @@ int new_dlg_uac(str *_cid, str *_ltag, unsigned int _lseq, str *_luri, memset(res, 0, sizeof(dlg_t)); /* Make a copy of Call-ID */ - if(str_duplicate(&res->id.call_id, _cid) < 0) + if(str_duplicate(&res->id.call_id, _cid) < 0) { + free_dlg(res); return -3; + } /* Make a copy of local tag (usually From tag) */ - if(str_duplicate(&res->id.loc_tag, _ltag) < 0) + if(str_duplicate(&res->id.loc_tag, _ltag) < 0) { + free_dlg(res); return -4; + } /* Make a copy of local URI (usually From) */ - if(str_duplicate(&res->loc_uri, _luri) < 0) + if(str_duplicate(&res->loc_uri, _luri) < 0) { + free_dlg(res); return -5; + } /* Make a copy of remote URI (usually To) */ - if(str_duplicate(&res->rem_uri, _ruri) < 0) + if(str_duplicate(&res->rem_uri, _ruri) < 0) { + free_dlg(res); return -6; + } /* Make a copy of local sequence (usually CSeq) */ res->loc_seq.value = _lseq; /* And mark it as set */ @@ -353,8 +361,9 @@ int new_dlg_uac(str *_cid, str *_ltag, unsigned int _lseq, str *_luri, if(calculate_hooks(*_d) < 0) { LM_ERR("error while calculating hooks\n"); - /* FIXME: free everything here */ - shm_free(res); + /* free everything here */ + free_dlg(res); + *_d = NULL; return -2; } #ifdef DIALOG_CALLBACKS @@ -368,7 +377,7 @@ int new_dlg_uac(str *_cid, str *_ltag, unsigned int _lseq, str *_luri, * @brief Store display names into a dialog * @param _d - dialog structure * @param _ldname - local party display name - * @param _rdname - remote party dispaly name + * @param _rdname - remote party display name * @return 0 on success; negative on error */ @@ -666,7 +675,7 @@ static inline int dlg_new_resp_uac(dlg_t *_d, struct sip_msg *_m) code = _m->first_line.u.reply.statuscode; if(code < 200) { - /* A provisional response, do nothing, we could + /* 100-199: a provisional response, do nothing, we could * update remote tag and route set but we will do that * for a positive final response anyway and I don't want * bet on presence of these fields in provisional responses @@ -674,8 +683,8 @@ static inline int dlg_new_resp_uac(dlg_t *_d, struct sip_msg *_m) * Send a request to jan@iptel.org if you need to update * the structures here */ - } else if((code >= 200) && (code < 299)) { - /* A final response, update the structures and transit + } else if(code < 299) { + /* 200-299: a final response, update the structures and transit * into DLG_CONFIRMED */ if(response2dlg(_m, _d) < 0) @@ -687,7 +696,7 @@ static inline int dlg_new_resp_uac(dlg_t *_d, struct sip_msg *_m) return -2; } } else { - /* A negative final response, mark the dialog as destroyed + /* 300-699: a negative final response, mark the dialog as destroyed * Again, I do not update the structures here because it * makes no sense to me, a dialog shouldn't be used after * it is destroyed @@ -712,8 +721,9 @@ static inline int dlg_early_resp_uac(dlg_t *_d, struct sip_msg *_m) if(code < 200) { /* We are in early state already, do nothing */ - } else if((code >= 200) && (code <= 299)) { - /* Warning - we can handle here response for non-initial request (for + } else if(code <= 299) { + /* (200-299) + * Warning - we can handle here response for non-initial request (for * example UPDATE within early INVITE/BYE dialog) and move into * confirmed state may be error! But this depends on dialog type... */ diff --git a/src/modules/tm/doc/event_routes.xml b/src/modules/tm/doc/event_routes.xml index 5c6111a07..d6a91f5c9 100644 --- a/src/modules/tm/doc/event_routes.xml +++ b/src/modules/tm/doc/event_routes.xml @@ -19,7 +19,7 @@ event_route[tm:branch-failure:id] - Named branch failure routes can be defined to run when when a failure + Named branch failure routes can be defined to run when a failure response is received. This allows handling failures on individual branches, for example, retrying an alternative outbound flow. diff --git a/src/modules/tm/doc/functions.xml b/src/modules/tm/doc/functions.xml index 5247ad5be..741505ec2 100644 --- a/src/modules/tm/doc/functions.xml +++ b/src/modules/tm/doc/functions.xml @@ -13,10 +13,11 @@ t_relay([host, port]) - Relay a message statefully either to the destination indicated in the + Relay a SIP request statefully either to the destination indicated in the current URI (if called without any parameters) or to the specified host and port. In the later case (host and port specified) the protocol - used is the same protocol on which the message was received. + used is the same protocol on which the message was received. It creates + the SIP transaction, if none was created before (e.g., with t_newtran()). t_relay() is the stateful version for @@ -41,7 +42,7 @@ ... if (!t_relay()) { - sl_reply_error(); + send_reply_error(); break; }; ... @@ -298,13 +299,12 @@ branch_route[1] { t_newtran() - Creates a new transaction, returns a negative value on error. This - is the only way a script can add a new transaction in an atomic - way. Typically, it is used to deploy a UAS. + Creates a new transaction, returns a negative value on error. Typically, + it is used to deploy a UAS. Note: once the t_newtran() is executed, the new message flag operations - (i.e., setflag() and resetflag()) are not syncronized to the transaction, + (i.e., setflag() and resetflag()) are not synchronized to the transaction, being stored only in the private memory SIP message structure. Use the tmx module function t_flush_flags() to synchronize the modified message flags to the already created transaction. @@ -359,6 +359,9 @@ if (t_newtran()) { + + This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE. + <function>t_reply</function> usage @@ -369,6 +372,27 @@ t_reply("404", "Not found"); +
+ + <function>t_reply_error()</function> + + + Sends a stateful reply based in internal error code, similar to + sl_send_error() from sl module. + + + This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE. + + + <function>t_reply_error</function> usage + +... +t_reply_error(); +... + + +
+
<function>t_send_reply(code, reason)</function> @@ -546,6 +570,8 @@ t_forward_nonack("1.2.3.4", "5060"); (in milliseconds) for INVITEs. See also <varname>fr_inv_timer</varname>. </para> + </listitem> + <listitem> <para><emphasis>fr_timeout</emphasis> - new final response timeout (in milliseconds) for non-INVITE transaction, or INVITEs which haven't received yet a provisional response. See also @@ -635,6 +661,8 @@ route { lifetime (in milliseconds). See also <varname>max_inv_lifetime</varname>. </para> + </listitem> + <listitem> <para><emphasis>noninv_lifetime</emphasis> - maximum non-INVITE transaction lifetime (in milliseconds). See also <varname>max_noninv_lifetime</varname>. @@ -703,7 +731,7 @@ route { Sets the retr_t1_interval and retr_t2_interval for the current transaction or for transactions created during the same script invocation, after calling this function. - If one of the parameters is 0, it's value won't be changed. + If one of the parameters is 0, its value won't be changed. If the transaction is already created (e.g called after <function>t_relay()</function> or in an onreply_route) all the existing branches will have their retransmissions intervals updated @@ -728,6 +756,8 @@ route { interval (in milliseconds). See also <varname>retr_t1_timeout</varname>. </para> + </listitem> + <listitem> <para><emphasis>retr_t2_interval</emphasis> - new T2 (or maximum) retransmission interval (in milliseconds). See also <varname>retr_t2_timeout</varname>. @@ -966,7 +996,7 @@ failure_route[0]{ <function>t_is_expired()</function> - Returns true if the current transaction has already been expired, + Returns true if the current transaction has already expired, i.e. the max_inv_lifetime/max_noninv_lifetime interval has already elapsed. @@ -1179,7 +1209,7 @@ failure_route[1] { If the current destination set contains more than one branch, the function sorts them according to the algorithm selected - with the 'mode' paramenter and then stores the branches in + with the 'mode' parameter and then stores the branches in reverse order into the XAVP. @@ -1913,7 +1943,7 @@ t_clean(); t_exists() - Return true of the transaction for current message exists, without + Return true if a transaction for the current message exists, without setting the global references. diff --git a/src/modules/tm/doc/params.xml b/src/modules/tm/doc/params.xml index 17b2c38ec..b8d7a8a3d 100644 --- a/src/modules/tm/doc/params.xml +++ b/src/modules/tm/doc/params.xml @@ -144,7 +144,7 @@ modparam("tm", "max_inv_lifetime", 150000) fr_timer is that the fr_timer is per branch, while max_noninv_lifetime is per the whole transaction. - An example when a transaction can live substantially more then its + An example when a transaction can live substantially more than its fr_timer and where max_noninv_lifetime will help is when DNS failover is used (each failed DNS SRV destination can introduce a new branch). @@ -372,7 +372,7 @@ modparam("tm", "unix_tx_timeout", 250)
<varname>aggregate_challenges</varname> (integer) - If set (default) and the final response is a 401 or a 407 and more than + If set (default), the final response is a 401 or a 407 and more than one branch received a 401 or 407, then all the WWW-Authenticate and Proxy-Authenticate headers from all the 401 and 407 replies will be aggregated in a new final response. If only one branch received the @@ -801,7 +801,7 @@ modparam("tm", "contact_flows_avp", "tm_contact_flows")
<varname>fr_timer_avp</varname> (string) - The value of fr_timer timer can be overriden on per-transaction + The value of fr_timer timer can be overridden on per-transaction basis. The administrator can provide a value to be used for a particular transaction in an AVP. This parameter contains the name of the AVP that will be checked. If the AVP exists then its value @@ -846,7 +846,7 @@ modparam("tm", "fr_timer_avp", "i:708")
<varname>fr_inv_timer_avp</varname> (string) - The value of fr_inv_timer timer can be overriden on + The value of fr_inv_timer timer can be overridden on per-transaction basis. The administrator can provide a value to be used for a particular transaction in an AVP. This parameter contains the name of the AVP that will be checked. If the AVP @@ -1177,7 +1177,7 @@ modparam("tm", "disable_6xx_block", 1) - Mode 1 and 2 does not follow RFC 3261, but are useful to deal with some simple UAs + Modes 1 and 2 do not follow RFC 3261, but are useful to deal with some simple UAs behind a NAT (no different routing for the ACK and the contact contains an address behind the NAT). @@ -1274,8 +1274,8 @@ modparam("tm", "failure_reply_mode", 0) > 0 - priority is decreased by given amount. - Do not make it higer than 10000 or faked replies will even loose - from 1xx clsss replies. + Do not make it higher than 10000 or faked replies will even loose + from 1xx class replies. @@ -1595,10 +1595,10 @@ modparam("tm", "exec_time_check", 0)
<varname>reply_relay_mode</varname> (int) - If set to 1, a received 200 OK response that was suspeneded is no + If set to 1, a received 200 OK response that was suspended is no longer forwarded in the transactional context if another final - response was forward while 200 OK was suspended. Forwarding the 200 OK, - even it was received first, results in overwritting the transaction + response was forwarded while 200 OK was suspended. Forwarding the 200 OK, + even it was received first, results in overwriting the transaction response buffer that can impact matching of incoming ACKs. @@ -1626,6 +1626,7 @@ modparam("tm", "reply_relay_mode", 0) Enable failure route trigger, for uac. This will copy the tm uac into uas. Thus, failure route can be triggered even for uac messages. + The default is 0 (disabled). enable_uac_fr example diff --git a/src/modules/tm/doc/tm.xml b/src/modules/tm/doc/tm.xml index a81e62327..006d6a5ba 100644 --- a/src/modules/tm/doc/tm.xml +++ b/src/modules/tm/doc/tm.xml @@ -248,7 +248,7 @@ request_route { Function t_next_contacts() takes the AVP created - by the previous function and extract the branches with highest q + by the previous function and extracts the branches with highest q values from it. In our example it is branch D. That branch is then put back into the destination set and when the script finally reaches t_relay(), the destination set only @@ -301,7 +301,7 @@ failure_route["serial"] we have more new branches to try and we need to setup the failure_route again and call t_relay(). In our example the request will now be forwarded to branches B and C in - paralell, because they were both added to the destination set + parallel, because they were both added to the destination set by t_next_contacts() at the same time. diff --git a/src/modules/tm/h_table.c b/src/modules/tm/h_table.c index cb9a56b36..7ee7c6747 100644 --- a/src/modules/tm/h_table.c +++ b/src/modules/tm/h_table.c @@ -52,7 +52,7 @@ - sizeof(((tm_cell_t *)0)->md5))) -static enum kill_reason kr; +static enum kill_reason _tm_kr; /* pointer to the big table where all the transaction data lives */ struct s_table *_tm_table; @@ -64,18 +64,18 @@ struct s_table *tm_get_table(void) void reset_kr(void) { - kr = 0; + _tm_kr = 0; } void set_kr(enum kill_reason _kr) { - kr |= _kr; + _tm_kr |= _kr; } enum kill_reason get_kr() { - return kr; + return _tm_kr; } @@ -329,7 +329,7 @@ struct cell *build_cell(struct sip_msg *p_msg) /* allocs a new cell, add space for: * md5 (MD5_LEN - sizeof(struct cell.md5)) - * uac (sr_dst_max_banches * sizeof(struct ua_client) ) */ + * uac (sr_dst_max_branches * sizeof(struct ua_client) ) */ cell_size = sizeof(struct cell) + MD5_LEN - sizeof(((struct cell *)0)->md5) + (sr_dst_max_branches * sizeof(struct ua_client)); @@ -516,7 +516,7 @@ error0: * backup xdata from/to msg context to local var and use T lists * - mode = 0 - from msg context to _txdata and use T lists * - mode = 1 - restore to msg context from _txdata - * the function can be also used to restore the core context from transacation data + * the function can be also used to restore the core context from transaction data */ void tm_xdata_swap(tm_cell_t *t, tm_xlinks_t *xd, int mode) { diff --git a/src/modules/tm/h_table.h b/src/modules/tm/h_table.h index 69f89ee3d..d95cb7d71 100644 --- a/src/modules/tm/h_table.h +++ b/src/modules/tm/h_table.h @@ -101,7 +101,7 @@ void unlock_hash(int i); * REQ_EXIST means that this request is a retransmission which does not * affect transactional state * REQ_ERR_DELAYED mean that tm wants to send reply(ser_error) but it - * delayed it to end-of-script to allow it to be overriden. + * delayed it to end-of-script to allow it to be overridden. * If this is set and all of the above flag are not => send reply * on end of script. If any of the above flags is set, do not * send (especially REQ_RPLD and REQ_RLSD). @@ -225,13 +225,11 @@ typedef struct ua_client */ struct retr_buf *local_ack; /* the route to take if no final positive reply arrived */ - unsigned short on_failure; + int on_failure; /* the route to take for all failure replies */ - unsigned short on_branch_failure; + int on_branch_failure; /* the onreply_route to be processed if registered to do so */ - unsigned short on_reply; - /* unused - keep the structure aligned to 32b */ - unsigned short on_unused; + int on_reply; } tm_ua_client_t; @@ -429,18 +427,18 @@ typedef struct cell /* nr of replied branch; 0..sr_dst_max_branches=branch value, * -1 no reply, -2 local reply */ - short relayed_reply_branch; + int relayed_reply_branch; /* the route to take if no final positive reply arrived */ - unsigned short on_failure; + int on_failure; /* the route to take for all failure replies */ - unsigned short on_branch_failure; + int on_branch_failure; /* the onreply_route to be processed if registered to do so */ - unsigned short on_reply; + int on_reply; /* The route to take for each downstream branch separately */ - unsigned short on_branch; + int on_branch; /* branch route backup for late branch add (t_append_branch) */ - unsigned short on_branch_delayed; + int on_branch_delayed; /* place holder for MD5checksum, MD5_LEN bytes are extra alloc'ed */ char md5[0]; diff --git a/src/modules/tm/rpc_uac.c b/src/modules/tm/rpc_uac.c index d461d123a..e63da4fb8 100644 --- a/src/modules/tm/rpc_uac.c +++ b/src/modules/tm/rpc_uac.c @@ -387,7 +387,6 @@ static int get_hfblock(str *uri, struct hdr_field *hf, int proto, if(!append_str_list(sock_name->s, sock_name->len, &last, &total_len)) goto error; - /* inefficient - FIXME --andrei*/ if(!append_str_list(":", 1, &last, &total_len)) goto error; if(!append_str_list(portname->s, portname->len, &last, diff --git a/src/modules/tm/select.c b/src/modules/tm/select.c index 433124dad..077d9e8d1 100644 --- a/src/modules/tm/select.c +++ b/src/modules/tm/select.c @@ -42,8 +42,8 @@ inline static int select_tm_get_cell( { /* make sure we know the associated transaction ... */ - if(t_check(msg, branch) == -1) /* it's not necessary whan calling - * from script because already done */ + if(t_check(msg, branch) == -1) /* it's not necessary when calling + * from script because already done */ return -1; /*... if there is none, tell the core router to fwd statelessly */ diff --git a/src/modules/tm/sip_msg.c b/src/modules/tm/sip_msg.c index 6ec58eb47..963cab748 100644 --- a/src/modules/tm/sip_msg.c +++ b/src/modules/tm/sip_msg.c @@ -72,7 +72,7 @@ struct sip_msg *sip_msg_cloner(struct sip_msg *org_msg, int *sip_msg_len) } /** - * @brief Indicates wheter we have already cloned the msg lumps or not + * @brief Indicates whether we have already cloned the msg lumps or not */ unsigned char lumps_are_cloned = 0; diff --git a/src/modules/tm/sip_msg.h b/src/modules/tm/sip_msg.h index b947df0f0..fd5e01fff 100644 --- a/src/modules/tm/sip_msg.h +++ b/src/modules/tm/sip_msg.h @@ -97,7 +97,7 @@ struct sip_msg *sip_msg_cloner(struct sip_msg *org_msg, int *sip_msg_len); /** - * @brief Indicates wheter we have already cloned the msg lumps or not + * @brief Indicates whether we have already cloned the msg lumps or not */ extern unsigned char lumps_are_cloned; diff --git a/src/modules/tm/t_fifo.c b/src/modules/tm/t_fifo.c index a732407c8..6d3e62f4a 100644 --- a/src/modules/tm/t_fifo.c +++ b/src/modules/tm/t_fifo.c @@ -280,7 +280,7 @@ int parse_tw_append(modparam_t type, void *val) goto parse_error; foo.len = s - foo.s; } - /* foo containes the elemet type */ + /* foo contains the element type */ if(foo.len == ELEM_TYPE_AVP_LEN && !strncasecmp(foo.s, ELEM_TYPE_AVP, foo.len)) { ha->type = ELEM_IS_AVP; @@ -339,7 +339,7 @@ int parse_tw_append(modparam_t type, void *val) } } } else if(ha->type == ELEM_IS_HDR) { - /* element is HDR - try to get it's coded type if defined */ + /* element is HDR - try to get its coded type if defined */ bar = foo.s[foo.len]; foo.s[foo.len] = ':'; /* parse header name */ diff --git a/src/modules/tm/t_funcs.c b/src/modules/tm/t_funcs.c index 40f7ce35e..5515a4aba 100644 --- a/src/modules/tm/t_funcs.c +++ b/src/modules/tm/t_funcs.c @@ -40,7 +40,7 @@ #include "t_stats.h" /* if defined t_relay* error reply generation will be delayed till script - * end (this allows the script writter to send its own error reply) */ + * end (this allows the script writer to send its own error reply) */ #define TM_DELAYED_REPLY #ifdef USE_DNS_FAILOVER @@ -177,6 +177,11 @@ int kill_transaction(struct cell *trans, int error) int reply_ret; int ret; + if((trans->uas.request != NULL) + && (trans->uas.request->msg_flags & FL_FINAL_REPLY)) { + return t_release_transaction(trans); + } + /* we reply statefully and enter WAIT state since error might have occurred in middle of forking and we do not want to put the forking burden on upstream client; @@ -205,6 +210,11 @@ int kill_transaction_unsafe(struct cell *trans, int error) int reply_ret; int ret; + if((trans->uas.request != NULL) + && (trans->uas.request->msg_flags & FL_FINAL_REPLY)) { + return t_release_transaction(trans); + } + /* we reply statefully and enter WAIT state since error might have occurred in middle of forking and we do not want to put the forking burden on upstream client; @@ -272,7 +282,7 @@ int t_relay_to( /* transaction previously found (E_SCRIPT) and msg==ACK => ack to neg. reply or ack to local trans. => process it and exit */ - /* FIXME: there's no way to distinguish here between acks to + /* - there's no way to distinguish here between acks to local trans. and neg. acks */ /* in normal operation we should never reach this point, if we do WARN(), it might hide some real bug (apart from possibly diff --git a/src/modules/tm/t_funcs.h b/src/modules/tm/t_funcs.h index e4943b286..c529ea31e 100644 --- a/src/modules/tm/t_funcs.h +++ b/src/modules/tm/t_funcs.h @@ -71,7 +71,7 @@ extern str contact_flows_avp; */ -/* send a buffer -- 'PR' means private, i.e., it is assumed noone +/* send a buffer -- 'PR' means private, i.e., it is assumed no one else can affect the buffer during sending time */ #ifdef EXTRA_DEBUG diff --git a/src/modules/tm/t_fwd.c b/src/modules/tm/t_fwd.c index c19d97c74..816568b18 100644 --- a/src/modules/tm/t_fwd.c +++ b/src/modules/tm/t_fwd.c @@ -333,7 +333,7 @@ static int prepare_new_uac(struct cell *t, struct sip_msg *i_req, int branch, rpl_snd_flags_bak = i_req->rpl_send_flags; force_send_socket_bak = i_req->force_send_socket; /* set the new values */ - i_req->fwd_send_flags = snd_flags /* intial value */; + i_req->fwd_send_flags = snd_flags /* initial value */; set_force_socket(i_req, fsocket); keng = sr_kemi_eng_get(); if(unlikely(keng != NULL)) { @@ -470,9 +470,11 @@ static int prepare_new_uac(struct cell *t, struct sip_msg *i_req, int branch, /* check if send_sock is ok */ if(t->uac[branch].request.dst.send_sock == 0) { - LM_ERR("can't fwd to af %d, proto %d " + LM_ERR("can't fwd to af %d (%s), proto %d (%s)" " (no corresponding listening socket)\n", - dst->to.s.sa_family, dst->proto); + dst->to.s.sa_family, + get_af_name((unsigned int)dst->to.s.sa_family), dst->proto, + get_proto_name((unsigned int)dst->proto)); ret = E_NO_SOCKET; goto error01; } @@ -878,10 +880,13 @@ static int add_uac_from_buf(struct cell *t, struct sip_msg *request, str *uri, /* check if send_sock is ok */ if(t->uac[branch].request.dst.send_sock == 0) { - LM_ERR("can't fwd to af %d, proto %d" + LM_ERR("can't fwd to af %d (%s), proto %d (%s)" " (no corresponding listening socket)\n", t->uac[branch].request.dst.to.s.sa_family, - t->uac[branch].request.dst.proto); + get_af_name((unsigned int)t->uac[branch] + .request.dst.to.s.sa_family), + t->uac[branch].request.dst.proto, + get_proto_name((unsigned int)t->uac[branch].request.dst.proto)); ret = ser_error = E_NO_SOCKET; goto error; } @@ -1107,7 +1112,7 @@ int e2e_cancel_branch(struct sip_msg *cancel_msg, struct cell *t_cancel, t_cancel->uac[branch].request.dst = t_invite->uac[branch].request.dst; /* print */ if(cfg_get(tm, tm_cfg, reparse_invite)) { - /* buffer is built localy from the INVITE which was sent out */ + /* buffer is built locally from the INVITE which was sent out */ /* lumps can be set outside of the lock, make sure that we read * the up-to-date values */ membar_depends(); @@ -1383,7 +1388,7 @@ void e2e_cancel(struct sip_msg *cancel_msg, struct cell *t_cancel, if(t_invite->uac[i].last_received >= 100) { /* Provisional reply received on this branch, send CANCEL */ /* we do need to stop the retr. timers if the request is not - * an invite and since the stop_rb_retr() cost is lower then + * an invite and since the stop_rb_retr() cost is lower than * the invite check we do it always --andrei */ stop_rb_retr(&t_invite->uac[i].request); if(SEND_BUFFER(&t_cancel->uac[i].request) == -1) { @@ -1761,7 +1766,7 @@ int t_forward_nonack( return lowest_ret; } - /* mark the fist branch in this fwd step */ + /* mark the first branch in this fwd step */ t->uac[first_branch].flags |= TM_UAC_FLAG_FB; ser_error = 0; /* clear branch adding errors */ @@ -1871,7 +1876,7 @@ int t_forward_cancel(struct sip_msg *p_msg, struct proxy_l *proxy, int proto, UNREF(t_invite); ret = 1; goto end; - } else /* no coresponding INVITE transaction */ + } else /* no corresponding INVITE transaction */ if(cfg_get(tm, tm_cfg, unmatched_cancel) == UM_CANCEL_DROP) { LM_DBG("non matching cancel dropped\n"); ret = 1; /* do nothing -> drop */ @@ -1918,8 +1923,8 @@ end: * return value: * 0: the CANCEL was successfully relayed * (or error occurred but reply cannot be sent) => DROP - * 1: no corresponding INVITE transaction exisis - * <0: corresponding INVITE transaction exisis but error occurred + * 1: no corresponding INVITE transaction exists + * <0: corresponding INVITE transaction exists but error occurred */ int t_relay_cancel(struct sip_msg *p_msg) { @@ -1950,7 +1955,7 @@ int t_relay_cancel(struct sip_msg *p_msg) goto end; } else { - /* no corresponding INVITE trasaction found */ + /* no corresponding INVITE transaction found */ ret = 1; } end: diff --git a/src/modules/tm/t_hooks.c b/src/modules/tm/t_hooks.c index d795272f7..0ad7437fa 100644 --- a/src/modules/tm/t_hooks.c +++ b/src/modules/tm/t_hooks.c @@ -184,14 +184,14 @@ int register_tmcb(struct sip_msg *p_msg, struct cell *t, int types, if((types != TMCB_MAX) && (types & TMCB_REQUEST_IN)) { if(types != TMCB_REQUEST_IN) { LM_CRIT("BUG: callback type TMCB_REQUEST_IN" - " can't be register along with types\n"); + " can't be registered along with types\n"); return E_BUG; } cb_list = req_in_tmcb_hl; } else if((types != TMCB_MAX) && (types & TMCB_LOCAL_REQUEST_IN)) { if(types != TMCB_LOCAL_REQUEST_IN) { LM_CRIT("BUG: callback type" - " TMCB_LOCAL_REQUEST_IN can't be register along with" + " TMCB_LOCAL_REQUEST_IN can't be registered along with" " other types\n"); return E_BUG; } diff --git a/src/modules/tm/t_hooks.h b/src/modules/tm/t_hooks.h index ff040ba20..aa566cb35 100644 --- a/src/modules/tm/t_hooks.h +++ b/src/modules/tm/t_hooks.h @@ -229,11 +229,11 @@ struct cell; * Note: if the send fails or via cannot be resolved, this callback is * _not_ called. * - * TMCB_LOCAL_COMPLETED -- final reply for localy initiated + * TMCB_LOCAL_COMPLETED -- final reply for locally initiated * transaction arrived. Message may be FAKED_REPLY. Can be called multiple * times, no lock is held. * - * TMCB_LOCAL_RESPONSE_OUT -- provisional reply for localy initiated + * TMCB_LOCAL_RESPONSE_OUT -- provisional reply for locally initiated * transaction. The message may be a FAKED_REPLY and the callback might be * called multiple time quasi-simultaneously. No lock is held. * Note: depends on tm.pass_provisional_replies. @@ -307,7 +307,7 @@ struct cell; * TMCB_RESPONSE_READY -- a reply is ready to be sent out. Callback is * is executed just before writing the reply content to network. * - * TMCB_DONT_ACK (requires AS support) -- for localy generated INVITEs, TM + * TMCB_DONT_ACK (requires AS support) -- for locally generated INVITEs, TM * automatically generates an ACK for the received 2xx replies. But, if this * flag is passed to TM when creating the initial UAC request, this won't * happen anymore: the ACK generation must be triggered from outside, using diff --git a/src/modules/tm/t_lookup.c b/src/modules/tm/t_lookup.c index abbc08a18..712f28fb7 100644 --- a/src/modules/tm/t_lookup.c +++ b/src/modules/tm/t_lookup.c @@ -114,7 +114,7 @@ static struct cell *T = NULL; * for the transaction currently processed. * It has a valid value only if T is valid (tm_global_ctx_id.{msgid, pid}==msg->{id, pid} * -- see above, and T!=0 and T!=T_UNDEFINED). - * For a request it's value is T_BR_UNDEFINED (it can have valid values only + * For a request its value is T_BR_UNDEFINED (it can have valid values only * for replies). */ static int T_branch = 0; @@ -400,14 +400,14 @@ static int matching_3261(struct sip_msg *p_msg, struct cell **trans, * purpose of accounting. We think it is a bad place here, among * other things because it is not reliable. If a transaction loops * via server the ACK can't be matched to proper INVITE transaction - * (it is a separate transactino with its own branch ID) and it + * (it is a separate transaction with its own branch ID) and it * matches all transaction instances in the loop dialog-wise. * Eventually, regardless to which transaction in the loop the * ACK belongs, only the first one will match. */ /* dialog matching needs to be applied for ACK/200s but only if - * this is a local transaction or its a proxied transaction interested + * this is a local transaction or it is a proxied transaction interested * in e2e ACKs (has E2EACK* callbacks installed) */ if(unlikely(is_ack && p_cell->uas.status < 300)) { if(unlikely(has_tran_tmcbs( @@ -429,7 +429,7 @@ static int matching_3261(struct sip_msg *p_msg, struct cell **trans, * which is interested in it (E2EACK* callbacks) * if ret==3 => partial match => we should at least * make sure the ACK is not for a negative reply - * (FIXME: ret==3 should never happen, it's a bug catch + * (note: ret==3 should never happen, it's a bug catch * case)*/ if(unlikely(ret == 1)) goto found; @@ -584,7 +584,7 @@ int t_request_search(struct sip_msg *p_msg, struct cell **r_cell) if(!t_msg) continue; /* skip UAC transactions */ /* for non-ACKs we want same method matching, we - * make an exception for pre-exisiting CANCELs because we + * make an exception for pre-existing CANCELs because we * want to set *cancel */ if((t_msg->REQ_METHOD != p_msg->REQ_METHOD) && (t_msg->REQ_METHOD != METHOD_CANCEL)) @@ -831,7 +831,7 @@ int t_lookup_request(struct sip_msg *p_msg, int leave_new_locked, int *cancel) if(!t_msg) continue; /* skip UAC transactions */ /* for non-ACKs we want same method matching, we - * make an exception for pre-exisiting CANCELs because we + * make an exception for pre-existing CANCELs because we * want to set *cancel */ if((t_msg->REQ_METHOD != p_msg->REQ_METHOD) && (t_msg->REQ_METHOD != METHOD_CANCEL)) diff --git a/src/modules/tm/t_msgbuilder.c b/src/modules/tm/t_msgbuilder.c index 22289830d..362ff6c5e 100644 --- a/src/modules/tm/t_msgbuilder.c +++ b/src/modules/tm/t_msgbuilder.c @@ -401,7 +401,7 @@ char *build_local_reparse(tm_cell_t *Trans, unsigned int branch, /* copy hf */ append_str(d, s1, s - s1); first_via = 0; - } /* else skip this line, we need olny the first via */ + } /* else skip this line, we need only the first via */ break; case HDR_TO_T: @@ -1059,7 +1059,7 @@ static int eval_uac_routing(sip_msg_t *rpl, const struct retr_buf *inv_rb, } else { /* trash last entry and replace with new remote target */ free_rte_list(t); - /* compact the rr_t struct along with rte. this way, free'ing + /* compact the rr_t struct along with rte. This way, free'ing * it can be done along with rte chunk, independent of Route * header parser's allocator (using pkg/shm) */ chklen = sizeof(struct rte) + sizeof(rr_t); @@ -1117,7 +1117,7 @@ error: /* * The function creates an ACK to 200 OK. Route set will be created * and parsed and the dst parameter will contain the destination to which - * the request should be send. The function is used by tm when it + * the request should be sent. The function is used by tm when it * generates local ACK to 200 OK (on behalf of applications using uac) */ char *build_dlg_ack(struct sip_msg *rpl, struct cell *Trans, @@ -1860,7 +1860,7 @@ void t_uas_request_clean_parsed(tm_cell_t *t) if(hdr->parsed && hdr_allocs_parse(hdr) && (hdr->parsed < mstart || hdr->parsed >= mend)) { /* header parsed filed doesn't point inside fake memory - * chunck -> it was added by failure funcs.-> free it as pkg */ + * chunk -> it was added by failure funcs.-> free it as pkg */ LM_DBG("removing hdr->parsed %d\n", hdr->type); clean_hdr_field(hdr); hdr->parsed = 0; diff --git a/src/modules/tm/t_msgbuilder.h b/src/modules/tm/t_msgbuilder.h index 78ee09e6e..260996af5 100644 --- a/src/modules/tm/t_msgbuilder.h +++ b/src/modules/tm/t_msgbuilder.h @@ -48,7 +48,7 @@ char *build_uac_cancel(str *headers, str *body, struct cell *cancelledT, /* * The function creates an ACK to 200 OK. Route set will be created * and parsed and the dst parameter will contain the destination to which the - * request should be send. The function is used by tm when it generates + * request should be sent. The function is used by tm when it generates * local ACK to 200 OK (on behalf of applications using uac */ char *build_dlg_ack(struct sip_msg *rpl, struct cell *Trans, diff --git a/src/modules/tm/t_reply.c b/src/modules/tm/t_reply.c index c612daa45..e012dc29c 100644 --- a/src/modules/tm/t_reply.c +++ b/src/modules/tm/t_reply.c @@ -121,7 +121,7 @@ extern int tm_reply_relay_mode; * Values: * - 0 - all branches are kept (default, and default ser 2.1.x behaviour) * - 1 - all branches are discarded - * - 2 - braches of last step of serial forking are discarded + * - 2 - branches of last step of serial forking are discarded * - 3 - all branches are discarded if a new leg of serial forking * is started (default kamailio 1.5.x behaviour) */ @@ -224,17 +224,17 @@ void t_on_reply(unsigned int go_to) } -unsigned int get_on_failure() +int get_on_failure() { return goto_on_failure; } -unsigned int get_on_branch_failure() +int get_on_branch_failure() { return goto_on_branch_failure; } -unsigned int get_on_reply() +int get_on_reply() { return goto_on_reply; } @@ -640,6 +640,11 @@ static int _reply_light(struct cell *trans, char *buf, unsigned int len, * (timer_allow_del()) (there's no chance of having the wait handler * executed while we still need t) --andrei */ put_on_wait(trans); + + /* mark the request with final reply flag */ + if(trans->uas.request != NULL) { + trans->uas.request->msg_flags |= FL_FINAL_REPLY; + } } pkg_free(buf); LM_DBG("finished\n"); @@ -736,7 +741,7 @@ static int _tm_faked_env_idx = -1; /** create or restore a "fake environment" for running a failure_route, * OR an "async environment" depending on is_async_value (0=std failure-faked, 1=async) * if msg is set -> it will fake the env. vars conforming with the msg; if NULL - * the env. will be restore to original. + * the env. will be restored to original. * Side-effect: mark_ruri_consumed() for faked env only. */ int faked_env(struct cell *t, struct sip_msg *msg, int is_async_env) @@ -967,7 +972,7 @@ void free_faked_req(struct sip_msg *faked_req, int len) if(hdr->parsed && hdr_allocs_parse(hdr) && (hdr->parsed < mstart || hdr->parsed >= mend)) { /* header parsed filed doesn't point inside fake memory - * chunck -> it was added by failure funcs.-> free it as pkg */ + * chunk -> it was added by failure funcs.-> free it as pkg */ LM_DBG("removing hdr->parsed %d\n", hdr->type); clean_hdr_field(hdr); hdr->parsed = 0; @@ -1531,7 +1536,7 @@ static enum rps t_should_relay_response(struct cell *Trans, int new_code, Trans->uac[branch].reply = 0; /* look if the callback perhaps replied transaction; it also - * covers the case in which a transaction is replied localy + * covers the case in which a transaction is replied locally * on CANCEL -- then it would make no sense to proceed to * new branches below */ @@ -1598,7 +1603,7 @@ static enum rps t_should_relay_response(struct cell *Trans, int new_code, /* really no more pending branches -- return lowest code */ *should_store = 0; *should_relay = picked_branch; - /* we dont need 'prepare_to_cancel' here -- all branches + /* we don't need 'prepare_to_cancel' here -- all branches * known to have completed */ /* prepare_to_cancel( Trans, cancel_bitmap, 0 ); */ LM_DBG("rps completed - uas status: %d branch: %d\n", Trans->uas.status, @@ -1827,7 +1832,7 @@ inline static int auth_reply_count(struct cell *t, struct sip_msg *crt_reply) } -/* must be called with the REPY_LOCK held */ +/* must be called with the REPLY_LOCK held */ inline static char *reply_aggregate_auth(int code, char *txt, str *new_tag, struct cell *t, unsigned int *res_len, struct bookmark *bm) { @@ -2183,7 +2188,7 @@ enum rps relay_reply(struct cell *t, struct sip_msg *p_msg, int branch, * failure_route or from a callback and the timer has been already * started. (Miklos) * - * put_on_wait() should always be called after we finished dealling + * put_on_wait() should always be called after we finished dealing * with t, because otherwise the wait timer might fire before we * finish with t, and by the time we want to use t it could * be already deleted. This could happen only if this function is @@ -2580,7 +2585,7 @@ int reply_received(struct sip_msg *p_msg) sr_event_exec(SREV_SIP_REPLY_OUT, &evp); } - /* restore brach last_received as before executing onreply_route */ + /* restore branch last_received as before executing onreply_route */ uac->last_received = last_uac_status; /* transfer current message context back to t */ if(t->uas.request) { @@ -2602,7 +2607,7 @@ int reply_received(struct sip_msg *p_msg) xavi_set_list(backup_xavis); /* handle a possible DROP in the script, but only if this * is not a final reply (final replies already stop the timers - * and droping them might leave a transaction living forever) */ + * and dropping them might leave a transaction living forever) */ #ifdef TM_ONREPLY_FINAL_DROP_OK if(unlikely(ctx.run_flags & DROP_R_F)) #else @@ -2614,7 +2619,7 @@ int reply_received(struct sip_msg *p_msg) #ifdef TM_ONREPLY_FINAL_DROP_OK if(msg_status >= 200) { /* stop final reply timers, now that we executed the onreply route - * and the reply was not DROPed */ + * and the reply was not DROPped */ stop_rb_timers(&uac->request); } #endif /* TM_ONREPLY_FINAL_DROP_OK */ @@ -2770,7 +2775,7 @@ done: /* don't try to relay statelessly neither on success * (we forwarded statefully) nor on error; on troubles, * simply do nothing; that will make the other party to - * retransmit; hopefuly, we'll then be better off */ + * retransmit; hopefully, we'll then be better off */ return 0; trans_not_found: @@ -2782,7 +2787,7 @@ trans_not_found: /* The script writer has a chance to decide whether to * forward the reply or not. * Pre- and post-script callbacks have already - * been execueted by the core. (Miklos) + * been executed by the core. (Miklos) */ return run_top_route( onreply_rt.rlist[goto_on_sl_reply], p_msg, 0); diff --git a/src/modules/tm/t_reply.h b/src/modules/tm/t_reply.h index 38fe67f5c..18ce47f45 100644 --- a/src/modules/tm/t_reply.h +++ b/src/modules/tm/t_reply.h @@ -178,6 +178,8 @@ int t_reply_str(struct cell *t, struct sip_msg *, unsigned int, str *); int t_reply_unsafe(struct cell *t, struct sip_msg *, unsigned int, char *); int t_reply_str_unsafe(struct cell *t, struct sip_msg *, unsigned int, str *); +int ki_t_reply_error(sip_msg_t *msg); + enum rps relay_reply(struct cell *t, struct sip_msg *p_msg, int branch, unsigned int msg_status, struct cancel_info *cancel_data, @@ -197,11 +199,11 @@ void on_failure_reply( replies arrive */ void t_on_failure(unsigned int go_to); -unsigned int get_on_failure(void); +int get_on_failure(void); void t_on_branch_failure(unsigned int go_to); -unsigned int get_on_branch_failure(void); +int get_on_branch_failure(void); void t_on_reply(unsigned int go_to); -unsigned int get_on_reply(void); +int get_on_reply(void); int t_retransmit_reply(struct cell *t); diff --git a/src/modules/tm/t_stats.h b/src/modules/tm/t_stats.h index 65a30659d..d5c901b3f 100644 --- a/src/modules/tm/t_stats.h +++ b/src/modules/tm/t_stats.h @@ -67,19 +67,19 @@ extern union t_stats *tm_stats; #ifdef TM_MORE_STATS inline void static t_stats_created(void) { - /* keep it in process's piece of shmem */ + /* keep it in process' piece of shmem */ tm_stats[process_no].s.t_created++; } inline void static t_stats_freed(void) { - /* keep it in process's piece of shmem */ + /* keep it in process' piece of shmem */ tm_stats[process_no].s.t_freed++; } inline void static t_stats_delayed_free(void) { - /* keep it in process's piece of shmem */ + /* keep it in process' piece of shmem */ tm_stats[process_no].s.delayed_free++; } #else /* TM_MORE_STATS */ @@ -98,7 +98,7 @@ inline void static t_stats_delayed_free(void) inline void static t_stats_new(int local) { - /* keep it in process's piece of shmem */ + /* keep it in process' piece of shmem */ tm_stats[process_no].s.transactions++; if(local) tm_stats[process_no].s.client_transactions++; @@ -106,7 +106,7 @@ inline void static t_stats_new(int local) inline void static t_stats_wait(void) { - /* keep it in process's piece of shmem */ + /* keep it in process' piece of shmem */ tm_stats[process_no].s.waiting++; } diff --git a/src/modules/tm/t_suspend.c b/src/modules/tm/t_suspend.c index b807b79c4..e0048f060 100644 --- a/src/modules/tm/t_suspend.c +++ b/src/modules/tm/t_suspend.c @@ -72,7 +72,7 @@ int t_suspend( return 1; } if(t->uas.status >= 200) { - LM_DBG("trasaction sent out a final response already - %d\n", + LM_DBG("transaction sent out a final response already - %d\n", t->uas.status); return -3; } diff --git a/src/modules/tm/timer.c b/src/modules/tm/timer.c index 614217ac7..c0cbade59 100644 --- a/src/modules/tm/timer.c +++ b/src/modules/tm/timer.c @@ -400,7 +400,7 @@ inline static void final_response_handler( && is_invite(t) /* parallel forking does not allow silent state discarding */ && t->nr_of_outgoings == 1 - /* on_negativ reply handler not installed -- serial forking + /* on_negative reply handler not installed -- serial forking * could occur otherwise */ && t->on_failure == 0 /* the same for FAILURE callbacks */ @@ -486,8 +486,8 @@ ticks_t retr_buf_handler(ticks_t ticks, struct timer_ln *tl, void *p) unsigned long crt_retr_interval_ms; struct cell *t; - rbuf = (struct retr_buf *)((void *)tl - - (void *)(&((struct retr_buf *)0)->timer)); + rbuf = ksr_container_of(tl, struct retr_buf, timer); + membar_depends(); /* to be on the safe side */ t = rbuf->my_T; diff --git a/src/modules/tm/timer.h b/src/modules/tm/timer.h index 23f0ac92e..20157cfc5 100644 --- a/src/modules/tm/timer.h +++ b/src/modules/tm/timer.h @@ -218,7 +218,7 @@ inline static int _set_fr_retr(struct retr_buf *rb, unsigned retr_ms) #endif if(ret == 0) rb->t_active = 1; - membar_write_atomic_op(); /* make sure t_active will be commited to mem. + membar_write_atomic_op(); /* make sure t_active will be committed to mem. before the transaction would be deref. by the current process */ return ret; diff --git a/src/modules/tm/tm.c b/src/modules/tm/tm.c index 2261430e5..31aa25338 100644 --- a/src/modules/tm/tm.c +++ b/src/modules/tm/tm.c @@ -112,6 +112,7 @@ static int t_failover_parse_reply_codes(); static int w_t_check(struct sip_msg *msg, char *str, char *str2); static int w_t_lookup_cancel(struct sip_msg *msg, char *str, char *str2); static int w_t_reply(struct sip_msg *msg, char *str, char *str2); +static int w_t_reply_error(struct sip_msg *msg, char *str, char *str2); static int w_t_send_reply(struct sip_msg *msg, char *p1, char *p2); static int w_t_release(struct sip_msg *msg, char *str, char *str2); static int w_t_retransmit_reply(struct sip_msg *p_msg, char *foo, char *bar); @@ -247,287 +248,293 @@ str tm_event_callback = STR_NULL; static int fixup_t_check_status(void **param, int param_no); +/* clang-format off */ static cmd_export_t cmds[] = { - {"t_newtran", w_t_newtran, 0, 0, 0, REQUEST_ROUTE}, - {"t_lookup_request", w_t_check, 0, 0, 0, REQUEST_ROUTE}, - {"t_lookup_cancel", w_t_lookup_cancel, 0, 0, 0, REQUEST_ROUTE}, - {"t_lookup_cancel", w_t_lookup_cancel, 1, fixup_int_1, 0, - REQUEST_ROUTE}, - {"t_reply", w_t_reply, 2, fixup_t_reply, 0, - REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE}, - {"t_send_reply", w_t_send_reply, 2, fixup_t_reply, 0, - REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE}, - {"t_retransmit_reply", w_t_retransmit_reply, 0, 0, 0, REQUEST_ROUTE}, - {"t_release", w_t_release, 0, 0, 0, REQUEST_ROUTE}, - {"t_relay_to_udp", w_t_relay_to_udp, 2, fixup_hostport2proxy, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, - {"t_relay_to_udp", w_t_relay_to_udp_uri, 0, 0, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, + {"t_newtran", w_t_newtran, 0, 0, 0, REQUEST_ROUTE}, + {"t_lookup_request", w_t_check, 0, 0, 0, REQUEST_ROUTE}, + {"t_lookup_cancel", w_t_lookup_cancel, 0, 0, 0, REQUEST_ROUTE}, + {"t_lookup_cancel", w_t_lookup_cancel, 1, fixup_int_1, 0, + REQUEST_ROUTE}, + {"t_reply", w_t_reply, 2, fixup_t_reply, 0, + REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE}, + {"t_reply_error", w_t_reply_error, 0, 0, 0, + REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE}, + {"t_send_reply", w_t_send_reply, 2, fixup_t_reply, 0, + REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE}, + {"t_retransmit_reply", w_t_retransmit_reply, 0, 0, 0, REQUEST_ROUTE}, + {"t_release", w_t_release, 0, 0, 0, REQUEST_ROUTE}, + {"t_relay_to_udp", w_t_relay_to_udp, 2, fixup_hostport2proxy, 0, + REQUEST_ROUTE | FAILURE_ROUTE}, + {"t_relay_to_udp", w_t_relay_to_udp_uri, 0, 0, 0, + REQUEST_ROUTE | FAILURE_ROUTE}, #ifdef USE_TCP - {"t_relay_to_tcp", w_t_relay_to_tcp, 2, fixup_hostport2proxy, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, - {"t_relay_to_tcp", w_t_relay_to_tcp_uri, 0, 0, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, + {"t_relay_to_tcp", w_t_relay_to_tcp, 2, fixup_hostport2proxy, 0, + REQUEST_ROUTE | FAILURE_ROUTE}, + {"t_relay_to_tcp", w_t_relay_to_tcp_uri, 0, 0, 0, + REQUEST_ROUTE | FAILURE_ROUTE}, #endif #ifdef USE_TLS - {"t_relay_to_tls", w_t_relay_to_tls, 2, fixup_hostport2proxy, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, - {"t_relay_to_tls", w_t_relay_to_tls_uri, 0, 0, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, + {"t_relay_to_tls", w_t_relay_to_tls, 2, fixup_hostport2proxy, 0, + REQUEST_ROUTE | FAILURE_ROUTE}, + {"t_relay_to_tls", w_t_relay_to_tls_uri, 0, 0, 0, + REQUEST_ROUTE | FAILURE_ROUTE}, #endif #ifdef USE_SCTP - {"t_relay_to_sctp", w_t_relay_to_sctp, 2, fixup_hostport2proxy, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, - {"t_relay_to_sctp", w_t_relay_to_sctp_uri, 0, 0, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, + {"t_relay_to_sctp", w_t_relay_to_sctp, 2, fixup_hostport2proxy, 0, + REQUEST_ROUTE | FAILURE_ROUTE}, + {"t_relay_to_sctp", w_t_relay_to_sctp_uri, 0, 0, 0, + REQUEST_ROUTE | FAILURE_ROUTE}, #endif - {"t_replicate", w_t_replicate_uri, 0, 0, 0, REQUEST_ROUTE}, - {"t_replicate", w_t_replicate_uri, 1, fixup_spve_null, 0, - REQUEST_ROUTE}, - {"t_replicate", w_t_replicate, 2, fixup_hostport2proxy, 0, - REQUEST_ROUTE}, - {"t_replicate_udp", w_t_replicate_udp, 2, fixup_hostport2proxy, 0, - REQUEST_ROUTE}, + {"t_replicate", w_t_replicate_uri, 0, 0, 0, REQUEST_ROUTE}, + {"t_replicate", w_t_replicate_uri, 1, fixup_spve_null, 0, + REQUEST_ROUTE}, + {"t_replicate", w_t_replicate, 2, fixup_hostport2proxy, 0, + REQUEST_ROUTE}, + {"t_replicate_udp", w_t_replicate_udp, 2, fixup_hostport2proxy, 0, + REQUEST_ROUTE}, #ifdef USE_TCP - {"t_replicate_tcp", w_t_replicate_tcp, 2, fixup_hostport2proxy, 0, - REQUEST_ROUTE}, + {"t_replicate_tcp", w_t_replicate_tcp, 2, fixup_hostport2proxy, 0, + REQUEST_ROUTE}, #endif #ifdef USE_TLS - {"t_replicate_tls", w_t_replicate_tls, 2, fixup_hostport2proxy, 0, - REQUEST_ROUTE}, + {"t_replicate_tls", w_t_replicate_tls, 2, fixup_hostport2proxy, 0, + REQUEST_ROUTE}, #endif #ifdef USE_SCTP - {"t_replicate_sctp", w_t_replicate_sctp, 2, fixup_hostport2proxy, 0, - REQUEST_ROUTE}, + {"t_replicate_sctp", w_t_replicate_sctp, 2, fixup_hostport2proxy, 0, + REQUEST_ROUTE}, #endif - {"t_replicate_to", w_t_replicate_to, 2, fixup_proto_hostport2proxy, 0, - REQUEST_ROUTE}, - {"t_relay", w_t_relay, 0, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE}, - {"t_relay", w_t_relay2, 2, fixup_hostport2proxy, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, - {"t_relay_to_avp", w_t_relay_to_avp, 2, fixup_proto_hostport2proxy, 0, - REQUEST_ROUTE}, - {"t_relay_to", w_t_relay_to, 0, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE}, - {"t_relay_to", w_t_relay_to, 1, fixup_t_relay_to, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, - {"t_relay_to", w_t_relay_to, 2, fixup_t_relay_to, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, - {"t_forward_nonack", w_t_forward_nonack, 2, fixup_hostport2proxy, 0, - REQUEST_ROUTE}, - {"t_forward_nonack_uri", w_t_forward_nonack_uri, 0, 0, 0, - REQUEST_ROUTE}, - {"t_forward_nonack_udp", w_t_forward_nonack_udp, 2, - fixup_hostport2proxy, 0, REQUEST_ROUTE}, + {"t_replicate_to", w_t_replicate_to, 2, fixup_proto_hostport2proxy, 0, + REQUEST_ROUTE}, + {"t_relay", w_t_relay, 0, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE}, + {"t_relay", w_t_relay2, 2, fixup_hostport2proxy, 0, + REQUEST_ROUTE | FAILURE_ROUTE}, + {"t_relay_to_avp", w_t_relay_to_avp, 2, fixup_proto_hostport2proxy, 0, + REQUEST_ROUTE}, + {"t_relay_to", w_t_relay_to, 0, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE}, + {"t_relay_to", w_t_relay_to, 1, fixup_t_relay_to, 0, + REQUEST_ROUTE | FAILURE_ROUTE}, + {"t_relay_to", w_t_relay_to, 2, fixup_t_relay_to, 0, + REQUEST_ROUTE | FAILURE_ROUTE}, + {"t_forward_nonack", w_t_forward_nonack, 2, fixup_hostport2proxy, 0, + REQUEST_ROUTE}, + {"t_forward_nonack_uri", w_t_forward_nonack_uri, 0, 0, 0, + REQUEST_ROUTE}, + {"t_forward_nonack_udp", w_t_forward_nonack_udp, 2, + fixup_hostport2proxy, 0, REQUEST_ROUTE}, #ifdef USE_TCP - {"t_forward_nonack_tcp", w_t_forward_nonack_tcp, 2, - fixup_hostport2proxy, 0, REQUEST_ROUTE}, + {"t_forward_nonack_tcp", w_t_forward_nonack_tcp, 2, + fixup_hostport2proxy, 0, REQUEST_ROUTE}, #endif #ifdef USE_TLS - {"t_forward_nonack_tls", w_t_forward_nonack_tls, 2, - fixup_hostport2proxy, 0, REQUEST_ROUTE}, + {"t_forward_nonack_tls", w_t_forward_nonack_tls, 2, + fixup_hostport2proxy, 0, REQUEST_ROUTE}, #endif #ifdef USE_SCTP - {"t_forward_nonack_sctp", w_t_forward_nonack_sctp, 2, - fixup_hostport2proxy, 0, REQUEST_ROUTE}, + {"t_forward_nonack_sctp", w_t_forward_nonack_sctp, 2, + fixup_hostport2proxy, 0, REQUEST_ROUTE}, #endif - {"t_forward_nonack_to", w_t_forward_nonack_to, 2, - fixup_proto_hostport2proxy, 0, REQUEST_ROUTE}, - {"t_relay_cancel", w_t_relay_cancel, 0, 0, 0, REQUEST_ROUTE}, - {"t_on_failure", w_t_on_failure, 1, fixup_on_failure, 0, - REQUEST_ROUTE | FAILURE_ROUTE | TM_ONREPLY_ROUTE - | BRANCH_ROUTE}, - {"t_on_branch_failure", w_t_on_branch_failure, 1, - fixup_on_branch_failure, 0, - REQUEST_ROUTE | FAILURE_ROUTE | TM_ONREPLY_ROUTE - | BRANCH_ROUTE}, - {"t_on_reply", w_t_on_reply, 1, fixup_on_reply, 0, - REQUEST_ROUTE | FAILURE_ROUTE | TM_ONREPLY_ROUTE - | BRANCH_ROUTE}, - {"t_on_branch", w_t_on_branch, 1, fixup_on_branch, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, - {"t_check_status", t_check_status, 1, fixup_t_check_status, 0, - REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, - {"t_write_req", t_write_req, 2, fixup_t_write, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, - {"t_write_unix", t_write_unix, 2, fixup_t_write, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, - {"t_set_fr", t_set_fr_inv, 1, fixup_var_int_1, 0, - REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE - | BRANCH_ROUTE}, - {"t_set_fr", t_set_fr_all, 2, fixup_var_int_12, 0, - REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE - | BRANCH_ROUTE}, - {"t_reset_fr", w_t_reset_fr, 0, 0, 0, - REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE - | BRANCH_ROUTE}, - {"t_set_retr", w_t_set_retr, 2, fixup_var_int_12, 0, - REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE - | BRANCH_ROUTE}, - {"t_reset_retr", w_t_reset_retr, 0, 0, 0, - REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE - | BRANCH_ROUTE}, - {"t_set_max_lifetime", w_t_set_max_lifetime, 2, fixup_var_int_12, 0, - REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE - | BRANCH_ROUTE}, - {"t_reset_max_lifetime", w_t_reset_max_lifetime, 0, 0, 0, - REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE - | BRANCH_ROUTE}, - {"t_set_auto_inv_100", w_t_set_auto_inv_100, 1, fixup_var_int_1, 0, - REQUEST_ROUTE}, - {"t_set_disable_6xx", w_t_set_disable_6xx, 1, fixup_var_int_1, 0, - REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE - | BRANCH_ROUTE}, - {"t_set_disable_failover", w_t_set_disable_failover, 1, fixup_var_int_1, - 0, - REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE - | BRANCH_ROUTE}, - {"t_set_no_e2e_cancel_reason", w_t_set_no_e2e_cancel_reason, 1, - fixup_var_int_1, 0, - REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE - | BRANCH_ROUTE}, - /* alias for t_set_no_e2e_cancel_reason */ - {"t_disable_e2e_cancel_reason", w_t_set_no_e2e_cancel_reason, 1, - fixup_var_int_1, 0, - REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE - | BRANCH_ROUTE}, - {"t_set_disable_internal_reply", w_t_set_disable_internal_reply, 1, - fixup_var_int_1, 0, - REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE - | BRANCH_ROUTE}, - {"t_branch_timeout", w_t_branch_timeout, 0, 0, 0, - FAILURE_ROUTE | EVENT_ROUTE}, - {"t_branch_replied", w_t_branch_replied, 0, 0, 0, - FAILURE_ROUTE | EVENT_ROUTE}, - {"t_any_timeout", w_t_any_timeout, 0, 0, 0, - REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE - | BRANCH_ROUTE}, - {"t_any_replied", w_t_any_replied, 0, 0, 0, - REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE - | BRANCH_ROUTE}, - {"t_is_canceled", w_t_is_canceled, 0, 0, 0, - REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE - | BRANCH_ROUTE}, - {"t_is_retr_async_reply", w_t_is_retr_async_reply, 0, 0, 0, - TM_ONREPLY_ROUTE}, - {"t_is_expired", w_t_is_expired, 0, 0, 0, - REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE - | BRANCH_ROUTE}, - {"t_grep_status", w_t_grep_status, 1, fixup_var_int_1, 0, - REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE - | BRANCH_ROUTE}, - {"t_drop_replies", w_t_drop_replies, 0, 0, 0, FAILURE_ROUTE}, - {"t_drop_replies", w_t_drop_replies, 1, 0, 0, FAILURE_ROUTE}, - {"t_save_lumps", w_t_save_lumps, 0, 0, 0, REQUEST_ROUTE}, - {"t_check_trans", w_t_check_trans, 0, 0, 0, - REQUEST_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"t_is_set", w_t_is_set, 1, fixup_t_is_set, 0, ANY_ROUTE}, - {"t_use_uac_headers", w_t_use_uac_headers, 0, 0, 0, ANY_ROUTE}, - {"t_uac_send", (cmd_function)w_t_uac_send, 6, fixup_spve_all, 0, - ANY_ROUTE}, - {"t_get_status_code", w_t_get_status_code, 0, 0, 0, - REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, - - {"t_load_contacts", t_load_contacts, 0, 0, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, - {"t_load_contacts", t_load_contacts, 1, fixup_var_int_1, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, - {"t_next_contacts", t_next_contacts, 0, 0, 0, - REQUEST_ROUTE | FAILURE_ROUTE}, - {"t_next_contact_flow", t_next_contact_flow, 0, 0, 0, REQUEST_ROUTE}, - {"t_clean", t_clean, 0, 0, 0, ANY_ROUTE}, - {"t_exists", w_t_exists, 0, 0, 0, ANY_ROUTE}, - - /* not applicable from the script */ - {"load_tm", (cmd_function)load_tm, NO_SCRIPT, 0, 0, 0}, - {"load_xtm", (cmd_function)load_xtm, NO_SCRIPT, 0, 0, 0}, - {0, 0, 0, 0, 0, 0}}; + {"t_forward_nonack_to", w_t_forward_nonack_to, 2, + fixup_proto_hostport2proxy, 0, REQUEST_ROUTE}, + {"t_relay_cancel", w_t_relay_cancel, 0, 0, 0, REQUEST_ROUTE}, + {"t_on_failure", w_t_on_failure, 1, fixup_on_failure, 0, + REQUEST_ROUTE | FAILURE_ROUTE | TM_ONREPLY_ROUTE + | BRANCH_ROUTE}, + {"t_on_branch_failure", w_t_on_branch_failure, 1, + fixup_on_branch_failure, 0, + REQUEST_ROUTE | FAILURE_ROUTE | TM_ONREPLY_ROUTE + | BRANCH_ROUTE}, + {"t_on_reply", w_t_on_reply, 1, fixup_on_reply, 0, + REQUEST_ROUTE | FAILURE_ROUTE | TM_ONREPLY_ROUTE + | BRANCH_ROUTE}, + {"t_on_branch", w_t_on_branch, 1, fixup_on_branch, 0, + REQUEST_ROUTE | FAILURE_ROUTE}, + {"t_check_status", t_check_status, 1, fixup_t_check_status, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE}, + {"t_write_req", t_write_req, 2, fixup_t_write, 0, + REQUEST_ROUTE | FAILURE_ROUTE}, + {"t_write_unix", t_write_unix, 2, fixup_t_write, 0, + REQUEST_ROUTE | FAILURE_ROUTE}, + {"t_set_fr", t_set_fr_inv, 1, fixup_var_int_1, 0, + REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE + | BRANCH_ROUTE}, + {"t_set_fr", t_set_fr_all, 2, fixup_var_int_12, 0, + REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE + | BRANCH_ROUTE}, + {"t_reset_fr", w_t_reset_fr, 0, 0, 0, + REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE + | BRANCH_ROUTE}, + {"t_set_retr", w_t_set_retr, 2, fixup_var_int_12, 0, + REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE + | BRANCH_ROUTE}, + {"t_reset_retr", w_t_reset_retr, 0, 0, 0, + REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE + | BRANCH_ROUTE}, + {"t_set_max_lifetime", w_t_set_max_lifetime, 2, fixup_var_int_12, 0, + REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE + | BRANCH_ROUTE}, + {"t_reset_max_lifetime", w_t_reset_max_lifetime, 0, 0, 0, + REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE + | BRANCH_ROUTE}, + {"t_set_auto_inv_100", w_t_set_auto_inv_100, 1, fixup_var_int_1, 0, + REQUEST_ROUTE}, + {"t_set_disable_6xx", w_t_set_disable_6xx, 1, fixup_var_int_1, 0, + REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE + | BRANCH_ROUTE}, + {"t_set_disable_failover", w_t_set_disable_failover, 1, fixup_var_int_1, + 0, + REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE + | BRANCH_ROUTE}, + {"t_set_no_e2e_cancel_reason", w_t_set_no_e2e_cancel_reason, 1, + fixup_var_int_1, 0, + REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE + | BRANCH_ROUTE}, + /* alias for t_set_no_e2e_cancel_reason */ + {"t_disable_e2e_cancel_reason", w_t_set_no_e2e_cancel_reason, 1, + fixup_var_int_1, 0, + REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE + | BRANCH_ROUTE}, + {"t_set_disable_internal_reply", w_t_set_disable_internal_reply, 1, + fixup_var_int_1, 0, + REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE + | BRANCH_ROUTE}, + {"t_branch_timeout", w_t_branch_timeout, 0, 0, 0, + FAILURE_ROUTE | EVENT_ROUTE}, + {"t_branch_replied", w_t_branch_replied, 0, 0, 0, + FAILURE_ROUTE | EVENT_ROUTE}, + {"t_any_timeout", w_t_any_timeout, 0, 0, 0, + REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE + | BRANCH_ROUTE}, + {"t_any_replied", w_t_any_replied, 0, 0, 0, + REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE + | BRANCH_ROUTE}, + {"t_is_canceled", w_t_is_canceled, 0, 0, 0, + REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE + | BRANCH_ROUTE}, + {"t_is_retr_async_reply", w_t_is_retr_async_reply, 0, 0, 0, + TM_ONREPLY_ROUTE}, + {"t_is_expired", w_t_is_expired, 0, 0, 0, + REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE + | BRANCH_ROUTE}, + {"t_grep_status", w_t_grep_status, 1, fixup_var_int_1, 0, + REQUEST_ROUTE | TM_ONREPLY_ROUTE | FAILURE_ROUTE + | BRANCH_ROUTE}, + {"t_drop_replies", w_t_drop_replies, 0, 0, 0, FAILURE_ROUTE}, + {"t_drop_replies", w_t_drop_replies, 1, 0, 0, FAILURE_ROUTE}, + {"t_save_lumps", w_t_save_lumps, 0, 0, 0, REQUEST_ROUTE}, + {"t_check_trans", w_t_check_trans, 0, 0, 0, + REQUEST_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"t_is_set", w_t_is_set, 1, fixup_t_is_set, 0, ANY_ROUTE}, + {"t_use_uac_headers", w_t_use_uac_headers, 0, 0, 0, ANY_ROUTE}, + {"t_uac_send", (cmd_function)w_t_uac_send, 6, fixup_spve_all, 0, + ANY_ROUTE}, + {"t_get_status_code", w_t_get_status_code, 0, 0, 0, + REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE}, + + {"t_load_contacts", t_load_contacts, 0, 0, 0, + REQUEST_ROUTE | FAILURE_ROUTE}, + {"t_load_contacts", t_load_contacts, 1, fixup_var_int_1, 0, + REQUEST_ROUTE | FAILURE_ROUTE}, + {"t_next_contacts", t_next_contacts, 0, 0, 0, + REQUEST_ROUTE | FAILURE_ROUTE}, + {"t_next_contact_flow", t_next_contact_flow, 0, 0, 0, REQUEST_ROUTE}, + {"t_clean", t_clean, 0, 0, 0, ANY_ROUTE}, + {"t_exists", w_t_exists, 0, 0, 0, ANY_ROUTE}, + + /* not applicable from the script */ + {"load_tm", (cmd_function)load_tm, NO_SCRIPT, 0, 0, 0}, + {"load_xtm", (cmd_function)load_xtm, NO_SCRIPT, 0, 0, 0}, + + {0, 0, 0, 0, 0, 0} +}; static param_export_t params[] = { - {"ruri_matching", PARAM_INT, &default_tm_cfg.ruri_matching}, - {"via1_matching", PARAM_INT, &default_tm_cfg.via1_matching}, - {"callid_matching", PARAM_INT, &default_tm_cfg.callid_matching}, - {"callid_cseq_matching", PARAM_INT, - &default_tm_cfg.callid_cseq_matching}, - {"fr_timer", PARAM_INT, &default_tm_cfg.fr_timeout}, - {"fr_inv_timer", PARAM_INT, &default_tm_cfg.fr_inv_timeout}, - {"wt_timer", PARAM_INT, &default_tm_cfg.wait_timeout}, - {"retr_timer1", PARAM_INT, &default_tm_cfg.rt_t1_timeout_ms}, - {"retr_timer2", PARAM_INT, &default_tm_cfg.rt_t2_timeout_ms}, - {"max_inv_lifetime", PARAM_INT, &default_tm_cfg.tm_max_inv_lifetime}, - {"max_noninv_lifetime", PARAM_INT, - &default_tm_cfg.tm_max_noninv_lifetime}, - {"noisy_ctimer", PARAM_INT, &default_tm_cfg.noisy_ctimer}, - {"auto_inv_100", PARAM_INT, &default_tm_cfg.tm_auto_inv_100}, - {"auto_inv_100_reason", PARAM_STRING, - &default_tm_cfg.tm_auto_inv_100_r}, - {"unix_tx_timeout", PARAM_INT, &default_tm_cfg.tm_unix_tx_timeout}, - {"restart_fr_on_each_reply", PARAM_INT, - &default_tm_cfg.restart_fr_on_each_reply}, - {"fr_timer_avp", PARAM_STRING, &fr_timer_param}, - {"fr_inv_timer_avp", PARAM_STRING, &fr_inv_timer_param}, - {"tw_append", PARAM_STRING | PARAM_USE_FUNC, (void *)parse_tw_append}, - {"pass_provisional_replies", PARAM_INT, - &default_tm_cfg.pass_provisional_replies}, - {"aggregate_challenges", PARAM_INT, &default_tm_cfg.tm_aggregate_auth}, - {"unmatched_cancel", PARAM_INT, &default_tm_cfg.unmatched_cancel}, - {"default_code", PARAM_INT, &default_tm_cfg.default_code}, - {"default_reason", PARAM_STRING, &default_tm_cfg.default_reason}, - {"reparse_invite", PARAM_INT, &default_tm_cfg.reparse_invite}, - {"ac_extra_hdrs", PARAM_STR, &default_tm_cfg.ac_extra_hdrs}, - {"blst_503", PARAM_INT, &default_tm_cfg.tm_blst_503}, - {"blst_503_def_timeout", PARAM_INT, - &default_tm_cfg.tm_blst_503_default}, - {"blst_503_min_timeout", PARAM_INT, &default_tm_cfg.tm_blst_503_min}, - {"blst_503_max_timeout", PARAM_INT, &default_tm_cfg.tm_blst_503_max}, - {"blst_methods_add", PARAM_INT, &default_tm_cfg.tm_blst_methods_add}, - {"blst_methods_lookup", PARAM_INT, - &default_tm_cfg.tm_blst_methods_lookup}, - {"cancel_b_method", PARAM_INT, &default_tm_cfg.cancel_b_flags}, - {"reparse_on_dns_failover", PARAM_INT, - &default_tm_cfg.reparse_on_dns_failover}, - {"on_sl_reply", PARAM_STR, &on_sl_reply_name}, - {"contacts_avp", PARAM_STR, &contacts_avp}, - {"contact_flows_avp", PARAM_STR, &contact_flows_avp}, - {"disable_6xx_block", PARAM_INT, &default_tm_cfg.disable_6xx}, - {"local_ack_mode", PARAM_INT, &default_tm_cfg.local_ack_mode}, - {"failure_reply_mode", PARAM_INT, &failure_reply_mode}, - {"faked_reply_prio", PARAM_INT, &faked_reply_prio}, - {"remap_503_500", PARAM_INT, &tm_remap_503_500}, - {"failure_exec_mode", PARAM_INT, &tm_failure_exec_mode}, - {"dns_reuse_rcv_socket", PARAM_INT, &tm_dns_reuse_rcv_socket}, - {"local_cancel_reason", PARAM_INT, &default_tm_cfg.local_cancel_reason}, - {"e2e_cancel_reason", PARAM_INT, &default_tm_cfg.e2e_cancel_reason}, - {"xavp_contact", PARAM_STR, &ulattrs_xavp_name}, - {"event_callback", PARAM_STR, &tm_event_callback}, - {"relay_100", PARAM_INT, &default_tm_cfg.relay_100}, - {"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}, - {"enable_uac_fr", PARAM_INT, &default_tm_cfg.enable_uac_fr}, + {"ruri_matching", PARAM_INT, &default_tm_cfg.ruri_matching}, + {"via1_matching", PARAM_INT, &default_tm_cfg.via1_matching}, + {"callid_matching", PARAM_INT, &default_tm_cfg.callid_matching}, + {"callid_cseq_matching", PARAM_INT, + &default_tm_cfg.callid_cseq_matching}, + {"fr_timer", PARAM_INT, &default_tm_cfg.fr_timeout}, + {"fr_inv_timer", PARAM_INT, &default_tm_cfg.fr_inv_timeout}, + {"wt_timer", PARAM_INT, &default_tm_cfg.wait_timeout}, + {"retr_timer1", PARAM_INT, &default_tm_cfg.rt_t1_timeout_ms}, + {"retr_timer2", PARAM_INT, &default_tm_cfg.rt_t2_timeout_ms}, + {"max_inv_lifetime", PARAM_INT, &default_tm_cfg.tm_max_inv_lifetime}, + {"max_noninv_lifetime", PARAM_INT, + &default_tm_cfg.tm_max_noninv_lifetime}, + {"noisy_ctimer", PARAM_INT, &default_tm_cfg.noisy_ctimer}, + {"auto_inv_100", PARAM_INT, &default_tm_cfg.tm_auto_inv_100}, + {"auto_inv_100_reason", PARAM_STRING, + &default_tm_cfg.tm_auto_inv_100_r}, + {"unix_tx_timeout", PARAM_INT, &default_tm_cfg.tm_unix_tx_timeout}, + {"restart_fr_on_each_reply", PARAM_INT, + &default_tm_cfg.restart_fr_on_each_reply}, + {"fr_timer_avp", PARAM_STRING, &fr_timer_param}, + {"fr_inv_timer_avp", PARAM_STRING, &fr_inv_timer_param}, + {"tw_append", PARAM_STRING | PARAM_USE_FUNC, (void *)parse_tw_append}, + {"pass_provisional_replies", PARAM_INT, + &default_tm_cfg.pass_provisional_replies}, + {"aggregate_challenges", PARAM_INT, &default_tm_cfg.tm_aggregate_auth}, + {"unmatched_cancel", PARAM_INT, &default_tm_cfg.unmatched_cancel}, + {"default_code", PARAM_INT, &default_tm_cfg.default_code}, + {"default_reason", PARAM_STRING, &default_tm_cfg.default_reason}, + {"reparse_invite", PARAM_INT, &default_tm_cfg.reparse_invite}, + {"ac_extra_hdrs", PARAM_STR, &default_tm_cfg.ac_extra_hdrs}, + {"blst_503", PARAM_INT, &default_tm_cfg.tm_blst_503}, + {"blst_503_def_timeout", PARAM_INT, + &default_tm_cfg.tm_blst_503_default}, + {"blst_503_min_timeout", PARAM_INT, &default_tm_cfg.tm_blst_503_min}, + {"blst_503_max_timeout", PARAM_INT, &default_tm_cfg.tm_blst_503_max}, + {"blst_methods_add", PARAM_INT, &default_tm_cfg.tm_blst_methods_add}, + {"blst_methods_lookup", PARAM_INT, + &default_tm_cfg.tm_blst_methods_lookup}, + {"cancel_b_method", PARAM_INT, &default_tm_cfg.cancel_b_flags}, + {"reparse_on_dns_failover", PARAM_INT, + &default_tm_cfg.reparse_on_dns_failover}, + {"on_sl_reply", PARAM_STR, &on_sl_reply_name}, + {"contacts_avp", PARAM_STR, &contacts_avp}, + {"contact_flows_avp", PARAM_STR, &contact_flows_avp}, + {"disable_6xx_block", PARAM_INT, &default_tm_cfg.disable_6xx}, + {"local_ack_mode", PARAM_INT, &default_tm_cfg.local_ack_mode}, + {"failure_reply_mode", PARAM_INT, &failure_reply_mode}, + {"faked_reply_prio", PARAM_INT, &faked_reply_prio}, + {"remap_503_500", PARAM_INT, &tm_remap_503_500}, + {"failure_exec_mode", PARAM_INT, &tm_failure_exec_mode}, + {"dns_reuse_rcv_socket", PARAM_INT, &tm_dns_reuse_rcv_socket}, + {"local_cancel_reason", PARAM_INT, &default_tm_cfg.local_cancel_reason}, + {"e2e_cancel_reason", PARAM_INT, &default_tm_cfg.e2e_cancel_reason}, + {"xavp_contact", PARAM_STR, &ulattrs_xavp_name}, + {"event_callback", PARAM_STR, &tm_event_callback}, + {"relay_100", PARAM_INT, &default_tm_cfg.relay_100}, + {"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}, + {"enable_uac_fr", PARAM_INT, &default_tm_cfg.enable_uac_fr}, #ifdef USE_DNS_FAILOVER - {"failover_reply_codes", PARAM_STR, &failover_reply_codes_str}, + {"failover_reply_codes", PARAM_STR, &failover_reply_codes_str}, #endif - {0, 0, 0}}; + {0, 0, 0} +}; #ifdef STATIC_TM struct module_exports tm_exports = { #else struct module_exports exports = { #endif - "tm", /* module name */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* cmd (cfg function) exports */ - params, /* param exports */ - tm_rpc, /* RPC method exports */ - 0, /* pv exports */ - reply_received, /* response handling function */ - mod_init, /* module init function */ - child_init, /* per-child init function */ - tm_shutdown /* module destroy function */ + "tm", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* cmd (cfg function) exports */ + params, /* param exports */ + tm_rpc, /* RPC method exports */ + 0, /* pv exports */ + reply_received, /* response handling function */ + mod_init, /* module init function */ + child_init, /* per-child init function */ + tm_shutdown /* module destroy function */ }; - +/* clang-format on */ /* helper for fixup_on_* */ static int fixup_routes(char *r_type, struct route_list *rt, void **param) @@ -656,7 +663,7 @@ static int fixup_hostport2proxy(void **param, int param_no) } s.s = host; s.len = strlen(host); - proxy = mk_proxy(&s, port, 0); /* FIXME: udp or tcp? */ + proxy = mk_proxy(&s, port, 0); if(proxy == 0) { LM_ERR("bad host name in URI <%s>\n", host); return E_BAD_ADDRESS; @@ -948,7 +955,7 @@ static int ki_t_get_status_code(sip_msg_t *msg) /* use the status of the winning reply */ ret = t_pick_branch(-1, 0, t, &scode); if(ret == -1) { - /* t_pick_branch() retuns error also when there are only + /* t_pick_branch() returns error also when there are only * blind UACs. Let us give it another chance including the * blind branches. */ LM_DBG("t_pick_branch returned error," @@ -1103,7 +1110,7 @@ static int t_check_status(struct sip_msg *msg, char *p1, char *foo) /* use the status of the winning reply */ ret = t_pick_branch(-1, 0, t, &lowest_status); if(ret == -1) { - /* t_pick_branch() retuns error also when there are only + /* t_pick_branch() returns error also when there are only * blind UACs. Let us give it another chance including the * blind branches. */ LM_DBG("t_pick_branch returned error," @@ -1208,7 +1215,7 @@ static int ki_t_check_status(sip_msg_t *msg, str *sexp) /* use the status of the winning reply */ ret = t_pick_branch(-1, 0, t, &lowest_status); if(ret == -1) { - /* t_pick_branch() retuns error also when there are only + /* t_pick_branch() returns error also when there are only * blind UACs. Let us give it another chance including the * blind branches. */ LM_DBG("t_pick_branch returned error," @@ -1591,6 +1598,42 @@ int w_t_reply_wrp(struct sip_msg *msg, unsigned int code, char *txt) return ki_t_reply(msg, code, &reason); } +/** + * kemi function to send reply based on internal error code + */ +int ki_t_reply_error(sip_msg_t *msg) +{ + char err_buffer[128]; + str reason; + int sip_err; + int ret; + + if(msg->msg_flags & FL_FINAL_REPLY) { + LM_INFO("message marked with final-reply flag\n"); + return -2; + } + + ret = err2reason_phrase( + prev_ser_error, &sip_err, err_buffer, sizeof(err_buffer), "TM"); + if(ret > 0) { + reason.s = err_buffer; + reason.len = strlen(reason.s); + return ki_t_reply(msg, sip_err, &reason); + } else { + LM_ERR("failed to get internal error reason phrase\n"); + return -1; + } +} + + +/** + * config function to send reply based on internal error code + */ +static int w_t_reply_error(sip_msg_t *msg, char *p1, char *p2) +{ + return ki_t_reply_error(msg); +} + /** * */ @@ -1801,16 +1844,26 @@ static int _w_t_relay_to( if(res <= 0) { if(res != E_CFG) { LM_ERR("t_forward_noack failed\n"); - /* let us save the error code, we might need it later - * when the failure_route has finished (Miklos) */ + if(get_kr() == REQ_ERR_DELAYED) { + p_msg->msg_flags |= FL_DELAYED_REPLY; + } } + /* let us save the error code, we might need it later + * when the failure_route has finished (Miklos) */ tm_error = ser_error; return -1; } return 1; } - if(is_route_type(REQUEST_ROUTE)) - return t_relay_to(p_msg, proxy, force_proto, 0 /* no replication */); + if(is_route_type(REQUEST_ROUTE)) { + res = t_relay_to(p_msg, proxy, force_proto, 0 /* no replication */); + if(res < 0) { + if(get_kr() == REQ_ERR_DELAYED) { + p_msg->msg_flags |= FL_DELAYED_REPLY; + } + } + return res; + } LM_CRIT("unsupported route type: %d\n", get_route_type()); return 0; } @@ -2534,7 +2587,7 @@ int t_check_trans(struct sip_msg *msg) if(msg->REQ_METHOD == METHOD_ACK) { /* ack to neg. reply or ack to local trans. * => process it and end the script */ - /* FIXME: there's no way to distinguish here + /* - there's no way to distinguish here * between acks to local trans. and neg. acks */ if(unlikely(has_tran_tmcbs(t, TMCB_ACK_NEG_IN))) run_trans_callbacks( @@ -2785,58 +2838,80 @@ static int ki_t_uac_send(sip_msg_t *msg, str *method, str *ruri, str *nexthop, } /* rpc docs */ +/* clang-format off */ +static const char *rpc_cancel_doc[2] = { + "Cancel a pending transaction", + 0 +}; -static const char *rpc_cancel_doc[2] = {"Cancel a pending transaction", 0}; - -static const char *rpc_reply_doc[2] = {"Reply transaction", 0}; +static const char *rpc_reply_doc[2] = { + "Reply transaction", + 0 +}; static const char *rpc_reply_callid_doc[2] = { - "Reply transaction by call-id", 0}; + "Reply transaction by call-id", + 0 +}; -static const char *tm_rpc_stats_doc[2] = {"Print transaction statistics.", 0}; +static const char *tm_rpc_stats_doc[2] = { + "Print transaction statistics.", + 0 +}; static const char *tm_rpc_hash_stats_doc[2] = { - "Prints hash table statistics (can be used only if tm is compiled" - " with -DTM_HASH_STATS).", - 0}; + "Prints hash table statistics (can be used only if tm is compiled" + " with -DTM_HASH_STATS).", + 0 +}; static const char *rpc_t_uac_start_doc[2] = { - "starts a tm uac using a list of string parameters: method, ruri, " - "dst_uri" - ", send_sock, headers (CRLF separated) and body (optional)", - 0}; + "starts a tm uac using a list of string parameters: method, ruri, " + "dst_uri" + ", send_sock, headers (CRLF separated) and body (optional)", + 0 +}; static const char *rpc_t_uac_wait_doc[2] = { - "starts a tm uac and waits for the final reply, using a list of string " - "parameters: method, ruri, dst_uri send_sock, headers (CRLF separated)" - " and body (optional)", - 0}; + "starts a tm uac and waits for the final reply, using a list of string " + "parameters: method, ruri, dst_uri send_sock, headers (CRLF separated)" + " and body (optional)", + 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}; + "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}; +static const char *tm_rpc_list_doc[2] = { + "List transactions.", + 0 +}; static const char *tm_rpc_clean_doc[2] = { - "Clean expired (lifetime exceeded) transactions.", 0}; + "Clean expired (lifetime exceeded) transactions.", + 0 +}; /* rpc exports */ -static rpc_export_t tm_rpc[] = {{"tm.cancel", rpc_cancel, rpc_cancel_doc, 0}, - {"tm.reply", rpc_reply, rpc_reply_doc, 0}, - {"tm.reply_callid", rpc_reply_callid, rpc_reply_callid_doc, 0}, - {"tm.stats", tm_rpc_stats, tm_rpc_stats_doc, 0}, - {"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}}; +static rpc_export_t tm_rpc[] = { + {"tm.cancel", rpc_cancel, rpc_cancel_doc, 0}, + {"tm.reply", rpc_reply, rpc_reply_doc, 0}, + {"tm.reply_callid", rpc_reply_callid, rpc_reply_callid_doc, 0}, + {"tm.stats", tm_rpc_stats, tm_rpc_stats_doc, 0}, + {"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} +}; +/* clang-format on */ /** * @@ -3131,7 +3206,7 @@ static int w_t_exists(struct sip_msg *msg, char *p1, char *p2) } #ifdef USE_DNS_FAILOVER -/* parse reply codes for failover given in module paraleter */ +/* parse reply codes for failover given in module parameter */ static int t_failover_parse_reply_codes() { param_t *params_list = NULL; @@ -3280,6 +3355,11 @@ static sr_kemi_t tm_kemi_exports[] = { { SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, + { str_init("tm"), str_init("t_reply_error"), + SR_KEMIP_INT, ki_t_reply_error, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, { str_init("tm"), str_init("t_send_reply"), SR_KEMIP_INT, ki_t_send_reply, { SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_NONE, diff --git a/src/modules/tm/tm_load.c b/src/modules/tm/tm_load.c index dced3edbe..714987351 100644 --- a/src/modules/tm/tm_load.c +++ b/src/modules/tm/tm_load.c @@ -143,6 +143,7 @@ int load_tm(struct tm_binds *tmb) tmb->set_fr = t_set_fr; tmb->t_release_transaction = t_release_transaction; tmb->t_uas_request_clean_parsed = t_uas_request_clean_parsed; + tmb->t_reply_error = ki_t_reply_error; return 1; } diff --git a/src/modules/tm/tm_load.h b/src/modules/tm/tm_load.h index f13c04cde..bf41eb789 100644 --- a/src/modules/tm/tm_load.h +++ b/src/modules/tm/tm_load.h @@ -43,6 +43,9 @@ /* export not usable from scripts */ #define NO_SCRIPT -1 +typedef void (*t_on_route_f)(unsigned int); +typedef int (*t_no_param_f)(struct sip_msg *); + struct tm_binds { register_tmcb_f register_tmcb; @@ -127,6 +130,7 @@ struct tm_binds tset_fr_f set_fr; trelease_t t_release_transaction; t_uas_request_clean_parsed_f t_uas_request_clean_parsed; + t_no_param_f t_reply_error; }; typedef struct tm_binds tm_api_t; @@ -165,9 +169,6 @@ static inline int tm_load_api(tm_api_t *tmb) * eXtra API - not common used in other modules */ -typedef void (*t_on_route_f)(unsigned int); -typedef int (*t_no_param_f)(struct sip_msg *); - int t_check_trans(struct sip_msg *msg); int t_is_canceled(struct sip_msg *msg); diff --git a/src/modules/tm/uac.c b/src/modules/tm/uac.c index e0b3bfff8..206f69ef5 100644 --- a/src/modules/tm/uac.c +++ b/src/modules/tm/uac.c @@ -326,7 +326,7 @@ static inline int t_run_local_req(char **buf, int *buf_len, uac_req_t *uac_r, & (FL_ADD_LOCAL_RPORT | FL_ADD_SRVID | FL_ADD_XAVP_VIA_PARAMS | FL_USE_XAVP_VIA_FIELDS))) { - LM_DBG("local Via update - new socket: [%.*s] - msg-flags: %u", + LM_DBG("local Via update - new socket: [%.*s] - msg-flags: %llu", (lreq.force_send_socket) ? lreq.force_send_socket->address_str.len : 4, @@ -829,8 +829,8 @@ struct retr_buf *local_ack_rb(sip_msg_t *rpl_2xx, struct cell *trans, } /* 'buffer' now points into a contiguous chunk of memory with enough * room to hold both the retr. buffer and the string raw buffer: it - * points to the begining of the string buffer; we iterate back to get - * the begining of the space for the retr. buffer. */ + * points to the beginning of the string buffer; we iterate back to get + * the beginning of the space for the retr. buffer. */ lack = &((struct retr_buf *)buffer)[-1]; lack->buffer = buffer; lack->buffer_len = buf_len; @@ -936,8 +936,7 @@ int ack_local_uac(struct cell *trans, str *hdrs, str *body) ret = 0; fin: - /* TODO: ugly! */ - /* FIXME: the T had been obtain by t_lookup_ident()'ing for it, so, it is + /* note: the T had been obtain by t_lookup_ident()'ing for it, so, it is * ref-counted. The t_unref() can not be used, as it requests a valid SIP * message (all available might be the reply, but if AS goes wrong and * tries to ACK before the final reply is received, we still have to diff --git a/src/modules/tmrec/README b/src/modules/tmrec/README index 1939721ac..5b24199b4 100644 --- a/src/modules/tmrec/README +++ b/src/modules/tmrec/README @@ -99,7 +99,7 @@ Chapter 1. Admin Guide 3.1. separator (str) - Separator character used to delimit attributes in time reccurrence + Separator character used to delimit attributes in time recurrence definitions. Default value is '|'. diff --git a/src/modules/tmrec/doc/tmrec_admin.xml b/src/modules/tmrec/doc/tmrec_admin.xml index 93ffce5ff..c4e4c6ba3 100644 --- a/src/modules/tmrec/doc/tmrec_admin.xml +++ b/src/modules/tmrec/doc/tmrec_admin.xml @@ -60,7 +60,7 @@ <varname>separator</varname> (str) Separator character used to delimit attributes in time - reccurrence definitions. + recurrence definitions. diff --git a/src/modules/tmrec/tmrec_mod.c b/src/modules/tmrec/tmrec_mod.c index 5cb57aa2c..78949a941 100644 --- a/src/modules/tmrec/tmrec_mod.c +++ b/src/modules/tmrec/tmrec_mod.c @@ -202,7 +202,7 @@ static int ki_tmrec_match_timestamp(sip_msg_t *msg, str *rv, int ti) if(ac_tm_set_time(&act, tv) < 0) goto error; - /* match the specified recurence */ + /* match the specified recurrence */ if(tr_check_recurrence(&tmr, &act, 0) != 0) goto error; diff --git a/src/modules/tmx/README b/src/modules/tmx/README index 5bf0e7989..c952b0c98 100644 --- a/src/modules/tmx/README +++ b/src/modules/tmx/README @@ -144,7 +144,7 @@ Chapter 1. Admin Guide This module collects extensions from Kamailio TM module. Kamailio TM (Transaction Management) module documentation is available - at: http://www.kamailio.org/docs/modules/stable/tm.html + at: https://www.kamailio.org/docs/modules/stable/modules/tm.html 2. Dependencies diff --git a/src/modules/tmx/doc/tmx_admin.xml b/src/modules/tmx/doc/tmx_admin.xml index 0f9ede1b5..c0a5e02ba 100644 --- a/src/modules/tmx/doc/tmx_admin.xml +++ b/src/modules/tmx/doc/tmx_admin.xml @@ -20,8 +20,8 @@ &kamailio; TM (Transaction Management) module documentation is available at: - - http://www.kamailio.org/docs/modules/stable/tm.html + + https://www.kamailio.org/docs/modules/stable/modules/tm.html
diff --git a/src/modules/tmx/tmx_pretran.c b/src/modules/tmx/tmx_pretran.c index 072df64e9..a7c7d52df 100644 --- a/src/modules/tmx/tmx_pretran.c +++ b/src/modules/tmx/tmx_pretran.c @@ -72,19 +72,20 @@ static int _tmx_ptran_size = 0; */ int tmx_init_pretran_table(void) { - int n; - int pn; + unsigned int n; + unsigned int pn; - pn = get_max_procs(); + pn = (unsigned int)get_max_procs(); - if(pn <= 0) + if(pn == 0) return -1; if(_tmx_ptran_table != NULL) return -1; + n = 1; /* get the highest power of two less than number of processes */ - n = -1; - while(pn >> ++n > 0) - ; + while((pn >> n) > 0) { + n++; + } n--; if(n <= 1) n = 2; @@ -336,7 +337,7 @@ int tmx_check_pretran(sip_msg_t *msg) if(_tmx_proc_ptran->vbranch.len != it->vbranch.len) continue; /* shortcut - check last char in Via branch - * - kamailio/ser adds there branch index => in case of paralel + * - kamailio/ser adds there branch index => in case of parallel * forking by previous hop, catch it here quickly */ if(_tmx_proc_ptran->vbranch.s[it->vbranch.len - 1] != it->vbranch.s[it->vbranch.len - 1]) diff --git a/src/modules/topoh/README b/src/modules/topoh/README index 2fa0f4fd3..0217b90d3 100644 --- a/src/modules/topoh/README +++ b/src/modules/topoh/README @@ -162,8 +162,10 @@ modparam("topoh", "mask_key", "some secret here") IP address to be used in masked headers to build valid SIP URIs. Can be any IP address, even a private-space or non-existing IP address (e.g., 192.168.1.1, 127.0.0.2), including the SIP server address, but must not - be an address potentially used by clients. It is not used at all for - SIP routing. + be an address potentially used by clients. If set to empty string, the + advertised IP of the incoming or outgoing socket is used when + specified, otherwise the IP of the socket is used. Note that the value + is actually not used at all for SIP routing. Default value is "127.0.0.8". diff --git a/src/modules/topoh/doc/topoh_admin.xml b/src/modules/topoh/doc/topoh_admin.xml index b6fc2ab02..1aaffcecb 100644 --- a/src/modules/topoh/doc/topoh_admin.xml +++ b/src/modules/topoh/doc/topoh_admin.xml @@ -92,7 +92,9 @@ modparam("topoh", "mask_key", "some secret here") SIP URIs. Can be any IP address, even a private-space or non-existing IP address (e.g., 192.168.1.1, 127.0.0.2), including the SIP server address, but must not be an address potentially used by clients. - It is not used at all for SIP routing. + If set to empty string, the advertised IP of the incoming or outgoing + socket is used when specified, otherwise the IP of the socket is used. + Note that the value is actually not used at all for SIP routing.
@@ -434,4 +436,3 @@ event_route[topoh:msg-sending] {
- diff --git a/src/modules/topoh/th_msg.c b/src/modules/topoh/th_msg.c index 47637d340..1984875e0 100644 --- a/src/modules/topoh/th_msg.c +++ b/src/modules/topoh/th_msg.c @@ -45,11 +45,8 @@ extern str th_cookie_name; extern str th_cookie_value; -extern str th_via_prefix; -extern str th_uri_prefix; extern str th_callid_prefix; -extern str th_ip; extern str th_uparam_name; extern str th_uparam_prefix; extern str th_vparam_name; @@ -121,7 +118,7 @@ int th_get_uri_param_value(str *uri, str *name, str *value) return th_get_param_value(&puri.params, name, value); } -int th_get_uri_type(str *uri, int *mode, str *value) +int th_get_uri_type(str *uri, int *mode, str *ip, str *value) { sip_uri_t puri; int ret; @@ -133,8 +130,8 @@ int th_get_uri_type(str *uri, int *mode, str *value) return -1; LM_DBG("PARAMS [%.*s]\n", puri.params.len, puri.params.s); - if(puri.host.len == th_ip.len - && strncasecmp(puri.host.s, th_ip.s, th_ip.len) == 0) { + if(puri.host.len == ip->len + && strncasecmp(puri.host.s, ip->s, ip->len) == 0) { /* host matches TH ip */ ret = th_get_param_value(&puri.params, &th_uparam_name, value); if(ret < 0) @@ -162,7 +159,7 @@ int th_get_uri_type(str *uri, int *mode, str *value) return 1; /* encode */ } -int th_mask_via(sip_msg_t *msg) +int th_mask_via(sip_msg_t *msg, str *via_prefix) { hdr_field_t *hdr; struct via_body *via; @@ -181,8 +178,9 @@ int th_mask_via(sip_msg_t *msg) LM_DBG("body: %d: [%.*s]\n", vlen, vlen, via->name.s); if(i != 1) { out.s = th_mask_encode( - via->name.s, vlen, &th_via_prefix, &out.len); - if(out.s == NULL) { + via->name.s, vlen, via_prefix, &out.len); + if(out.s == NULL) + { LM_ERR("cannot encode via %d\n", i); return -1; } @@ -240,7 +238,7 @@ int th_mask_callid(sip_msg_t *msg) return 0; } -int th_mask_contact(sip_msg_t *msg) +int th_mask_contact(sip_msg_t *msg, str *uri_prefix) { struct lump *l; str out; @@ -265,7 +263,7 @@ int th_mask_contact(sip_msg_t *msg) } in = c->uri; - out.s = th_mask_encode(in.s, in.len, &th_uri_prefix, &out.len); + out.s = th_mask_encode(in.s, in.len, uri_prefix, &out.len); if(out.s == NULL) { LM_ERR("cannot encode contact uri\n"); return -1; @@ -302,7 +300,7 @@ int th_mask_contact(sip_msg_t *msg) return 0; } -int th_mask_record_route(sip_msg_t *msg) +int th_mask_record_route(sip_msg_t *msg, str *uri_prefix) { hdr_field_t *hdr; struct lump *l; @@ -327,7 +325,7 @@ int th_mask_record_route(sip_msg_t *msg) i++; if(i != 1) { out.s = th_mask_encode(rr->nameaddr.uri.s, rr->nameaddr.uri.len, - &th_uri_prefix, &out.len); + uri_prefix, &out.len); if(out.s == NULL) { LM_ERR("cannot encode r-r %d\n", i); return -1; @@ -353,7 +351,7 @@ int th_mask_record_route(sip_msg_t *msg) return 0; } -int th_unmask_via(sip_msg_t *msg, str *cookie) +int th_unmask_via(sip_msg_t *msg, str *ip, str *cookie) { hdr_field_t *hdr; struct via_body *via; @@ -374,11 +372,11 @@ int th_unmask_via(sip_msg_t *msg, str *cookie) LM_DBG("body: %d: [%.*s]\n", vlen, vlen, via->name.s); if(i != 1) { /* Skip if via is not encoded */ - if(th_uri_prefix_checks - && (via->host.len != th_ip.len - || strncasecmp(via->host.s, th_ip.s, th_ip.len) - != 0)) { - LM_DBG("via %d is not encoded - skip\n", i); + if (th_uri_prefix_checks + && (via->host.len != ip->len + || strncasecmp(via->host.s, ip->s, ip->len) + != 0)) { + LM_DBG("via %d is not encoded - skip\n",i); continue; } @@ -554,7 +552,7 @@ int th_unmask_callid_str(str *icallid, str *ocallid) return 0; } -int th_flip_record_route(sip_msg_t *msg, int mode) +int th_flip_record_route(sip_msg_t *msg, str *uri_prefix, str *ip, int mode) { hdr_field_t *hdr; struct lump *l; @@ -585,7 +583,7 @@ int th_flip_record_route(sip_msg_t *msg, int mode) while(rr) { i++; r2 = 0; - utype = th_get_uri_type(&rr->nameaddr.uri, &r2, &pval); + utype = th_get_uri_type(&rr->nameaddr.uri, &r2, ip, &pval); if(utype == 0 && mode == 1) { if(r2 == 1) { act--; @@ -601,7 +599,7 @@ int th_flip_record_route(sip_msg_t *msg, int mode) case 1: /* encode */ if(act != 0 && mode == 1) { out.s = th_mask_encode(rr->nameaddr.uri.s, - rr->nameaddr.uri.len, &th_uri_prefix, &out.len); + rr->nameaddr.uri.len, uri_prefix, &out.len); if(out.s == NULL) { LM_ERR("cannot encode r-r %d\n", i); return -1; @@ -641,7 +639,7 @@ int th_flip_record_route(sip_msg_t *msg, int mode) return 0; } -int th_unmask_route(sip_msg_t *msg) +int th_unmask_route(sip_msg_t *msg, str *uri_prefix) { hdr_field_t *hdr; struct lump *l; @@ -667,10 +665,10 @@ int th_unmask_route(sip_msg_t *msg) i++; if(i != 1) { /* Skip if route is not encoded */ - if(th_uri_prefix_checks - && ((rr->nameaddr.uri.len < th_uri_prefix.len) - || (strncasecmp(rr->nameaddr.uri.s, - th_uri_prefix.s, th_uri_prefix.len) + if (th_uri_prefix_checks + && ((rr->nameaddr.uri.lenlen) + || (strncasecmp(rr->nameaddr.uri.s, + uri_prefix->s, uri_prefix->len) != 0))) { LM_DBG("rr %d is not encoded: [%.*s] - missing prefix\n", i, rr->nameaddr.uri.len, rr->nameaddr.uri.s); @@ -716,19 +714,19 @@ int th_unmask_route(sip_msg_t *msg) return 0; } -int th_unmask_ruri(sip_msg_t *msg) +int th_unmask_ruri(sip_msg_t *msg, str *uri_prefix) { str eval; struct lump *l; str out; /* Do nothing if ruri is not encoded */ - if(th_uri_prefix_checks - && ((REQ_LINE(msg).uri.len < th_uri_prefix.len) - || (strncasecmp(REQ_LINE(msg).uri.s, th_uri_prefix.s, - th_uri_prefix.len) + if (th_uri_prefix_checks + && ((REQ_LINE(msg).uri.lenlen) + || (strncasecmp(REQ_LINE(msg).uri.s, uri_prefix->s, + uri_prefix->len) != 0))) { - LM_DBG("ruri [%.*s] is not encoded", REQ_LINE(msg).uri.len, + LM_DBG("ruri [%.*s] is not encoded",REQ_LINE(msg).uri.len, REQ_LINE(msg).uri.s); return 0; } @@ -763,7 +761,7 @@ int th_unmask_ruri(sip_msg_t *msg) return 0; } -int th_unmask_refer_to(sip_msg_t *msg) +int th_unmask_refer_to(sip_msg_t *msg, str *uri_prefix) { str eval; str *uri; @@ -786,11 +784,11 @@ int th_unmask_refer_to(sip_msg_t *msg) uri = &(get_refer_to(msg)->uri); /* Do nothing if refer_to is not encoded */ - if(th_uri_prefix_checks - && ((uri->len < th_uri_prefix.len) - || (strncasecmp(uri->s, th_uri_prefix.s, th_uri_prefix.len) + if (th_uri_prefix_checks + && ((uri->lenlen) + || (strncasecmp(uri->s, uri_prefix->s, uri_prefix->len) != 0))) { - LM_DBG("refer-to [%.*s] is not encoded", uri->len, uri->s); + LM_DBG("refer-to [%.*s] is not encoded",uri->len,uri->s); return 0; } diff --git a/src/modules/topoh/th_msg.h b/src/modules/topoh/th_msg.h index c298e535c..6df98f34b 100644 --- a/src/modules/topoh/th_msg.h +++ b/src/modules/topoh/th_msg.h @@ -29,18 +29,18 @@ #include "../../core/parser/msg_parser.h" -int th_mask_via(sip_msg_t *msg); +int th_mask_via(sip_msg_t *msg, str *via_prefix); int th_mask_callid(sip_msg_t *msg); int th_mask_callid_str(str *icallid, str *ocallid); -int th_mask_contact(sip_msg_t *msg); -int th_mask_record_route(sip_msg_t *msg); -int th_unmask_via(sip_msg_t *msg, str *cookie); +int th_mask_contact(sip_msg_t *msg, str *uri_prefix); +int th_mask_record_route(sip_msg_t *msg, str *uri_prefix); +int th_unmask_via(sip_msg_t *msg, str *ip, str *cookie); int th_unmask_callid(sip_msg_t *msg); int th_unmask_callid_str(str *icallid, str *ocallid); -int th_flip_record_route(sip_msg_t *msg, int mode); -int th_unmask_ruri(sip_msg_t *msg); -int th_unmask_route(sip_msg_t *msg); -int th_unmask_refer_to(sip_msg_t *msg); +int th_flip_record_route(sip_msg_t *msg, str *uri_prefix, str *ip, int mode); +int th_unmask_ruri(sip_msg_t *msg, str *uri_prefix); +int th_unmask_route(sip_msg_t *msg, str *uri_prefix); +int th_unmask_refer_to(sip_msg_t *msg, str *uri_prefix); int th_update_hdr_replaces(sip_msg_t *msg); char *th_msg_update(sip_msg_t *msg, unsigned int *olen); int th_add_via_cookie(sip_msg_t *msg, struct via_body *via); diff --git a/src/modules/topoh/topoh_mod.c b/src/modules/topoh/topoh_mod.c index c819d8e9e..fe63bf88c 100644 --- a/src/modules/topoh/topoh_mod.c +++ b/src/modules/topoh/topoh_mod.c @@ -46,6 +46,7 @@ #include "../../core/fmsg.h" #include "../../core/onsend.h" #include "../../core/kemi.h" +#include "../../core/str_hash.h" #include "../../core/parser/msg_parser.h" #include "../../core/parser/parse_uri.h" #include "../../core/parser/parse_to.h" @@ -61,6 +62,14 @@ MODULE_VERSION #define TH_MASKMODE_SLIP3XXCONTACT 1 +#define TH_HT_SIZE 10 + +struct th_socket_strings +{ + str ip; + str via_prefix; + str uri_prefix; +}; /** module parameters */ str _th_key = str_init("aL9.n8~Hm]Z"); @@ -84,12 +93,17 @@ int th_uri_prefix_checks = 0; int th_mask_addr_myself = 0; int _th_use_mode = 0; -sanity_api_t scb; +struct str_hash_table *th_socket_hash_table; + +static sanity_api_t _tph_scb; int th_msg_received(sr_event_param_t *evp); int th_msg_sent(sr_event_param_t *evp); int th_execute_event_route(sip_msg_t *msg, sr_event_param_t *evp, int evtype, int evidx, str *evname); +int th_build_via_prefix(str *via_prefix, str *ip); +int th_build_uri_prefix(str *uri_prefix, str *ip); +int th_parse_socket_list(socket_info_t *socket); /** module functions */ static int mod_init(void); @@ -103,38 +117,44 @@ static str _th_eventrt_outgoing_name = str_init("topoh:msg-outgoing"); static int _th_eventrt_sending = -1; static str _th_eventrt_sending_name = str_init("topoh:msg-sending"); -static param_export_t params[] = {{"mask_key", PARAM_STR, &_th_key}, - {"mask_ip", PARAM_STR, &th_ip}, - {"mask_callid", PARAM_INT, &th_param_mask_callid}, - {"mask_mode", PARAM_INT, &th_param_mask_mode}, - {"uparam_name", PARAM_STR, &th_uparam_name}, - {"uparam_prefix", PARAM_STR, &th_uparam_prefix}, - {"vparam_name", PARAM_STR, &th_vparam_name}, - {"vparam_prefix", PARAM_STR, &th_vparam_prefix}, - {"callid_prefix", PARAM_STR, &th_callid_prefix}, - {"sanity_checks", PARAM_INT, &th_sanity_checks}, - {"uri_prefix_checks", PARAM_INT, &th_uri_prefix_checks}, - {"event_callback", PARAM_STR, &_th_eventrt_callback}, - {"event_mode", PARAM_INT, &_th_eventrt_mode}, - {"use_mode", PARAM_INT, &_th_use_mode}, {0, 0, 0}}; +/* clang-format off */ +static param_export_t params[] = { + {"mask_key", PARAM_STR, &_th_key}, + {"mask_ip", PARAM_STR, &th_ip}, + {"mask_callid", PARAM_INT, &th_param_mask_callid}, + {"mask_mode", PARAM_INT, &th_param_mask_mode}, + {"uparam_name", PARAM_STR, &th_uparam_name}, + {"uparam_prefix", PARAM_STR, &th_uparam_prefix}, + {"vparam_name", PARAM_STR, &th_vparam_name}, + {"vparam_prefix", PARAM_STR, &th_vparam_prefix}, + {"callid_prefix", PARAM_STR, &th_callid_prefix}, + {"sanity_checks", PARAM_INT, &th_sanity_checks}, + {"uri_prefix_checks", PARAM_INT, &th_uri_prefix_checks}, + {"event_callback", PARAM_STR, &_th_eventrt_callback}, + {"event_mode", PARAM_INT, &_th_eventrt_mode}, + {"use_mode", PARAM_INT, &_th_use_mode}, + {0, 0, 0} +}; static cmd_export_t cmds[] = { - {"bind_topoh", (cmd_function)bind_topoh, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0}}; + {"bind_topoh", (cmd_function)bind_topoh, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0} +}; /** module exports */ struct module_exports exports = { - "topoh", /* module name */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* exported functions */ - params, /* exported parameters */ - 0, /* exported rpc functions */ - 0, /* exported pseudo-variables */ - 0, /* response handling function */ - mod_init, /* module init function */ - 0, /* per-child init function */ - 0 /* module destroy function */ + "topoh", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* exported functions */ + params, /* exported parameters */ + 0, /* exported rpc functions */ + 0, /* exported pseudo-variables */ + 0, /* response handling function */ + mod_init, /* module init function */ + 0, /* per-child init function */ + 0 /* module destroy function */ }; +/* clang-format on */ /** * init module function @@ -166,84 +186,237 @@ static int mod_init(void) } if(th_sanity_checks != 0) { - if(sanity_load_api(&scb) < 0) { + if(sanity_load_api(&_tph_scb) < 0) { LM_ERR("cannot bind to sanity module\n"); goto error; } } - if(th_ip.len <= 0) { - LM_ERR("mask IP parameter is invalid\n"); - goto error; - } - if(th_ip.len + 32 >= MAX_URI_SIZE) { - LM_ERR("mask address is too long\n"); - goto error; - } - memcpy(buri, "sip:", 4); - memcpy(buri + 4, th_ip.s, th_ip.len); - buri[th_ip.len + 8] = '\0'; + if(th_ip.len != 0) { + if(th_ip.len + 32 >= MAX_URI_SIZE) { + LM_ERR("mask address is too long\n"); + goto error; + } + memcpy(buri, "sip:", 4); + memcpy(buri + 4, th_ip.s, th_ip.len); + buri[th_ip.len + 8] = '\0'; - if(parse_uri(buri, th_ip.len + 4, &puri) < 0) { - LM_ERR("mask uri is invalid\n"); - goto error; - } - if(check_self(&puri.host, puri.port_no, 0) == 1) { - th_mask_addr_myself = 1; - LM_INFO("mask address matches myself [%.*s]\n", th_ip.len, th_ip.s); + if(parse_uri(buri, th_ip.len + 4, &puri) < 0) { + LM_ERR("mask uri is invalid\n"); + goto error; + } + if(check_self(&puri.host, puri.port_no, 0) == 1) { + th_mask_addr_myself = 1; + LM_INFO("mask address matches myself [%.*s]\n", th_ip.len, th_ip.s); + } + + if(th_build_via_prefix(&th_via_prefix, &th_ip)) { + goto error; + } + if(th_build_uri_prefix(&th_uri_prefix, &th_ip)) { + goto error; + } + } else { + th_socket_hash_table = pkg_malloc(sizeof(struct str_hash_table)); + if(th_socket_hash_table == NULL) { + PKG_MEM_ERROR_FMT("th_socket_hash_table\n"); + goto error; + } + if(str_hash_alloc(th_socket_hash_table, TH_HT_SIZE)) + goto error; + + str_hash_init(th_socket_hash_table); + if(th_parse_socket_list(*get_sock_info_list(PROTO_UDP)) != 0 + || th_parse_socket_list(*get_sock_info_list(PROTO_TCP)) != 0 + || th_parse_socket_list(*get_sock_info_list(PROTO_TLS)) != 0 + || th_parse_socket_list(*get_sock_info_list(PROTO_SCTP)) != 0) + goto error; } + th_mask_init(); + sr_event_register_cb(SREV_NET_DATA_IN, th_msg_received); + sr_event_register_cb(SREV_NET_DATA_OUT, th_msg_sent); +#ifdef USE_TCP + tcp_set_clone_rcvbuf(1); +#endif + return 0; +error: + if(th_socket_hash_table != NULL && th_socket_hash_table->table) + pkg_free(th_socket_hash_table->table); + + if(th_socket_hash_table != NULL) + pkg_free(th_socket_hash_table); + return -1; +} + +/** + * + */ +int th_build_via_prefix(str *via_prefix, str *ip) +{ /* 'SIP/2.0/UDP ' + ip + ';' + param + '=' + prefix (+ '\0') */ - th_via_prefix.len = - 12 + th_ip.len + 1 + th_vparam_name.len + 1 + th_vparam_prefix.len; - th_via_prefix.s = (char *)pkg_malloc(th_via_prefix.len + 1); - if(th_via_prefix.s == NULL) { - PKG_MEM_ERROR_FMT("via prefix parameter\n"); - goto error; - } - /* 'sip:' + ip + ';' + param + '=' + prefix (+ '\0') */ - th_uri_prefix.len = - 4 + th_ip.len + 1 + th_uparam_name.len + 1 + th_uparam_prefix.len; - th_uri_prefix.s = (char *)pkg_malloc(th_uri_prefix.len + 1); - if(th_uri_prefix.s == NULL) { - pkg_free(th_via_prefix.s); - PKG_MEM_ERROR_FMT("uri prefix parameter\n"); - goto error; + via_prefix->len = + 12 + ip->len + 1 + th_vparam_name.len + 1 + th_vparam_prefix.len; + via_prefix->s = (char *)pkg_malloc(via_prefix->len + 1); + if(via_prefix->s == NULL) { + PKG_MEM_ERROR_FMT("via prefix\n"); + return 1; } + /* build via prefix */ - memcpy(th_via_prefix.s, "SIP/2.0/UDP ", 12); - memcpy(th_via_prefix.s + 12, th_ip.s, th_ip.len); - th_via_prefix.s[12 + th_ip.len] = ';'; - memcpy(th_via_prefix.s + 12 + th_ip.len + 1, th_vparam_name.s, + memcpy(via_prefix->s, "SIP/2.0/UDP ", 12); + memcpy(via_prefix->s + 12, ip->s, ip->len); + via_prefix->s[12 + ip->len] = ';'; + memcpy(via_prefix->s + 12 + ip->len + 1, th_vparam_name.s, th_vparam_name.len); - th_via_prefix.s[12 + th_ip.len + 1 + th_vparam_name.len] = '='; - memcpy(th_via_prefix.s + 12 + th_ip.len + 1 + th_vparam_name.len + 1, + via_prefix->s[12 + ip->len + 1 + th_vparam_name.len] = '='; + memcpy(via_prefix->s + 12 + ip->len + 1 + th_vparam_name.len + 1, th_vparam_prefix.s, th_vparam_prefix.len); - th_via_prefix.s[th_via_prefix.len] = '\0'; - LM_DBG("VIA prefix: [%s]\n", th_via_prefix.s); + via_prefix->s[via_prefix->len] = '\0'; + LM_DBG("VIA prefix: [%s]\n", via_prefix->s); + + return 0; +} + +/** + * + */ +int th_build_uri_prefix(str *uri_prefix, str *ip) +{ + /* 'sip:' + ip + ';' + param + '=' + prefix (+ '\0') */ + uri_prefix->len = + 4 + ip->len + 1 + th_uparam_name.len + 1 + th_uparam_prefix.len; + uri_prefix->s = (char *)pkg_malloc(uri_prefix->len + 1); + if(uri_prefix->s == NULL) { + PKG_MEM_ERROR_FMT("uri prefix\n"); + return 1; + } + /* build uri prefix */ - memcpy(th_uri_prefix.s, "sip:", 4); - memcpy(th_uri_prefix.s + 4, th_ip.s, th_ip.len); - th_uri_prefix.s[4 + th_ip.len] = ';'; - memcpy(th_uri_prefix.s + 4 + th_ip.len + 1, th_uparam_name.s, + memcpy(uri_prefix->s, "sip:", 4); + memcpy(uri_prefix->s + 4, ip->s, ip->len); + uri_prefix->s[4 + ip->len] = ';'; + memcpy(uri_prefix->s + 4 + ip->len + 1, th_uparam_name.s, th_uparam_name.len); - th_uri_prefix.s[4 + th_ip.len + 1 + th_uparam_name.len] = '='; - memcpy(th_uri_prefix.s + 4 + th_ip.len + 1 + th_uparam_name.len + 1, + uri_prefix->s[4 + ip->len + 1 + th_uparam_name.len] = '='; + memcpy(uri_prefix->s + 4 + ip->len + 1 + th_uparam_name.len + 1, th_uparam_prefix.s, th_uparam_prefix.len); - th_uri_prefix.s[th_uri_prefix.len] = '\0'; - LM_DBG("URI prefix: [%s]\n", th_uri_prefix.s); + uri_prefix->s[uri_prefix->len] = '\0'; + LM_DBG("URI prefix: [%s]\n", uri_prefix->s); - th_mask_init(); - sr_event_register_cb(SREV_NET_DATA_IN, th_msg_received); - sr_event_register_cb(SREV_NET_DATA_OUT, th_msg_sent); -#ifdef USE_TCP - tcp_set_clone_rcvbuf(1); -#endif return 0; +} + +/** + * + */ +int th_build_socket_strings(socket_info_t *socket) +{ + struct th_socket_strings *socket_strings = NULL; + struct str_hash_entry *table_entry = NULL; + str *socket_ip = NULL; + + if(str_hash_get( + th_socket_hash_table, socket->sockname.s, socket->sockname.len) + != 0) + return 0; + + socket_strings = pkg_malloc(sizeof(struct th_socket_strings)); + if(socket_strings == NULL) { + PKG_MEM_ERROR_FMT("socket_strings\n"); + goto error; + } + table_entry = pkg_malloc(sizeof(struct str_hash_entry)); + if(table_entry == NULL) { + PKG_MEM_ERROR_FMT("table_entry\n"); + goto error; + } + if(pkg_str_dup(&table_entry->key, &socket->sockname)) { + PKG_MEM_ERROR_FMT("table_entry.key.s\n"); + goto error; + } + table_entry->u.p = socket_strings; + + if(socket->useinfo.address_str.len > 0) { + LM_DBG("Using socket %s advertised ip %s\n", socket->sockname.s, + socket->useinfo.address_str.s); + socket_ip = &socket->useinfo.address_str; + } else { + LM_DBG("using socket %s ip %s\n", socket->sockname.s, + socket->address_str.s); + socket_ip = &socket->address_str; + } + if(pkg_str_dup(&socket_strings->ip, socket_ip)) { + PKG_MEM_ERROR_FMT("socket_strings.ip\n"); + goto error; + } + th_build_via_prefix(&socket_strings->via_prefix, socket_ip); + th_build_uri_prefix(&socket_strings->uri_prefix, socket_ip); + str_hash_add(th_socket_hash_table, table_entry); + + return 0; + error: + if(socket_strings != NULL) { + if(socket_strings->ip.s != NULL) { + pkg_free(socket_strings->ip.s); + } + pkg_free(socket_strings); + } + if(table_entry != NULL) { + if(table_entry->key.s != NULL) { + pkg_free(table_entry->key.s); + } + pkg_free(table_entry); + } return -1; } +/** + * + */ +int th_parse_socket_list(socket_info_t *socket) +{ + while(socket != NULL) { + if(th_build_socket_strings(socket) != 0) + return -1; + socket = socket->next; + } + + return 0; +} + +/** + * + */ +int th_get_socket_strings( + socket_info_t *socket, str **ip, str **via_prefix, str **uri_prefix) +{ + struct th_socket_strings *socket_strings; + struct str_hash_entry *table_entry; + + if(th_ip.len > 0) { + *ip = &th_ip; + *via_prefix = &th_via_prefix; + *uri_prefix = &th_uri_prefix; + } else { + table_entry = str_hash_get( + th_socket_hash_table, socket->sockname.s, socket->sockname.len); + if(table_entry == 0) { + LM_DBG("No entry for socket %s", socket->sockname.s); + return -1; + } else { + socket_strings = table_entry->u.p; + } + + *ip = &socket_strings->ip; + *via_prefix = &socket_strings->via_prefix; + *uri_prefix = &socket_strings->uri_prefix; + } + + return 0; +} + /** * */ @@ -314,6 +487,15 @@ int th_msg_received(sr_event_param_t *evp) char *nbuf = NULL; int direction; int dialog; + str *ip; + str *via_prefix; + str *uri_prefix; + + if(th_get_socket_strings( + evp->rcv->bind_address, &ip, &via_prefix, &uri_prefix)) { + LM_ERR("Socket address handling failed\n"); + return -1; + } obuf = (str *)evp->data; memset(&msg, 0, sizeof(sip_msg_t)); @@ -333,7 +515,7 @@ int th_msg_received(sr_event_param_t *evp) th_cookie_value.len = 2; if(msg.first_line.type == SIP_REQUEST) { if(th_sanity_checks != 0) { - if(scb.check_defaults(&msg) < 1) { + if(_tph_scb.check_defaults(&msg) < 1) { LM_ERR("sanity checks failed\n"); goto done; } @@ -351,9 +533,9 @@ int th_msg_received(sr_event_param_t *evp) } if(dialog) { /* dialog request */ - th_unmask_ruri(&msg); - th_unmask_route(&msg); - th_unmask_refer_to(&msg); + th_unmask_ruri(&msg, uri_prefix); + th_unmask_route(&msg, uri_prefix); + th_unmask_refer_to(&msg, uri_prefix); if(direction == 1) { th_unmask_callid(&msg); } @@ -367,8 +549,8 @@ int th_msg_received(sr_event_param_t *evp) goto done; } - th_unmask_via(&msg, &th_cookie_value); - th_flip_record_route(&msg, 0); + th_unmask_via(&msg, ip, &th_cookie_value); + th_flip_record_route(&msg, uri_prefix, ip, 0); if(th_cookie_value.s[0] == 'u') { th_cookie_value.s = "dc"; } else { @@ -409,6 +591,15 @@ int th_msg_sent(sr_event_param_t *evp) int dialog; int local; str nbuf = STR_NULL; + str *ip; + str *via_prefix; + str *uri_prefix; + + if(th_get_socket_strings( + evp->dst->send_sock, &ip, &via_prefix, &uri_prefix)) { + LM_ERR("Socket address handling failed\n"); + return -1; + } obuf = (str *)evp->data; @@ -472,9 +663,9 @@ int th_msg_sent(sr_event_param_t *evp) goto done; } } - th_mask_via(&msg); - th_mask_contact(&msg); - th_mask_record_route(&msg); + th_mask_via(&msg, via_prefix); + th_mask_contact(&msg, uri_prefix); + th_mask_record_route(&msg, uri_prefix); if(dialog) { /* dialog request */ if(direction == 0) { @@ -498,11 +689,11 @@ int th_msg_sent(sr_event_param_t *evp) th_mask_callid(&msg); } } else { - th_flip_record_route(&msg, 1); + th_flip_record_route(&msg, uri_prefix, ip, 1); if(!(th_param_mask_mode & TH_MASKMODE_SLIP3XXCONTACT) || msg.first_line.u.reply.statuscode < 300 || msg.first_line.u.reply.statuscode > 399) { - th_mask_contact(&msg); + th_mask_contact(&msg, uri_prefix); } if(th_cookie_value.s[0] == 'd') { th_mask_callid(&msg); diff --git a/src/modules/topos/README b/src/modules/topos/README index be21cb2ef..70af19ae4 100644 --- a/src/modules/topos/README +++ b/src/modules/topos/README @@ -52,6 +52,7 @@ Frederic Gaisnon 3.19. methods_nocontact (str) 3.20. header_mode (int) 3.21. methods_noinitial (str) + 3.22. version_table (integer) 4. Functions @@ -87,11 +88,12 @@ Frederic Gaisnon 1.19. Set methods_nocontact parameter 1.20. Set header_mode parameter 1.21. Set methods_noinitial parameter - 1.22. tps_set_context usage - 1.23. Usage of event_route[topos:msg-outgoing] - 1.24. Usage of event_route[topos:msg-sending] - 1.25. Usage of event_route[topos:msg-incoming] - 1.26. Usage of event_route[topos:msg-receoving] + 1.22. version_table parameter usage + 1.23. tps_set_context usage + 1.24. Usage of event_route[topos:msg-outgoing] + 1.25. Usage of event_route[topos:msg-sending] + 1.26. Usage of event_route[topos:msg-incoming] + 1.27. Usage of event_route[topos:msg-receiving] Chapter 1. Admin Guide @@ -126,6 +128,7 @@ Chapter 1. Admin Guide 3.19. methods_nocontact (str) 3.20. header_mode (int) 3.21. methods_noinitial (str) + 3.22. version_table (integer) 4. Functions @@ -202,6 +205,7 @@ Chapter 1. Admin Guide 3.19. methods_nocontact (str) 3.20. header_mode (int) 3.21. methods_noinitial (str) + 3.22. version_table (integer) 3.1. storage (str) @@ -233,7 +237,7 @@ modparam("topos", "db_url", "dbdriver://username:password@dbhost/dbname") Call-id in the SIP message payload or header, so it is safe to not encode Call-id in such cases. Well-known extensions such as call transfer or conference join will be added to work with encoded Call-id. - Topoh module should be loaded with use_mode paramerter set to 1 + Topoh module should be loaded with use_mode parameter set to 1 Default value is 0 (do not mask). @@ -410,7 +414,7 @@ modparam("topos", "xavu_field_a_contact", "a_contact") 3.14. xavu_field_a_contact (str) - Name of the field inside root XAVU specifed by `xavu_cfg` to evaluate + Name of the field inside root XAVU specified by `xavu_cfg` to evaluate for the A-side Contact Header user part. This parameter is only necessary in contact_mode (2). @@ -426,7 +430,7 @@ modparam("topos", "xavu_field_a_contact", "a_contact") 3.15. xavu_field_b_contact (str) - Name of the field inside root XAVU specifed by `xavu_cfg` to evaluate + Name of the field inside root XAVU specified by `xavu_cfg` to evaluate for the B-side Contact Header user part. This parameter is only necessary in contact_mode (2). @@ -516,7 +520,7 @@ modparam("topos", "header_mode", 1) 3.21. methods_noinitial (str) - List of SIP methods to skip doing topos if it is an intial request (no + List of SIP methods to skip doing topos if it is an initial request (no To-tag). Default value is “” (no method). @@ -526,6 +530,17 @@ modparam("topos", "header_mode", 1) modparam("topos", "methods_noinitial", "OPTIONS,NOTIFY") ... +3.22. version_table (integer) + + If set to 0, the module will skip checking the version of the tables. + + Default value is “1 (check for table version)”. + + Example 1.22. version_table parameter usage +... +modparam("topos", "version_table", 0) +... + 4. Functions 4.1. tps_set_context(ctx) @@ -537,7 +552,7 @@ modparam("topos", "methods_noinitial", "OPTIONS,NOTIFY") This function can be used from ANY_ROUTE. - Example 1.22. tps_set_context usage + Example 1.23. tps_set_context usage ... request_route { ... @@ -565,7 +580,7 @@ request_route { reparsing the outgoing SIP message for the cases when topology hiding is not wanted. - Example 1.23. Usage of event_route[topos:msg-outgoing] + Example 1.24. Usage of event_route[topos:msg-outgoing] ... event_route[topos:msg-outgoing] { if($sndto(ip)=="10.1.1.10") { @@ -584,7 +599,7 @@ event_route[topos:msg-outgoing] { $sndto(proto) point to the destination. The SIP message is the one to be sent out. - Example 1.24. Usage of event_route[topos:msg-sending] + Example 1.25. Usage of event_route[topos:msg-sending] ... event_route[topos:msg-sending] { if(is_request() and $fU=="alice") { @@ -604,7 +619,7 @@ event_route[topos:msg-sending] { internally generated one at startup, to avoid reparsing the outgoing SIP message for the cases when topology hiding is not wanted. - Example 1.25. Usage of event_route[topos:msg-incoming] + Example 1.26. Usage of event_route[topos:msg-incoming] ... event_route[topos:msg-incoming] { if($si=="10.1.1.10") { @@ -622,7 +637,7 @@ event_route[topos:msg-incoming] { Inside the event route the variables $si, $sp and $proto point to the source address. The SIP message is the one to be sent out. - Example 1.26. Usage of event_route[topos:msg-receoving] + Example 1.27. Usage of event_route[topos:msg-receiving] ... event_route[topos:msg-receiving] { if(is_request() and $fU=="alice") { diff --git a/src/modules/topos/doc/topos_admin.xml b/src/modules/topos/doc/topos_admin.xml index 69cd53818..4ccc4b779 100644 --- a/src/modules/topos/doc/topos_admin.xml +++ b/src/modules/topos/doc/topos_admin.xml @@ -141,7 +141,7 @@ modparam("topos", "db_url", "&exampledb;") not encode Call-id in such cases. Well-known extensions such as call transfer or conference join will be added to work with encoded Call-id. - Topoh module should be loaded with use_mode paramerter set to 1 + Topoh module should be loaded with use_mode parameter set to 1
@@ -415,7 +415,7 @@ modparam("topos", "xavu_field_a_contact", "a_contact")
<varname>xavu_field_a_contact</varname> (str) - Name of the field inside root XAVU specifed by `xavu_cfg` + Name of the field inside root XAVU specified by `xavu_cfg` to evaluate for the A-side Contact Header user part. This parameter is only necessary in contact_mode (2). @@ -439,7 +439,7 @@ modparam("topos", "xavu_field_a_contact", "a_contact")
<varname>xavu_field_b_contact</varname> (str) - Name of the field inside root XAVU specifed by `xavu_cfg` + Name of the field inside root XAVU specified by `xavu_cfg` to evaluate for the B-side Contact Header user part. This parameter is only necessary in contact_mode (2). @@ -583,7 +583,7 @@ modparam("topos", "header_mode", 1)
<varname>methods_noinitial</varname> (str) - List of SIP methods to skip doing topos if it is an intial request + List of SIP methods to skip doing topos if it is an initial request (no To-tag). @@ -600,6 +600,23 @@ modparam("topos", "methods_noinitial", "OPTIONS,NOTIFY")
+
+ <varname>version_table</varname> (integer) + + If set to 0, the module will skip checking the version of the tables. + + + Default value is 1 (check for table version). + + + <varname>version_table</varname> parameter usage + +... +modparam("topos", "version_table", 0) +... + + +
@@ -722,7 +739,7 @@ event_route[topos:msg-incoming] { to be sent out. - Usage of event_route[topos:msg-receoving] + Usage of event_route[topos:msg-receiving] ... event_route[topos:msg-receiving] { diff --git a/src/modules/topos/topos_mod.c b/src/modules/topos/topos_mod.c index 4540382b7..e37ca847b 100644 --- a/src/modules/topos/topos_mod.c +++ b/src/modules/topos/topos_mod.c @@ -79,6 +79,9 @@ db_func_t _tpsdbf; /* sruid to get internal uid */ sruid_t _tps_sruid; +extern str tt_table_name; +extern str td_table_name; + /** module parameters */ static str _tps_db_url = str_init(DEFAULT_DB_URL); int _tps_param_mask_callid = 0; @@ -102,6 +105,11 @@ int _tps_clean_interval = 60; #define TPS_EVENTRT_SENDING 2 #define TPS_EVENTRT_INCOMING 4 #define TPS_EVENTRT_RECEIVING 8 +#define TT_TABLE_VERSION 2 +#define TD_TABLE_VERSION 2 + +static int _tps_version_table_check = 1; + static int _tps_eventrt_mode = TPS_EVENTRT_OUTGOING | TPS_EVENTRT_SENDING | TPS_EVENTRT_INCOMING | TPS_EVENTRT_RECEIVING; static int _tps_eventrt_outgoing = -1; @@ -115,7 +123,7 @@ static int _tps_eventrt_receiving = -1; static str _tps_eventrt_receiving_name = str_init("topos:msg-receiving"); str _tps_contact_host = str_init(""); -int _tps_contact_mode = 0; +int _tps_contact_mode = TPS_CONTACT_MODE_SKEYUSER; str _tps_cparam_name = str_init("tps"); str _tps_xavu_cfg = STR_NULL; @@ -126,7 +134,7 @@ str _tps_xavu_field_contact_host = STR_NULL; str _tps_context_param = STR_NULL; str _tps_context_value = STR_NULL; -sanity_api_t scb; +static sanity_api_t _tps_scb; int tps_msg_received(sr_event_param_t *evp); int tps_msg_sent(sr_event_param_t *evp); @@ -146,58 +154,65 @@ static int w_tps_set_context(sip_msg_t *msg, char *pctx, char *p2); int bind_topos(topos_api_t *api); +/* clang-format off */ static cmd_export_t cmds[] = { - {"tps_set_context", (cmd_function)w_tps_set_context, 1, fixup_spve_null, - fixup_free_spve_null, ANY_ROUTE}, - - {"bind_topos", (cmd_function)bind_topos, 0, 0, 0, 0}, - - {0, 0, 0, 0, 0, 0}}; - -static param_export_t params[] = {{"storage", PARAM_STR, &_tps_storage}, - {"db_url", PARAM_STR, &_tps_db_url}, - {"mask_callid", PARAM_INT, &_tps_param_mask_callid}, - {"sanity_checks", PARAM_INT, &_tps_sanity_checks}, - {"header_mode", PARAM_INT, &_tps_header_mode}, - {"branch_expire", PARAM_INT, &_tps_branch_expire}, - {"dialog_expire", PARAM_INT, &_tps_dialog_expire}, - {"clean_interval", PARAM_INT, &_tps_clean_interval}, - {"event_callback", PARAM_STR, &_tps_eventrt_callback}, - {"event_mode", PARAM_INT, &_tps_eventrt_mode}, - {"contact_host", PARAM_STR, &_tps_contact_host}, - {"contact_mode", PARAM_INT, &_tps_contact_mode}, - {"cparam_name", PARAM_STR, &_tps_cparam_name}, - {"xavu_cfg", PARAM_STR, &_tps_xavu_cfg}, - {"xavu_field_a_contact", PARAM_STR, &_tps_xavu_field_acontact}, - {"xavu_field_b_contact", PARAM_STR, &_tps_xavu_field_bcontact}, - {"xavu_field_contact_host", PARAM_STR, &_tps_xavu_field_contact_host}, - {"rr_update", PARAM_INT, &_tps_rr_update}, - {"context", PARAM_STR, &_tps_context_param}, - {"methods_nocontact", PARAM_STR, &_tps_methods_nocontact_list}, - {"methods_noinitial", PARAM_STR, &_tps_methods_noinitial_list}, - - {0, 0, 0}}; + {"tps_set_context", (cmd_function)w_tps_set_context, 1, fixup_spve_null, + fixup_free_spve_null, ANY_ROUTE}, + + {"bind_topos", (cmd_function)bind_topos, 0, 0, 0, 0}, + + {0, 0, 0, 0, 0, 0} +}; + +static param_export_t params[] = { + {"storage", PARAM_STR, &_tps_storage}, + {"db_url", PARAM_STR, &_tps_db_url}, + {"mask_callid", PARAM_INT, &_tps_param_mask_callid}, + {"sanity_checks", PARAM_INT, &_tps_sanity_checks}, + {"header_mode", PARAM_INT, &_tps_header_mode}, + {"branch_expire", PARAM_INT, &_tps_branch_expire}, + {"dialog_expire", PARAM_INT, &_tps_dialog_expire}, + {"clean_interval", PARAM_INT, &_tps_clean_interval}, + {"event_callback", PARAM_STR, &_tps_eventrt_callback}, + {"event_mode", PARAM_INT, &_tps_eventrt_mode}, + {"contact_host", PARAM_STR, &_tps_contact_host}, + {"contact_mode", PARAM_INT, &_tps_contact_mode}, + {"cparam_name", PARAM_STR, &_tps_cparam_name}, + {"xavu_cfg", PARAM_STR, &_tps_xavu_cfg}, + {"xavu_field_a_contact", PARAM_STR, &_tps_xavu_field_acontact}, + {"xavu_field_b_contact", PARAM_STR, &_tps_xavu_field_bcontact}, + {"xavu_field_contact_host", PARAM_STR, &_tps_xavu_field_contact_host}, + {"rr_update", PARAM_INT, &_tps_rr_update}, + {"context", PARAM_STR, &_tps_context_param}, + {"methods_nocontact", PARAM_STR, &_tps_methods_nocontact_list}, + {"methods_noinitial", PARAM_STR, &_tps_methods_noinitial_list}, + {"version_table", INT_PARAM, &_tps_version_table_check}, + + {0, 0, 0} +}; /** module exports */ struct module_exports exports = { - "topos", /* module name */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* exported functions */ - params, /* exported parameters */ - 0, /* exported rpc functions */ - 0, /* exported pseudo-variables */ - 0, /* response handling function */ - mod_init, /* module initialization function */ - child_init, /* child initialization function */ - destroy /* destroy function */ + "topos", /* module name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* exported functions */ + params, /* exported parameters */ + 0, /* exported rpc functions */ + 0, /* exported pseudo-variables */ + 0, /* response handling function */ + mod_init, /* module initialization function */ + child_init, /* child initialization function */ + destroy /* destroy function */ }; +/* clang-format on */ /** * init module function */ static int mod_init(void) { + db1_con_t *topos_db_con = NULL; _tps_eventrt_outgoing = route_lookup(&event_rt, _tps_eventrt_outgoing_name.s); if(_tps_eventrt_outgoing < 0 @@ -252,6 +267,27 @@ static int mod_init(void) "provide all functions needed\n"); return -1; } + if(_tps_version_table_check != 0) { + topos_db_con = _tpsdbf.init(&_tps_db_url); + if(topos_db_con == NULL) { + LM_ERR("failed to open database connection\n"); + goto dberror; + } + if(db_check_table_version( + &_tpsdbf, topos_db_con, &td_table_name, TD_TABLE_VERSION) + < 0) { + DB_TABLE_VERSION_ERROR(td_table_name); + goto dberror; + } + if(db_check_table_version( + &_tpsdbf, topos_db_con, &tt_table_name, TT_TABLE_VERSION) + < 0) { + DB_TABLE_VERSION_ERROR(tt_table_name); + goto dberror; + } + _tpsdbf.close(topos_db_con); + topos_db_con = NULL; + } } else { if(_tps_storage.len != 7 && strncmp(_tps_storage.s, "redis", 5) != 0) { LM_ERR("unknown storage type: %.*s\n", _tps_storage.len, @@ -261,7 +297,7 @@ static int mod_init(void) } if(_tps_sanity_checks != 0) { - if(sanity_load_api(&scb) < 0) { + if(sanity_load_api(&_tps_scb) < 0) { LM_ERR("cannot bind to sanity module\n"); goto error; } @@ -274,7 +310,7 @@ static int mod_init(void) if(sruid_init(&_tps_sruid, '-', "tpsh", SRUID_INC) < 0) return -1; - if(_tps_contact_mode == 2 + if(_tps_contact_mode == TPS_CONTACT_MODE_XAVPUSER && (_tps_xavu_cfg.len <= 0 || _tps_xavu_field_acontact.len <= 0 || _tps_xavu_field_bcontact.len <= 0)) { LM_ERR("contact_mode parameter is 2," @@ -303,6 +339,12 @@ static int mod_init(void) return 0; error: return -1; +dberror: + if(topos_db_con) { + _tpsdbf.close(topos_db_con); + topos_db_con = NULL; + } + return -1; } /** @@ -497,7 +539,7 @@ int tps_msg_received(sr_event_param_t *evp) if(msg.first_line.type == SIP_REQUEST) { if(_tps_sanity_checks != 0) { - if(scb.check_defaults(&msg) < 1) { + if(_tps_scb.check_defaults(&msg) < 1) { LM_ERR("sanity checks failed\n"); goto done; } diff --git a/src/modules/topos/tps_msg.c b/src/modules/topos/tps_msg.c index 32818c45f..e0e1c2119 100644 --- a/src/modules/topos/tps_msg.c +++ b/src/modules/topos/tps_msg.c @@ -324,7 +324,8 @@ int tps_dlg_message_update(sip_msg_t *msg, tps_data_t *ptsd, int ctmode) return -1; } - if(ctmode == 1 || ctmode == 2) { + if(ctmode == TPS_CONTACT_MODE_RURIUSER + || ctmode == TPS_CONTACT_MODE_XAVPUSER) { if(msg->parsed_uri.sip_params.len < TPS_TUUID_MIN_LEN) { LM_DBG("not an expected param format\n"); return 1; @@ -910,10 +911,12 @@ int tps_request_received(sip_msg_t *msg, int dialog) goto error; } metid = get_cseq(msg)->method_id; - if((metid & (METHOD_BYE | METHOD_INFO | METHOD_PRACK | METHOD_UPDATE)) + if((metid + & (METHOD_BYE | METHOD_INFO | METHOD_PRACK | METHOD_UPDATE + | METHOD_NOTIFY)) && stsd.b_contact.len <= 0) { /* no B-side contact, look for INVITE transaction record */ - if(metid & (METHOD_BYE | METHOD_UPDATE)) { + if(metid & (METHOD_BYE | METHOD_UPDATE | METHOD_NOTIFY)) { /* detect direction - via from-tag */ if(tps_dlg_detect_direction(msg, &stsd, &direction) < 0) { goto error; @@ -960,7 +963,9 @@ int tps_request_received(sip_msg_t *msg, int dialog) LM_DBG("use branch for routing information, request from direction " "%d\n", direction); - if(tps_reappend_route(msg, &stsd, &stsd.s_rr, 1) < 0) { + if(tps_reappend_route(msg, &stsd, &stsd.s_rr, + (direction == TPS_DIR_UPSTREAM) ? 0 : 1) + < 0) { LM_ERR("failed to reappend s-route\n"); return -1; } diff --git a/src/modules/topos/tps_storage.c b/src/modules/topos/tps_storage.c index 70c003c94..946092c04 100644 --- a/src/modules/topos/tps_storage.c +++ b/src/modules/topos/tps_storage.c @@ -223,6 +223,7 @@ int tps_storage_fill_contact( int i; int contact_len; int cparam_len; + int cuser_len = 0; sr_xavp_t *vavu = NULL; if(dir == TPS_DIR_DOWNSTREAM) { @@ -241,10 +242,12 @@ int tps_storage_fill_contact( } contact_len = sv.len; - if(_tps_contact_host.len) + if(_tps_contact_host.len) { contact_len = sv.len - puri.host.len + _tps_contact_host.len; + } - if(ctmode == 1 || ctmode == 2) { + if(ctmode == TPS_CONTACT_MODE_RURIUSER + || ctmode == TPS_CONTACT_MODE_XAVPUSER) { cparam_len = _tps_cparam_name.len; } else { cparam_len = 0; @@ -282,57 +285,62 @@ int tps_storage_fill_contact( for(i = 0; i < sv.len; i++) { *td->cp = sv.s[i]; td->cp++; - if(sv.s[i] == ':') + if(sv.s[i] == ':') { break; + } } - if(ctmode == 1 || ctmode == 2) { + if(ctmode == TPS_CONTACT_MODE_RURIUSER + || ctmode == TPS_CONTACT_MODE_XAVPUSER) { /* create new URI parameter for Contact header */ - if(ctmode == 1) { + if(ctmode == TPS_CONTACT_MODE_RURIUSER) { if(dir == TPS_DIR_DOWNSTREAM) { /* extract the contact address */ if(parse_headers(msg, HDR_CONTACT_F, 0) < 0 || msg->contact == NULL) { LM_WARN("bad sip message or missing Contact hdr\n"); return -1; + } + if(parse_contact(msg->contact) < 0 + || ((contact_body_t *)msg->contact->parsed)->contacts + == NULL + || ((contact_body_t *)msg->contact->parsed) + ->contacts->next + != NULL) { + LM_ERR("bad Contact header\n"); + return -1; + } + if(parse_uri(((contact_body_t *)msg->contact->parsed) + ->contacts->uri.s, + ((contact_body_t *)msg->contact->parsed) + ->contacts->uri.len, + &curi) + < 0) { + LM_ERR("failed to parse the contact uri\n"); + return -1; + } + if(curi.user.len > 0) { + memcpy(td->cp, curi.user.s, curi.user.len); + td->cp += curi.user.len; + cuser_len = curi.user.len; } else { - if(parse_contact(msg->contact) < 0 - || ((contact_body_t *)msg->contact->parsed) - ->contacts - == NULL - || ((contact_body_t *)msg->contact->parsed) - ->contacts->next - != NULL) { - LM_ERR("bad Contact header\n"); - return -1; - } else { - if(parse_uri(((contact_body_t *)msg->contact->parsed) - ->contacts->uri.s, - ((contact_body_t *)msg->contact->parsed) - ->contacts->uri.len, - &curi) - < 0) { - LM_ERR("failed to parse the contact uri\n"); - return -1; - } - } + LM_DBG("no contact user - skipping it\n"); } - memcpy(td->cp, curi.user.s, curi.user.len); - td->cp += curi.user.len; } else { /* extract the ruri */ if(parse_sip_msg_uri(msg) < 0) { LM_ERR("failed to parse r-uri\n"); return -1; } - if(msg->parsed_uri.user.len == 0) { - LM_ERR("no r-uri user\n"); - return -1; + if(msg->parsed_uri.user.len > 0) { + memcpy(td->cp, msg->parsed_uri.user.s, + msg->parsed_uri.user.len); + td->cp += msg->parsed_uri.user.len; + cuser_len = msg->parsed_uri.user.len; + } else { + LM_DBG("no r-uri user - skipping it\n"); } - memcpy(td->cp, msg->parsed_uri.user.s, - msg->parsed_uri.user.len); - td->cp += msg->parsed_uri.user.len; } - } else if(ctmode == 2) { + } else if(ctmode == TPS_CONTACT_MODE_XAVPUSER) { if(dir == TPS_DIR_DOWNSTREAM) { /* extract the a contact */ vavu = xavu_get_child_with_sval( @@ -343,6 +351,7 @@ int tps_storage_fill_contact( } memcpy(td->cp, vavu->val.v.s.s, vavu->val.v.s.len); td->cp += vavu->val.v.s.len; + cuser_len = vavu->val.v.s.len; } else { /* extract the b contact */ vavu = xavu_get_child_with_sval( @@ -353,11 +362,11 @@ int tps_storage_fill_contact( } memcpy(td->cp, vavu->val.v.s.s, vavu->val.v.s.len); td->cp += vavu->val.v.s.len; + cuser_len = vavu->val.v.s.len; } } - if(!((ctmode == 1) && (dir == TPS_DIR_DOWNSTREAM) - && (curi.user.len <= 0))) { + if(cuser_len > 0) { *td->cp = '@'; td->cp++; } @@ -1130,9 +1139,7 @@ int tps_db_load_branch( db_val_t db_vals[5]; db_key_t db_cols[TPS_NR_KEYS]; db1_res_t *db_res = NULL; - str sinv = str_init("INVITE"); - str ssub = str_init("SUBSCRIBE"); - int bInviteDlg = 1; + str sMethodDlg = str_init("INVITE"); int nr_keys; int nr_cols; int n; @@ -1144,10 +1151,13 @@ int tps_db_load_branch( nr_keys = 0; nr_cols = 0; - if((get_cseq(msg)->method_id == METHOD_SUBSCRIBE) - || ((get_cseq(msg)->method_id == METHOD_NOTIFY) - && (msg->event && msg->event->len > 0))) { - bInviteDlg = 0; + if(get_cseq(msg)->method_id == METHOD_SUBSCRIBE) { + sMethodDlg.s = "SUBSCRIBE"; + sMethodDlg.len = 9; + } else if(get_cseq(msg)->method_id == METHOD_NOTIFY) { + /* NOTIFY can be also sent during call setup - ignore dialog method */ + sMethodDlg.s = ""; + sMethodDlg.len = 0; } if(mode == 0) { @@ -1178,12 +1188,14 @@ int tps_db_load_branch( } nr_keys++; - db_keys[nr_keys] = &tt_col_s_method; - db_ops[nr_keys] = OP_EQ; - db_vals[nr_keys].type = DB1_STR; - db_vals[nr_keys].nul = 0; - db_vals[nr_keys].val.str_val = bInviteDlg ? sinv : ssub; - nr_keys++; + if(sMethodDlg.len > 0) { + db_keys[nr_keys] = &tt_col_s_method; + db_ops[nr_keys] = OP_EQ; + db_vals[nr_keys].type = DB1_STR; + db_vals[nr_keys].nul = 0; + db_vals[nr_keys].val.str_val = sMethodDlg; + nr_keys++; + } if(md->a_uuid.len > 0) { if(md->a_uuid.s[0] == 'a') { diff --git a/src/modules/topos/tps_storage.h b/src/modules/topos/tps_storage.h index 4c2585a1f..245a15956 100644 --- a/src/modules/topos/tps_storage.h +++ b/src/modules/topos/tps_storage.h @@ -37,6 +37,10 @@ #define TPS_IFLAG_INIT 1 #define TPS_IFLAG_DLGON 2 +#define TPS_CONTACT_MODE_SKEYUSER 0 +#define TPS_CONTACT_MODE_RURIUSER 1 +#define TPS_CONTACT_MODE_XAVPUSER 2 + #define TPS_DBU_CONTACT (1 << 0) #define TPS_DBU_RPLATTRS (1 << 1) #define TPS_DBU_ARR (1 << 2) diff --git a/src/modules/tsilo/README b/src/modules/tsilo/README index 9592ae72b..142cf6536 100644 --- a/src/modules/tsilo/README +++ b/src/modules/tsilo/README @@ -246,8 +246,8 @@ if (is_method("REGISTER")) { Example 1.5. ts_append_by_contact usage ... if (is_method("REGISTER")) { - $var(formated_ct) = $(x_hdr(Contact){nameaddr.uri}); - ts_append_by_contact("location", "$tu", "$var(formated_ct)"); + $var(formatted_ct) = $(x_hdr(Contact){nameaddr.uri}); + ts_append_by_contact("location", "$tu", "$var(formatted_ct)"); } ... diff --git a/src/modules/tsilo/doc/tsilo_admin.xml b/src/modules/tsilo/doc/tsilo_admin.xml index da7eb0a97..75b23d952 100644 --- a/src/modules/tsilo/doc/tsilo_admin.xml +++ b/src/modules/tsilo/doc/tsilo_admin.xml @@ -259,8 +259,8 @@ if (is_method("REGISTER")) { ... if (is_method("REGISTER")) { - $var(formated_ct) = $(x_hdr(Contact){nameaddr.uri}); - ts_append_by_contact("location", "$tu", "$var(formated_ct)"); + $var(formatted_ct) = $(x_hdr(Contact){nameaddr.uri}); + ts_append_by_contact("location", "$tu", "$var(formatted_ct)"); } ... diff --git a/src/modules/tsilo/ts_append.c b/src/modules/tsilo/ts_append.c index 1dc29ef0f..aab11130d 100644 --- a/src/modules/tsilo/ts_append.c +++ b/src/modules/tsilo/ts_append.c @@ -125,13 +125,13 @@ int ts_append_to(struct sip_msg *msg, int tindex, int tlabel, char *table, /* check if the dialog is still in the early stage */ if(t->flags & T_CANCELED) { - LM_DBG("trasaction [%u:%u] was cancelled\n", tindex, tlabel); + LM_DBG("transaction [%u:%u] was cancelled\n", tindex, tlabel); ret = -2; goto done; } if(t->uas.status >= 200) { - LM_DBG("trasaction [%u:%u] sent out a final response already - %d\n", + LM_DBG("transaction [%u:%u] sent out a final response already - %d\n", tindex, tlabel, t->uas.status); ret = -3; goto done; diff --git a/src/modules/tsilo/tsilo.c b/src/modules/tsilo/tsilo.c index 0ec96b669..5fe6535ba 100644 --- a/src/modules/tsilo/tsilo.c +++ b/src/modules/tsilo/tsilo.c @@ -380,7 +380,7 @@ static int w_ts_append_to2( } if(fixup_get_svalue(msg, (gparam_t *)ruri, &suri) != 0) { - LM_ERR("failed to conert r-uri parameter\n"); + LM_ERR("failed to convert r-uri parameter\n"); return -1; } if(ts_check_uri(&suri) < 0) @@ -690,7 +690,7 @@ static int w_ts_store1(struct sip_msg *msg, char *_ruri, char *p2) str suri; if(fixup_get_svalue(msg, (gparam_t *)_ruri, &suri) != 0) { - LM_ERR("failed to conert r-uri parameter\n"); + LM_ERR("failed to convert r-uri parameter\n"); return -1; } return ts_store(msg, &suri); diff --git a/src/modules/uac/README b/src/modules/uac/README index 652344958..5b827e72a 100644 --- a/src/modules/uac/README +++ b/src/modules/uac/README @@ -314,7 +314,7 @@ Chapter 1. Admin Guide Name of Record-Route header parameter that will be used to store an encoded version of the original FROM URI. - This parameter is optional, it's default value being “vsf”. + The default value is “vsf”. Example 1.1. Set rr_from_store_param parameter ... @@ -326,7 +326,7 @@ modparam("uac","rr_from_store_param","my_param") Name of Record-Route header parameter that will be used to store (encoded) the original TO URI. - This parameter is optional, it's default value being “vst”. + The default value is “vst”. Example 1.2. Set rr_to_store_param parameter ... @@ -346,7 +346,7 @@ modparam("uac","rr_to_store_param","my_param") updated based on stored original URI. For this option you have to set “modparam("rr", "append_fromtag", 1)”. - This parameter is optional, it's default value being “auto”. + The default value is “auto”. Example 1.3. Set restore_mode parameter ... @@ -543,7 +543,7 @@ modparam("uac", "reg_hash_size", 10) DB table name to fetch user profiles for registration. - This parameter is optional, it's default value being “uacreg”. + The default value is “uacreg”. Example 1.17. Set reg_db_table parameter ... @@ -580,7 +580,7 @@ modparam("uac", "reg_keep_callid", 1) 3.20. reg_active (int) If set to 0, no remote regisrations are done. In other words, it can - control at once if the module should do remote registratios or not. It + control at once if the module should do remote registrations or not. It can be changed at runtime via rpc command 'uac.reg_active 0|1'. The default value is 1 (active). @@ -1129,7 +1129,7 @@ event_route[uac:reply] { 8.2. uac.reg_info Return the details of a remote registration record based on a filter. - The command has two parameter: attribute and value. The attribute can + The command has two parameters: attribute and value. The attribute can be: l_uuid, l_username, r_username or auth_username. The value is what should be matched against the value of the attribute in the remote registration record. @@ -1138,7 +1138,7 @@ event_route[uac:reply] { * 1 (2^0) - registration profile is disabled * 2 (2^1) - registration in progress * 4 (2^2) - registration succeeded - * 8 (2^3) - registration in progres with authentication + * 8 (2^3) - registration in progress with authentication * 16 (2^4) - registration initialized (after loading from database, the registration process was initialized) @@ -1151,7 +1151,7 @@ event_route[uac:reply] { 8.3. uac.reg_enable Enable a remote registration record based on a filter. The command has - two parameter: attribute and value. The attribute can be: l_uuid, + two parameters: attribute and value. The attribute can be: l_uuid, l_username, r_username or auth_username. The value is what should be matched against the value of the attribute in the remote registration record. @@ -1165,7 +1165,7 @@ event_route[uac:reply] { 8.4. uac.reg_disable Disable a remote registration record based on a filter. The command has - two parameter: attribute and value. The attribute can be: l_uuid, + two parameters: attribute and value. The attribute can be: l_uuid, l_username, r_username or auth_username. The value is what should be matched against the value of the attribute in the remote registration record. @@ -1179,7 +1179,7 @@ event_route[uac:reply] { 8.5. uac.reg_unregister Send REGISTER with expires 0 for matching record, disabling it. The - command has two parameter: attribute and value. The attribute can be: + command has two parameters: attribute and value. The attribute can be: l_uuid, l_username, r_username or auth_username. The value is what should be matched against the value of the attribute in the remote registration record. @@ -1270,36 +1270,39 @@ event_route[uac:reply] { The module can register contact addresses to remote REGISTRAR servers. You have to add records to uacreg table. The table stores following attributes: - * l_uuid - local unique user id, e.g.,: 12345678 + * l_uuid - local unique user id, e.g.: 12345678 - * l_username - local user name, e.g.,: test + * l_username - local user name, e.g.: test - * l_domain - local domain, e.g.,: mysipserver.com + * l_domain - local domain, e.g.: mysipserver.com - * r_username - remote username, e.g.,: test123 + * r_username - remote username, e.g.: test123 - * r_domain - remote domain, e.g.,: sipprovider.com + * r_domain - remote domain, e.g.: sipprovider.com. Used to contstruct + RURI, From: and To: domains. - * realm - remote realm, e.g.,: sipprovider.com + * realm - remote realm, e.g.: sipprovider.com. Must match realm= + parameter in incoming WWW-Authenticate headers. - * auth_username - authentication username, e.g.,: test123 + * auth_username - authentication username, e.g.: test123 - * auth_password - authentication password in clear text, e.g.,: - xxxxxx + * auth_password - authentication password in clear text, e.g.: xxxxxx * auth_ha1 - hashed (HA1) authentication password, it has priority over auth_password. - * auth_proxy - SIP address of authentication proxy, e.g.,: - sip:sipprovider.com + * auth_proxy - SIP address of authentication proxy, e.g.: + sip:sipprovider.com or sips:sipprovider.com. It is used to find the + IP address of the proxy and determine whether UDP or TLS shall be + used. It has no impact on the content of generated messages. - * expires - expiration time for registration, in seconds, e.g.,: 360 + * expires - expiration time for registration, in seconds, e.g.: 360 * flags - the state of the registration, see Section 8.2, “ uac.reg_info ” * reg_delay - delay initial registration with at least reg_delay - seconds, e.g.,: 3 + seconds, e.g.: 3 * contact_addr - contact address to be used for this record instead of reg_contact_addr module parameter, e.g.:, 192.168.0.125:5060. It diff --git a/src/modules/uac/auth.c b/src/modules/uac/auth.c index d21ec78db..2bb376c2f 100644 --- a/src/modules/uac/auth.c +++ b/src/modules/uac/auth.c @@ -211,7 +211,7 @@ void destroy_credentials(void) } -struct hdr_field *get_autenticate_hdr(struct sip_msg *rpl, int rpl_code) +struct hdr_field *get_authenticate_hdr(struct sip_msg *rpl, int rpl_code) { struct hdr_field *hdr; str hdr_name; @@ -360,7 +360,7 @@ static inline int apply_urihdr_changes(struct sip_msg *req, str *uri, str *hdr) } if(insert_new_lump_before(anchor, hdr->s, hdr->len, 0) == 0) { - LM_ERR("faield to insert lump\n"); + LM_ERR("failed to insert lump\n"); goto error; } @@ -412,7 +412,7 @@ int uac_auth_mode(sip_msg_t *msg, int mode) goto error; } - hdr = get_autenticate_hdr(rpl, code); + hdr = get_authenticate_hdr(rpl, code); if(hdr == 0) { LM_ERR("failed to extract authenticate hdr\n"); goto error; @@ -486,4 +486,4 @@ error: int uac_auth(sip_msg_t *msg) { return uac_auth_mode(msg, 0); -} \ No newline at end of file +} diff --git a/src/modules/uac/auth.h b/src/modules/uac/auth.h index 9add2de3e..188fe8e47 100644 --- a/src/modules/uac/auth.h +++ b/src/modules/uac/auth.h @@ -69,7 +69,7 @@ int add_credential(unsigned int type, void *val); void destroy_credentials(void); -struct hdr_field *get_autenticate_hdr(struct sip_msg *rpl, int rpl_code); +struct hdr_field *get_authenticate_hdr(struct sip_msg *rpl, int rpl_code); int uac_auth(sip_msg_t *msg); int uac_auth_mode(sip_msg_t *msg, int mode); diff --git a/src/modules/uac/doc/uac_admin.xml b/src/modules/uac/doc/uac_admin.xml index 51fbf7e0b..af34e3e6f 100644 --- a/src/modules/uac/doc/uac_admin.xml +++ b/src/modules/uac/doc/uac_admin.xml @@ -123,8 +123,7 @@ - This parameter is optional, it's default value being - vsf. + The default value is vsf. @@ -144,8 +143,7 @@ modparam("uac","rr_from_store_param","my_param") - This parameter is optional, it's default value being - vst. + The default value is vst. @@ -186,8 +184,7 @@ modparam("uac","rr_to_store_param","my_param") - This parameter is optional, it's default value being - auto. + The default value is auto. @@ -486,8 +483,7 @@ modparam("uac", "reg_hash_size", 10) - This parameter is optional, it's default value being - uacreg. + The default value is uacreg. @@ -546,7 +542,7 @@ modparam("uac", "reg_keep_callid", 1) <varname>reg_active</varname> (int) If set to 0, no remote regisrations are done. In other words, - it can control at once if the module should do remote registratios + it can control at once if the module should do remote registrations or not. It can be changed at runtime via rpc command 'uac.reg_active 0|1'. @@ -1316,7 +1312,7 @@ event_route[uac:reply] { Return the details of a remote registration record based on - a filter. The command has two parameter: attribute and value. + a filter. The command has two parameters: attribute and value. The attribute can be: l_uuid, l_username, r_username or auth_username. The value is what should be matched against the value of the attribute in the remote registration record. @@ -1334,7 +1330,7 @@ event_route[uac:reply] { 4 (2^2) - registration succeeded - 8 (2^3) - registration in progres with authentication + 8 (2^3) - registration in progress with authentication 16 (2^4) - registration initialized (after loading from database, @@ -1359,7 +1355,7 @@ event_route[uac:reply] { Enable a remote registration record based on - a filter. The command has two parameter: attribute and value. + a filter. The command has two parameters: attribute and value. The attribute can be: l_uuid, l_username, r_username or auth_username. The value is what should be matched against the value of the attribute in the remote registration record. @@ -1381,7 +1377,7 @@ event_route[uac:reply] { Disable a remote registration record based on - a filter. The command has two parameter: attribute and value. + a filter. The command has two parameters: attribute and value. The attribute can be: l_uuid, l_username, r_username or auth_username. The value is what should be matched against the value of the attribute in the remote registration record. @@ -1403,7 +1399,7 @@ event_route[uac:reply] { Send REGISTER with expires 0 for matching record, disabling it. - The command has two parameter: attribute and value. + The command has two parameters: attribute and value. The attribute can be: l_uuid, l_username, r_username or auth_username. The value is what should be matched against the value of the attribute in the remote registration record. @@ -1551,49 +1547,49 @@ event_route[uac:reply] { - l_uuid - local unique user id, e.g.,: + l_uuid - local unique user id, e.g.: 12345678 - l_username - local user name, e.g.,: test + l_username - local user name, e.g.: test - l_domain - local domain, e.g.,: + l_domain - local domain, e.g.: mysipserver.com - r_username - remote username, e.g.,: + r_username - remote username, e.g.: test123 - r_domain - remote domain, e.g.,: - sipprovider.com + r_domain - remote domain, e.g.: + sipprovider.com. Used to contstruct RURI, From: and To: domains. - realm - remote realm, e.g.,: - sipprovider.com + realm - remote realm, e.g.: + sipprovider.com. Must match realm= parameter in incoming WWW-Authenticate headers. auth_username - authentication username, - e.g.,: test123 + e.g.: test123 auth_password - authentication password in - clear text, e.g.,: xxxxxx + clear text, e.g.: xxxxxx @@ -1605,13 +1601,15 @@ event_route[uac:reply] { auth_proxy - SIP address of authentication - proxy, e.g.,: sip:sipprovider.com + proxy, e.g.: sip:sipprovider.com or sips:sipprovider.com. It is used + to find the IP address of the proxy and determine whether UDP or TLS + shall be used. It has no impact on the content of generated messages. expires - expiration time for registration, - in seconds, e.g.,: 360 + in seconds, e.g.: 360 @@ -1621,7 +1619,7 @@ event_route[uac:reply] { - reg_delay - delay initial registration with at least reg_delay seconds, e.g.,: 3 + reg_delay - delay initial registration with at least reg_delay seconds, e.g.: 3 diff --git a/src/modules/uac/replace.c b/src/modules/uac/replace.c index 459951b55..f13a661ca 100644 --- a/src/modules/uac/replace.c +++ b/src/modules/uac/replace.c @@ -248,7 +248,7 @@ int replace_uri(struct sip_msg *msg, str *display, str *uri, char *p; str param; str buf; - unsigned int uac_flag; + msg_flags_t uac_flag; int i; int_str avp_value; struct dlg_cell *dlg = 0; @@ -558,7 +558,7 @@ int restore_uri( char *p; int i; int_str avp_value; - int flag; + msg_flags_t flag; int bsize; /* we should process only sequential request, but since we are looking @@ -1056,7 +1056,7 @@ static void uac_on_load_callback( * method call at this point in time anymore. Therefore we just install a * callback for both FROM and TO replace cases. This might be a bit * inefficient in cases where only one of the functions is used. But as - * this applies only e.g. to a proxy restart with runnning dialogs, it + * this applies only e.g. to a proxy restart with running dialogs, it * does not matter. The replace_callback function will just not find * an entry in the dialog variables table and log an error. */ diff --git a/src/modules/uac/uac_reg.c b/src/modules/uac/uac_reg.c index 0dbe742f3..4885f4d40 100644 --- a/src/modules/uac/uac_reg.c +++ b/src/modules/uac/uac_reg.c @@ -558,8 +558,8 @@ int reg_ht_add(reg_uac_t *reg) reg_ht_add_byuuid(nr); counter_inc(regtotal); - LM_DBG("added uuid: %.*s - l_user: %.*s\n", nr->l_uuid.len, nr->l_uuid.s, - nr->l_username.len, nr->l_username.s); + LM_DBG("added uuid: %.*s - l_username: %.*s\n", nr->l_uuid.len, + nr->l_uuid.s, nr->l_username.len, nr->l_username.s); return 0; } @@ -881,7 +881,7 @@ void uac_reg_tm_callback(struct cell *t, int type, struct tmcb_params *ps) ri->l_uuid.s); goto error; } - hdr = get_autenticate_hdr(ps->rpl, ps->code); + hdr = get_authenticate_hdr(ps->rpl, ps->code); if(hdr == 0) { LM_ERR("failed to extract authenticate hdr\n"); goto error; diff --git a/src/modules/uac/uac_send.c b/src/modules/uac/uac_send.c index b1dfd78c6..c29e9b4b9 100644 --- a/src/modules/uac/uac_send.c +++ b/src/modules/uac/uac_send.c @@ -50,7 +50,7 @@ #define MAX_UACD_SIZE 128 /** TM bind */ -struct tm_binds tmb; +static struct tm_binds _uac_send_tmb = {0}; typedef struct _uac_send_info { @@ -120,7 +120,7 @@ uac_send_info_t *uac_send_info_clone(uac_send_info_t *ur) int pv_get_uac_req(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { - if(param == NULL || tmb.t_request == NULL) + if(param == NULL || _uac_send_tmb.t_request == NULL) return -1; switch(param->pvn.u.isname.name.n) { @@ -191,7 +191,7 @@ int pv_set_uac_req( { pv_value_t *tval; - if(param == NULL || tmb.t_request == NULL) + if(param == NULL || _uac_send_tmb.t_request == NULL) return -1; tval = val; @@ -545,9 +545,9 @@ error: void uac_req_init(void) { /* load the TM API */ - if(load_tm_api(&tmb) != 0) { + if(load_tm_api(&_uac_send_tmb) != 0) { LM_DBG("can't load TM API - disable it\n"); - memset(&tmb, 0, sizeof(struct tm_binds)); + memset(&_uac_send_tmb, 0, sizeof(struct tm_binds)); return; } memset(&_uac_req, 0, sizeof(struct _uac_send_info)); @@ -727,7 +727,7 @@ void uac_send_tm_callback(struct cell *t, int type, struct tmcb_params *ps) LM_DBG("completed with status %d\n", ps->code); - hdr = get_autenticate_hdr(ps->rpl, ps->code); + hdr = get_authenticate_hdr(ps->rpl, ps->code); if(hdr == 0) { LM_ERR("failed to extract authenticate hdr\n"); goto error; @@ -788,7 +788,7 @@ void uac_send_tm_callback(struct cell *t, int type, struct tmcb_params *ps) /* Callback parameter */ uac_r.cbp = (void *)tp; } - ret = tmb.t_request_within(&uac_r); + ret = _uac_send_tmb.t_request_within(&uac_r); if(ret < 0) { LM_ERR("failed to send request with authentication\n"); @@ -816,7 +816,7 @@ int uac_req_send(void) uac_send_info_t *tp = NULL; if(_uac_req.s_ruri.len <= 0 || _uac_req.s_method.len == 0 - || tmb.t_request == NULL) + || _uac_send_tmb.t_request == NULL) return -1; memset(&uac_r, '\0', sizeof(uac_r)); @@ -856,8 +856,8 @@ int uac_req_send(void) uac_r.cbp = (void *)tp; } uac_r.callid = (_uac_req.s_callid.len <= 0) ? NULL : &_uac_req.s_callid; - ret = tmb.t_request(&uac_r, /* UAC Req */ - &_uac_req.s_ruri, /* Request-URI */ + ret = _uac_send_tmb.t_request(&uac_r, /* UAC Req */ + &_uac_req.s_ruri, /* Request-URI */ (_uac_req.s_turi.len <= 0) ? &_uac_req.s_ruri : &_uac_req.s_turi, /* To */ (_uac_req.s_furi.len <= 0) ? &_uac_req.s_ruri diff --git a/src/modules/uac_redirect/README b/src/modules/uac_redirect/README index d1a5d2b97..e89d8175d 100644 --- a/src/modules/uac_redirect/README +++ b/src/modules/uac_redirect/README @@ -93,7 +93,7 @@ Chapter 1. Admin Guide UAC REDIRECT - User Agent Client redirection - module enhances Kamailio with the functionality of being able to handle (interpret, filter, log - and follow) redirect responses ( 3xx replies class). + and follow) redirect responses (3xx replies class). UAC REDIRECT module offers stateful processing, gathering the contacts from all 3xx branches of a call. @@ -173,11 +173,11 @@ modparam("uac_redirect","default_filter","deny") contacts matching the deny_filter will be rejected; the rest of them will be accepted for redirection. - The parameter may be defined only one - multiple definition will + The parameter may be defined only once - multiple definition will overwrite the previous definitions. If more regular expression need to be defined, use the set_deny_filter() scripting function. - This parameter is optional, it's default value being NULL. + The default value is NULL. Example 1.2. Set deny_filter module parameter ... @@ -191,11 +191,11 @@ modparam("uac_redirect","deny_filter",".*@siphub\.net") contacts matching the accept_filter will be accepted; the rest of them will be rejected for redirection. - The parameter may be defined only one - multiple definition will + The parameter may be defined only once - multiple definition will overwrite the previous definitions. If more regular expression need to be defined, use the set_accept_filter() scripting function. - This parameter is optional, it's default value being NULL. + The default value is NULL. Example 1.3. Set accept_filter module parameter ... @@ -240,7 +240,7 @@ modparam("uac_redirect","acc_db_table","acc_redirect") This parameter defines the branch-flags to be set for new, added branch. - This parameter is optional, it's default value being 0. + The default value is 0. Example 1.6. Set bflags module parameter ... @@ -378,7 +378,7 @@ get_redirects("*"); The function has same functionality as get_redirects(max) function, but it will produce accounting records. - The accounting records will be mark by the reason phrase. + The accounting records will be marked by the reason phrase. If this function appears in the script, at startup, the module will import the accounting function. Otherwise not. diff --git a/src/modules/uac_redirect/doc/uac_redirect_admin.xml b/src/modules/uac_redirect/doc/uac_redirect_admin.xml index e18483f27..d5f1de836 100644 --- a/src/modules/uac_redirect/doc/uac_redirect_admin.xml +++ b/src/modules/uac_redirect/doc/uac_redirect_admin.xml @@ -19,7 +19,7 @@ UAC REDIRECT - User Agent Client redirection - module enhances &kamailio; with the functionality of being able to handle (interpret, filter, - log and follow) redirect responses ( 3xx replies class). + log and follow) redirect responses (3xx replies class). UAC REDIRECT module offers stateful processing, gathering the @@ -154,7 +154,7 @@ modparam("uac_redirect","default_filter","deny") of them will be accepted for redirection. - The parameter may be defined only one - multiple definition will + The parameter may be defined only once - multiple definition will overwrite the previous definitions. If more regular expression need to be defined, use the set_deny_filter() scripting @@ -162,8 +162,7 @@ modparam("uac_redirect","default_filter","deny") - This parameter is optional, it's default - value being NULL. + The default value is NULL. @@ -186,7 +185,7 @@ modparam("uac_redirect","deny_filter",".*@siphub\.net") of them will be rejected for redirection. - The parameter may be defined only one - multiple definition will + The parameter may be defined only once - multiple definition will overwrite the previous definitions. If more regular expression need to be defined, use the set_accept_filter() scripting @@ -194,8 +193,7 @@ modparam("uac_redirect","deny_filter",".*@siphub\.net") - This parameter is optional, it's default - value being NULL. + The default value is NULL. @@ -276,8 +274,7 @@ modparam("uac_redirect","acc_db_table","acc_redirect") - This parameter is optional, it's default - value being 0. + The default value is 0. @@ -531,7 +528,7 @@ get_redirects("*"); function, but it will produce accounting records. - The accounting records will be mark by the + The accounting records will be marked by the reason phrase. diff --git a/src/modules/uac_redirect/rd_funcs.c b/src/modules/uac_redirect/rd_funcs.c index 05ba6d577..d3abb68af 100644 --- a/src/modules/uac_redirect/rd_funcs.c +++ b/src/modules/uac_redirect/rd_funcs.c @@ -69,7 +69,7 @@ int get_redirect(struct sip_msg *msg, int maxt, int maxb, str *reason, LM_DBG("resume branch=%d\n", first_branch); cts_added = 0; /* no contact added */ - backup_uri = msg->new_uri; /* shmcontact2dset will ater this value */ + backup_uri = msg->new_uri; /* shmcontact2dset will alter this value */ /* look if there are any 3xx branches starting from resume_branch */ for(i = first_branch; i < t->nr_of_outgoings; i++) { diff --git a/src/modules/uid_auth_db/README b/src/modules/uid_auth_db/README index a5ecbbcec..a0c23de56 100644 --- a/src/modules/uid_auth_db/README +++ b/src/modules/uid_auth_db/README @@ -83,8 +83,8 @@ Chapter 1. Admin Guide 2. Dependencies - The module depends on the following modules (in the other words the - listed modules must be loaded before this module): + The module depends on the following modules (in other words the listed + modules must be loaded before this module): * auth. Generic authentication functions. * database. Any database module (currently mysql, postgres, dbtext) @@ -201,7 +201,7 @@ modparam("auth_db", "plain_password_column", "password") As described in the previous section this parameter contains name of column holding pre-calculated HA1 string that were calculated including the domain in the username. This parameter is used only when - calculate_ha1 is set to 0 and user agent send a credentials containing + calculate_ha1 is set to 0 and user agent sends credentials containing the domain in the username. Default value of the parameter is ha1b. diff --git a/src/modules/uid_auth_db/authorize.c b/src/modules/uid_auth_db/authorize.c index ee3804a55..fa86b23d1 100644 --- a/src/modules/uid_auth_db/authorize.c +++ b/src/modules/uid_auth_db/authorize.c @@ -216,7 +216,7 @@ static int generate_avps(db_res_t *result, db_rec_t *row) } /* this is a dirty work around to check the credentials of all users, - * if the database query returned more then one result + * if the database query returned more than one result * * Fills res (which must be db_free'd afterwards if the call was successful) * returns 0 on success, 1 on no match (?) diff --git a/src/modules/uid_auth_db/doc/params.xml b/src/modules/uid_auth_db/doc/params.xml index 0e411a861..a066737a8 100644 --- a/src/modules/uid_auth_db/doc/params.xml +++ b/src/modules/uid_auth_db/doc/params.xml @@ -167,7 +167,7 @@ modparam("auth_db", "plain_password_column", "password") of column holding pre-calculated HA1 string that were calculated including the domain in the username. This parameter is used only when calculate_ha1 is set to 0 and user agent - send a credentials containing the domain in the username. + sends credentials containing the domain in the username. Default value of the parameter is ha1b. diff --git a/src/modules/uid_auth_db/doc/uid_auth_db.xml b/src/modules/uid_auth_db/doc/uid_auth_db.xml index a276847b1..e48e6ddcc 100644 --- a/src/modules/uid_auth_db/doc/uid_auth_db.xml +++ b/src/modules/uid_auth_db/doc/uid_auth_db.xml @@ -46,7 +46,7 @@
Dependencies - The module depends on the following modules (in the other words the listed modules + The module depends on the following modules (in other words the listed modules must be loaded before this module): diff --git a/src/modules/uid_auth_db/uid_auth_db_mod.c b/src/modules/uid_auth_db/uid_auth_db_mod.c index 4c7808073..06cb3030d 100644 --- a/src/modules/uid_auth_db/uid_auth_db_mod.c +++ b/src/modules/uid_auth_db/uid_auth_db_mod.c @@ -328,7 +328,7 @@ static authdb_table_info_t *register_table(str *table) memcpy(info->table.s, table->s, table->len); info->table.s[table->len] = 0; - /* append to the begining (we don't care about order) */ + /* append to the beginning (we don't care about order) */ info->next = registered_tables; registered_tables = info; diff --git a/src/modules/uid_avp_db/avp_db.xml b/src/modules/uid_avp_db/avp_db.xml index eac685c82..a047b9a27 100644 --- a/src/modules/uid_avp_db/avp_db.xml +++ b/src/modules/uid_avp_db/avp_db.xml @@ -158,7 +158,7 @@ Allowed in request, reply, and failure processing. - The unlock_extra_attrs() function releaes the + The unlock_extra_attrs() function releases the lock on the key given by the argument key of the extra attribute group given by the argument group previously imposed by a call to the function @@ -342,7 +342,7 @@ Extra attribute groups are defined through the module parameter attr_group. Each - occurence of the parameter defines a group. The value of the parameter + occurrence of the parameter defines a group. The value of the parameter contains key/value pairs. Key and value are separated by an equals sign, several pairs are separated by a comma. @@ -539,7 +539,7 @@ VARCHAR(255) - The value field contans the value of the + The value field contains the value of the attribute. @@ -644,7 +644,7 @@ VARCHAR(255) - The value field contans the value of the + The value field contains the value of the attribute. @@ -724,7 +724,7 @@ VARCHAR(255) - The value field contans the value of the + The value field contains the value of the attribute. diff --git a/src/modules/uid_avp_db/extra_attrs.c b/src/modules/uid_avp_db/extra_attrs.c index e5dfa968d..c8fde1bb1 100644 --- a/src/modules/uid_avp_db/extra_attrs.c +++ b/src/modules/uid_avp_db/extra_attrs.c @@ -465,7 +465,7 @@ int extra_attrs_fixup(void **param, int param_no) gen_lock_t *locks = NULL; /* set of mutexes allocated in shared memory */ int lock_counters - [LOCK_CNT]; /* set of counters (each proces has its own counters) */ + [LOCK_CNT]; /* set of counters (each process has its own counters) */ static int avpdb_post_script_cb( struct sip_msg *msg, unsigned int flags, void *param) diff --git a/src/modules/uid_domain/README b/src/modules/uid_domain/README index 58ba5a023..a49342f21 100644 --- a/src/modules/uid_domain/README +++ b/src/modules/uid_domain/README @@ -276,8 +276,8 @@ iptel 2. Dependencies - The module depends on the following modules (in the other words the - listed modules must be loaded before this module): + The module depends on the following modules (in other words the listed + modules must be loaded before this module): * database - Any database module 3. Known Limitations diff --git a/src/modules/uid_domain/doc/uid_domain.xml b/src/modules/uid_domain/doc/uid_domain.xml index c4f8166c3..3b8955b3e 100644 --- a/src/modules/uid_domain/doc/uid_domain.xml +++ b/src/modules/uid_domain/doc/uid_domain.xml @@ -213,7 +213,7 @@ iptel
Dependencies - The module depends on the following modules (in the other words + The module depends on the following modules (in other words the listed modules must be loaded before this module): diff --git a/src/modules/uid_domain/domain.c b/src/modules/uid_domain/domain.c index da5998d70..f2ce3bc56 100644 --- a/src/modules/uid_domain/domain.c +++ b/src/modules/uid_domain/domain.c @@ -114,7 +114,7 @@ static void free_domain(domain_t *d) /* - * Create a new domain structure which will initialy have + * Create a new domain structure which will initially have * one domain name */ static domain_t *new_domain(str *did, str *domain, unsigned int flags) diff --git a/src/modules/uri_db/checks.c b/src/modules/uri_db/checks.c index 7b8d6b7d6..9b4ebfb3d 100644 --- a/src/modules/uri_db/checks.c +++ b/src/modules/uri_db/checks.c @@ -204,7 +204,7 @@ int check_from(struct sip_msg *_m, char *_s1, char *_s2) /* * Checks username part of the supplied sip URI. - * Optinal with supplied credentials. + * Optional with supplied credentials. */ int ki_check_uri_realm( struct sip_msg *msg, str *suri, str *susername, str *srealm) diff --git a/src/modules/uri_db/checks.h b/src/modules/uri_db/checks.h index 51328ad0e..ccdf5ffd5 100644 --- a/src/modules/uri_db/checks.h +++ b/src/modules/uri_db/checks.h @@ -44,7 +44,7 @@ int check_from(struct sip_msg *_msg, char *_str1, char *_str2); /* * Checks username part of the supplied sip URI. - * Optinal with supplied credentials. + * Optional with supplied credentials. */ int check_uri(struct sip_msg *msg, char *uri, char *username, char *realm); diff --git a/src/modules/userblocklist/README b/src/modules/userblocklist/README index 180bebc05..33fca80b6 100644 --- a/src/modules/userblocklist/README +++ b/src/modules/userblocklist/README @@ -169,7 +169,7 @@ Chapter 1. Admin Guide the global blocklist cache. Please note that only numerical strings for matching are supported at - the moment (the used library supports this already, but its not yet + the moment (the used library supports this already, but it is not yet implemented in the module). Non-digits on the beginning of the matched string are skipped, any later non-digits will stop the matching on this position. @@ -181,8 +181,8 @@ Chapter 1. Admin Guide 2.1. Kamailio Modules - The module depends on the following modules (in the other words the - listed modules must be loaded before this module): + The module depends on the following modules (in other words the listed + modules must be loaded before this module): * database -- Any db_* database module 2.2. External Libraries or Applications diff --git a/src/modules/userblocklist/doc/userblocklist_admin.xml b/src/modules/userblocklist/doc/userblocklist_admin.xml index dbba7b428..bb9c66a25 100644 --- a/src/modules/userblocklist/doc/userblocklist_admin.xml +++ b/src/modules/userblocklist/doc/userblocklist_admin.xml @@ -38,7 +38,7 @@ Please note that only numerical strings for matching are supported at the - moment (the used library supports this already, but its not yet implemented + moment (the used library supports this already, but it is not yet implemented in the module). Non-digits on the beginning of the matched string are skipped, any later non-digits will stop the matching on this position. @@ -49,7 +49,7 @@
&kamailio; Modules - The module depends on the following modules (in the other words + The module depends on the following modules (in other words the listed modules must be loaded before this module): diff --git a/src/modules/userblocklist/userblocklist.c b/src/modules/userblocklist/userblocklist.c index 4a73c0257..ced0a0956 100644 --- a/src/modules/userblocklist/userblocklist.c +++ b/src/modules/userblocklist/userblocklist.c @@ -884,7 +884,7 @@ static void dump_dtrie_mi(const struct dtrie_node_t *root, /* If data found, add a new node to the reply tree */ if(root->data) { - /* Create new node and add it to the roots's kids */ + /* Create new node and add it to the roots' kids */ if(!(crt_node = add_mi_node_child( &reply->node, MI_DUP_NAME, prefix, *length, 0, 0))) { LM_ERR("cannot add the child node to the tree\n"); @@ -1004,7 +1004,7 @@ static struct mi_root *check_list_mi(struct mi_root *cmd, int list_type) } lock_release(lock); - /* Create new node and add it to the reply roots's kids */ + /* Create new node and add it to the reply roots' kids */ if(!(crt_node = add_mi_node_child( &tmp->node, MI_DUP_NAME, prefix.s, prefix.len, 0, 0))) { LM_ERR("cannot add the child node to the tree\n"); @@ -1150,7 +1150,7 @@ static struct mi_root *check_userlist_mi(struct mi_root *cmd, int list_type) } - /* Create new node and add it to the reply roots's kids */ + /* Create new node and add it to the reply roots' kids */ if(!(crt_node = add_mi_node_child( &tmp->node, MI_DUP_NAME, prefix.s, prefix.len, 0, 0))) { LM_ERR("cannot add the child node to the tree\n"); diff --git a/src/modules/usrloc/README b/src/modules/usrloc/README index 2eedbf74d..f4e10e873 100644 --- a/src/modules/usrloc/README +++ b/src/modules/usrloc/README @@ -95,10 +95,13 @@ Carsten Bock 3.53. ka_domain (str) 3.54. ka_filter (int) 3.55. ka_timeout (int) - 3.56. ka_loglevel (int) - 3.57. ka_logmsg (str) - 3.58. load_rank (int) - 3.59. db_clean_tcp (int) + 3.56. ka_interval (int) + 3.57. ka_randomize (int) + 3.58. ka_loglevel (int) + 3.59. ka_logmsg (str) + 3.60. ka_reply_codes (str) + 3.61. load_rank (int) + 3.62. db_clean_tcp (int) 4. RPC Commands @@ -201,10 +204,13 @@ Carsten Bock 1.53. ka_domain parameter usage 1.54. ka_filter parameter usage 1.55. Set ka_timeout parameter - 1.56. ka_loglevel parameter usage - 1.57. ka_logmsg parameter usage - 1.58. load_rank parameter usage - 1.59. db_clean_tcp parameter usage + 1.56. Set ka_interval parameter + 1.57. Set ka_randomize parameter + 1.58. ka_loglevel parameter usage + 1.59. ka_logmsg parameter usage + 1.60. ka_reply_codes parameter usage + 1.61. load_rank parameter usage + 1.62. db_clean_tcp parameter usage Chapter 1. Admin Guide @@ -276,10 +282,13 @@ Chapter 1. Admin Guide 3.53. ka_domain (str) 3.54. ka_filter (int) 3.55. ka_timeout (int) - 3.56. ka_loglevel (int) - 3.57. ka_logmsg (str) - 3.58. load_rank (int) - 3.59. db_clean_tcp (int) + 3.56. ka_interval (int) + 3.57. ka_randomize (int) + 3.58. ka_loglevel (int) + 3.59. ka_logmsg (str) + 3.60. ka_reply_codes (str) + 3.61. load_rank (int) + 3.62. db_clean_tcp (int) 4. RPC Commands @@ -414,10 +423,13 @@ Chapter 1. Admin Guide 3.53. ka_domain (str) 3.54. ka_filter (int) 3.55. ka_timeout (int) - 3.56. ka_loglevel (int) - 3.57. ka_logmsg (str) - 3.58. load_rank (int) - 3.59. db_clean_tcp (int) + 3.56. ka_interval (int) + 3.57. ka_randomize (int) + 3.58. ka_loglevel (int) + 3.59. ka_logmsg (str) + 3.60. ka_reply_codes (str) + 3.61. load_rank (int) + 3.62. db_clean_tcp (int) 3.1. nat_bflag (int) @@ -1199,19 +1211,47 @@ modparam("usrloc", "ka_filter", 1) modparam("usrloc", "ka_timeout", 120) ... -3.56. ka_loglevel (int) +3.56. ka_interval (int) + + The parameter sets the interval in seconds after which a new keepalive + request should be sent for a location record. + + Default value is “40”. + + Example 1.56. Set ka_interval parameter +... +modparam("usrloc", "ka_interval", 30) +... + +3.57. ka_randomize (int) + + The parameter sets the the upper limit to the range of random seconds + to be added to ka_interval before checking if a new keepalive request + has to be sent. It should help to distribute better the sending of + keepalive requests. The keepalive for a location record is going to be + sent in a random fashion between (ka_interval + 0) and (ka_interval + + ka_randomize). + + Default value is “20”. + + Example 1.57. Set ka_randomize parameter +... +modparam("usrloc", "ka_interval", 30) +... + +3.58. 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.56. ka_loglevel parameter usage + Example 1.58. ka_loglevel parameter usage ... modparam("usrloc", "ka_loglevel", 1) ... -3.57. ka_logmsg (str) +3.59. 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 @@ -1223,24 +1263,40 @@ modparam("usrloc", "ka_loglevel", 1) Default value is “ to-uri: [$tu] remote-addr: [$sas]”. - Example 1.57. ka_logmsg parameter usage + Example 1.59. ka_logmsg parameter usage ... modparam("usrloc", "ka_logmsg", " to-uri: [$tu] remote-addr: [$sas]") ... -3.58. load_rank (int) +3.60. ka_reply_codes (str) + + Comma separated list of reply code values or reply code classes to be + considered valid for keepalive processing. If the reply code does not + match any of them, then the reply is ignored, not considered a valid + response to keepalive request. It could be useful to skip replies from + intermediary proxies that could not forward the request. + + Default value is “0” (checking of reply code is not done, are responses + are considered valid). + + Example 1.60. ka_reply_codes parameter usage +... +modparam("usrloc", "ka_reply_codes", "2,405,486") +... + +3.61. load_rank (int) Allows to set the rank of the child SIP worker to load the location records. Default value is “1” (PROC_SIPINIT). - Example 1.58. load_rank parameter usage + Example 1.61. load_rank parameter usage ... modparam("usrloc", "load_rank", 1) ... -3.59. db_clean_tcp (int) +3.62. db_clean_tcp (int) If set to 1, when Kamailio starts it removes the contacts with transport TCP, TLS or WSS, no longer loading them. Useful when end @@ -1251,7 +1307,7 @@ modparam("usrloc", "load_rank", 1) Default value is “0” (do not clean tcp contacts). - Example 1.59. db_clean_tcp parameter usage + Example 1.62. db_clean_tcp parameter usage ... modparam("usrloc", "db_clean_tcp", 1) ... @@ -1305,7 +1361,9 @@ modparam("usrloc", "db_clean_tcp", 1) 4.5. ul.flush - Triggers the flush of USRLOC memory cache into DB. + Triggers the flush of USRLOC memory cache into DB from the RPC process. + It succeeds only if the the db_mode is set to a value that enables + connectivity to database. 4.6. ul.add diff --git a/src/modules/usrloc/doc/usrloc_admin.xml b/src/modules/usrloc/doc/usrloc_admin.xml index 0e0f086ac..d7d78ae7b 100644 --- a/src/modules/usrloc/doc/usrloc_admin.xml +++ b/src/modules/usrloc/doc/usrloc_admin.xml @@ -1460,6 +1460,52 @@ modparam("usrloc", "ka_timeout", 120)
+
+ <varname>ka_interval</varname> (int) + + The parameter sets the interval in seconds after which a new keepalive + request should be sent for a location record. + + + + Default value is 40. + + + + Set <varname>ka_interval</varname> parameter + +... +modparam("usrloc", "ka_interval", 30) +... + + +
+ +
+ <varname>ka_randomize</varname> (int) + + The parameter sets the the upper limit to the range of random seconds + to be added to ka_interval before checking if a new keepalive request + has to be sent. It should help to distribute better the sending of + keepalive requests. The keepalive for a location record is going to be + sent in a random fashion between (ka_interval + 0) and + (ka_interval + ka_randomize). + + + + Default value is 20. + + + + Set <varname>ka_randomize</varname> parameter + +... +modparam("usrloc", "ka_interval", 30) +... + + +
+
<varname>ka_loglevel</varname> (int) @@ -1504,6 +1550,29 @@ modparam("usrloc", "ka_logmsg", " to-uri: [$tu] remote-addr: [$sas]")
+
+ <varname>ka_reply_codes</varname> (str) + + Comma separated list of reply code values or reply code classes to be + considered valid for keepalive processing. If the reply code does not + match any of them, then the reply is ignored, not considered a valid + response to keepalive request. It could be useful to skip replies + from intermediary proxies that could not forward the request. + + + Default value is 0 (checking of reply code is not done, + are responses are considered valid). + + + <varname>ka_reply_codes</varname> parameter usage + +... +modparam("usrloc", "ka_reply_codes", "2,405,486") +... + + +
+
<varname>load_rank</varname> (int) @@ -1633,7 +1702,9 @@ modparam("usrloc", "db_clean_tcp", 1) ul.flush - Triggers the flush of USRLOC memory cache into DB. + Triggers the flush of USRLOC memory cache into DB from the RPC process. It + succeeds only if the the db_mode is set to a value that enables connectivity + to database.
diff --git a/src/modules/usrloc/ucontact.c b/src/modules/usrloc/ucontact.c index ee3a1ce2c..f95fe987d 100644 --- a/src/modules/usrloc/ucontact.c +++ b/src/modules/usrloc/ucontact.c @@ -50,10 +50,10 @@ void ul_set_xavp_contact_clone(int v) } /*! - * \brief Store xavp list per contact + * \brief Store xavp list per contact from core, update existing contact as well * \param _c contact structure */ -void ucontact_xavp_store(ucontact_t *_c) +static void ucontact_xavp_store(ucontact_t *_c) { sr_xavp_t *xavp; if(_c == NULL) @@ -62,12 +62,15 @@ void ucontact_xavp_store(ucontact_t *_c) return; if(ul_xavp_contact_name.s == NULL) return; - /* remove old list if it is set -- update case */ - if(_c->xavp) - xavp_destroy_list(&_c->xavp); + /* XAVP from core */ xavp = xavp_get(&ul_xavp_contact_name, NULL); - if(xavp == NULL) + if(xavp == NULL) { return; + } + /* remove old xavp if it is set -- update case */ + if(_c->xavp) { + xavp_destroy_list(&_c->xavp); + } /* clone the xavp found in core */ LM_DBG("trying to clone per contact xavps\n"); _c->xavp = xavp_clone_level_nodata(xavp); @@ -124,6 +127,15 @@ ucontact_t *new_ucontact( if(shm_str_dup(&c->instance, &_ci->instance) < 0) goto error; } + /* we got a xavp from e.g. DMQ */ + if(_ci->xavp) { + /* destroy the existing contact xavp */ + if(c->xavp) { + xavp_destroy_list(&c->xavp); + } + /* clone the DMQ xavp because it will be destroyed */ + c->xavp = xavp_clone_level_nodata(_ci->xavp); + } c->domain = _dom; c->aor = _aor; @@ -141,6 +153,8 @@ ucontact_t *new_ucontact( c->tcpconn_id = _ci->tcpconn_id; c->server_id = _ci->server_id; c->keepalive = (_ci->cflags & ul_nat_bflag) ? 1 : 0; + + /* Use core xavp if set, otherwise does nothing */ ucontact_xavp_store(c); @@ -317,6 +331,16 @@ int mem_update_ucontact(ucontact_t *_c, ucontact_info_t *_ci) _c->path.len = 0; } + /* we got a xavp from e.g. DMQ */ + if(_ci->xavp) { + /* destroy the existing contact xavp */ + if(_c->xavp) { + xavp_destroy_list(&_c->xavp); + } + /* clone the DMQ xavp because it will be destroyed */ + _c->xavp = xavp_clone_level_nodata(_ci->xavp); + } + /* Use core xavp if set, otherwise does nothing */ ucontact_xavp_store(_c); _c->sock = _ci->sock; @@ -1028,6 +1052,11 @@ int db_update_ucontact_ruid(ucontact_t *_c) return -1; } + if(ul_dbh == NULL) { + LM_ERR("database connection handle not initialized\n"); + return -1; + } + n1 = 0; keys1[n1] = &ul_ruid_col; vals1[n1].type = DB1_STR; diff --git a/src/modules/usrloc/udomain.c b/src/modules/usrloc/udomain.c index 0c1296bf1..43278fca0 100644 --- a/src/modules/usrloc/udomain.c +++ b/src/modules/usrloc/udomain.c @@ -221,7 +221,7 @@ void print_udomain(FILE *_f, udomain_t *_d) * \brief Convert database values into ucontact_info * * Convert database values into ucontact_info, - * expects 12 rows (contact, expirs, q, callid, cseq, flags, + * expects 12 rows (contact, expires, q, callid, cseq, flags, * ua, received, path, socket, methods, last_modified) * \param vals database values * \param contact contact @@ -1071,7 +1071,7 @@ int udomain_contact_expired_cb(db1_con_t *_c, udomain_t *_d) continue; } user.len = strlen(user.s); - if(user.len < AORBUF_SIZE) { + if(user.len + 1 < AORBUF_SIZE) { memcpy(aorbuf, user.s, user.len); aor.s = aorbuf; aor.len = user.len; @@ -1090,7 +1090,7 @@ int udomain_contact_expired_cb(db1_con_t *_c, udomain_t *_d) if(ul_use_domain) { domain.s = (char *)VAL_STRING(ROW_VALUES(row) + 20); domain.len = strlen(domain.s); - if(domain.len + aor.len < AORBUF_SIZE) { + if(domain.len + aor.len + 2 < AORBUF_SIZE) { aorbuf[aor.len] = '@'; memcpy(aorbuf + aor.len + 1, domain.s, domain.len); aor.len += domain.len + 1; diff --git a/src/modules/usrloc/ul_keepalive.c b/src/modules/usrloc/ul_keepalive.c index 9897233ea..e5a013b45 100644 --- a/src/modules/usrloc/ul_keepalive.c +++ b/src/modules/usrloc/ul_keepalive.c @@ -43,6 +43,8 @@ #include "ul_keepalive.h" extern int ul_keepalive_timeout; +extern int ul_ka_interval; +extern int ul_ka_randomize; static int ul_ka_send(str *kamsg, dest_info_t *kadst); @@ -109,6 +111,7 @@ int ul_ka_urecord(urecord_t *ur) int i; struct timeval tv; time_t tnow = 0; + int ka_limit = 0; if(ul_ka_mode == ULKA_NONE) { return 0; @@ -159,6 +162,13 @@ int ul_ka_urecord(urecord_t *ur) } } } + if(ul_ka_interval > 0 && uc->last_keepalive > 0) { + ka_limit = ul_ka_interval + (fastrand() % ul_ka_randomize); + if((uc->last_keepalive + ka_limit) > tnow) { + /* not yet the time for keepalive */ + continue; + } + } if(uc->received.len > 0) { sdst = uc->received; } else { @@ -315,6 +325,47 @@ unsigned long ul_ka_fromhex(str *shex, int *err) return v; } +/** + * + */ +#define UL_KA_REPLY_CODES_SIZE 32 +static int _ul_ka_reply_codes[UL_KA_REPLY_CODES_SIZE] = {0}; + +/** + * + */ +int ul_ka_parse_reply_codes(char *vcodes) +{ + int nb = 0; + char *p; + char *e; + + _ul_ka_reply_codes[0] = 0; + if(vcodes == NULL || strlen(vcodes) == 0) { + LM_ERR("invalid parameter\n"); + return -1; + } + p = vcodes; + while(nb < UL_KA_REPLY_CODES_SIZE && *p) { + _ul_ka_reply_codes[nb] = strtol(p, &e, 10); + if(_ul_ka_reply_codes[nb] > 0) { + nb++; + } else { + _ul_ka_reply_codes[nb] = 0; + } + while(*e == ',' || *e == ' ') { + e++; + } + p = e; + } + if(nb == UL_KA_REPLY_CODES_SIZE) { + LM_ERR("exceeded maximum number of reply code rules\n"); + return -1; + } + _ul_ka_reply_codes[nb] = 0; + return 0; +} + /** * */ @@ -329,6 +380,7 @@ int ul_ka_reply_received(sip_msg_t *msg) struct timeval tvm; struct timeval tvn; unsigned int tvdiff; + int i; if(msg->cseq == NULL) { if((parse_headers(msg, HDR_CSEQ_F, 0) == -1) || (msg->cseq == NULL)) { @@ -345,6 +397,19 @@ int ul_ka_reply_received(sip_msg_t *msg) return 1; } + for(i = 0; _ul_ka_reply_codes[i] != 0; i++) { + if(_ul_ka_reply_codes[i] == msg->first_line.u.reply.statuscode + || _ul_ka_reply_codes[i] + == (msg->first_line.u.reply.statuscode / 100)) { + break; + } + } + + if(i > 0 && _ul_ka_reply_codes[i] == 0) { + /* no match of status code */ + return 1; + } + /* there must be no second via */ if(!(parse_headers(msg, HDR_VIA2_F, 0) == -1 || (msg->via2 == 0) || (msg->via2->error != PARSE_OK))) { diff --git a/src/modules/usrloc/ul_keepalive.h b/src/modules/usrloc/ul_keepalive.h index b807d392c..8e5e684b3 100644 --- a/src/modules/usrloc/ul_keepalive.h +++ b/src/modules/usrloc/ul_keepalive.h @@ -35,5 +35,6 @@ int ul_ka_urecord(urecord_t *ur); int ul_ka_reply_received(sip_msg_t *msg); +int ul_ka_parse_reply_codes(char *vcodes); -#endif \ No newline at end of file +#endif diff --git a/src/modules/usrloc/usrloc_mod.c b/src/modules/usrloc/usrloc_mod.c index 16a48e44a..b14fe7273 100644 --- a/src/modules/usrloc/usrloc_mod.c +++ b/src/modules/usrloc/usrloc_mod.c @@ -127,6 +127,8 @@ str ul_ka_domain = str_init("kamailio.org"); str ul_ka_method = str_init("OPTIONS"); int ul_ka_mode = 0; int ul_ka_filter = 0; +int ul_ka_interval = 40; +int ul_ka_randomize = 20; int ul_ka_loglevel = 255; str ul_ka_logmsg = str_init(" to-uri: [$tu] remote-addr: [$sas]"); pv_elem_t *ul_ka_logfmt = NULL; @@ -220,6 +222,8 @@ int ul_hash_size = 10; int ul_db_insert_null = 0; int ul_db_timer_clean = 0; +char *ul_ka_reply_codes_str = "0"; + /* flags */ unsigned int ul_nat_bflag = (unsigned int)-1; unsigned int ul_init_flag = 0; @@ -298,9 +302,12 @@ 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_interval", PARAM_INT, &ul_ka_interval}, + {"ka_randomize", PARAM_INT, &ul_ka_randomize}, {"ka_timeout", PARAM_INT, &ul_keepalive_timeout}, {"ka_loglevel", PARAM_INT, &ul_ka_loglevel}, {"ka_logmsg", PARAM_STR, &ul_ka_logmsg}, + {"ka_reply_codes", PARAM_STRING, &ul_ka_reply_codes_str}, {"load_rank", PARAM_INT, &ul_load_rank}, {"db_clean_tcp", PARAM_INT, &ul_db_clean_tcp}, {0, 0, 0} @@ -335,6 +342,9 @@ static int mod_init(void) int i; udomain_t *d; + if(ul_ka_parse_reply_codes(ul_ka_reply_codes_str)) { + return -1; + } if(ul_rm_expired_delay != 0) { if(ul_db_mode != DB_ONLY) { LM_ERR("rm expired delay feature is available for db only mode\n"); diff --git a/src/modules/utils/conf.c b/src/modules/utils/conf.c index dc79a6bd2..d4e95a98b 100644 --- a/src/modules/utils/conf.c +++ b/src/modules/utils/conf.c @@ -284,7 +284,7 @@ static int update_proxy(int id, char *host_str, char *port_str) free_shm_proxy(fwd_settings[id].proxy); shm_free(fwd_settings[id].proxy); } - fwd_settings[id].proxy = proxy; /* new proxy is now acitvated */ + fwd_settings[id].proxy = proxy; /* new proxy is now activated */ return 0; } diff --git a/src/modules/xcap_client/xcap_client.c b/src/modules/xcap_client/xcap_client.c index ac77228bf..4de2d367b 100644 --- a/src/modules/xcap_client/xcap_client.c +++ b/src/modules/xcap_client/xcap_client.c @@ -41,6 +41,9 @@ #include "../../core/mem/shm_mem.h" #include "../../core/rpc.h" #include "../../core/rpc_lookup.h" +#define KSR_RTHREAD_NEED_4L +#define KSR_RTHREAD_SKIP_P +#include "../../core/rthreads.h" #include "../presence/utils_func.h" #include "xcap_functions.h" #include "xcap_client.h" @@ -140,7 +143,7 @@ static int mod_init(void) xcap_dbf.close(xcap_db); xcap_db = NULL; - curl_global_init(CURL_GLOBAL_ALL); + run_thread4L((_thread_proto4L)curl_global_init, CURL_GLOBAL_ALL); if(periodical_query) { register_timer(query_xcap_update, 0, query_period); diff --git a/src/modules/xhttp/xhttp_mod.c b/src/modules/xhttp/xhttp_mod.c index 0660d409a..af27baffa 100644 --- a/src/modules/xhttp/xhttp_mod.c +++ b/src/modules/xhttp/xhttp_mod.c @@ -65,7 +65,7 @@ static char *xhttp_url_skip = NULL; static regex_t xhttp_url_skip_regexp; /** SL API structure */ -sl_api_t slb; +static sl_api_t _xhttp_slb; static str xhttp_event_callback = STR_NULL; @@ -149,7 +149,7 @@ static int mod_init(void) } /* bind the SL API */ - if(sl_load_api(&slb) != 0) { + if(sl_load_api(&_xhttp_slb) != 0) { LM_ERR("cannot bind to SL API\n"); return -1; } @@ -424,7 +424,7 @@ static int xhttp_send_reply( 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(_xhttp_slb.sreply(msg, code, reason) < 0) { LM_ERR("Error while sending reply\n"); return -1; } diff --git a/src/modules/xhttp_prom/xhttp_prom.c b/src/modules/xhttp_prom/xhttp_prom.c index 198fea7d0..ee5a5520f 100644 --- a/src/modules/xhttp_prom/xhttp_prom.c +++ b/src/modules/xhttp_prom/xhttp_prom.c @@ -114,7 +114,7 @@ int prom_histogram_param(modparam_t type, void *val); * being currently processed. * @sa prom_ctx */ -static prom_ctx_t ctx; +static prom_ctx_t _prom_ctx; static xhttp_api_t xhttp_api; @@ -251,6 +251,8 @@ static int mod_init(void) if(buf_size == 0) buf_size = pkg_mem_size / 3; + memset(&_prom_ctx, 0, sizeof(prom_ctx_t)); + /* Initialize Prometheus metrics. */ if(prom_metric_init()) { LM_ERR("Cannot initialize Prometheus metrics\n"); @@ -441,22 +443,22 @@ static int ki_xhttp_prom_dispatch(sip_msg_t *msg) } /* Init xhttp_prom context */ - if(ctx.reply.buf.s) { - LM_ERR("Unexpected buf value [%p][%d]\n", ctx.reply.buf.s, - ctx.reply.buf.len); + if(_prom_ctx.reply.buf.s) { + LM_ERR("Unexpected buf value [%p][%d]\n", _prom_ctx.reply.buf.s, + _prom_ctx.reply.buf.len); /* Something happened and this memory was not freed. */ - xhttp_prom_reply_free(&ctx); + xhttp_prom_reply_free(&_prom_ctx); } - memset(&ctx, 0, sizeof(prom_ctx_t)); - ctx.msg = msg; - if(init_xhttp_prom_reply(&ctx) < 0) { + memset(&_prom_ctx, 0, sizeof(prom_ctx_t)); + _prom_ctx.msg = msg; + if(init_xhttp_prom_reply(&_prom_ctx) < 0) { goto send_reply; } send_reply: - if(!ctx.reply_sent) { - ret = prom_send(&ctx); + if(!_prom_ctx.reply_sent) { + ret = prom_send(&_prom_ctx); } if(ret < 0) { return -1; @@ -2317,18 +2319,18 @@ static void rpc_prom_histogram_observe(rpc_t *rpc, void *ct) static void rpc_prom_metric_list_print(rpc_t *rpc, void *ct) { /* We reuse ctx->reply for the occasion. */ - if(init_xhttp_prom_reply(&ctx) < 0) { + if(init_xhttp_prom_reply(&_prom_ctx) < 0) { goto clean; } - if(prom_metric_list_print(&ctx)) { + if(prom_metric_list_print(&_prom_ctx)) { LM_ERR("Cannot print a list of metrics\n"); goto clean; } /* Convert to zero terminated string. */ struct xhttp_prom_reply *reply; - reply = &(ctx.reply); + reply = &(_prom_ctx.reply); reply->body.s[reply->body.len] = '\0'; /* Print content of reply buffer. */ @@ -2339,7 +2341,7 @@ static void rpc_prom_metric_list_print(rpc_t *rpc, void *ct) clean: - xhttp_prom_reply_free(&ctx); + xhttp_prom_reply_free(&_prom_ctx); return; } diff --git a/src/modules/xhttp_rpc/xhttp_rpc.c b/src/modules/xhttp_rpc/xhttp_rpc.c index 1e305a919..3b43469fd 100644 --- a/src/modules/xhttp_rpc/xhttp_rpc.c +++ b/src/modules/xhttp_rpc/xhttp_rpc.c @@ -72,7 +72,7 @@ static int xhttp_rpc_dispatch(sip_msg_t *msg, char *s1, char *s2); * being currently processed. * @sa rpc_ctx */ -static rpc_ctx_t ctx; +static rpc_ctx_t _xhttp_rpc_ctx; static xhttp_api_t xhttp_api; @@ -841,64 +841,65 @@ static int ki_xhttp_rpc_dispatch(sip_msg_t *msg) } /* Init xhttp_rpc context */ - if(ctx.reply.buf.s) - LM_ERR("Unexpected buf value [%p][%d]\n", ctx.reply.buf.s, - ctx.reply.buf.len); - memset(&ctx, 0, sizeof(rpc_ctx_t)); - ctx.msg = msg; - ctx.mod = ctx.cmd = -1; - if(init_xhttp_rpc_reply(&ctx) < 0) + if(_xhttp_rpc_ctx.reply.buf.s) + LM_ERR("Unexpected buf value [%p][%d]\n", _xhttp_rpc_ctx.reply.buf.s, + _xhttp_rpc_ctx.reply.buf.len); + memset(&_xhttp_rpc_ctx, 0, sizeof(rpc_ctx_t)); + _xhttp_rpc_ctx.msg = msg; + _xhttp_rpc_ctx.mod = _xhttp_rpc_ctx.cmd = -1; + if(init_xhttp_rpc_reply(&_xhttp_rpc_ctx) < 0) goto send_reply; /* Extract arguments from url */ if(0 - != xhttp_rpc_parse_url( - &msg->first_line.u.request.uri, &ctx.mod, &ctx.cmd, &arg)) { - rpc_fault(&ctx, 500, "Bad URL"); + != xhttp_rpc_parse_url(&msg->first_line.u.request.uri, + &_xhttp_rpc_ctx.mod, &_xhttp_rpc_ctx.cmd, &arg)) { + rpc_fault(&_xhttp_rpc_ctx, 500, "Bad URL"); goto send_reply; } if(arg.s) { if(arg.len) { /* Unescape args */ - ctx.arg.s = pkg_malloc((arg.len + 1) * sizeof(char)); - if(ctx.arg.s == NULL) { + _xhttp_rpc_ctx.arg.s = pkg_malloc((arg.len + 1) * sizeof(char)); + if(_xhttp_rpc_ctx.arg.s == NULL) { PKG_MEM_ERROR; - rpc_fault(&ctx, 500, "Internal Server Error (oom)"); + rpc_fault(&_xhttp_rpc_ctx, 500, "Internal Server Error (oom)"); goto send_reply; } for(i = 0; i < arg.len; i++) if(arg.s[i] == '+') arg.s[i] = ' '; - if(0 > un_escape(&arg, &ctx.arg)) { + if(0 > un_escape(&arg, &_xhttp_rpc_ctx.arg)) { LM_ERR("unable to escape [%.*s]\n", arg.len, arg.s); - rpc_fault(&ctx, 500, "Bad arg in URL"); + rpc_fault(&_xhttp_rpc_ctx, 500, "Bad arg in URL"); goto send_reply; } - ctx.arg.s[ctx.arg.len] = '\0'; - ctx.arg.len++; - ctx.arg2scan = ctx.arg; + _xhttp_rpc_ctx.arg.s[_xhttp_rpc_ctx.arg.len] = '\0'; + _xhttp_rpc_ctx.arg.len++; + _xhttp_rpc_ctx.arg2scan = _xhttp_rpc_ctx.arg; } - ctx.arg_received = 1; + _xhttp_rpc_ctx.arg_received = 1; } else { goto send_reply; } /* - rpc_e=find_rpc_export((char*)rpc_sarray[xhttp_rpc_mod_cmds[ctx.mod].rpc_e_index+ctx.cmd]->name, 0); + rpc_e=find_rpc_export((char*)rpc_sarray[xhttp_rpc_mod_cmds[_xhttp_rpc_ctx.mod].rpc_e_index+_xhttp_rpc_ctx.cmd]->name, 0); if ((rpc_e==NULL) || (rpc_e->function==NULL)){ LM_ERR("Unable to find rpc command [%s]\n", - rpc_sarray[xhttp_rpc_mod_cmds[ctx.mod].rpc_e_index+ctx.cmd]->name); - rpc_fault(&ctx, 500, "Method not found"); + rpc_sarray[xhttp_rpc_mod_cmds[_xhttp_rpc_ctx.mod].rpc_e_index+_xhttp_rpc_ctx.cmd]->name); + rpc_fault(&_xhttp_rpc_ctx, 500, "Method not found"); goto send_reply; } */ - rpc_e = rpc_sarray[xhttp_rpc_mod_cmds[ctx.mod].rpc_e_index + ctx.cmd]; - rpc_e->r.function(&func_param, &ctx); + rpc_e = rpc_sarray[xhttp_rpc_mod_cmds[_xhttp_rpc_ctx.mod].rpc_e_index + + _xhttp_rpc_ctx.cmd]; + rpc_e->r.function(&func_param, &_xhttp_rpc_ctx); send_reply: - if(!ctx.reply_sent) { - ret = rpc_send(&ctx); + if(!_xhttp_rpc_ctx.reply_sent) { + ret = rpc_send(&_xhttp_rpc_ctx); } if(ret < 0) return -1; diff --git a/src/modules/xlog/xlog.c b/src/modules/xlog/xlog.c index 03063bbfb..c7d239ea2 100644 --- a/src/modules/xlog/xlog.c +++ b/src/modules/xlog/xlog.c @@ -878,8 +878,9 @@ error: /** * write message after evaluation of lmsg for pseudo-variables */ -int ki_xlog_ex(sip_msg_t *msg, int llevel, str *lmsg) +int ki_xlog_ex(sip_msg_t *msg, str *lfacility, int llevel, str *lmsg) { + int lf = xlog_facility; pv_elem_t *xmodel = NULL; str txt = {0, 0}; @@ -896,13 +897,23 @@ int ki_xlog_ex(sip_msg_t *msg, int llevel, str *lmsg) pv_elem_free_all(xmodel); return -1; } - LOG_FN(xlog_facility, llevel, _xlog_prefix, "%.*s", txt.len, txt.s); + + if(lfacility != NULL) { + lfacility->s[lfacility->len] = '\0'; + lf = str2facility(lfacility->s); + if(lf == -1) { + LM_WARN("invalid syslog facility %.*s, using default\n", + lfacility->len, lfacility->s); + lf = xlog_facility; + } + } + LOG_FN(lf, llevel, _xlog_prefix, "%.*s", txt.len, txt.s); ; pv_elem_free_all(xmodel); return 1; } -int ki_xlog(sip_msg_t *msg, str *slevel, str *lmsg) +int ki_xlog_get_level(str *slevel) { int llevel; @@ -927,42 +938,55 @@ int ki_xlog(sip_msg_t *msg, str *slevel, str *lmsg) } else { llevel = L_ERR; } - return ki_xlog_ex(msg, llevel, lmsg); + + return llevel; +} + +int ki_xlog_facility(sip_msg_t *msg, str *lfacility, str *slevel, str *lmsg) +{ + int llevel = ki_xlog_get_level(slevel); + return ki_xlog_ex(msg, lfacility, llevel, lmsg); +} + +int ki_xlog(sip_msg_t *msg, str *slevel, str *lmsg) +{ + int llevel = ki_xlog_get_level(slevel); + return ki_xlog_ex(msg, NULL, llevel, lmsg); } int ki_xdbg(sip_msg_t *msg, str *lmsg) { - return ki_xlog_ex(msg, L_DBG, lmsg); + return ki_xlog_ex(msg, NULL, L_DBG, lmsg); } int ki_xerr(sip_msg_t *msg, str *lmsg) { - return ki_xlog_ex(msg, L_ERR, lmsg); + return ki_xlog_ex(msg, NULL, L_ERR, lmsg); } int ki_xinfo(sip_msg_t *msg, str *lmsg) { - return ki_xlog_ex(msg, L_INFO, lmsg); + return ki_xlog_ex(msg, NULL, L_INFO, lmsg); } int ki_xnotice(sip_msg_t *msg, str *lmsg) { - return ki_xlog_ex(msg, L_NOTICE, lmsg); + return ki_xlog_ex(msg, NULL, L_NOTICE, lmsg); } int ki_xwarn(sip_msg_t *msg, str *lmsg) { - return ki_xlog_ex(msg, L_WARN, lmsg); + return ki_xlog_ex(msg, NULL, L_WARN, lmsg); } int ki_xalert(sip_msg_t *msg, str *lmsg) { - return ki_xlog_ex(msg, L_ALERT, lmsg); + return ki_xlog_ex(msg, NULL, L_ALERT, lmsg); } int ki_xcrit(sip_msg_t *msg, str *lmsg) { - return ki_xlog_ex(msg, L_CRIT, lmsg); + return ki_xlog_ex(msg, NULL, L_CRIT, lmsg); } /** @@ -1010,6 +1034,11 @@ static sr_kemi_t sr_kemi_xlog_exports[] = { { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, + { str_init("xlog"), str_init("xlog_facility"), + SR_KEMIP_INT, ki_xlog_facility, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } } }; diff --git a/utils/db_berkeley/kambdb_recover.c b/utils/db_berkeley/kambdb_recover.c index 2555299b3..46987248a 100644 --- a/utils/db_berkeley/kambdb_recover.c +++ b/utils/db_berkeley/kambdb_recover.c @@ -29,54 +29,55 @@ #include "kambdb_recover.h" tbl_cache_p tables; -char *schema_dir = NULL; -char *db_home = NULL; +char* schema_dir = NULL; +char* db_home = NULL; const char *progname; /** * main -- */ -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { int ret, ch, i; ret = 0; progname = argv[0]; - while((ch = getopt(argc, argv, "s:h:c:C:r:R:")) != EOF) - switch(ch) { - case 's': - schema_dir = optarg; - load_schema(optarg); - break; + while ((ch = getopt(argc, argv, "s:h:c:C:r:R:")) != EOF) + switch (ch) + { + case 's': + schema_dir = optarg; + load_schema(optarg); + break; - case 'c': /*create */ - ret = create(optarg); - break; + case 'c': /*create */ + ret = create(optarg); + break; - case 'C': /*Create all*/ - ret = create_all(); - break; + case 'C': /*Create all*/ + ret = create_all(); + break; - case 'r': /*recover */ - ret = recover(optarg); - break; + case 'r': /*recover */ + ret = recover(optarg); + break; - case 'R': /*recover_all */ - ret = sscanf(optarg, "%i", &i); - if(ret != 1) - return -1; - ret = recover_all(i); - break; + case 'R': /*recover_all */ + ret = sscanf(optarg,"%i", &i); + if(ret != 1) return -1; + ret = recover_all(i); + break; - case 'h': - db_home = optarg; - break; + case 'h': + db_home = optarg; + break; - case '?': - default: - return (usage()); - } + case '?': + default: + return(usage()); + + } argc -= optind; argv += optind; @@ -95,16 +96,16 @@ int main(int argc, char *argv[]) int usage(void) { fprintf(stderr, "usage: %s %s\n", progname, - "-s schemadir [-h home] [-c tablename]"); + "-s schemadir [-h home] [-c tablename]"); fprintf(stderr, "usage: %s %s\n", progname, - "-s schemadir [-h home] [-C all]"); + "-s schemadir [-h home] [-C all]"); fprintf(stderr, "usage: %s %s\n", progname, - "-s schemadir [-h home] [-r journal-file]"); + "-s schemadir [-h home] [-r journal-file]"); fprintf(stderr, "usage: %s %s\n", progname, - "-s schemadir [-h home] [-R lastN]"); + "-s schemadir [-h home] [-R lastN]"); return (EXIT_FAILURE); } @@ -115,28 +116,31 @@ int usage(void) * the needed metadata. * requires the schema data to be already parsed '-L' option. */ -int create(char *tn) +int create(char* tn) { - DB *db; + DB* db; int rc; tbl_cache_p tbc = NULL; table_p tp = NULL; rc = 0; tbc = get_table(tn); - if(!tbc) { - fprintf(stderr, "[create] Table %s is not supported.\n", tn); + if(!tbc) + { fprintf(stderr, "[create] Table %s is not supported.\n",tn); return 1; } - tp = tbc->dtp; + tp = tbc->dtp; db = get_db(tp); - if(db) { - printf("Created table %s\n", tn); + if(db) + { + printf("Created table %s\n",tn); rc = 0; - } else { - fprintf(stderr, "[create] Failed to create table %s\n", tn); + } + else + { + fprintf(stderr, "[create] Failed to create table %s\n",tn); rc = 1; } @@ -158,9 +162,10 @@ int create_all(void) time_t tim2; #endif - while(_tbc) { + while(_tbc) + { if(_tbc->dtp) - if((rc = create(_tbc->dtp->name)) != 0) + if((rc = create(_tbc->dtp->name)) != 0 ) break; _tbc = _tbc->next; } @@ -179,14 +184,14 @@ int create_all(void) * file_list -- * returns a sorted linkedlist of all files in d * - * parmameter d is the directory name + * parameter d is the directory name * parameter tn is optional, * if tablename (tn) is specified returns only jnl files for tablename (tn) * else returns a sorted linkedlist of all files in d * returns lnode_p * the head linknode points to the latests file. */ -lnode_p file_list(char *d, char *tn) +lnode_p file_list(char* d, char* tn) { DIR *dirp; int i, j, len; @@ -194,12 +199,13 @@ lnode_p file_list(char *d, char *tn) char *list[MAXFILES]; char dir[MAX_FILENAME_SIZE]; struct dirent *dp; - lnode_p h, n; + lnode_p h,n; h = n = NULL; i = j = 0; - if(!d) { + if(!d) + { fprintf(stderr, "[file_list]: null path to schema files.\n"); return NULL; } @@ -210,43 +216,41 @@ lnode_p file_list(char *d, char *tn) //strcat(dir, "."); dirp = opendir(dir); - while((dp = readdir(dirp)) != NULL) { - j = 0; - if(i > (MAXFILES - 1)) - continue; - - fn = dp->d_name; - - if(fn[0] == '.') - continue; - - if(tn) { - /* only looking for jnl files */ - len = strlen(tn); - if(!strstr(fn, ".jnl")) - continue; - if(strncmp(fn, tn, len)) - continue; - } - - j = strlen(fn) + 1; - list[i] = malloc(sizeof(char) * j); - memset(list[i], 0, j); - strcat(list[i], fn); - i++; + while ((dp = readdir(dirp)) != NULL) + { j=0; + if (i> (MAXFILES-1) ) + continue; + + fn = dp->d_name; + + if (fn[0] == '.') + continue; + + if(tn) + { + /* only looking for jnl files */ + len = strlen(tn); + if (!strstr(fn, ".jnl")) continue; + if (strncmp(fn, tn, len)) continue; + } + + j = strlen(fn) +1; + list[i] = malloc(sizeof(char) * j); + memset(list[i], 0 , j); + strcat(list[i], fn); + i++; } closedir(dirp); - qsort(list, i, sizeof(char *), compare); + qsort(list, i, sizeof(char*), compare); - for(j = 0; j < i; j++) { + for(j=0;jprev = NULL; + if(!n) return NULL; + n->prev=NULL; n->p = list[j]; - if(h) - h->prev = n; + if(h) h->prev = n; n->next = h; h = n; } @@ -255,14 +259,15 @@ lnode_p file_list(char *d, char *tn) /** qsort C-string comparison function */ -int compare(const void *a, const void *b) +int compare (const void *a, const void *b) { - const char **ia = (const char **)a; - const char **ib = (const char **)b; - return strcmp(*ia, *ib); + const char **ia = (const char **)a; + const char **ib = (const char **)b; + return strcmp(*ia, *ib); } + /** * recover -- given a journal filename, creates a new db w. metadata, and replays * the events in journalized order. @@ -271,7 +276,7 @@ int compare(const void *a, const void *b) * fn (filename) must be in the form: * location-20070803175446.jnl */ -int recover(char *jfn) +int recover(char* jfn) { #ifdef EXTRA_DEBUG @@ -281,23 +286,24 @@ int recover(char *jfn) int len, i, cs, ci, cd, cu; char *v, *s; - char line[MAX_ROW_SIZE]; - char tn[MAX_TABLENAME_SIZE]; - char fn[MAX_FILENAME_SIZE]; - char op[7]; //INSERT, DELETE, UPDATE are all 7 char wide (w. null) - FILE *fp = NULL; + char line [MAX_ROW_SIZE]; + char tn [MAX_TABLENAME_SIZE]; + char fn [MAX_FILENAME_SIZE]; + char op [7]; //INSERT, DELETE, UPDATE are all 7 char wide (w. null) + FILE * fp = NULL; tbl_cache_p tbc = NULL; table_p tp = NULL; - i = 0; + i = 0 ; cs = ci = cd = cu = 0; - if(!strstr(jfn, ".jnl")) { - fprintf(stderr, "[recover]: Does NOT look like a journal file: %s.\n", - jfn); + if(!strstr(jfn, ".jnl")) + { + fprintf(stderr, "[recover]: Does NOT look like a journal file: %s.\n", jfn); return 1; } - if(!db_home) { + if(!db_home) + { fprintf(stderr, "[recover]: null path to db_home.\n"); return 1; } @@ -309,41 +315,42 @@ int recover(char *jfn) tn[len] = 0; /*create abs path to journal file relative to db_home*/ - memset(fn, 0, MAX_FILENAME_SIZE); + memset(fn, 0 , MAX_FILENAME_SIZE); strcat(fn, db_home); strcat(fn, "/"); strcat(fn, jfn); fp = fopen(fn, "r"); - if(!fp) { + if(!fp) + { fprintf(stderr, "[recover]: FAILED to load journal file: %s.\n", jfn); return 2; } tbc = get_table(tn); - if(!tbc) { - fprintf(stderr, "[recover]: Table %s is not supported.\n", tn); + if(!tbc) + { + fprintf(stderr, "[recover]: Table %s is not supported.\n",tn); fprintf(stderr, "[recover]: FAILED to load journal file: %s.\n", jfn); fclose(fp); return 2; } - if(!tbc || !tbc->dtp) { - fprintf(stderr, "[recover]: FAILED to get find metadata for : %s.\n", - tn); + if(!tbc || !tbc->dtp) + { + fprintf(stderr, "[recover]: FAILED to get find metadata for : %s.\n", tn); fclose(fp); return 3; } - tp = tbc->dtp; + tp = tbc->dtp; - while(fgets(line, MAX_ROW_SIZE, fp) != NULL) { + while ( fgets(line , MAX_ROW_SIZE, fp) != NULL ) + { len = strlen(line); - if(line[0] == '#' || line[0] == '\n') - continue; + if(line[0] == '#' || line[0] == '\n') continue; - if(len > 0) - line[len - 1] = 0; /*chomp trailing \n */ + if(len > 0) line[len-1] = 0; /*chomp trailing \n */ v = strchr(line, '|'); len = v - line; @@ -351,44 +358,44 @@ int recover(char *jfn) strncpy(op, line, len); op[len] = 0; - switch(get_op(op, len)) { - case INSERT: - v++; //now v points to data - len = strlen(v); - insert(tp, v, len); - ci++; - break; + switch( get_op(op, len) ) + { + case INSERT: + v++; //now v points to data + len = strlen(v); + insert(tp, v, len); + ci++; + break; - case UPDATE: - v++; - len = strlen(v); - update(tp, v, len); - cu++; - break; + case UPDATE: + v++; + len = strlen(v); + update(tp, v, len); + cu++; + break; - case DELETE: - //v is really the key - delete(tp, v, len); - cd++; - break; + case DELETE: + //v is really the key + delete(tp, v, len); + cd++; + break; - case UNKNOWN_OP: - fprintf(stderr, "[recover]: UnknownOP - Skipping ROW: %s\n", - line); - cs++; - continue; + case UNKNOWN_OP: + fprintf(stderr,"[recover]: UnknownOP - Skipping ROW: %s\n",line); + cs++; + continue; } i++; } #ifdef EXTRA_DEBUG printf("Processed journal file: %s.\n", jfn); - printf("INSERT %i records.\n", ci); - printf("UPDATE %i records.\n", cu); - printf("DELETE %i records.\n", cd); - printf("SKIPed %i records.\n", cs); + printf("INSERT %i records.\n", ci); + printf("UPDATE %i records.\n", cu); + printf("DELETE %i records.\n", cd); + printf("SKIPped %i records.\n", cs); printf("------------------------\n"); - printf("Total %i records.\n", i); + printf("Total %i records.\n", i); tim2 = time(NULL); i = tim2 - tim1; @@ -415,20 +422,22 @@ int recover_all(int lastn) lnode_p n, h; tbl_cache_p _tbc = tables; - if(MAXFILES < lastn) - return 1; + if(MAXFILES < lastn) return 1; - if(!schema_dir) { + if(!schema_dir) + { fprintf(stderr, "[recover_all]: null path to schema files.\n"); return 1; } - if(!db_home) { + if(!db_home) + { fprintf(stderr, "[recover_all]: null path to db_home.\n"); return 1; } - while(_tbc) { + while(_tbc) + { int j; if(_tbc->dtp) @@ -436,22 +445,18 @@ int recover_all(int lastn) n = h; /*lastn; move to the oldest of the N*/ - for(j = 1; j < lastn; j++) - if(n && (n->next != NULL)) + for(j=1;jnext != NULL) ) n = n->next; - while(n) { - printf("[recover_all] recovering file: %s\n", n->p); + while(n) + { printf("[recover_all] recovering file: %s\n",n->p); if(recover(n->p)) - fprintf(stderr, - "[recover_all]: Error while recovering: [%s]\n. " - "Continuing..\n", - n->p); + fprintf(stderr, "[recover_all]: Error while recovering: [%s]\n. Continuing..\n",n->p); n = n->prev; } while(h) /*free mem*/ - { - n = h->next; + { n = h->next; free(h->p); free(h); h = n; @@ -467,18 +472,17 @@ int recover_all(int lastn) /** * extract_key -- uses the internal schema to extract the key from the data * row that was found in the journal. -* caller provides inititialize memory for destination key (k). +* caller provides initialized memory for destination key (k). * data is provided ; key is filled in */ -int extract_key(table_p tp, char *k, char *d) +int extract_key(table_p tp, char* k, char* d) { char *s, *p; char buf[MAX_ROW_SIZE]; int n, len; - if(!tp || !k || !d) - return -1; - len = n = 0; + if(!tp || !k || !d) return -1; + len=n=0; p = k; /*copy data so we can tokenize w.o trampling */ @@ -487,19 +491,22 @@ int extract_key(table_p tp, char *k, char *d) buf[len] = 0; s = strtok(buf, "|"); - while(s != NULL && n < MAX_NUM_COLS) { + while(s!=NULL && nncols - 1) > n) { - if(tp->colp[n]->kflag) { + if( (tp->ncols-1) > n) + { + if( tp->colp[n]->kflag ) + { strncpy(p, s, len); - p += len; + p+=len; *p = '|'; p++; } } - s = strtok(NULL, "|"); + s=strtok(NULL, "|"); n++; } @@ -510,22 +517,21 @@ int extract_key(table_p tp, char *k, char *d) /** * delete -- deletes a row from the db we are trying to rebuild */ -int delete(table_p tp, char *k, int len) +int delete(table_p tp, char* k, int len) { DBT key; DB *db; - if(!tp || !k) - return 1; - if((db = get_db(tp)) == NULL) - return 2; + if(!tp || !k) return 1; + if((db = get_db(tp)) == NULL) return 2; memset(&key, 0, sizeof(DBT)); key.data = k; key.ulen = MAX_ROW_SIZE; key.size = len; - if(db->del(db, NULL, &key, 0)) { + if ( db->del(db, NULL, &key, 0)) + { fprintf(stderr, "[delete] FAILED --> [%.*s] \n", len, k); return 3; } @@ -538,14 +544,13 @@ int delete(table_p tp, char *k, int len) * _insert -- inserts a new row in to the db we are trying to rebuild * I needed this to directly insert metadata when the db is created. */ -int _insert(DB *db, char *k, char *v, int klen, int vlen) +int _insert(DB* db, char* k, char* v, int klen, int vlen) { DBT key, data; - if(!db || !k || !v) - return 1; + if(!db || !k || !v) return 1; - memset(&key, 0, sizeof(DBT)); + memset(&key, 0, sizeof(DBT)); key.data = k; key.ulen = MAX_ROW_SIZE; key.size = klen; @@ -554,7 +559,8 @@ int _insert(DB *db, char *k, char *v, int klen, int vlen) data.data = v; data.ulen = MAX_ROW_SIZE; data.size = vlen; - if(db->put(db, NULL, &key, &data, 0)) { + if (db->put(db, NULL, &key, &data, 0)) + { fprintf(stderr, "[insert] FAILED --> [%.*s] \n", vlen, v); return 1; } @@ -567,21 +573,19 @@ int _insert(DB *db, char *k, char *v, int klen, int vlen) * key, and insert the data in to the db. * This will over-right the value if already present. */ -int insert(table_p tp, char *v, int vlen) +int insert(table_p tp, char* v, int vlen) { char k[MAX_ROW_SIZE]; int rc, klen; DB *db; - if(!tp || !v) - return 1; - if((db = get_db(tp)) == NULL) - return 2; + if(!tp || !v) return 1; + if((db = get_db(tp)) == NULL) return 2; - memset(k, 0, MAX_ROW_SIZE); - if(extract_key(tp, k, v)) { - fprintf(stderr, "[insert] failed to extract key for row: %.*s", vlen, - v); + memset(k,0,MAX_ROW_SIZE); + if( extract_key(tp, k, v) ) + { + fprintf(stderr, "[insert] failed to extract key for row: %.*s",vlen, v); return 2; } @@ -597,37 +601,34 @@ int insert(table_p tp, char *v, int vlen) * key, and update the data in the db. * This is implemented as DELETE + INSERT. */ -int update(table_p tp, char *v, int len) +int update(table_p tp, char* v, int len) { char k[MAX_ROW_SIZE]; - if(!tp || !v) - return 1; + if(!tp || !v) return 1; - memset(k, 0, MAX_ROW_SIZE); - if(extract_key(tp, k, v)) { - fprintf(stderr, "[update] failed to extract key for row: %.*s", len, v); + memset(k,0,MAX_ROW_SIZE); + if( extract_key(tp, k, v) ) + { + fprintf(stderr, "[update] failed to extract key for row: %.*s",len, v); return 2; } - /* if( delete(tp, k, strlen(k)) ) return 3; */ - if(insert(tp, v, len)) - return 4; +/* if( delete(tp, k, strlen(k)) ) return 3; */ + if( insert(tp, v, len) ) return 4; return 0; } + /** * get_op -- used to convert the string operation name to an enumerated op */ -int get_op(char *op, int len) +int get_op(char* op, int len) { - if((len == 6) && strstr("INSERT", op)) - return INSERT; - if((len == 6) && strstr("UPDATE", op)) - return UPDATE; - if((len == 6) && strstr("DELETE", op)) - return DELETE; + if((len==6) && strstr("INSERT",op) ) return INSERT; + if((len==6) && strstr("UPDATE",op) ) return UPDATE; + if((len==6) && strstr("DELETE",op) ) return DELETE; return UNKNOWN_OP; } @@ -636,96 +637,95 @@ int get_op(char *op, int len) /** * load_schema -- sets up the internal representation of the schema. */ -int load_schema(char *d) -{ - int rc; +int load_schema(char* d) +{ int rc; char *tn; - char line1[MAX_ROW_SIZE]; - char line2[MAX_ROW_SIZE]; - char fn[MAX_FILENAME_SIZE]; + char line1 [MAX_ROW_SIZE]; + char line2 [MAX_ROW_SIZE]; + char fn [MAX_FILENAME_SIZE]; tbl_cache_p tbc = NULL; table_p tp = NULL; - FILE *fp = NULL; - lnode_p h, n; + FILE * fp = NULL; + lnode_p h,n; - rc = 0; + rc=0; h = n = NULL; - if(!d) { + if(!d) + { fprintf(stderr, "[load_schema]: null path to schema files.\n"); return 1; } tables = (tbl_cache_p)malloc(sizeof(tbl_cache_t)); - if(!tables) - return 1; + if(!tables) return 1; h = file_list(d, NULL); - while(h) { + while(h) + { n = h->next; /*create abs path to journal file (relative to db_home) */ - memset(fn, 0, MAX_FILENAME_SIZE); + memset(fn, 0 , MAX_FILENAME_SIZE); strcat(fn, d); strcat(fn, "/"); strcat(fn, h->p); fp = fopen(fn, "r"); - if(!fp) { - fprintf(stderr, "[load_schema]: FAILED to load schema file: %s.\n", - h->p); + if(!fp) + { + fprintf(stderr, "[load_schema]: FAILED to load schema file: %s.\n", h->p); break; } tn = h->p; tbc = get_table(tn); - if(!tbc) { - fprintf(stderr, "[load_schema]: Table %s is not supported.\n", tn); - fprintf(stderr, - "[load_schema]: FAILED to load data for table: %s.\n", tn); + if(!tbc) + { + fprintf(stderr, "[load_schema]: Table %s is not supported.\n",tn); + fprintf(stderr, "[load_schema]: FAILED to load data for table: %s.\n", tn); goto done; } tp = tbc->dtp; - while(fgets(line1, MAX_ROW_SIZE, fp) != NULL) { - if(fgets(line2, MAX_ROW_SIZE, fp) != NULL) { - if(strstr(line1, METADATA_COLUMNS)) { - if(0 != load_metadata_columns(tp, line2)) { - fprintf(stderr, - "[load_schema]: FAILED to load METADATA COLS " - "in table: %s.\n", - tn); + while ( fgets(line1 , MAX_ROW_SIZE, fp) != NULL ) + { + if ( fgets(line2 , MAX_ROW_SIZE, fp) != NULL ) + { + if(strstr(line1, METADATA_COLUMNS)) + { + if(0!=load_metadata_columns(tp, line2)) + { + fprintf(stderr, "[load_schema]: FAILED to load METADATA COLS in table: %s.\n", tn); goto done; } } - if(strstr(line1, METADATA_KEY)) { - if(0 != load_metadata_key(tp, line2)) { - fprintf(stderr, - "[load_schema]: FAILED to load METADATA KEYS " - "in table: %s.\n", - tn); + if(strstr(line1, METADATA_KEY)) + { + if(0!=load_metadata_key(tp, line2)) + { + fprintf(stderr, "[load_schema]: FAILED to load METADATA KEYS in table: %s.\n", tn); goto done; } } - } else { - fprintf(stderr, - "[load_schema]: FAILED to read schema value in table: " - "%s.\n", - tn); + } + else + { + fprintf(stderr, "[load_schema]: FAILED to read schema value in table: %s.\n", tn); goto done; } + } - done: +done: fclose(fp); h = n; } while(h) /*free mem*/ - { - n = h->next; + { n = h->next; free(h->p); free(h); h = n; @@ -735,6 +735,7 @@ int load_schema(char *d) } + /** * get_table -- return pointer to lazy initialized table struct */ @@ -743,9 +744,13 @@ tbl_cache_p get_table(char *_s) tbl_cache_p _tbc = tables; table_p _tp = NULL; - while(_tbc) { - if(_tbc->dtp) { - if(_tbc->dtp->name && !strcmp(_tbc->dtp->name, _s)) { + while(_tbc) + { + if(_tbc->dtp) + { + if(_tbc->dtp->name + && !strcmp(_tbc->dtp->name,_s)) + { return _tbc; } } @@ -758,7 +763,8 @@ tbl_cache_p get_table(char *_s) _tp = create_table(_s); - if(!_tp) { + if(!_tp) + { fprintf(stderr, "[get_table]: failed to create table.\n"); free(_tbc); return NULL; @@ -785,20 +791,19 @@ table_p create_table(char *_s) table_p tp = NULL; tp = (table_p)malloc(sizeof(table_t)); - if(!tp) - return NULL; + if(!tp) return NULL; - i = strlen(_s) + 1; - tp->name = (char *)malloc(i * sizeof(char)); + i=strlen(_s)+1; + tp->name = (char*)malloc(i*sizeof(char)); strncpy(tp->name, _s, i); - tp->ncols = 0; - tp->nkeys = 0; - tp->ro = 0; - tp->logflags = 0; + tp->ncols=0; + tp->nkeys=0; + tp->ro=0; + tp->logflags=0; tp->db = NULL; - for(i = 0; i < MAX_NUM_COLS; i++) + for(i=0;icolp[i] = NULL; return tp; @@ -809,46 +814,45 @@ table_p create_table(char *_s) * load_metadata_columns -- parses the METADATA_COLUMNS line into the internal * representation. */ -int load_metadata_columns(table_p _tp, char *line) +int load_metadata_columns(table_p _tp, char* line) { - int n, len; + int n,len; char *s = NULL; char cn[64], ct[16]; column_p col; n = len = 0; - if(!_tp) - return -1; - if(_tp->ncols != 0) - return 0; + if(!_tp) return -1; + if(_tp->ncols!=0) return 0; /* eg: line = "table_name(str) table_version(int)" */ s = strtok(line, " \t"); - while(s != NULL && n < MAX_NUM_COLS) { + while(s!=NULL && nname = (char *)malloc(len * sizeof(char)); - strcpy(col->name, cn); + len = strlen( cn )+1; + col->name = (char*)malloc(len * sizeof(char)); + strcpy(col->name, cn ); /* set type*/ - len = strlen(ct) + 1; - col->type = (char *)malloc(len * sizeof(char)); - strcpy(col->type, ct); + len = strlen( ct )+1; + col->type = (char*)malloc(len * sizeof(char)); + strcpy(col->type, ct ); _tp->colp[n] = col; n++; _tp->ncols++; - s = strtok(NULL, " \t"); + s=strtok(NULL, " \t"); } return 0; @@ -859,26 +863,25 @@ int load_metadata_columns(table_p _tp, char *line) * load_metadata_key -- parses the METADATA_KEY line into the internal * representation. */ -int load_metadata_key(table_p _tp, char *line) +int load_metadata_key(table_p _tp, char* line) { - int ret, n, ci; + int ret,n,ci; char *s = NULL; ret = n = ci = 0; - if(!_tp) - return -1; + if(!_tp)return -1; s = strtok(line, " \t"); - while(s != NULL && n < _tp->ncols) { - ret = sscanf(s, "%i", &ci); - if(ret != 1) - return -1; - if(_tp->colp[ci]) { - _tp->colp[ci]->kflag = 1; + while(s!=NULL && n< _tp->ncols) + { + ret = sscanf(s,"%i", &ci); + if(ret != 1) return -1; + if( _tp->colp[ci] ) + { _tp->colp[ci]->kflag = 1; _tp->nkeys++; } n++; - s = strtok(NULL, " "); + s=strtok(NULL, " "); } return 0; @@ -892,19 +895,18 @@ int load_metadata_key(table_p _tp, char *line) * The db file on disk will be named: * .new */ -DB *get_db(table_p tp) +DB* get_db(table_p tp) { int rc; - DB *db; + DB* db; char dfn[MAX_FILENAME_SIZE]; - if(!tp) - return NULL; - if(tp->db) - return tp->db; + if( !tp) return NULL; + if( tp->db) return tp->db; memset(dfn, 0, MAX_FILENAME_SIZE); - if(db_home) { + if(db_home) + { strcpy(dfn, db_home); strcat(dfn, "/"); } @@ -912,15 +914,16 @@ DB *get_db(table_p tp) /*creation of DB follows*/ strcat(dfn, tp->name); - if((rc = db_create(&db, NULL, 0)) != 0) { - fprintf(stderr, "[create_table]: error db_create for table: %s.\n", - dfn); + if ((rc = db_create(&db, NULL, 0)) != 0) + { + fprintf(stderr, "[create_table]: error db_create for table: %s.\n",dfn); return NULL; } - if((rc = db->open(db, NULL, dfn, NULL, DB_HASH, DB_CREATE, 0664)) != 0) { - fprintf(stderr, "[create_table]: error opening %s.\n", dfn); - fprintf(stderr, "[create_table]: error msg: %s.\n", db_strerror(rc)); + if ((rc = db->open(db, NULL, dfn, NULL, DB_HASH, DB_CREATE, 0664)) != 0) + { + fprintf(stderr, "[create_table]: error opening %s.\n",dfn); + fprintf(stderr, "[create_table]: error msg: %s.\n",db_strerror(rc)); return NULL; } tp->db = db; @@ -936,56 +939,58 @@ DB *get_db(table_p tp) int import_schema(table_p tp) { int rc, len1, len2; - char line1[MAX_ROW_SIZE]; - char line2[MAX_ROW_SIZE]; - char fn[MAX_FILENAME_SIZE]; - FILE *fp = NULL; + char line1 [MAX_ROW_SIZE]; + char line2 [MAX_ROW_SIZE]; + char fn [MAX_FILENAME_SIZE]; + FILE * fp = NULL; rc = 0; - if(!schema_dir) { + if(!schema_dir) + { fprintf(stderr, "[import_schema]: null schema dir.\n"); return 1; } - if(!tp) { + if(!tp) + { fprintf(stderr, "[import_schema]: null table parameter.\n"); return 1; } /*create abs path to journal file (relative to db_home) */ - memset(fn, 0, MAX_FILENAME_SIZE); + memset(fn, 0 , MAX_FILENAME_SIZE); strcat(fn, schema_dir); strcat(fn, "/"); strcat(fn, tp->name); fp = fopen(fn, "r"); - if(!fp) { - fprintf(stderr, - "[import_schema]: FAILED to open def schema file: %s.\n", fn); + if(!fp) + { + fprintf(stderr, "[import_schema]: FAILED to open def schema file: %s.\n", fn); return 1; } - while(fgets(line1, MAX_ROW_SIZE, fp) != NULL) { - if(fgets(line2, MAX_ROW_SIZE, fp) != NULL) { - len1 = strlen(line1) - 1; - len2 = strlen(line2) - 1; + while ( fgets(line1 , MAX_ROW_SIZE, fp) != NULL ) + { + if ( fgets(line2 , MAX_ROW_SIZE, fp) != NULL ) + { + len1 = strlen(line1)-1; + len2 = strlen(line2)-1; line1[len1] = 0; line2[len2] = 0; - if((rc = _insert(tp->db, line1, line2, len1, len2)) != 0) { - fprintf(stderr, - "[import_schema]: FAILED to write schema def into " - "table: %s.\n", - tp->name); + if((rc = _insert(tp->db, line1, line2, len1, len2) )!=0) + { + fprintf(stderr, "[import_schema]: FAILED to write schema def into table: %s.\n", tp->name); goto done; } - } else { - fprintf(stderr, - "[import_schema]: FAILED to read schema def value in " - "table: %s.\n", - tp->name); + } + else + { + fprintf(stderr, "[import_schema]: FAILED to read schema def value in table: %s.\n", tp->name); goto done; } + } done: fclose(fp); @@ -993,19 +998,22 @@ done: } + /** * cleanup -- frees memory; closes any files. */ void cleanup(void) { //cleanup - while(tables) { - int i; - tbl_cache_p n = tables->next; - table_p tp = tables->dtp; - if(tp) { + while(tables) + { int i; + tbl_cache_p n = tables->next; + table_p tp = tables->dtp; + if(tp) + { free(tp->name); - for(i = 0; i < tp->ncols; i++) { + for(i=0;i< tp->ncols;i++) + { free(tp->colp[i]->name); free(tp->colp[i]->type); free(tp->colp[i]); @@ -1020,3 +1028,4 @@ void cleanup(void) tables = n; } } + diff --git a/utils/db_berkeley/kambdb_recover.h b/utils/db_berkeley/kambdb_recover.h index 9153766b2..2341eb228 100644 --- a/utils/db_berkeley/kambdb_recover.h +++ b/utils/db_berkeley/kambdb_recover.h @@ -62,7 +62,7 @@ enum typedef struct _lnode { - char *p; + char* p; struct _lnode *prev; struct _lnode *next; } lnode_t, *lnode_p; @@ -70,21 +70,21 @@ typedef struct _lnode typedef struct _column { - char *name; - char *type; + char* name; + char* type; int kflag; } column_t, *column_p; typedef struct _table { - char *name; - column_p colp[MAX_NUM_COLS]; + char* name; + column_p colp [MAX_NUM_COLS]; int ncols; int nkeys; int ro; int logflags; - DB *db; + DB* db; } table_t, *table_p; @@ -97,24 +97,24 @@ typedef struct _tbl_cache int usage(void); -DB *get_db(table_p tp); -int get_op(char *op, int len); -int delete(table_p tp, char *v, int len); -int insert(table_p tp, char *v, int len); -int _insert(DB *db, char *k, char *v, int klen, int vlen); -int update(table_p tp, char *v, int len); -int create(char *tn); -int _version(DB *db); +DB* get_db(table_p tp); +int get_op(char* op, int len); +int delete(table_p tp, char* v, int len); +int insert(table_p tp, char* v, int len); +int _insert(DB* db, char* k, char* v, int klen, int vlen); +int update(table_p tp, char* v, int len); +int create(char* tn); +int _version(DB* db); int create_all(void); -int recover(char *tn); +int recover(char* tn); int recover_all(int lastn); -lnode_p file_list(char *d, char *tn); -int compare(const void *a, const void *b); -int extract_key(table_p tp, char *key, char *data); -int load_schema(char *dir); +lnode_p file_list(char* d, char* tn); +int compare (const void *a, const void *b); +int extract_key(table_p tp, char* key, char* data); +int load_schema(char* dir); tbl_cache_p get_table(char *s); table_p create_table(char *_s); -int load_metadata_columns(table_p _tp, char *line); -int load_metadata_key(table_p _tp, char *line); +int load_metadata_columns(table_p _tp, char* line); +int load_metadata_key(table_p _tp, char* line); int import_schema(table_p tp); void cleanup(void); diff --git a/utils/db_oracle/getres.c b/utils/db_oracle/getres.c index 6cac7bf65..8ed27d8e5 100644 --- a/utils/db_oracle/getres.c +++ b/utils/db_oracle/getres.c @@ -9,61 +9,58 @@ static char st_buf[65536]; -enum type_t -{ - DB_STR = 0, - DB_DATETIME, - /* end of left alignment */ - DB_INT, - DB_BITMAP, - DB_DOUBLE /* MUST belast */ +enum type_t { + DB_STR = 0, + DB_DATETIME, + /* end of left alignment */ + DB_INT, + DB_BITMAP, + DB_DOUBLE /* MUST belast */ }; //--------------------------------------------------------- -struct dmap -{ - OCIDefine **defh; - union - { - dvoid *v; - double *f; - int *i; - char *c; - OCIDate *o; - } * pv; - dvoid **pval; - ub2 *ilen; - sb2 *ind; - ub2 *len; +struct dmap { + OCIDefine** defh; + union { + dvoid* v; + double* f; + int* i; + char* c; + OCIDate* o; + }* pv; + dvoid** pval; + ub2* ilen; + sb2* ind; + ub2* len; }; typedef struct dmap dmap_t; //----------------------------------------------------------------------------- -static void dmap_init(dmap_t *_d, unsigned n) +static void dmap_init(dmap_t* _d, unsigned n) { - size_t sz = sizeof(*_d->defh) + sizeof(*_d->pv) + sizeof(*_d->pval) - + sizeof(*_d->ilen) + sizeof(*_d->ind) + sizeof(*_d->len); + size_t sz = sizeof(*_d->defh) + sizeof(*_d->pv) + sizeof(*_d->pval) + + sizeof(*_d->ilen) + sizeof(*_d->ind) + sizeof(*_d->len); unsigned char *p = safe_malloc(sz * n); - _d->defh = (void *)p; - p += n * sizeof(*_d->defh); - _d->pv = (void *)p; - p += n * sizeof(*_d->pv); - _d->pval = (void *)p; - p += n * sizeof(*_d->pval); - _d->ilen = (void *)p; - p += n * sizeof(*_d->ilen); - _d->ind = (void *)p; - p += n * sizeof(*_d->ind); - _d->len = (void *)p; - // p += n*sizeof(*_d->len); + _d->defh = (void*)p; + p += n*sizeof(*_d->defh); + _d->pv = (void*)p; + p += n*sizeof(*_d->pv); + _d->pval = (void*)p; + p += n*sizeof(*_d->pval); + _d->ilen = (void*)p; + p += n*sizeof(*_d->ilen); + _d->ind = (void*)p; + p += n*sizeof(*_d->ind); + _d->len = (void*)p; +// p += n*sizeof(*_d->len); } //----------------------------------------------------------------------------- /* * Get and convert columns from a result. Define handlers and buffers */ -static void get_columns(const con_t *con, res_t *_r, dmap_t *_d) +static void get_columns(const con_t* con, res_t* _r, dmap_t* _d) { OCIParam *param; size_t tsz; @@ -73,139 +70,129 @@ static void get_columns(const con_t *con, res_t *_r, dmap_t *_d) status = OCIAttrGet(con->stmthp, OCI_HTYPE_STMT, &n, NULL, OCI_ATTR_PARAM_COUNT, con->errhp); - if(status != OCI_SUCCESS) - oraxit(status, con); + if (status != OCI_SUCCESS) oraxit(status, con); - if(!n) - donegood("Empty table"); + if (!n) donegood("Empty table"); dmap_init(_d, n); - _r->names = (Str **)safe_malloc(n * sizeof(Str *)); - _r->types = (unsigned char *)safe_malloc(n * sizeof(unsigned char)); + _r->names = (Str**)safe_malloc(n * sizeof(Str*)); + _r->types = (unsigned char*)safe_malloc(n * sizeof(unsigned char)); _r->col_n = n; tsz = 0; memset(_d->defh, 0, sizeof(_d->defh[0]) * n); - for(i = 0; i < n; i++) { + for (i = 0; i < n; i++) { ub4 len; ub2 dtype; unsigned char ctype = DB_DOUBLE; status = OCIParamGet(con->stmthp, OCI_HTYPE_STMT, con->errhp, - (dvoid **)(dvoid *)¶m, i + 1); - if(status != OCI_SUCCESS) - goto ora_err; + (dvoid**)(dvoid*)¶m, i+1); + if (status != OCI_SUCCESS) goto ora_err; { text *name; status = OCIAttrGet(param, OCI_DTYPE_PARAM, - (dvoid **)(dvoid *)&name, &len, OCI_ATTR_NAME, con->errhp); - if(status != OCI_SUCCESS) - goto ora_err; - _r->names[i] = str_alloc((char *)name, len); + (dvoid**)(dvoid*)&name, &len, + OCI_ATTR_NAME, con->errhp); + if (status != OCI_SUCCESS) goto ora_err; + _r->names[i] = str_alloc((char*)name, len); } - status = OCIAttrGet(param, OCI_DTYPE_PARAM, (dvoid **)(dvoid *)&dtype, - NULL, OCI_ATTR_DATA_TYPE, con->errhp); - if(status != OCI_SUCCESS) - goto ora_err; - - switch(dtype) { - case SQLT_UIN: - set_bitmap: - ctype = DB_BITMAP; - len = sizeof(unsigned); - break; - - case SQLT_INT: - set_int: - ctype = DB_INT; - len = sizeof(int); - break; - - case SQLT_VNU: - case SQLT_NUM: - len = 0; /* PRECISION is ub1 (byte) */ + status = OCIAttrGet(param, OCI_DTYPE_PARAM, + (dvoid**)(dvoid*)&dtype, NULL, + OCI_ATTR_DATA_TYPE, con->errhp); + if (status != OCI_SUCCESS) goto ora_err; + + switch (dtype) { + case SQLT_UIN: +set_bitmap: + ctype = DB_BITMAP; + len = sizeof(unsigned); + break; + + case SQLT_INT: +set_int: + ctype = DB_INT; + len = sizeof(int); + break; + + case SQLT_VNU: + case SQLT_NUM: + len = 0; /* PRECISION is ub1 (byte) */ + status = OCIAttrGet(param, OCI_DTYPE_PARAM, + (dvoid**)(dvoid*)&len, NULL, + OCI_ATTR_PRECISION, con->errhp); + if (status != OCI_SUCCESS) goto ora_err; + if (len <= 11) { + sb1 sc; status = OCIAttrGet(param, OCI_DTYPE_PARAM, - (dvoid **)(dvoid *)&len, NULL, OCI_ATTR_PRECISION, - con->errhp); - if(status != OCI_SUCCESS) - goto ora_err; - if(len <= 11) { - sb1 sc; - status = OCIAttrGet(param, OCI_DTYPE_PARAM, - (dvoid **)(dvoid *)&sc, NULL, OCI_ATTR_SCALE, - con->errhp); - if(status != OCI_SUCCESS) - goto ora_err; - if(!sc) { - dtype = SQLT_INT; - if(len != 11) - goto set_int; - dtype = SQLT_UIN; - goto set_bitmap; - } - if(sc < 0) - sc = 0; - ctype += sc; + (dvoid**)(dvoid*)&sc, NULL, + OCI_ATTR_SCALE, con->errhp); + if (status != OCI_SUCCESS) goto ora_err; + if (!sc) { + dtype = SQLT_INT; + if (len != 11) goto set_int; + dtype = SQLT_UIN; + goto set_bitmap; } - case SQLT_FLT: - case SQLT_BFLOAT: - case SQLT_BDOUBLE: - case SQLT_IBFLOAT: - case SQLT_IBDOUBLE: - case SQLT_PDN: - len = sizeof(double); - dtype = SQLT_FLT; - break; - - case SQLT_DATE: - case SQLT_DAT: - case SQLT_ODT: - case SQLT_TIMESTAMP: - case SQLT_TIMESTAMP_TZ: - case SQLT_TIMESTAMP_LTZ: - ctype = DB_DATETIME; - len = sizeof(OCIDate); - dtype = SQLT_ODT; - break; - - case SQLT_CLOB: - case SQLT_BLOB: - case SQLT_CHR: - case SQLT_STR: - case SQLT_VST: - case SQLT_VCS: - case SQLT_AFC: - case SQLT_AVC: - ctype = DB_STR; - dtype = SQLT_CHR; - len = 0; /* DATA_SIZE is ub2 (word) */ - status = OCIAttrGet(param, OCI_DTYPE_PARAM, - (dvoid **)(dvoid *)&len, NULL, OCI_ATTR_DATA_SIZE, - con->errhp); - if(status != OCI_SUCCESS) - goto ora_err; - ++len; - break; - - default: - errxit("unsupported datatype"); + if(sc < 0) sc = 0; + ctype += sc; + } + case SQLT_FLT: + case SQLT_BFLOAT: + case SQLT_BDOUBLE: + case SQLT_IBFLOAT: + case SQLT_IBDOUBLE: + case SQLT_PDN: + len = sizeof(double); + dtype = SQLT_FLT; + break; + + case SQLT_DATE: + case SQLT_DAT: + case SQLT_ODT: + case SQLT_TIMESTAMP: + case SQLT_TIMESTAMP_TZ: + case SQLT_TIMESTAMP_LTZ: + ctype = DB_DATETIME; + len = sizeof(OCIDate); + dtype = SQLT_ODT; + break; + + case SQLT_CLOB: + case SQLT_BLOB: + case SQLT_CHR: + case SQLT_STR: + case SQLT_VST: + case SQLT_VCS: + case SQLT_AFC: + case SQLT_AVC: + ctype = DB_STR; + dtype = SQLT_CHR; + len = 0; /* DATA_SIZE is ub2 (word) */ + status = OCIAttrGet(param, OCI_DTYPE_PARAM, + (dvoid**)(dvoid*)&len, NULL, + OCI_ATTR_DATA_SIZE, con->errhp); + if (status != OCI_SUCCESS) goto ora_err; + ++len; + break; + + default: + errxit("unsupported datatype"); } _r->types[i] = ctype; _d->ilen[i] = (ub2)len; _d->pv[i].v = st_buf + tsz; tsz += len; - status = OCIDefineByPos(con->stmthp, &_d->defh[i], con->errhp, i + 1, - _d->pv[i].v, len, dtype, &_d->ind[i], &_d->len[i], NULL, - OCI_DEFAULT); - if(status != OCI_SUCCESS) - goto ora_err; + status = OCIDefineByPos(con->stmthp, &_d->defh[i], con->errhp, + i+1, _d->pv[i].v, len, dtype, &_d->ind[i], + &_d->len[i], NULL, OCI_DEFAULT); + if (status != OCI_SUCCESS) goto ora_err; } - if(tsz > sizeof(st_buf)) - errxit("too large row"); + if (tsz > sizeof(st_buf)) errxit("too large row"); return; ora_err: @@ -216,83 +203,84 @@ ora_err: /* * Convert data fron db format to internal format */ -static void convert_row(const res_t *_res, Str ***_r, const dmap_t *_d) +static void convert_row(const res_t* _res, Str*** _r, const dmap_t* _d) { unsigned i, n = _res->col_n; - Str **v; + Str** v; - *_r = v = (Str **)safe_malloc(n * sizeof(Str **)); + *_r = v = (Str**)safe_malloc(n * sizeof(Str**)); - for(i = 0; i < n; i++, v++) { + for (i = 0; i < n; i++, v++) { char buf[64]; unsigned char t = _res->types[i]; - if(_d->ind[i] == -1) { - static const struct - { - unsigned len; - char s[1]; - } _empty = {0, ""}; + if (_d->ind[i] == -1) { + static const struct { + unsigned len; + char s[1]; + }_empty = { 0, "" }; #ifdef NULL_ID - static const struct - { - unsigned len; - char s[sizeof(NULL_ID)]; - } _null = {sizeof(NULL_ID) - 1, NULL_ID}; + static const struct { + unsigned len; + char s[sizeof(NULL_ID)]; + }_null = { sizeof(NULL_ID)-1, NULL_ID }; - *v = (Str *)&_null; - if(t != DB_STR) - continue; + *v = (Str*)&_null; + if (t != DB_STR) continue; #endif - *v = (Str *)&_empty; + *v = (Str*)&_empty; continue; } - // if (_d->ind[i]) errxit("truncated value in DB"); +// if (_d->ind[i]) errxit("truncated value in DB"); - switch(t) { - case DB_STR: - *v = str_alloc(_d->pv[i].c, _d->len[i]); - break; + switch (t) { + case DB_STR: + *v = str_alloc(_d->pv[i].c, _d->len[i]); + break; - case DB_INT: - *v = str_alloc( - buf, snprintf(buf, sizeof(buf), "%i", *_d->pv[i].i)); - break; + case DB_INT: + *v = str_alloc(buf, snprintf(buf, sizeof(buf), "%i", + *_d->pv[i].i)); + break; - case DB_BITMAP: - *v = str_alloc( - buf, snprintf(buf, sizeof(buf), "0x%X", *_d->pv[i].i)); - break; + case DB_BITMAP: + *v = str_alloc(buf, snprintf(buf, sizeof(buf), "0x%X", + *_d->pv[i].i)); + break; - case DB_DATETIME: { + case DB_DATETIME: + { struct tm tm; memset(&tm, 0, sizeof(tm)); - OCIDateGetTime( - _d->pv[i].o, &tm.tm_hour, &tm.tm_min, &tm.tm_sec); - OCIDateGetDate( - _d->pv[i].o, &tm.tm_year, &tm.tm_mon, &tm.tm_mday); - if(tm.tm_mon) + OCIDateGetTime(_d->pv[i].o, &tm.tm_hour, + &tm.tm_min, &tm.tm_sec); + OCIDateGetDate(_d->pv[i].o, &tm.tm_year, + &tm.tm_mon, &tm.tm_mday); + if (tm.tm_mon) --tm.tm_mon; - if(tm.tm_year >= 1900) + if (tm.tm_year >= 1900) tm.tm_year -= 1900; - *v = str_alloc( - buf, strftime(buf, sizeof(buf), "%d-%b-%Y %T", &tm)); - } break; + *v = str_alloc(buf, strftime(buf, sizeof(buf), + "%d-%b-%Y %T", &tm)); + } + break; - case DB_DOUBLE: - *v = str_alloc( - buf, snprintf(buf, sizeof(buf), "%g", *_d->pv[i].f)); - break; + case DB_DOUBLE: + *v = str_alloc(buf, snprintf(buf, sizeof(buf), "%g", + *_d->pv[i].f)); + break; - default: { + default: + { double x = fabs(*_d->pv[i].f); const char *fmt = "%.*f"; - if(x && (x >= 1.0e6 || x < 1.0e-5)) + if (x && (x >= 1.0e6 || x < 1.0e-5)) fmt = "%.*e"; - *v = str_alloc(buf, snprintf(buf, sizeof(buf), fmt, - (t - DB_DOUBLE), *_d->pv[i].f)); - } break; + *v = str_alloc(buf, snprintf(buf, sizeof(buf), + fmt, (t - DB_DOUBLE), *_d->pv[i].f)); + } + break; } } } @@ -301,7 +289,7 @@ static void convert_row(const res_t *_res, Str ***_r, const dmap_t *_d) /* * Get rows and convert it from oracle to db API representation */ -static void get_rows(const con_t *con, res_t *_r, dmap_t *_d) +static void get_rows(const con_t* con, res_t* _r, dmap_t* _d) { ub4 rcnt; sword status; @@ -309,33 +297,28 @@ static void get_rows(const con_t *con, res_t *_r, dmap_t *_d) memcpy(_d->len, _d->ilen, sizeof(_d->len[0]) * n); - status = OCIStmtFetch2( - con->stmthp, con->errhp, 1, OCI_FETCH_LAST, 0, OCI_DEFAULT); - if(status != OCI_SUCCESS) { - if(status == OCI_NO_DATA) - donegood("Empty set"); + status = OCIStmtFetch2(con->stmthp, con->errhp, 1, OCI_FETCH_LAST, 0, + OCI_DEFAULT); + if (status != OCI_SUCCESS) { + if (status == OCI_NO_DATA) donegood("Empty set"); goto ora_err; } status = OCIAttrGet(con->stmthp, OCI_HTYPE_STMT, &rcnt, NULL, OCI_ATTR_CURRENT_POSITION, con->errhp); - if(status != OCI_SUCCESS) - goto ora_err; - if(!rcnt) - errxit("lastpos==0"); + if (status != OCI_SUCCESS) goto ora_err; + if (!rcnt) errxit("lastpos==0"); _r->row_n = rcnt; - _r->rows = (Str ***)safe_malloc(rcnt * sizeof(Str **)); - while(1) { + _r->rows = (Str***)safe_malloc(rcnt * sizeof(Str**)); + while ( 1 ) { convert_row(_r, &_r->rows[--rcnt], _d); - if(!rcnt) - return; + if (!rcnt) return; memcpy(_d->len, _d->ilen, sizeof(_d->len[0]) * n); - status = OCIStmtFetch2( - con->stmthp, con->errhp, 1, OCI_FETCH_PRIOR, 0, OCI_DEFAULT); - if(status != OCI_SUCCESS) - break; + status = OCIStmtFetch2(con->stmthp, con->errhp, 1, + OCI_FETCH_PRIOR, 0, OCI_DEFAULT); + if (status != OCI_SUCCESS) break; } ora_err: oraxit(status, con); @@ -345,7 +328,7 @@ ora_err: /* * Read database answer and fill the structure */ -void get_res(const con_t *con, res_t *_r) +void get_res(const con_t* con, res_t* _r) { dmap_t dmap; unsigned n; @@ -359,7 +342,7 @@ void get_res(const con_t *con, res_t *_r) --n; assert(DB_STR == 0 && DB_DATETIME == 1); pt[n] = (pt[n] <= DB_DATETIME); - } while(n); + }while(n); } //----------------------------------------------------------------------------- diff --git a/utils/db_oracle/orasel.c b/utils/db_oracle/orasel.c index 2bb16e90a..70d8bfac0 100644 --- a/utils/db_oracle/orasel.c +++ b/utils/db_oracle/orasel.c @@ -5,22 +5,18 @@ outmode_t outmode; //----------------------------------------------------------------------------- -static void prepare_uri(con_t *con, const char *uri) +static void prepare_uri(con_t* con, const char *uri) { const char *p = strchr(uri, '/'); - if(!p || p == uri) - goto bad; + if(!p || p == uri) goto bad; con->username = str_alloc(uri, p - uri); - uri = p + 1; + uri = p+1; p = strchr(uri, '@'); - if(!p || p == uri) - goto bad; + if(!p || p == uri) goto bad; con->password = str_alloc(uri, p - uri); - if(strchr(con->password->s, '/')) - goto bad; - if(!*++p) - goto bad; + if(strchr(con->password->s, '/')) goto bad; + if(!*++p) goto bad; con->uri = str_alloc(p, strlen(p)); return; @@ -29,76 +25,63 @@ bad: } //----------------------------------------------------------------------------- -static const Str *prepare_req(const char *req) +static const Str* prepare_req(const char* req) { - Str *ps; + Str* ps; char *p; - while(*req && isspace((unsigned char)*req)) - ++req; - if(strncasecmp(req, "select", sizeof("select") - 1)) - goto bad; - p = (char *)req + sizeof("select") - 1; - if(!*p || !isspace((unsigned char)*p)) - goto bad; + while(*req && isspace((unsigned char)*req)) ++req; + if(strncasecmp(req, "select", sizeof("select")-1)) goto bad; + p = (char*)req + sizeof("select")-1; + if(!*p || !isspace((unsigned char)*p)) goto bad; ps = str_alloc(req, strlen(req)); - p = (char *)ps->s + sizeof("select") - 1; - do - if(isspace((unsigned char)*p)) - *p = ' '; - while(*++p); - do - --p; - while(isspace((unsigned char)*p)); - if(*p != ';') - goto bad; + p = (char*) ps->s + sizeof("select")-1; + do if(isspace((unsigned char)*p)) *p = ' '; while(*++p); + do --p; while(isspace((unsigned char)*p)); + if(*p != ';') goto bad; do { - do - --p; - while(isspace((unsigned char)*p)); - } while(*p == ';'); + do --p; while(isspace((unsigned char)*p)); + }while(*p == ';'); *++p = '\0'; ps->len = p - ps->s; - if(ps->len <= sizeof("select") - 1) { - bad: + if(ps->len <= sizeof("select")-1) { +bad: errxit("support only 'select ...;' request"); } return ps; } //----------------------------------------------------------------------------- -static void get_opt(int argc, char *argv[]) +static void get_opt(int argc, char* argv[]) { int opt = 0; if(argc <= 1 || (argc == 2 && !strcmp(argv[1], "--help"))) { - help: +help: fprintf(stderr, "Kamailio for oracle 'select' request utility\n"); - opt = -2; /* flag for help print */ + opt = -2; /* flag for help print */ } else { - while((opt = getopt(argc - 1, argv + 1, "BLNe:")) != -1) { + while((opt = getopt(argc-1, argv+1, "BLNe:")) != -1) { switch(opt) { - case 'B': - outmode.raw = 1; - ; - break; - case 'L': - outmode.hdr = 1; - break; - case 'N': - outmode.emp = 1; - break; - case 'e': - if(optind == argc - 1) - return; - // pass thru - default: - goto help; + case 'B': + outmode.raw = 1;; + break; + case 'L': + outmode.hdr = 1; + break; + case 'N': + outmode.emp = 1; + break; + case 'e': + if(optind == argc-1) return; + // pass thru + default: + goto help; } } } fprintf(stderr, "use: %s user/password@db [-BLN] -e \"select ...;\"\n", - argv[0]); + argv[0]); if(opt == -2) { fprintf(stderr, " where -B - print using tab separator\n"); fprintf(stderr, " -L - skip column headers\n"); @@ -108,11 +91,11 @@ static void get_opt(int argc, char *argv[]) } //----------------------------------------------------------------------------- -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { con_t con; res_t res; - const Str *req; + const Str* req; get_opt(argc, argv); diff --git a/utils/db_oracle/orasel.h b/utils/db_oracle/orasel.h index 8a75683b0..e229b56b0 100644 --- a/utils/db_oracle/orasel.h +++ b/utils/db_oracle/orasel.h @@ -7,49 +7,47 @@ #include #include -typedef struct -{ - unsigned len; - char s[]; -} Str; - -typedef struct -{ - const Str *username; - const Str *password; - const Str *uri; - OCIError *errhp; - OCISvcCtx *svchp; - OCIEnv *envhp; - OCISession *authp; - OCIServer *srvhp; - OCIStmt *stmthp; -} con_t; - -typedef struct -{ - Str **names; - Str ***rows; - unsigned char *types; - unsigned col_n; - unsigned row_n; -} res_t; +typedef struct { + unsigned len; + char s[]; +}Str; + +typedef struct { + const Str* username; + const Str* password; + const Str* uri; + OCIError* errhp; + OCISvcCtx* svchp; + OCIEnv* envhp; + OCISession* authp; + OCIServer* srvhp; + OCIStmt* stmthp; +}con_t; + +typedef struct { + Str** names; + Str*** rows; + unsigned char* types; + unsigned col_n; + unsigned row_n; +}res_t; void __attribute__((noreturn)) donegood(const char *msg); void __attribute__((noreturn)) errxit(const char *msg); -void __attribute__((noreturn)) oraxit(sword status, const con_t *con); -void *safe_malloc(size_t sz); -Str *str_alloc(const char *s, size_t len); - -void open_sess(con_t *con); -void send_req(con_t *con, const Str *req); -void get_res(const con_t *con, res_t *_r); -void out_res(const res_t *_r); - -typedef struct -{ - unsigned raw : 1, hdr : 1, emp : 1; -} outmode_t; +void __attribute__((noreturn)) oraxit(sword status, const con_t* con); +void* safe_malloc(size_t sz); +Str* str_alloc(const char *s, size_t len); + +void open_sess(con_t* con); +void send_req(con_t* con, const Str* req); +void get_res(const con_t* con, res_t* _r); +void out_res(const res_t* _r); + +typedef struct { + unsigned raw : 1, + hdr : 1, + emp : 1; +}outmode_t; extern outmode_t outmode; #endif diff --git a/utils/db_oracle/outres.c b/utils/db_oracle/outres.c index 13cbf6393..15bc3a4da 100644 --- a/utils/db_oracle/outres.c +++ b/utils/db_oracle/outres.c @@ -1,7 +1,7 @@ #include "orasel.h" //----------------------------------------------------------------------------- -static void out_delim(const unsigned *pl, unsigned nc) +static void out_delim(const unsigned* pl, unsigned nc) { unsigned i; @@ -9,19 +9,17 @@ static void out_delim(const unsigned *pl, unsigned nc) unsigned j = pl[i] + 2; putchar('+'); - do - putchar('-'); - while(--j); + do putchar('-'); while(--j); } printf("+\n"); } //----------------------------------------------------------------------------- -void out_res(const res_t *_r) +void out_res(const res_t* _r) { - unsigned *pl = NULL; - unsigned nc = _r->col_n, nr = _r->row_n, i, j; - Str **ps = _r->names; + unsigned* pl = NULL; + unsigned nc = _r->col_n, nr = _r->row_n, i, j; + Str** ps = _r->names; if(!outmode.raw) { pl = safe_malloc(nc * sizeof(unsigned)); @@ -30,8 +28,7 @@ void out_res(const res_t *_r) for(j = 0; j < nr; j++) { ps = _r->rows[j]; for(i = 0; i < nc; i++) - if(pl[i] < ps[i]->len) - pl[i] = ps[i]->len; + if(pl[i] < ps[i]->len) pl[i] = ps[i]->len; } out_delim(pl, nc); @@ -42,13 +39,11 @@ void out_res(const res_t *_r) if(!outmode.raw) { printf("| %-*.*s ", pl[i], ps[i]->len, ps[i]->s); } else { - if(i) - putchar('\t'); + if(i) putchar('\t'); printf("%.*s", ps[i]->len, ps[i]->s); } } - if(outmode.raw) - putchar('\n'); + if(outmode.raw) putchar('\n'); else { printf("|\n"); out_delim(pl, nc); @@ -58,20 +53,18 @@ void out_res(const res_t *_r) ps = _r->rows[j]; if(!outmode.raw) { for(i = 0; i < nc; i++) - printf(_r->types[i] ? "| %-*.*s " : "| %*.*s ", pl[i], - ps[i]->len, ps[i]->s); + printf(_r->types[i] ? "| %-*.*s " : "| %*.*s ", + pl[i], ps[i]->len, ps[i]->s); printf("|\n"); } else { for(i = 0; i < nc; i++) { - if(i) - putchar('\t'); + if(i) putchar('\t'); printf("%.*s", ps[i]->len, ps[i]->s); } putchar('\n'); } } - if(!outmode.raw) - out_delim(pl, nc); + if(!outmode.raw) out_delim(pl, nc); } //----------------------------------------------------------------------------- diff --git a/utils/db_oracle/selcon.c b/utils/db_oracle/selcon.c index c60ef490d..04d617e0c 100644 --- a/utils/db_oracle/selcon.c +++ b/utils/db_oracle/selcon.c @@ -1,72 +1,63 @@ #include "orasel.h" //----------------------------------------------------------------------------- -void open_sess(con_t *con) +void open_sess(con_t* con) { sword status; - if(OCIEnvCreate(&con->envhp, OCI_DEFAULT | OCI_NEW_LENGTH_SEMANTICS, NULL, - NULL, NULL, NULL, 0, - NULL) != OCI_SUCCESS - || OCIHandleAlloc(con->envhp, (dvoid **)(dvoid *)&con->errhp, - OCI_HTYPE_ERROR, 0, NULL) - != OCI_SUCCESS - || OCIHandleAlloc(con->envhp, (dvoid **)(dvoid *)&con->srvhp, - OCI_HTYPE_SERVER, 0, NULL) - != OCI_SUCCESS - || OCIHandleAlloc(con->envhp, (dvoid **)(dvoid *)&con->svchp, - OCI_HTYPE_SVCCTX, 0, NULL) - != OCI_SUCCESS - || OCIHandleAlloc(con->envhp, (dvoid **)(dvoid *)&con->authp, - OCI_HTYPE_SESSION, 0, NULL) - != OCI_SUCCESS - || OCIHandleAlloc(con->envhp, (dvoid **)(dvoid *)&con->stmthp, - OCI_HTYPE_STMT, 0, NULL) - != OCI_SUCCESS) { + if ( OCIEnvCreate(&con->envhp, OCI_DEFAULT | OCI_NEW_LENGTH_SEMANTICS, + NULL, NULL, NULL, NULL, 0, NULL) != OCI_SUCCESS + || OCIHandleAlloc(con->envhp, (dvoid**)(dvoid*)&con->errhp, + OCI_HTYPE_ERROR, 0, NULL) != OCI_SUCCESS + || OCIHandleAlloc(con->envhp, (dvoid**)(dvoid*)&con->srvhp, + OCI_HTYPE_SERVER, 0, NULL) != OCI_SUCCESS + || OCIHandleAlloc(con->envhp, (dvoid**)(dvoid*)&con->svchp, + OCI_HTYPE_SVCCTX, 0, NULL) != OCI_SUCCESS + || OCIHandleAlloc(con->envhp, (dvoid**)(dvoid*)&con->authp, + OCI_HTYPE_SESSION, 0, NULL) != OCI_SUCCESS + || OCIHandleAlloc(con->envhp, (dvoid**)(dvoid*)&con->stmthp, + OCI_HTYPE_STMT, 0, NULL) != OCI_SUCCESS) + { errxit("no oracle memory left"); } status = OCIAttrSet(con->svchp, OCI_HTYPE_SVCCTX, con->srvhp, 0, OCI_ATTR_SERVER, con->errhp); - if(status != OCI_SUCCESS) - goto connect_err; - status = OCIAttrSet(con->authp, OCI_HTYPE_SESSION, (text *)con->username->s, - con->username->len, OCI_ATTR_USERNAME, con->errhp); - if(status != OCI_SUCCESS) - goto connect_err; - status = OCIAttrSet(con->authp, OCI_HTYPE_SESSION, (text *)con->password->s, - con->password->len, OCI_ATTR_PASSWORD, con->errhp); - if(status != OCI_SUCCESS) - goto connect_err; + if (status != OCI_SUCCESS) goto connect_err; + status = OCIAttrSet(con->authp, OCI_HTYPE_SESSION, + (text*)con->username->s, con->username->len, + OCI_ATTR_USERNAME, con->errhp); + if (status != OCI_SUCCESS) goto connect_err; + status = OCIAttrSet(con->authp, OCI_HTYPE_SESSION, + (text*)con->password->s, con->password->len, + OCI_ATTR_PASSWORD, con->errhp); + if (status != OCI_SUCCESS) goto connect_err; status = OCIAttrSet(con->svchp, OCI_HTYPE_SVCCTX, con->authp, 0, OCI_ATTR_SESSION, con->errhp); - if(status != OCI_SUCCESS) - goto connect_err; - status = OCIServerAttach( - con->srvhp, con->errhp, (OraText *)con->uri->s, con->uri->len, 0); - if(status != OCI_SUCCESS) - goto connect_err; - status = OCISessionBegin( - con->svchp, con->errhp, con->authp, OCI_CRED_RDBMS, OCI_DEFAULT); - if(status != OCI_SUCCESS) { - connect_err: + if (status != OCI_SUCCESS) goto connect_err; + status = OCIServerAttach(con->srvhp, con->errhp, (OraText*)con->uri->s, + con->uri->len, 0); + if (status != OCI_SUCCESS) goto connect_err; + status = OCISessionBegin(con->svchp, con->errhp, con->authp, + OCI_CRED_RDBMS, OCI_DEFAULT); + if (status != OCI_SUCCESS) { +connect_err: oraxit(status, con); } } //----------------------------------------------------------------------------- -void send_req(con_t *con, const Str *req) +void send_req(con_t* con, const Str* req) { sword status; - status = OCIStmtPrepare(con->stmthp, con->errhp, (text *)req->s, req->len, + status = OCIStmtPrepare(con->stmthp, con->errhp, (text*)req->s, req->len, OCI_NTV_SYNTAX, OCI_DEFAULT); - if(status != OCI_SUCCESS) - goto request_err; + if (status != OCI_SUCCESS) goto request_err; status = OCIStmtExecute(con->svchp, con->stmthp, con->errhp, 0, 0, NULL, NULL, OCI_STMT_SCROLLABLE_READONLY); - if(status != OCI_SUCCESS) { - request_err: + if (status != OCI_SUCCESS) { +request_err: fprintf(stderr, "%.*s\n", req->len, req->s); oraxit(status, con); } diff --git a/utils/db_oracle/util.c b/utils/db_oracle/util.c index 32bb39a3d..e49d805d7 100644 --- a/utils/db_oracle/util.c +++ b/utils/db_oracle/util.c @@ -4,7 +4,7 @@ void __attribute__((noreturn)) donegood(const char *msg) { OCITerminate(OCI_DEFAULT); - if(msg && !outmode.emp) + if (msg && !outmode.emp) printf("%s\n", msg); exit(0); } @@ -18,52 +18,52 @@ void __attribute__((noreturn)) errxit(const char *msg) } //----------------------------------------------------------------------------- -void __attribute__((noreturn)) oraxit(sword status, const con_t *con) +void __attribute__((noreturn)) oraxit(sword status, const con_t* con) { const char *p = NULL; char buf[512]; sword ecd; - switch(status) { - case OCI_SUCCESS_WITH_INFO: - case OCI_ERROR: - ecd = 0; - if(OCIErrorGet(con->errhp, 1, NULL, &ecd, (OraText *)buf, - sizeof(buf), OCI_HTYPE_ERROR) - != OCI_SUCCESS) { - snprintf(buf, sizeof(buf), "unknown ORAERR %u", ecd); - } - break; + switch (status) { + case OCI_SUCCESS_WITH_INFO: + case OCI_ERROR: + ecd = 0; + if(OCIErrorGet(con->errhp, 1, NULL, &ecd, (OraText*)buf, + sizeof(buf), OCI_HTYPE_ERROR) != OCI_SUCCESS) + { + snprintf(buf, sizeof(buf), "unknown ORAERR %u", ecd); + } + break; - default: - snprintf(buf, sizeof(buf), "unknown status %u", status); - break; + default: + snprintf(buf, sizeof(buf), "unknown status %u", status); + break; - case OCI_SUCCESS: - p = "success"; - break; + case OCI_SUCCESS: + p = "success"; + break; - case OCI_NEED_DATA: - p = "need data"; - break; + case OCI_NEED_DATA: + p = "need data"; + break; - case OCI_NO_DATA: - p = "no data"; - break; + case OCI_NO_DATA: + p = "no data"; + break; - case OCI_INVALID_HANDLE: - p = "invalid handle"; - break; + case OCI_INVALID_HANDLE: + p = "invalid handle"; + break; - case OCI_STILL_EXECUTING: /* ORA-3123 */ - p = "executing"; - break; + case OCI_STILL_EXECUTING: /* ORA-3123 */ + p = "executing"; + break; - case OCI_CONTINUE: - p = "continue"; - break; + case OCI_CONTINUE: + p = "continue"; + break; } - if(p) { + if (p) { snprintf(buf, sizeof(buf), "logic error (%s)", p); } errxit(buf); @@ -77,18 +77,17 @@ static void __attribute__((noreturn)) nomem(void) } //----------------------------------------------------------------------------- -void *safe_malloc(size_t sz) +void* safe_malloc(size_t sz) { void *p = malloc(sz); - if(!p) - nomem(); + if (!p) nomem(); return p; } //----------------------------------------------------------------------------- -Str *str_alloc(const char *s, size_t len) +Str* str_alloc(const char *s, size_t len) { - Str *ps = (Str *)safe_malloc(sizeof(Str) + len + 1); + Str* ps = (Str*)safe_malloc(sizeof(Str) + len + 1); ps->len = len; memcpy(ps->s, s, len); ps->s[len] = '\0'; diff --git a/utils/kamcmd/kamcmd.8 b/utils/kamcmd/kamcmd.8 index c2355243f..9798cbc8a 100644 --- a/utils/kamcmd/kamcmd.8 +++ b/utils/kamcmd/kamcmd.8 @@ -40,4 +40,4 @@ see .BR kamailio.cfg(5) .PP Full documentation about kamailio is available at -.I http://www.kamailio.org/. +.I https://www.kamailio.org/. diff --git a/utils/kamcmd/kamcmd.c b/utils/kamcmd/kamcmd.c index d26b15b11..9190b6138 100644 --- a/utils/kamcmd/kamcmd.c +++ b/utils/kamcmd/kamcmd.c @@ -634,7 +634,7 @@ static int binrpc_errno = 0; * returns < 0 on error, reply size on success + initializes in_pkt * if ret==-2 (parse error), sets binrpc_errno to the binrpc error * error returns: -1 - read error (check errno) - * -2 - binrpc parse error (chekc binrpc_errno) + * -2 - binrpc parse error (check binrpc_errno) * -3 - cookie error (the cookied doesn't match) * -4 - message too big */ static int get_reply(int s, unsigned char *reply_buf, int max_reply_size, diff --git a/utils/kamcmd/parse_listen_id.c b/utils/kamcmd/parse_listen_id.c index 32e2cf9db..0a84b34c0 100644 --- a/utils/kamcmd/parse_listen_id.c +++ b/utils/kamcmd/parse_listen_id.c @@ -246,9 +246,9 @@ end: port = str2s(port_str, strlen(port_str), &err); if(err) { /* try getservbyname */ - se = getservbyname(port_str, (proto == TCP_SOCK) ? "tcp" - : (proto == UDP_SOCK) ? "udp" - : 0); + se = getservbyname(port_str, + (proto == TCP_SOCK) ? "tcp" + : (proto == UDP_SOCK) ? "udp" : 0); if(se) port = ntohs(se->s_port); else diff --git a/utils/kamctl/dbtextdb/dbtextdb_test.py b/utils/kamctl/dbtextdb/dbtextdb_test.py index 54ce274c7..8762de1b3 100644 --- a/utils/kamctl/dbtextdb/dbtextdb_test.py +++ b/utils/kamctl/dbtextdb/dbtextdb_test.py @@ -500,7 +500,7 @@ class DBTextTest(unittest.TestCase): db_conn.CleanUp() query = ('delete from unsorted_table where id = 5;') - result = db_conn.Execute(query, writethru) + db_conn.Execute(query, writethru) self.assertEqual(db_conn.data, [{'id': 1, 'user': 'fred', 'domain': 'test.com', 'number': 2125551234}, {'id': 4, 'user': 'alex', 'domain': @@ -514,7 +514,7 @@ class DBTextTest(unittest.TestCase): # test insert with auto increment query = ("insert into unsorted_table set user='jake', domain='test.com'," 'number = 2125551456;') - result = db_conn.Execute(query, writethru) + db_conn.Execute(query, writethru) self.assertEqual(db_conn.data, [{'id': 1, 'user': 'fred', 'domain': 'test.com', 'number': 2125551234}, {'id': 4, 'user': 'alex', 'domain': @@ -531,7 +531,7 @@ class DBTextTest(unittest.TestCase): # test insert with null value query = ("insert into test set col1='asdf';") - result = db_conn.Execute(query, writethru) + db_conn.Execute(query, writethru) self.assertEqual(db_conn.data, [{'col2': 'item2', 'id': 1, 'col1': 'item1\\:'}, {'col2': '', 'id': 2, 'col1': @@ -543,7 +543,7 @@ class DBTextTest(unittest.TestCase): # test insert with null value alternate syntax query = ("insert test ( col1) values ('asdf');") - result = db_conn.Execute(query, writethru) + db_conn.Execute(query, writethru) self.assertEqual(db_conn.data, [{'col2': 'item2', 'id': 1, 'col1': 'item1\\:'}, {'col2': '', 'id': 2, 'col1': @@ -555,7 +555,7 @@ class DBTextTest(unittest.TestCase): # test insert with colon inside value query = ("insert into test set col1='as:df';") - result = db_conn.Execute(query, writethru) + db_conn.Execute(query, writethru) self.assertEqual(db_conn.data, [{'col2': 'item2', 'id': 1, 'col1': 'item1\\:'}, {'col2': '', 'id': 2, 'col1': @@ -567,7 +567,7 @@ class DBTextTest(unittest.TestCase): # test insert with escaped colon inside value query = ("insert into test set col1='as\:df';") - result = db_conn.Execute(query, writethru) + db_conn.Execute(query, writethru) self.assertEqual(db_conn.data, [{'col2': 'item2', 'id': 1, 'col1': 'item1\\:'}, {'col2': '', 'id': 2, 'col1': @@ -589,7 +589,7 @@ class DBTextTest(unittest.TestCase): # test update with null value query = ("update test set col2='' where id = 3;") - result = db_conn.Execute(query, writethru) + db_conn.Execute(query, writethru) self.assertEqual(db_conn.data, [{'col2': 'item2', 'id': 1, 'col1': 'item1\\:'}, {'col2': '', 'id': 2, 'col1': diff --git a/utils/kamctl/kamctl b/utils/kamctl/kamctl index 7eea9be64..6bdcfa20b 100755 --- a/utils/kamctl/kamctl +++ b/utils/kamctl/kamctl @@ -5,7 +5,7 @@ #=================================================================== ### version for this script -VERSION='5.7.0' +VERSION='5.8.0' PATH=$PATH:/usr/local/sbin/ @@ -18,6 +18,7 @@ else fi ### include config files +RC_FILE_SOURCED="false" # check for rc file at same location with kamctl which greadlink >/dev/null 2>&1 @@ -39,11 +40,13 @@ if [ -n "$KAMCTLFULLPATH" ] ; then fi # check for rc file at standard locations -if [ -f /etc/kamailio/kamctlrc -a -r /etc/kamailio/kamctlrc ]; then +if [ $RC_FILE_SOURCED = "false" ] && [ -f /etc/kamailio/kamctlrc -a -r /etc/kamailio/kamctlrc ]; then . /etc/kamailio/kamctlrc + RC_FILE_SOURCED="true" fi -if [ -f /usr/local/etc/kamailio/kamctlrc -a -r /usr/local/etc/kamailio/kamctlrc ]; then +if [ $RC_FILE_SOURCED = "false" ] && [ -f /usr/local/etc/kamailio/kamctlrc -a -r /usr/local/etc/kamailio/kamctlrc ]; then . /usr/local/etc/kamailio/kamctlrc + RC_FILE_SOURCED="true" fi if [ -f ~/.kamctlrc -a -r ~/.kamctlrc ]; then . ~/.kamctlrc @@ -83,7 +86,7 @@ fi if [ -f "$MYLIBDIR/kamctl.base" ]; then . "$MYLIBDIR/kamctl.base" else - echo -e "Cannot load core functions '$MYLIBDIR/kamctl.base' - exiting ...\n" + printf "Cannot load core functions '%s' - exiting ...\n\n" "$MYLIBDIR/kamctl.base" exit -1 fi @@ -1756,6 +1759,40 @@ dispatcher() { fi ;; + rmip) + require_dbengine + shift + if [ $# -ne 2 ] ; then + merr "missing gateway ip address and/or setid to be removed" + exit 1 + fi + + QUERY="delete from $DISPATCHER_TABLE where $DISPATCHER_SETID_COLUMN='$2' and $DISPATCHER_DESTINATION_COLUMN like 'sip:$1:%';" + $DBCMD "$QUERY" + + if [ $? -ne 0 ] ; then + merr "dispatcher - SQL Error" + exit 1 + fi + + ;; + rmset) + require_dbengine + shift + if [ $# -ne 2 ] ; then + merr "missing gateway setid to be removed" + exit 1 + fi + + QUERY="delete from $DISPATCHER_TABLE where $DISPATCHER_SETID_COLUMN='$1'' and $DISPATCHER_DESTINATION_COLUMN like 'sip:$1:%'';" + $DBCMD "$QUERY" + + if [ $? -ne 0 ] ; then + merr "dispatcher - SQL Error" + exit 1 + fi + + ;; reload) require_ctlengine ctl_cmd_run dispatcher.reload @@ -3221,4 +3258,3 @@ case $1 in exit 1 ;; esac - diff --git a/utils/kamctl/kamctl.base b/utils/kamctl/kamctl.base index 08cd44120..ea0fff943 100644 --- a/utils/kamctl/kamctl.base +++ b/utils/kamctl/kamctl.base @@ -512,6 +512,8 @@ cat < [flags] [priority] [attrs] [description] .......................... add gateway dispatcher rm .................. delete gateway + dispatcher rmip ......... delete gateway in + dispatcher rmset ............. delete all gateways in EOF } USAGE_FUNCTIONS="$USAGE_FUNCTIONS usage_dispatcher" @@ -579,7 +581,7 @@ USAGE_FUNCTIONS="$USAGE_FUNCTIONS usage_mtree" usage_acc() { echo - mecho " -- command 'acc' - manage accounding records" + mecho " -- command 'acc' - manage accounting records" echo cat < + acc show acc @@ -51,7 +51,7 @@ - + acc_cdrs show acc_cdrs @@ -92,7 +92,7 @@ - + missed_calls show missed_calls diff --git a/utils/kamctl/xhttp_pi/alias_db-mod b/utils/kamctl/xhttp_pi/alias_db-mod index 62c97d72b..c59a1befb 100644 --- a/utils/kamctl/xhttp_pi/alias_db-mod +++ b/utils/kamctl/xhttp_pi/alias_db-mod @@ -1,4 +1,4 @@ - + dbaliases show dbaliases diff --git a/utils/kamctl/xhttp_pi/auth_db-mod b/utils/kamctl/xhttp_pi/auth_db-mod index 019d367cb..e1b966631 100644 --- a/utils/kamctl/xhttp_pi/auth_db-mod +++ b/utils/kamctl/xhttp_pi/auth_db-mod @@ -1,4 +1,4 @@ - + subscriber show subscriber diff --git a/utils/kamctl/xhttp_pi/avpops-mod b/utils/kamctl/xhttp_pi/avpops-mod index 845714526..9b8b6da74 100644 --- a/utils/kamctl/xhttp_pi/avpops-mod +++ b/utils/kamctl/xhttp_pi/avpops-mod @@ -1,4 +1,4 @@ - + usr_preferences show usr_preferences diff --git a/utils/kamctl/xhttp_pi/carrierroute-mod b/utils/kamctl/xhttp_pi/carrierroute-mod index 0623cf1c3..e170941af 100644 --- a/utils/kamctl/xhttp_pi/carrierroute-mod +++ b/utils/kamctl/xhttp_pi/carrierroute-mod @@ -1,4 +1,4 @@ - + carrierroute show carrierroute @@ -63,7 +63,7 @@ - + carrierfailureroute show carrierfailureroute @@ -122,7 +122,7 @@ - + carrier_name show carrier_name @@ -157,7 +157,7 @@ - + domain_name show domain_name diff --git a/utils/kamctl/xhttp_pi/cpl-mod b/utils/kamctl/xhttp_pi/cpl-mod index a35dc31d3..33e1cb303 100644 --- a/utils/kamctl/xhttp_pi/cpl-mod +++ b/utils/kamctl/xhttp_pi/cpl-mod @@ -1,4 +1,4 @@ - + cpl show cpl diff --git a/utils/kamctl/xhttp_pi/dialog-mod b/utils/kamctl/xhttp_pi/dialog-mod index db4295cb8..fec8aef9e 100644 --- a/utils/kamctl/xhttp_pi/dialog-mod +++ b/utils/kamctl/xhttp_pi/dialog-mod @@ -1,4 +1,4 @@ - + dialog show dialog @@ -99,7 +99,7 @@ - + dialog_vars show dialog_vars diff --git a/utils/kamctl/xhttp_pi/dialplan-mod b/utils/kamctl/xhttp_pi/dialplan-mod index c84f022e7..87d853f9c 100644 --- a/utils/kamctl/xhttp_pi/dialplan-mod +++ b/utils/kamctl/xhttp_pi/dialplan-mod @@ -1,4 +1,4 @@ - + dialplan show dialplan diff --git a/utils/kamctl/xhttp_pi/dispatcher-mod b/utils/kamctl/xhttp_pi/dispatcher-mod index b24acda44..9a63dbc67 100644 --- a/utils/kamctl/xhttp_pi/dispatcher-mod +++ b/utils/kamctl/xhttp_pi/dispatcher-mod @@ -1,4 +1,4 @@ - + dispatcher show dispatcher diff --git a/utils/kamctl/xhttp_pi/domain-mod b/utils/kamctl/xhttp_pi/domain-mod index 10049b306..040a96aed 100644 --- a/utils/kamctl/xhttp_pi/domain-mod +++ b/utils/kamctl/xhttp_pi/domain-mod @@ -1,4 +1,4 @@ - + domain show domain @@ -39,7 +39,7 @@ - + domain_attrs show domain_attrs diff --git a/utils/kamctl/xhttp_pi/domainpolicy-mod b/utils/kamctl/xhttp_pi/domainpolicy-mod index 93bf0fd8e..1e2b1e92b 100644 --- a/utils/kamctl/xhttp_pi/domainpolicy-mod +++ b/utils/kamctl/xhttp_pi/domainpolicy-mod @@ -1,4 +1,4 @@ - + domainpolicy show domainpolicy diff --git a/utils/kamctl/xhttp_pi/drouting-mod b/utils/kamctl/xhttp_pi/drouting-mod index 0d95ab170..11739f463 100644 --- a/utils/kamctl/xhttp_pi/drouting-mod +++ b/utils/kamctl/xhttp_pi/drouting-mod @@ -1,4 +1,4 @@ - + dr_gateways show dr_gateways @@ -48,7 +48,7 @@ - + dr_rules show dr_rules @@ -101,7 +101,7 @@ - + dr_gw_lists show dr_gw_lists @@ -139,7 +139,7 @@ - + dr_groups show dr_groups diff --git a/utils/kamctl/xhttp_pi/group-mod b/utils/kamctl/xhttp_pi/group-mod index 3f71a7552..b99bc21c7 100644 --- a/utils/kamctl/xhttp_pi/group-mod +++ b/utils/kamctl/xhttp_pi/group-mod @@ -1,4 +1,4 @@ - + grp show grp @@ -42,7 +42,7 @@ - + re_grp show re_grp diff --git a/utils/kamctl/xhttp_pi/htable-mod b/utils/kamctl/xhttp_pi/htable-mod index c01eee869..fa330bb85 100644 --- a/utils/kamctl/xhttp_pi/htable-mod +++ b/utils/kamctl/xhttp_pi/htable-mod @@ -1,4 +1,4 @@ - + htable show htable diff --git a/utils/kamctl/xhttp_pi/imc-mod b/utils/kamctl/xhttp_pi/imc-mod index f4fc9e251..4109b6abd 100644 --- a/utils/kamctl/xhttp_pi/imc-mod +++ b/utils/kamctl/xhttp_pi/imc-mod @@ -1,4 +1,4 @@ - + imc_rooms show imc_rooms @@ -39,7 +39,7 @@ - + imc_members show imc_members diff --git a/utils/kamctl/xhttp_pi/lcr-mod b/utils/kamctl/xhttp_pi/lcr-mod index b329d1f9d..f9876b612 100644 --- a/utils/kamctl/xhttp_pi/lcr-mod +++ b/utils/kamctl/xhttp_pi/lcr-mod @@ -1,4 +1,4 @@ - + lcr_gw show lcr_gw @@ -69,7 +69,7 @@ - + lcr_rule_target show lcr_rule_target @@ -116,7 +116,7 @@ - + lcr_rule show lcr_rule diff --git a/utils/kamctl/xhttp_pi/matrix-mod b/utils/kamctl/xhttp_pi/matrix-mod index a5607b3f6..808f3d861 100644 --- a/utils/kamctl/xhttp_pi/matrix-mod +++ b/utils/kamctl/xhttp_pi/matrix-mod @@ -1,4 +1,4 @@ - + matrix show matrix diff --git a/utils/kamctl/xhttp_pi/mohqueue-mod b/utils/kamctl/xhttp_pi/mohqueue-mod index bb8981e2b..f26475cf0 100644 --- a/utils/kamctl/xhttp_pi/mohqueue-mod +++ b/utils/kamctl/xhttp_pi/mohqueue-mod @@ -1,4 +1,4 @@ - + mohqcalls show mohqcalls @@ -48,7 +48,7 @@ - + mohqueues show mohqueues diff --git a/utils/kamctl/xhttp_pi/msilo-mod b/utils/kamctl/xhttp_pi/msilo-mod index e79dcc0b8..acfe004b1 100644 --- a/utils/kamctl/xhttp_pi/msilo-mod +++ b/utils/kamctl/xhttp_pi/msilo-mod @@ -1,4 +1,4 @@ - + silo show silo diff --git a/utils/kamctl/xhttp_pi/mtree-mod b/utils/kamctl/xhttp_pi/mtree-mod index 8118b52f7..8faf525b3 100644 --- a/utils/kamctl/xhttp_pi/mtree-mod +++ b/utils/kamctl/xhttp_pi/mtree-mod @@ -1,4 +1,4 @@ - + mtree show mtree @@ -36,7 +36,7 @@ - + mtrees show mtrees diff --git a/utils/kamctl/xhttp_pi/pdt-mod b/utils/kamctl/xhttp_pi/pdt-mod index 991fa088d..2eaf839d8 100644 --- a/utils/kamctl/xhttp_pi/pdt-mod +++ b/utils/kamctl/xhttp_pi/pdt-mod @@ -1,4 +1,4 @@ - + pdt show pdt diff --git a/utils/kamctl/xhttp_pi/permissions-mod b/utils/kamctl/xhttp_pi/permissions-mod index 4e62446bd..5bbd4bfd5 100644 --- a/utils/kamctl/xhttp_pi/permissions-mod +++ b/utils/kamctl/xhttp_pi/permissions-mod @@ -1,4 +1,4 @@ - + trusted show trusted @@ -48,7 +48,7 @@ - + address show address diff --git a/utils/kamctl/xhttp_pi/pi_framework.xml b/utils/kamctl/xhttp_pi/pi_framework.xml index 6dd91a726..95180efed 100644 --- a/utils/kamctl/xhttp_pi/pi_framework.xml +++ b/utils/kamctl/xhttp_pi/pi_framework.xml @@ -1033,7 +1033,7 @@ - '!=' '!=' --> - + acc show acc @@ -1086,7 +1086,7 @@ - + acc_cdrs show acc_cdrs @@ -1127,7 +1127,7 @@ - + missed_calls show missed_calls @@ -1180,7 +1180,7 @@ - + dbaliases show dbaliases @@ -1224,7 +1224,7 @@ - + subscriber show subscriber @@ -1271,7 +1271,7 @@ - + usr_preferences show usr_preferences @@ -1324,7 +1324,7 @@ - + carrierroute show carrierroute @@ -1389,7 +1389,7 @@ - + carrierfailureroute show carrierfailureroute @@ -1448,7 +1448,7 @@ - + carrier_name show carrier_name @@ -1483,7 +1483,7 @@ - + domain_name show domain_name @@ -1518,7 +1518,7 @@ - + cpl show cpl @@ -1562,7 +1562,7 @@ - + dialog show dialog @@ -1663,7 +1663,7 @@ - + dialog_vars show dialog_vars @@ -1707,7 +1707,7 @@ - + dialplan show dialplan @@ -1763,7 +1763,7 @@ - + dispatcher show dispatcher @@ -1813,7 +1813,7 @@ - + domain show domain @@ -1854,7 +1854,7 @@ - + domain_attrs show domain_attrs @@ -1901,7 +1901,7 @@ - + domainpolicy show domainpolicy @@ -1948,7 +1948,7 @@ - + dr_gateways show dr_gateways @@ -1998,7 +1998,7 @@ - + dr_rules show dr_rules @@ -2051,7 +2051,7 @@ - + dr_gw_lists show dr_gw_lists @@ -2089,7 +2089,7 @@ - + dr_groups show dr_groups @@ -2133,7 +2133,7 @@ - + grp show grp @@ -2177,7 +2177,7 @@ - + re_grp show re_grp @@ -2215,7 +2215,7 @@ - + htable show htable @@ -2262,7 +2262,7 @@ - + imc_rooms show imc_rooms @@ -2303,7 +2303,7 @@ - + imc_members show imc_members @@ -2347,7 +2347,7 @@ - + lcr_gw show lcr_gw @@ -2418,7 +2418,7 @@ - + lcr_rule_target show lcr_rule_target @@ -2465,7 +2465,7 @@ - + lcr_rule show lcr_rule @@ -2518,7 +2518,7 @@ - + matrix show matrix @@ -2559,7 +2559,7 @@ - + mohqcalls show mohqcalls @@ -2609,7 +2609,7 @@ - + mohqueues show mohqueues @@ -2656,7 +2656,7 @@ - + silo show silo @@ -2724,7 +2724,7 @@ - + mtree show mtree @@ -2762,7 +2762,7 @@ - + mtrees show mtrees @@ -2803,7 +2803,7 @@ - + pdt show pdt @@ -2844,7 +2844,7 @@ - + trusted show trusted @@ -2894,7 +2894,7 @@ - + address show address @@ -2941,7 +2941,7 @@ - + pl_pipes show pl_pipes @@ -2982,7 +2982,7 @@ - + presentity show presentity @@ -3044,7 +3044,7 @@ - + active_watchers show active_watchers @@ -3154,7 +3154,7 @@ - + watchers show watchers @@ -3207,7 +3207,7 @@ - + xcap show xcap @@ -3263,7 +3263,7 @@ - + pua show pua @@ -3349,7 +3349,7 @@ - + purplemap show purplemap @@ -3393,7 +3393,7 @@ - + aliases show aliases @@ -3491,7 +3491,7 @@ - + rls_presentity show rls_presentity @@ -3547,7 +3547,7 @@ - + rls_watchers show rls_watchers @@ -3648,7 +3648,7 @@ - + rtpengine show rtpengine @@ -3695,7 +3695,7 @@ - + rtpproxy show rtpproxy @@ -3742,7 +3742,7 @@ - + sca_subscriptions show sca_subscriptions @@ -3813,7 +3813,7 @@ - + secfilter show secfilter @@ -3854,7 +3854,7 @@ - + sip_trace show sip_trace @@ -3922,7 +3922,7 @@ - + speed_dial show speed_dial @@ -3978,7 +3978,7 @@ - + version show version @@ -4016,7 +4016,7 @@ - + topos_d show topos_d @@ -4120,7 +4120,7 @@ - + topos_t show topos_t @@ -4227,7 +4227,7 @@ - + uacreg show uacreg @@ -4304,7 +4304,7 @@ - + uid_credentials show uid_credentials @@ -4360,7 +4360,7 @@ - + uid_user_attrs show uid_user_attrs @@ -4407,7 +4407,7 @@ - + uid_domain show uid_domain @@ -4448,7 +4448,7 @@ - + uid_domain_attrs show uid_domain_attrs @@ -4495,7 +4495,7 @@ - + uid_global_attrs show uid_global_attrs @@ -4539,7 +4539,7 @@ - + uid_uri show uid_uri @@ -4586,7 +4586,7 @@ - + uid_uri_attrs show uid_uri_attrs @@ -4639,7 +4639,7 @@ - + uri show uri @@ -4683,7 +4683,7 @@ - + userblocklist show userblocklist @@ -4727,7 +4727,7 @@ - + globalblocklist show globalblocklist @@ -4768,7 +4768,7 @@ - + location show location @@ -4866,7 +4866,7 @@ - + location_attrs show location_attrs diff --git a/utils/kamctl/xhttp_pi/pipelimit-mod b/utils/kamctl/xhttp_pi/pipelimit-mod index a2f3686fa..48fdea63a 100644 --- a/utils/kamctl/xhttp_pi/pipelimit-mod +++ b/utils/kamctl/xhttp_pi/pipelimit-mod @@ -1,4 +1,4 @@ - + pl_pipes show pl_pipes diff --git a/utils/kamctl/xhttp_pi/presence-mod b/utils/kamctl/xhttp_pi/presence-mod index 652c2a421..59a58fa07 100644 --- a/utils/kamctl/xhttp_pi/presence-mod +++ b/utils/kamctl/xhttp_pi/presence-mod @@ -1,4 +1,4 @@ - + presentity show presentity @@ -60,7 +60,7 @@ - + active_watchers show active_watchers @@ -170,7 +170,7 @@ - + watchers show watchers @@ -223,7 +223,7 @@ - + xcap show xcap @@ -279,7 +279,7 @@ - + pua show pua diff --git a/utils/kamctl/xhttp_pi/purple-mod b/utils/kamctl/xhttp_pi/purple-mod index b54a802a8..c2e9edde4 100644 --- a/utils/kamctl/xhttp_pi/purple-mod +++ b/utils/kamctl/xhttp_pi/purple-mod @@ -1,4 +1,4 @@ - + purplemap show purplemap diff --git a/utils/kamctl/xhttp_pi/registrar-mod b/utils/kamctl/xhttp_pi/registrar-mod index c5aad1091..747675fc6 100644 --- a/utils/kamctl/xhttp_pi/registrar-mod +++ b/utils/kamctl/xhttp_pi/registrar-mod @@ -1,4 +1,4 @@ - + aliases show aliases diff --git a/utils/kamctl/xhttp_pi/rls-mod b/utils/kamctl/xhttp_pi/rls-mod index dada3b76e..92d72b96e 100644 --- a/utils/kamctl/xhttp_pi/rls-mod +++ b/utils/kamctl/xhttp_pi/rls-mod @@ -1,4 +1,4 @@ - + rls_presentity show rls_presentity @@ -54,7 +54,7 @@ - + rls_watchers show rls_watchers diff --git a/utils/kamctl/xhttp_pi/rtpengine-mod b/utils/kamctl/xhttp_pi/rtpengine-mod index df9eafce9..c9680f7d7 100644 --- a/utils/kamctl/xhttp_pi/rtpengine-mod +++ b/utils/kamctl/xhttp_pi/rtpengine-mod @@ -1,4 +1,4 @@ - + rtpengine show rtpengine diff --git a/utils/kamctl/xhttp_pi/rtpproxy-mod b/utils/kamctl/xhttp_pi/rtpproxy-mod index c13a40ee8..18860d4d2 100644 --- a/utils/kamctl/xhttp_pi/rtpproxy-mod +++ b/utils/kamctl/xhttp_pi/rtpproxy-mod @@ -1,4 +1,4 @@ - + rtpproxy show rtpproxy diff --git a/utils/kamctl/xhttp_pi/sca-mod b/utils/kamctl/xhttp_pi/sca-mod index 0aed314d1..d774b40fd 100644 --- a/utils/kamctl/xhttp_pi/sca-mod +++ b/utils/kamctl/xhttp_pi/sca-mod @@ -1,4 +1,4 @@ - + sca_subscriptions show sca_subscriptions diff --git a/utils/kamctl/xhttp_pi/secfilter-mod b/utils/kamctl/xhttp_pi/secfilter-mod index 3a45d6d42..abad1bc50 100644 --- a/utils/kamctl/xhttp_pi/secfilter-mod +++ b/utils/kamctl/xhttp_pi/secfilter-mod @@ -1,4 +1,4 @@ - + secfilter show secfilter diff --git a/utils/kamctl/xhttp_pi/siptrace-mod b/utils/kamctl/xhttp_pi/siptrace-mod index ce7e1cc64..09d62d305 100644 --- a/utils/kamctl/xhttp_pi/siptrace-mod +++ b/utils/kamctl/xhttp_pi/siptrace-mod @@ -1,4 +1,4 @@ - + sip_trace show sip_trace diff --git a/utils/kamctl/xhttp_pi/speeddial-mod b/utils/kamctl/xhttp_pi/speeddial-mod index 883c7dfd8..d452b0fb7 100644 --- a/utils/kamctl/xhttp_pi/speeddial-mod +++ b/utils/kamctl/xhttp_pi/speeddial-mod @@ -1,4 +1,4 @@ - + speed_dial show speed_dial diff --git a/utils/kamctl/xhttp_pi/standard-mod b/utils/kamctl/xhttp_pi/standard-mod index 95b1068e9..11d90d2a3 100644 --- a/utils/kamctl/xhttp_pi/standard-mod +++ b/utils/kamctl/xhttp_pi/standard-mod @@ -1,4 +1,4 @@ - + version show version diff --git a/utils/kamctl/xhttp_pi/topos-mod b/utils/kamctl/xhttp_pi/topos-mod index cfae6af96..55004e12c 100644 --- a/utils/kamctl/xhttp_pi/topos-mod +++ b/utils/kamctl/xhttp_pi/topos-mod @@ -1,4 +1,4 @@ - + topos_d show topos_d @@ -102,7 +102,7 @@ - + topos_t show topos_t diff --git a/utils/kamctl/xhttp_pi/uac-mod b/utils/kamctl/xhttp_pi/uac-mod index 284be1b47..c1017f540 100644 --- a/utils/kamctl/xhttp_pi/uac-mod +++ b/utils/kamctl/xhttp_pi/uac-mod @@ -1,4 +1,4 @@ - + uacreg show uacreg diff --git a/utils/kamctl/xhttp_pi/uid_auth_db-mod b/utils/kamctl/xhttp_pi/uid_auth_db-mod index 93cbea723..2f538898b 100644 --- a/utils/kamctl/xhttp_pi/uid_auth_db-mod +++ b/utils/kamctl/xhttp_pi/uid_auth_db-mod @@ -1,4 +1,4 @@ - + uid_credentials show uid_credentials diff --git a/utils/kamctl/xhttp_pi/uid_avp_db-mod b/utils/kamctl/xhttp_pi/uid_avp_db-mod index 61dfb043b..d419d74d6 100644 --- a/utils/kamctl/xhttp_pi/uid_avp_db-mod +++ b/utils/kamctl/xhttp_pi/uid_avp_db-mod @@ -1,4 +1,4 @@ - + uid_user_attrs show uid_user_attrs diff --git a/utils/kamctl/xhttp_pi/uid_domain-mod b/utils/kamctl/xhttp_pi/uid_domain-mod index 639b68b64..e4a058b1b 100644 --- a/utils/kamctl/xhttp_pi/uid_domain-mod +++ b/utils/kamctl/xhttp_pi/uid_domain-mod @@ -1,4 +1,4 @@ - + uid_domain show uid_domain @@ -39,7 +39,7 @@ - + uid_domain_attrs show uid_domain_attrs diff --git a/utils/kamctl/xhttp_pi/uid_gflags-mod b/utils/kamctl/xhttp_pi/uid_gflags-mod index a856f4cc1..d11f09ba7 100644 --- a/utils/kamctl/xhttp_pi/uid_gflags-mod +++ b/utils/kamctl/xhttp_pi/uid_gflags-mod @@ -1,4 +1,4 @@ - + uid_global_attrs show uid_global_attrs diff --git a/utils/kamctl/xhttp_pi/uid_uri_db-mod b/utils/kamctl/xhttp_pi/uid_uri_db-mod index b9de6f2a6..dab23a8e1 100644 --- a/utils/kamctl/xhttp_pi/uid_uri_db-mod +++ b/utils/kamctl/xhttp_pi/uid_uri_db-mod @@ -1,4 +1,4 @@ - + uid_uri show uid_uri @@ -45,7 +45,7 @@ - + uid_uri_attrs show uid_uri_attrs diff --git a/utils/kamctl/xhttp_pi/uri_db-mod b/utils/kamctl/xhttp_pi/uri_db-mod index d396f34da..36ac282ce 100644 --- a/utils/kamctl/xhttp_pi/uri_db-mod +++ b/utils/kamctl/xhttp_pi/uri_db-mod @@ -1,4 +1,4 @@ - + uri show uri diff --git a/utils/kamctl/xhttp_pi/userblocklist-mod b/utils/kamctl/xhttp_pi/userblocklist-mod index bd9347734..1affb5d8e 100644 --- a/utils/kamctl/xhttp_pi/userblocklist-mod +++ b/utils/kamctl/xhttp_pi/userblocklist-mod @@ -1,4 +1,4 @@ - + userblocklist show userblocklist @@ -42,7 +42,7 @@ - + globalblocklist show globalblocklist diff --git a/utils/kamctl/xhttp_pi/usrloc-mod b/utils/kamctl/xhttp_pi/usrloc-mod index 9f456baeb..bfc2c9359 100644 --- a/utils/kamctl/xhttp_pi/usrloc-mod +++ b/utils/kamctl/xhttp_pi/usrloc-mod @@ -1,4 +1,4 @@ - + location show location @@ -96,7 +96,7 @@ - + location_attrs show location_attrs diff --git a/utils/kamunix/kamunix.8 b/utils/kamunix/kamunix.8 index afe0b3a31..645dc189e 100644 --- a/utils/kamunix/kamunix.8 +++ b/utils/kamunix/kamunix.8 @@ -19,7 +19,7 @@ This is a binary alternative to the textual FIFO interface. .B kamunix reads from standard input one .B Kamailio -command along with its paramters (if any) and prints the response +command along with its parameters (if any) and prints the response to standard output. .SH PARAMETERS @@ -46,11 +46,11 @@ see .BR kamailio(8), kamailio.cfg(5), kamctl(8) .PP Full documentation on Kamailio is available at -.I http://www.kamailio.org/. +.I https://www.kamailio.org/. .PP Mailing lists: .nf -users@lists.kamailio.org - Kamailio user community +sr-users@lists.kamailio.org - Kamailio user community .nf -devel@lists.kamailio.org - Kamailio development, new features and unstable version +sr-dev@lists.kamailio.org - Kamailio development, new features and unstable version diff --git a/utils/kamunix/kamunix.c b/utils/kamunix/kamunix.c index f914aec56..6b06e29a2 100644 --- a/utils/kamunix/kamunix.c +++ b/utils/kamunix/kamunix.c @@ -41,15 +41,15 @@ /* solaris doesn't have SUN_LEN */ #ifndef SUN_LEN -#define SUN_LEN(sa) \ - (strlen((sa)->sun_path) + (size_t)(((struct sockaddr_un *)0)->sun_path)) +#define SUN_LEN(sa) ( strlen((sa)->sun_path) + \ + (size_t)(((struct sockaddr_un*)0)->sun_path) ) #endif #define BUF_SIZE 65536 #define DEFAULT_TIMEOUT 5 -int main(int argc, char **argv) +int main(int argc, char** argv) { int sock, len; socklen_t from_len; @@ -58,13 +58,13 @@ int main(int argc, char **argv) static char buffer[BUF_SIZE]; char *chroot_dir; - if(argc != 2) { + if (argc != 2) { printf("Usage: %s \n", argv[0]); return 1; } sock = socket(PF_LOCAL, SOCK_DGRAM, 0); - if(sock == -1) { + if (sock == -1) { fprintf(stderr, "Error while opening socket: %s\n", strerror(errno)); return -1; } @@ -73,25 +73,25 @@ int main(int argc, char **argv) from.sun_family = PF_LOCAL; chroot_dir = getenv("CHROOT_DIR"); - if(chroot_dir == NULL) + if (chroot_dir == NULL) chroot_dir = ""; snprintf(name, 256, "%s/tmp/Kamailio.%d.XXXXXX", chroot_dir, getpid()); umask(0); /* set mode to 0666 for when Kamailio is running as non-root user * and kamctl is running as root */ - if(mkstemp(name) == -1) { - fprintf(stderr, "Error in mkstemp with name=%s: %s\n", name, - strerror(errno)); + if (mkstemp(name) == -1) { + fprintf(stderr, "Error in mkstemp with name=%s: %s\n", + name, strerror(errno)); return -2; } - if(unlink(name) == -1) { + if (unlink(name) == -1) { fprintf(stderr, "Error in unlink of %s: %s\n", name, strerror(errno)); return -2; } strncpy(from.sun_path, name, strlen(name)); - if(bind(sock, (struct sockaddr *)&from, SUN_LEN(&from)) == -1) { + if (bind(sock, (struct sockaddr*)&from, SUN_LEN(&from)) == -1) { fprintf(stderr, "Error in bind: %s\n", strerror(errno)); goto err; } @@ -102,16 +102,16 @@ int main(int argc, char **argv) len = fread(buffer, 1, BUF_SIZE, stdin); - if(len) { - if(sendto(sock, buffer, len, 0, (struct sockaddr *)&to, SUN_LEN(&to)) - == -1) { + if (len) { + if (sendto(sock, buffer, len, 0, (struct sockaddr*)&to, + SUN_LEN(&to)) == -1) { fprintf(stderr, "Error in sendto: %s\n", strerror(errno)); - goto err; + goto err; } from_len = sizeof(from); - len = recvfrom( - sock, buffer, BUF_SIZE, 0, (struct sockaddr *)&from, &from_len); - if(len == -1) { + len = recvfrom(sock, buffer, BUF_SIZE, 0, + (struct sockaddr*)&from, &from_len); + if (len == -1) { fprintf(stderr, "Error in recvfrom: %s\n", strerror(errno)); goto err; } @@ -123,13 +123,13 @@ int main(int argc, char **argv) } close(sock); - if(unlink(name) == -1) + if (unlink(name) == -1) fprintf(stderr, "Error in unlink of %s: %s\n", name, strerror(errno)); return 0; -err: + err: close(sock); - if(unlink(name) == -1) + if (unlink(name) == -1) fprintf(stderr, "Error in unlink of %s: %s\n", name, strerror(errno)); return -1; } diff --git a/utils/pdbt/carrier.c b/utils/pdbt/carrier.c index c71d9f2ab..d7edf1ccc 100644 --- a/utils/pdbt/carrier.c +++ b/utils/pdbt/carrier.c @@ -27,93 +27,92 @@ #include -char *cnames[MAX_CARRIERID + 1]; +char *cnames[MAX_CARRIERID+1]; -void init_carrier_names() -{ + + + +void init_carrier_names() { int i; - for(i = 0; i <= MAX_CARRIERID; i++) - cnames[i] = NULL; + for (i=0; i<=MAX_CARRIERID; i++) cnames[i]=NULL; cnames[OTHER_CARRIERID] = "other carriers merged by this tool"; } -int load_carrier_names(char *filename) -{ - FILE *fp; - char *line = NULL; + + +int load_carrier_names(char *filename) { + FILE * fp; + char * line = NULL; size_t len = 0; ssize_t read; char *p; int n; char idstr[4]; long int id; - int ret = 0; + int ret=0; - idstr[3] = 0; + idstr[3]=0; fp = fopen(filename, "r"); - if(fp == NULL) { + if (fp == NULL) { LERR("cannot open file '%s'\n", filename); return -1; } - n = 1; - while((read = getline(&line, &len, fp)) != -1) { - p = line; - len = strlen(p); + n=1; + while ((read = getline(&line, &len, fp)) != -1) { + p=line; + len=strlen(p); - if(len <= 5) { + if (len<=5) { LWARNING("invalid line %ld\n", (long int)n); - ret = -1; + ret=-1; goto nextline; } idstr[0] = p[1]; idstr[1] = p[2]; idstr[2] = p[3]; - p += 5; - len -= 5; + p+=5; + len-=5; id = strtol(idstr, NULL, 10); - if(!IS_VALID_PDB_CARRIERID(id)) { + if (!IS_VALID_PDB_CARRIERID(id)) { LWARNING("invalid carrier id '%s'\n", idstr); - ret = -1; + ret=-1; goto nextline; } - cnames[id] = malloc(len + 1); - if(cnames[id] == NULL) { + cnames[id]=malloc(len+1); + if (cnames[id]==NULL) { LERR("out of memory (needed %ld bytes)\n", (long int)len); - ret = -1; + ret=-1; exit(-1); } strncpy(cnames[id], p, len - 1); - cnames[id][len - 1] = 0; + cnames[id][len - 1]=0; nextline: n++; } - if(line) - free(line); + if (line) free(line); fclose(fp); return ret; } -char *carrierid2name(carrier_t carrier) -{ + + +char *carrierid2name(carrier_t carrier) { char *s; - if(!IS_VALID_CARRIERID(carrier)) - s = "invalid carrier id"; - else - s = cnames[carrier]; - if(s == NULL) - s = "unknown carrier"; + if (!IS_VALID_CARRIERID(carrier)) s="invalid carrier id"; + else s=cnames[carrier]; + if (s==NULL) s="unknown carrier"; return s; } diff --git a/utils/pdbt/carrier.h b/utils/pdbt/carrier.h index 2e527e0ba..7eed56422 100644 --- a/utils/pdbt/carrier.h +++ b/utils/pdbt/carrier.h @@ -22,9 +22,13 @@ #define _CARRIER_H_ + + #include "common.h" + + /* Initializes data structures. Must be called before any of the other functions! @@ -45,4 +49,6 @@ int load_carrier_names(char *filename); char *carrierid2name(carrier_t carrier); + + #endif diff --git a/utils/pdbt/common.c b/utils/pdbt/common.c index 13c9bf3ae..f5bc54ecc 100644 --- a/utils/pdbt/common.c +++ b/utils/pdbt/common.c @@ -2,47 +2,48 @@ #include "log.h" #include -void pdb_msg_dbg(struct pdb_msg msg) -{ - int i; - - LERR("version = %d\n", msg.hdr.version); - LERR("type = %d\n", msg.hdr.type); - LERR("code = %d\n", msg.hdr.code); - LERR("id = %d\n", msg.hdr.id); - LERR("len = %d\n", msg.hdr.length); - LERR("payload = "); - - if(msg.hdr.length > sizeof(msg.hdr)) { - for(i = 0; i < msg.hdr.length - sizeof(msg.hdr); i++) { - LERR("%02X ", msg.bdy.payload[i]); - } - } else { - LERR("Incorrect value in msg.hdr.length \n"); - } - - LERR("\n"); - - return; +void pdb_msg_dbg(struct pdb_msg msg) { + int i; + + LERR("version = %d\n", msg.hdr.version); + LERR("type = %d\n", msg.hdr.type); + LERR("code = %d\n", msg.hdr.code); + LERR("id = %d\n", msg.hdr.id); + LERR("len = %d\n", msg.hdr.length); + LERR("payload = "); + + if(msg.hdr.length > sizeof(msg.hdr)) { + for (i = 0; i < msg.hdr.length - sizeof(msg.hdr); i++) { + LERR("%02X ", msg.bdy.payload[i]); + } + } else { + LERR("Incorrect value in msg.hdr.length \n"); + } + + LERR("\n"); + + return ; } -int pdb_msg_format_send(struct pdb_msg *msg, uint8_t version, uint8_t type, - uint8_t code, uint16_t id, char *payload, uint16_t payload_len) +int pdb_msg_format_send(struct pdb_msg *msg, + uint8_t version, uint8_t type, + uint8_t code, uint16_t id, + char *payload, uint16_t payload_len) { - msg->hdr.version = version; - msg->hdr.type = type; - msg->hdr.code = code; - msg->hdr.id = id; - - if(payload == NULL) { - /* just ignore the NULL buff (called when just want to set the len) */ - msg->hdr.length = sizeof(struct pdb_hdr); - return 0; - } else { - msg->hdr.length = sizeof(struct pdb_hdr) + payload_len; - memcpy(msg->bdy.payload, payload, payload_len); - return 0; - } - - return 0; + msg->hdr.version = version; + msg->hdr.type = type; + msg->hdr.code = code; + msg->hdr.id = id; + + if (payload == NULL) { + /* just ignore the NULL buff (called when just want to set the len) */ + msg->hdr.length = sizeof(struct pdb_hdr); + return 0; + } else { + msg->hdr.length = sizeof(struct pdb_hdr) + payload_len; + memcpy(msg->bdy.payload, payload, payload_len); + return 0; + } + + return 0; } diff --git a/utils/pdbt/common.h b/utils/pdbt/common.h index 7d121430f..2146109a2 100644 --- a/utils/pdbt/common.h +++ b/utils/pdbt/common.h @@ -22,9 +22,13 @@ #define _COMMON_H_ + + #include + + /* 0 no carrier id defined. 1..999 are regular carrier ids. @@ -40,61 +44,57 @@ #define PAYLOADSIZE 256 -#define IS_VALID_PDB_CARRIERID(id) \ - ((id >= MIN_PDB_CARRIERID) && (id <= MAX_PDB_CARRIERID)) -#define IS_VALID_CARRIERID(id) \ - ((id >= MIN_PDB_CARRIERID) && (id <= MAX_CARRIERID)) +#define IS_VALID_PDB_CARRIERID(id) ((id>=MIN_PDB_CARRIERID) && (id<=MAX_PDB_CARRIERID)) +#define IS_VALID_CARRIERID(id) ((id>=MIN_PDB_CARRIERID) && (id<=MAX_CARRIERID)) + +#define PDB_VERSION 1 -#define PDB_VERSION 1 typedef int16_t carrier_t; -enum __attribute__((packed)) pdb_versions -{ - PDB_VERSION_1 = 1, - PDB_VERSION_MAX +enum __attribute__((packed)) pdb_versions { + PDB_VERSION_1 = 1, + PDB_VERSION_MAX }; -enum __attribute__((packed)) pdb_types -{ - PDB_TYPE_REQUEST_ID = 0, /* request pdb type */ - PDB_TYPE_REPLY_ID, /* reply pdb type */ - PDB_TYPE_MAX +enum __attribute__((packed)) pdb_types { + PDB_TYPE_REQUEST_ID = 0, /* request pdb type */ + PDB_TYPE_REPLY_ID, /* reply pdb type */ + PDB_TYPE_MAX }; -enum __attribute__((packed)) pdb_codes -{ - PDB_CODE_DEFAULT = 0, /* for request */ - PDB_CODE_OK, /* for response - OK */ - PDB_CODE_NOT_NUMBER, /* for response - letters found in the number */ - PDB_CODE_NOT_FOUND, /* for response - no pdb_id found for the number */ - PDB_CODE_MAX +enum __attribute__((packed)) pdb_codes { + PDB_CODE_DEFAULT = 0, /* for request */ + PDB_CODE_OK, /* for response - OK */ + PDB_CODE_NOT_NUMBER, /* for response - letters found in the number */ + PDB_CODE_NOT_FOUND, /* for response - no pdb_id found for the number */ + PDB_CODE_MAX }; -struct __attribute__((packed)) pdb_hdr -{ - uint8_t version; - uint8_t type; - uint8_t code; - uint8_t length; - uint16_t id; +struct __attribute__((packed)) pdb_hdr { + uint8_t version; + uint8_t type; + uint8_t code; + uint8_t length; + uint16_t id; }; -struct __attribute__((packed)) pdb_bdy -{ - char payload[PAYLOADSIZE]; +struct __attribute__((packed)) pdb_bdy { + char payload[PAYLOADSIZE]; }; -struct __attribute__((packed)) pdb_msg -{ - struct pdb_hdr hdr; - struct pdb_bdy bdy; +struct __attribute__((packed)) pdb_msg { + struct pdb_hdr hdr; + struct pdb_bdy bdy; }; -void pdb_msg_dbg(struct pdb_msg msg); -int pdb_msg_format_send(struct pdb_msg *msg, uint8_t version, uint8_t type, - uint8_t code, uint16_t id, char *payload, uint16_t payload_len); + +void pdb_msg_dbg (struct pdb_msg msg); +int pdb_msg_format_send(struct pdb_msg *msg, + uint8_t version, uint8_t type, + uint8_t code, uint16_t id, + char *payload, uint16_t payload_len); #endif diff --git a/utils/pdbt/docs/network_protocol.txt b/utils/pdbt/docs/network_protocol.txt index 3830c1076..c3d8ee7e4 100644 --- a/utils/pdbt/docs/network_protocol.txt +++ b/utils/pdbt/docs/network_protocol.txt @@ -12,7 +12,7 @@ in network byte order (most significant byte first). Possible values for the search request: * 0: the number could not be found * 1-999 the number was found and the result represents its carrier ID - * 1000: the number could be found, but its owned from a carriers which is + * 1000: the number could be found, but it is owned from a carrier which is not interesting for us and belongs to the "other carrier" group diff --git a/utils/pdbt/dt.c b/utils/pdbt/dt.c index 44df67389..8c4f2a670 100644 --- a/utils/pdbt/dt.c +++ b/utils/pdbt/dt.c @@ -27,12 +27,14 @@ #include + + struct dt_node_t *dt_init() { struct dt_node_t *root; root = malloc(sizeof(struct dt_node_t)); - if(root == NULL) { + if (root == NULL) { LERR("dt_init() cannot allocate memory for dt_node_t.\n"); return NULL; } @@ -43,25 +45,27 @@ struct dt_node_t *dt_init() } + + void dt_delete(struct dt_node_t *root, struct dt_node_t *node) { int i; - if(node == NULL) - return; + if (node==NULL) return; - for(i = 0; i < 10; i++) { + for (i=0; i<10; i++) { dt_delete(root, node->child[i]); node->child[i] = NULL; } - if(node != root) - free(node); + if (node != root) free(node); } + + void dt_destroy(struct dt_node_t **root) { - if((root != NULL) && (*root != NULL)) { + if ((root != NULL) && (*root != NULL)) { dt_delete(*root, *root); free(*root); *root = NULL; @@ -69,6 +73,8 @@ void dt_destroy(struct dt_node_t **root) } + + void dt_clear(struct dt_node_t *root) { dt_delete(root, root); @@ -76,25 +82,26 @@ void dt_clear(struct dt_node_t *root) } -int dt_insert(struct dt_node_t *root, const char *number, int numberlen, - carrier_t carrier) + + +int dt_insert(struct dt_node_t *root, const char *number, int numberlen, carrier_t carrier) { struct dt_node_t *node = root; - int i = 0; + int i=0; unsigned int digit; - while(i < numberlen) { + while (i 9) { + if (digit>9) { LERR("dt_insert() cannot insert non-numerical number\n"); return -1; } - if(node->child[digit] == NULL) { + if (node->child[digit] == NULL) { node->child[digit] = malloc(sizeof(struct dt_node_t)); #ifdef DT_MEM_ASSERT assert(node->child[digit] != NULL); #else - if(node->child[digit] == NULL) { + if (node->child[digit] == NULL) { LERR("dt_insert() cannot allocate memory\n"); return -1; } @@ -112,79 +119,80 @@ int dt_insert(struct dt_node_t *root, const char *number, int numberlen, } + + int dt_size(struct dt_node_t *root) { int i; int sum = 0; - if(root == NULL) - return 0; + if (root == NULL) return 0; - for(i = 0; i < 10; i++) { + for (i=0; i<10; i++) { sum += dt_size(root->child[i]); } - return sum + 1; + return sum+1; } -int dt_loaded_nodes(struct dt_node_t *root) -{ + + +int dt_loaded_nodes(struct dt_node_t *root) { int i; int sum = 0; - if(root == NULL) - return 0; + if (root == NULL) return 0; - for(i = 0; i < 10; i++) { + for (i=0; i<10; i++) { sum += dt_loaded_nodes(root->child[i]); } - if(root->carrier > 0) - sum++; + if (root->carrier > 0) sum++; return sum; } + + int dt_leaves(struct dt_node_t *root) { int i; int sum = 0; int leaf = 1; - for(i = 0; i < 10; i++) { - if(root->child[i]) { + for (i=0; i<10; i++) { + if (root->child[i]) { sum += dt_leaves(root->child[i]); leaf = 0; } } - return sum + leaf; + return sum+leaf; } -int dt_longest_match(struct dt_node_t *root, const char *number, int numberlen, - carrier_t *carrier) + + +int dt_longest_match(struct dt_node_t *root, const char *number, int numberlen, carrier_t *carrier) { struct dt_node_t *node = root; int nmatch = -1; - int i = 0; + int i=0; unsigned int digit; - if(node->carrier > 0) { - nmatch = 0; + if (node->carrier > 0) { + nmatch=0; *carrier = node->carrier; } - while(i < numberlen) { + while (i 9) - return nmatch; - if(node->child[digit] == NULL) - return nmatch; + if (digit>9) return nmatch; + if (node->child[digit] == NULL) return nmatch; node = node->child[digit]; i++; - if(node->carrier > 0) { - nmatch = i; + if (node->carrier > 0) { + nmatch=i; *carrier = node->carrier; } } @@ -193,44 +201,45 @@ int dt_longest_match(struct dt_node_t *root, const char *number, int numberlen, } -int dt_contains(struct dt_node_t *root, const char *number, int numberlen, - carrier_t *carrier) + + +int dt_contains(struct dt_node_t *root, const char *number, int numberlen, carrier_t *carrier) { - return (dt_longest_match(root, number, numberlen, carrier) == numberlen); + return (dt_longest_match(root, number, numberlen, carrier) == numberlen); } + + /* Returns the carrier if all children have the same carrier, 0 otherwise. */ -carrier_t dt_allcce(struct dt_node_t *root) -{ +carrier_t dt_allcce(struct dt_node_t *root) { int i; carrier_t ret = 0; /* determine single child carrier */ - for(i = 0; i < 10; i++) { - if(root->child[i] == NULL) + for (i=0; i<10; i++) { + if (root->child[i] == NULL) return 0; - else if(root->child[i]->carrier > 0) { - ret = root->child[i]->carrier; + else if (root->child[i]->carrier > 0) { + ret=root->child[i]->carrier; break; } } - if(ret == 0) - return 0; + if (ret==0) return 0; /* check if all children share the same carrier */ - for(i = 0; i < 10; i++) { - if((root->child[i] == NULL) || (root->child[i]->carrier != ret)) - return 0; + for (i=0; i<10; i++) { + if ((root->child[i] == NULL) || (root->child[i]->carrier != ret)) return 0; } return ret; } + /* Cuts off tree branches which share a common carrier id with a node located more upwards in the tree. To do so, the subtree starting at root will be @@ -249,34 +258,29 @@ int dt_optimize_leaf(struct dt_node_t *root, carrier_t lastcarrier) carrier_t allcce; int i; - if(node == NULL) - return 0; + if (node == NULL) return 0; - if(node->carrier == lastcarrier) { - node->carrier = 0; /* this is a node sharing carrier id */ + if (node->carrier == lastcarrier) { + node->carrier = 0; /* this is a node sharing carrier id */ } - if(node->carrier > 0) - currentcarrier = - node->carrier; /* new common carrier id starts at this node */ - else - currentcarrier = lastcarrier; /* carry over common carrier id */ + if (node->carrier>0) currentcarrier=node->carrier; /* new common carrier id starts at this node */ + else currentcarrier=lastcarrier; /* carry over common carrier id */ /* Nodes with children sharing the same carrier may be generalized into a common node (prefix). Note that the code in the following if-statement is the reason why dt_optimize() calls this function multiple times. */ - if((allcce = dt_allcce(node))) { + if ((allcce=dt_allcce(node))) { /* generalization requires having an intermediary parent node or a common carrier id between all children and the current node */ - if((node->carrier == 0) - || (node->carrier < 0 && allcce == currentcarrier)) { - currentcarrier = allcce; - node->carrier = currentcarrier; - for(i = 0; i < 10; i++) { + if ((node->carrier == 0) || (node->carrier < 0 && allcce == currentcarrier)) { + currentcarrier=allcce; + node->carrier=currentcarrier; + for(i=0; i<10; i++) { /* Negative carrier ids mark children eligible for generalization into a parent node. Carrier id 0 cannot be used because it could ambiguously refer to an @@ -293,27 +297,25 @@ int dt_optimize_leaf(struct dt_node_t *root, carrier_t lastcarrier) } /* preliminarily assume leaf nodes without carrier to be eligible for removal */ - if(node->carrier <= 0) - deleteret = 1; - else - deleteret = 0; + if (node->carrier <= 0) deleteret=1; + else deleteret=0; /* optimize children */ - for(i = 0; i < 10; i++) { - delete = dt_optimize_leaf(node->child[i], currentcarrier); - if(delete) { + for (i=0; i<10; i++) { + delete=dt_optimize_leaf(node->child[i], currentcarrier); + if (delete) { dt_delete(node, node->child[i]); node->child[i] = NULL; } /* this is no leaf node ==> revert removal assumption */ - if(node->child[i]) - deleteret = 0; + if (node->child[i]) deleteret = 0; } return deleteret; } + /* Replaces negative carrier ids in the given, root-based subtree by zeros to comply with other functions which may @@ -321,37 +323,36 @@ int dt_optimize_leaf(struct dt_node_t *root, carrier_t lastcarrier) */ void dt_clear_negatives(struct dt_node_t *root) { - struct dt_node_t *node = root; - int i; + struct dt_node_t *node = root; + int i; - if(node == NULL) - return; + if (node == NULL) return; - for(i = 0; i < 10; i++) { - dt_clear_negatives(node->child[i]); - } + for (i=0; i<10; i++) { + dt_clear_negatives(node->child[i]); + } - if(node->carrier < 0) - node->carrier = 0; + if (node->carrier < 0) node->carrier = 0; } + void dt_optimize(struct dt_node_t *root) { int size; int oldsize = 0; - size = dt_size(root); + size=dt_size(root); /* optimization gradually trims leaf nodes in each invocation of dt_optimize_leaf() ==> keep calling this function until the size of the tree stabilizes */ - while(size != oldsize) { + while (size!=oldsize) { dt_optimize_leaf(root, 0); - oldsize = size; - size = dt_size(root); + oldsize=size; + size=dt_size(root); } /* turn negative carrier ids into zero's */ diff --git a/utils/pdbt/dt.h b/utils/pdbt/dt.h index 0d4f49f4b..a9a9419bb 100644 --- a/utils/pdbt/dt.h +++ b/utils/pdbt/dt.h @@ -22,16 +22,21 @@ #define _DT_H_ + + #include "common.h" -struct dt_node_t -{ + + +struct dt_node_t { struct dt_node_t *child[10]; carrier_t carrier; }; + + /* Allocates memory for the root node and initializes it. Returns a pointer to an initialized root node on success, NULL otherwise. @@ -62,8 +67,7 @@ void dt_clear(struct dt_node_t *root); digit is marked with the given carrier id. Returns 0 on success, -1 otherwise. */ -int dt_insert(struct dt_node_t *root, const char *number, int numberlen, - carrier_t carrier); +int dt_insert(struct dt_node_t *root, const char *number, int numberlen, carrier_t carrier); /* Returns the number of nodes in the given tree. @@ -89,16 +93,14 @@ int dt_leaves(struct dt_node_t *root); In case no (partial) match is found, return -1 (i.e, not even the very first digit could be prefixed). */ -int dt_longest_match(struct dt_node_t *root, const char *number, int numberlen, - carrier_t *carrier); +int dt_longest_match(struct dt_node_t *root, const char *number, int numberlen, carrier_t *carrier); /* Returns 1 if number is found in root and set *carrier according to value in dtree. Returns 0 if the number is not found. */ -int dt_contains(struct dt_node_t *root, const char *number, int numberlen, - carrier_t *carrier); +int dt_contains(struct dt_node_t *root, const char *number, int numberlen, carrier_t *carrier); /* Optimizes the tree by means of compression. Effectively, @@ -108,4 +110,6 @@ int dt_contains(struct dt_node_t *root, const char *number, int numberlen, void dt_optimize(struct dt_node_t *root); + + #endif diff --git a/utils/pdbt/dtm.c b/utils/pdbt/dtm.c index 862adfce0..34c76dfa1 100644 --- a/utils/pdbt/dtm.c +++ b/utils/pdbt/dtm.c @@ -31,30 +31,29 @@ #include -struct dtm_node_t *dtm_load(char *filename) -{ + + +struct dtm_node_t *dtm_load(char *filename) { struct dtm_node_t *mroot; int fd; int len; int nodes; fd = open(filename, O_RDONLY); - if(fd < 0) { + if (fd < 0) { LERR("cannot open file '%s'\n", filename); return NULL; } - len = lseek(fd, 0, SEEK_END); + len=lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); - nodes = len / sizeof(struct dtm_node_t); - LINFO("file contains %ld nodes (size=%ld, rest=%ld)\n", (long int)nodes, - (long int)len, (long int)len % sizeof(struct dtm_node_t)); + nodes=len/sizeof(struct dtm_node_t); + LINFO("file contains %ld nodes (size=%ld, rest=%ld)\n", (long int)nodes, (long int)len, (long int)len%sizeof(struct dtm_node_t)); - mroot = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0); - if(mroot == MAP_FAILED) { - LERR("cannot mmap file '%s', error=%d (%s)\n", filename, errno, - strerror(errno)); + mroot=mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0); + if (mroot==MAP_FAILED) { + LERR("cannot mmap file '%s', error=%d (%s)\n", filename, errno, strerror(errno)); close(fd); return NULL; } @@ -63,34 +62,33 @@ struct dtm_node_t *dtm_load(char *filename) } -int dtm_longest_match(struct dtm_node_t *mroot, const char *number, - int numberlen, carrier_t *carrier) + + +int dtm_longest_match(struct dtm_node_t *mroot, const char *number, int numberlen, carrier_t *carrier) { dtm_node_index_t node = 0; - int nmatch = -1; - int i = 0; + int nmatch = -1; + int i=0; unsigned int digit; - if(mroot[node].carrier > 0) { - nmatch = 0; + if (mroot[node].carrier > 0) { + nmatch=0; *carrier = mroot[node].carrier; } - while(i < numberlen) { + while (i 9) - return nmatch; + if (digit>9) return nmatch; node = mroot[node].child[digit]; - if(node == NULL_CARRIERID) - return nmatch; + if (node == NULL_CARRIERID) return nmatch; i++; - if(node < 0) { - nmatch = i; + if (node<0) { + nmatch=i; *carrier = -node; return nmatch; } - if(mroot[node].carrier > 0) { - nmatch = i; + if (mroot[node].carrier > 0) { + nmatch=i; *carrier = mroot[node].carrier; } } diff --git a/utils/pdbt/dtm.h b/utils/pdbt/dtm.h index 9a2cc8ef8..107681025 100644 --- a/utils/pdbt/dtm.h +++ b/utils/pdbt/dtm.h @@ -22,17 +22,24 @@ #define _DTM_H_ + + #include "common.h" + + typedef int32_t dtm_node_index_t; -struct dtm_node_t -{ + + +struct dtm_node_t { dtm_node_index_t child[10]; carrier_t carrier; -} __attribute__((packed)); +} __attribute__ ((packed)); + + /* @@ -46,8 +53,9 @@ struct dtm_node_t *dtm_load(char *filename); Return the number of matched digits. In case no match is found, return -1. */ -int dtm_longest_match(struct dtm_node_t *mroot, const char *number, - int numberlen, carrier_t *carrier); +int dtm_longest_match(struct dtm_node_t *mroot, const char *number, int numberlen, carrier_t *carrier); + + #endif diff --git a/utils/pdbt/log.c b/utils/pdbt/log.c index 0f9926dee..23890ebb7 100644 --- a/utils/pdbt/log.c +++ b/utils/pdbt/log.c @@ -23,49 +23,54 @@ #include + + static int use_syslog = 0; static int log_level = LOG_WARNING; -void init_log(char *_prgname, int _use_syslog) -{ + + +void init_log(char *_prgname, int _use_syslog) { use_syslog = _use_syslog; - if(use_syslog) { + if (use_syslog) { openlog(_prgname, LOG_PID, LOG_DAEMON); } } -void set_log_level(int level) -{ + + +void set_log_level(int level) { log_level = level; } -void destroy_log(void) -{ - if(use_syslog) - closelog(); + + +void destroy_log(void) { + if (use_syslog) closelog(); } -void log_stderr(char *format, va_list ap) + + +void log_stderr(char * format, va_list ap) { vfprintf(stderr, format, ap); fflush(stderr); } -void pdb_log(int priority, char *format, ...) -{ + + +void pdb_log(int priority, char * format, ...) { va_list ap; - if(priority <= log_level) { + if (priority<=log_level) { va_start(ap, format); - if(use_syslog) - vsyslog(priority, format, ap); - else - log_stderr(format, ap); + if (use_syslog) vsyslog(priority, format, ap); + else log_stderr(format, ap); va_end(ap); } } diff --git a/utils/pdbt/log.h b/utils/pdbt/log.h index 94b06298c..d2ef7e925 100644 --- a/utils/pdbt/log.h +++ b/utils/pdbt/log.h @@ -24,30 +24,31 @@ #include + + void init_log(char *_prgname, int _use_syslog); void set_log_level(int level); void destroy_log(void); -void pdb_log(int priority, char *format, ...); +void pdb_log(int priority, char * format, ...); -#define LEMERG(fmt, args...) pdb_log(LOG_EMERG, fmt, ##args) -#define LALERT(fmt, args...) pdb_log(LOG_ALERT, fmt, ##args) -#define LCRIT(fmt, args...) pdb_log(LOG_CRIT, fmt, ##args) -#define LERR(fmt, args...) pdb_log(LOG_ERR, fmt, ##args) -#define LWARNING(fmt, args...) pdb_log(LOG_WARNING, fmt, ##args) -#define LNOTICE(fmt, args...) pdb_log(LOG_NOTICE, fmt, ##args) -#define LINFO(fmt, args...) pdb_log(LOG_INFO, fmt, ##args) -#define LDEBUG(fmt, args...) pdb_log(LOG_DEBUG, fmt, ##args) +#define LEMERG(fmt, args...) pdb_log(LOG_EMERG, fmt, ## args) +#define LALERT(fmt, args...) pdb_log(LOG_ALERT, fmt, ## args) +#define LCRIT(fmt, args...) pdb_log(LOG_CRIT, fmt, ## args) +#define LERR(fmt, args...) pdb_log(LOG_ERR, fmt, ## args) +#define LWARNING(fmt, args...) pdb_log(LOG_WARNING, fmt, ## args) +#define LNOTICE(fmt, args...) pdb_log(LOG_NOTICE, fmt, ## args) +#define LINFO(fmt, args...) pdb_log(LOG_INFO, fmt, ## args) +#define LDEBUG(fmt, args...) pdb_log(LOG_DEBUG, fmt, ## args) /* several shell exit codes for the application pdbt */ -#define PDB_OK 0 /* Everything ok */ -#define PDB_USE_ERROR \ - 1 /* Wrong usage of application (unknown command, file not found, etc.) */ -#define PDB_NOT_IN_PDB 2 /* A queried number is not in the pdb */ -#define PDB_TIMEOUT 3 /* A timeout (server not responding) occurred */ -#define PDB_OTHER 4 /* Another application error occurred */ +#define PDB_OK 0 /* Everything ok */ +#define PDB_USE_ERROR 1 /* Wrong usage of application (unknown command, file not found, etc.) */ +#define PDB_NOT_IN_PDB 2 /* A queried number is not in the pdb */ +#define PDB_TIMEOUT 3 /* A timeout (server not responding) occurred */ +#define PDB_OTHER 4 /* Another application error occurred */ #endif diff --git a/utils/pdbt/pdb_server.c b/utils/pdbt/pdb_server.c index 6ce32557c..2de2ba789 100644 --- a/utils/pdbt/pdb_server.c +++ b/utils/pdbt/pdb_server.c @@ -151,7 +151,7 @@ int udp_server(int so) carrierid = lookup_number(msg.bdy.payload); /* check if not found pdb_id */ - if(carrierid == 0) { + if(carrierid == -1) { pdb_msg_format_send(&msg, PDB_VERSION_1, PDB_TYPE_REPLY_ID, PDB_CODE_NOT_FOUND, htons(msg.hdr.id), NULL, 0); goto msg_send; diff --git a/utils/pdbt/pdb_server_backend.c b/utils/pdbt/pdb_server_backend.c index dc4028bee..931e28d76 100644 --- a/utils/pdbt/pdb_server_backend.c +++ b/utils/pdbt/pdb_server_backend.c @@ -44,8 +44,8 @@ carrier_t lookup_number(char *number) carrier_t carrierid; int nmatch = dtm_longest_match(mroot, number, strlen(number), &carrierid); if(nmatch <= 0) { - /* nothing found - return id 0 */ - carrierid = 0; + /* nothing found - return id -1 */ + carrierid = -1; } LINFO("request='%s', nmatch=%ld, carrier=%ld\n", number, (long int)nmatch, (long int)carrierid); diff --git a/utils/pdbt/pdb_server_backend.h b/utils/pdbt/pdb_server_backend.h index 30f354bdd..89f3ccf99 100644 --- a/utils/pdbt/pdb_server_backend.h +++ b/utils/pdbt/pdb_server_backend.h @@ -22,9 +22,13 @@ #define _PDB_SERVER_BACKEND_H_ + + #include "common.h" + + /* Initializes the backend and loads the required data from the given file. Returns 0 on success, -1 otherwise. @@ -38,4 +42,6 @@ int init_backend(char *filename); carrier_t lookup_number(char *number); + + #endif diff --git a/utils/pdbt/pdbt.c b/utils/pdbt/pdbt.c index 2a335129a..be670eeb7 100644 --- a/utils/pdbt/pdbt.c +++ b/utils/pdbt/pdbt.c @@ -46,18 +46,14 @@ uint16_t id = 0; typedef int (*query_func_t)(char *number, char *comment, void *data); -void print_usage(char *program) -{ + + +void print_usage(char *program) { set_log_level(LOG_INFO); LINFO("version: pdbt %d\n", PDB_VERSION); LINFO("Usage: %s [