New upstream version 5.8.2

mr13.0 upstream/5.8.2
Victor Seva 11 months ago
parent bedfb412c1
commit e4059b36fc

@ -1,3 +1,852 @@
===================== 2024-06-12 Version 5.8.2 Released =====================
===================== Changes Since Version 5.8.1 ===========================
commit 5a090532b2e702ae758b384b54550fed5ddddfdb
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Jun 12 10:02:55 2024 +0200
Makefile.defs: version set to 5.8.2
commit 2ce09cbd669753266bba8659073320af6f53664b
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Jun 12 09:40:58 2024 +0200
pkg: deb specs updated for v5.8.2
commit f3daac3024c6a623fa9021d92f77daf2cf866c8d
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Jun 12 08:57:25 2024 +0200
pkg/kamailio: version set 5.8.2 for rpms and alpine
commit 955c6e02ed0e31a4c7f148518bf44edb12c37a07
Author: Kamailio Dev <kamailio.dev@kamailio.org>
Date: Sat Jun 8 20:31:20 2024 +0200
modules: readme files regenerated - modules ... [skip ci]
commit 8ef8db05dbc3a4cf5246354ce31dff18180a8e12
Author: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com>
Date: Fri Jun 7 14:00:43 2024 +0000
pua_dialoginfo: Fix ruri length
(cherry picked from commit 2c7c2d215ec9277fa706053579a38f058f15ae85)
commit ed0cdf3a3c85a8d05aacec8917fe35a24dcdd62e
Author: Bastian Triller <bastian.triller@gmail.com>
Date: Fri Jun 7 13:24:17 2024 +0200
ims_ipsec_pcscf: Fix typo
(cherry picked from commit 16e1b38fcc1593ad09eb03d86cd056ab8ff7f7f7)
commit 5571ea0ff8877a8a19b3fb76030af19b59f141db
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Jun 4 16:29:50 2024 +0200
dmq_usrloc: reformat exported structures
(cherry picked from commit e94812149c6f2867a5b23f1218a9af139590bf51)
commit e8dc8506dbc4d8964e02c3be175d7f18f5fe69a4
Author: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com>
Date: Tue Jun 4 09:37:01 2024 +0000
nathelper: remove magic constant
(cherry picked from commit 3d187336f22e30800acefd28e4d0f98e0f677a49)
commit eb4ec6f9305e334d9749e1fd56ad195c383cef77
Author: codenot <codenot@msn.com>
Date: Wed May 29 10:10:28 2024 +0800
nathelper: fixed handle_ruri_alias_mode(1) cannot proper handle multi alias
(cherry picked from commit 8e0b2e4b6450fa50bd573fa013dc888aaaccd2bf)
commit 5999529be9ac2187dad465518bea3dee1b06d0f7
Author: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com>
Date: Fri May 24 08:03:49 2024 +0000
core/resolve: Check dns_cache_init and choose appropriate functions
(cherry picked from commit 06d583e356351ae9d8a559c9f5de3e57fb128a38)
commit eb4a8e326b10d0c3e922cc524d8f46d2ba7e6eff
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Sun Jun 2 21:28:19 2024 +0200
iims_registrar_scscf: include header for common c functions
- GH #3855
(cherry picked from commit b508ef253cf996a5efd8bf13ded0c804f3557ada)
commit 54f9adb03ebbacf35eb0785dc46b55ce5dd00deb
Author: Bastian Triller <bastian.triller@gmail.com>
Date: Mon Jun 3 08:48:40 2024 +0200
geoip2: Reload database before accessing it
Re-add reloading of database.
GH #3861
Fixes: 293193c55c ("geoip2: clang format module file")
(cherry picked from commit 51dcab019a42e5b1f3b81247ca71ffcaf46180de)
commit c27094b8288b7a949fbfc766eb9223c0085340ef
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Sun Jun 2 04:58:23 2024 +0200
geoip2: clang format module file
(cherry picked from commit 293193c55caaf5d0c39dc456babe92f574b58b3b)
commit 45f2e2670a3eac768b97b58eeec228b06273050a
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Sun Jun 2 04:51:33 2024 +0200
geoip2: keep global structure per process
- parsing db file allocates private memory
- reworked reload to rely on a global counter
- GH #3861
(cherry picked from commit baccbe0298f9fa46db285505bc4386f997de5a47)
commit ae3be6af4ea8d50c29fe8e523c9548217956849a
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Sat Jun 1 07:50:45 2024 +0200
geoip2: rename global lock variable
(cherry picked from commit 4bd619d3517f129362de3ce50eed2620d5002b42)
commit 2cc901e8be63791432a49f87d434eeb009e48d28
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Sat Jun 1 07:39:54 2024 +0200
geoip2: do not close global MMDB_s on destroy
- GH #3861
(cherry picked from commit e066613cac308d1129baebc47d7c245b36eba4b0)
commit 614b5601170578c2d0eb79e7e5c64e68d80d885b
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri May 31 19:23:41 2024 +0200
geoip2: init MMDB_s global pointer and check on destroy
(cherry picked from commit 8ba4ee4e00798ca015adc48542d0e4de8ed9daad)
commit 5c9c13080be2b15252492dca388777d06915045c
Author: Victor Seva <linuxmaniac@torreviejawireless.org>
Date: Thu May 30 16:24:03 2024 +0200
regex: fix pcre2 migration
instead of reserving an array in pkg_mem and later
copy the pointers to shm_mem just use shm_mem in
the first place.
fixes #3812
(cherry picked from commit d89333748662c0e7c72e3579d41fd14ef05c0fee)
commit ebc8acef7617a69dcc06b163c47e88a99d835f9e
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed May 29 10:18:44 2024 +0200
siputils: free head of params list for get_uri_param()
- GH #3857
(cherry picked from commit 8363208fff7c101a2779ff64783e5b7dbf8ffd7c)
commit 833b93563f43fa95e4bfdd175b144670b66a11cd
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed May 29 10:15:21 2024 +0200
siputils: free head of params list for get_uri_param()
- GH #3857
(cherry picked from commit d72a3fbc903da02ae3b26f3aae2ea228c9f8b255)
commit f4eea76a15b220b15337b60a77f7978b0694b0fd
Author: Bastian Triller <bastian.triller@gmail.com>
Date: Tue May 28 14:17:58 2024 +0200
rtpengine: Fix extra process in pkg.stats
When DTMF events socket is not configured, pkg.stats RPC method returns
an empty entry.
{
entry: 13
pid: 0
rank: -128
used: 0
free: 0
real_used: 0
total_size: 67108864
total_frags: 0
desc:
}
Fixes: 26f6e57c8f ("Register a new worker process for dtmf event listener")
(cherry picked from commit e67f6048f4883d446df2d88fe7a7d7f2ff6daf8c)
commit 7087ce6aa496de9b6015e5054d8fd70bf2e055b3
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue May 28 11:45:37 2024 +0200
htable: error on not finding htable in pv get
(cherry picked from commit 24b27214231166366cceb88fcb3724298cc53b32)
commit 9a7e3e54f1c52ee69c68b1165de115894c2afc55
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon May 27 09:11:48 2024 +0200
htable: error on not finding htable in pv set
(cherry picked from commit 82cfea317fd8d02a6c94347bc1be18c8a06e580f)
commit deb11ee814e1591698d120a113630aa7a9791ad7
Author: Rick Barenthin <rick@ng-voice.com>
Date: Thu Apr 25 19:16:58 2024 +0200
usrloc: delete location_attrs in db_only mode on delete_urecord
When calling delete_urecord in DB_ONLY mode the location_attrs are not deleted.
This fix makes sure to delete location_attrs when calling db_delete_urecord is called.
(cherry picked from commit 6b8f6d3b5d563d91234b8d4b7e155b7e74b9d313)
commit d53843c75da9115a9c3cb6b1b909fd3827b6c437
Author: Sergey Safarov <s.safarov@gmail.com>
Date: Sat May 11 17:45:08 2024 +0300
db_mysql: fixed build on CentOS 7
(cherry picked from commit 767b3faee3af450d6482b919c81431ea6d707807)
commit 5c4f687d0ed06d6c7a5696917982b1cf03f9c8bd
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri May 10 12:45:25 2024 +0200
sipcapture: use local static buffers for ip address and port
- GH #3835
(cherry picked from commit d1f377ff23f491bfd5162cb7bf510759440dd8e5)
commit f9bd2c5a4341913ac3e887e0324a19d5cd071a12
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu May 9 08:17:15 2024 +0200
tcpops: reformat exported structures
(cherry picked from commit 9b087fd618ab6c5cbd6a29c352b09c7198f1b594)
commit c8e4fe87985a413dfe6871463c31375750d3a6f2
Author: Victor Seva <linuxmaniac@torreviejawireless.org>
Date: Thu May 30 14:59:05 2024 +0200
dialplan: don't call free on empty pcre pointer
fixes #3851
(cherry picked from commit 630a6f2c11c10c4f3be3570553d86486942d60fe)
commit c1c8c066b29798189a50dd9b4f27c5af574d991d
Author: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com>
Date: Mon Apr 29 13:37:24 2024 +0000
db_cluster: Update log levels
(cherry picked from commit 467dbf3e1be16d5a760178d0801834ac67bad888)
commit 3a34b468ad93904c507bd0fc7ef592b25321807f
Author: Juha Heinanen <jh@tutpro.com>
Date: Mon May 20 11:41:42 2024 +0300
tm: add mandatory Max-Forwards header to local AC
commit ba7a4901268493f5432d5efd59d6dbd7b422742f
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed May 8 06:58:13 2024 +0200
etc/kamailio.cfg: remove executable flag
commit 191aec6ef644024741c23776c35fc712aa82a6b5
Author: Kamailio Dev <kamailio.dev@kamailio.org>
Date: Tue May 7 21:16:19 2024 +0200
modules: readme files regenerated - modules ... [skip ci]
commit 29ef69b8807023e082d7c9880c63bee11d4f3b30
Author: Henning Westerholt <hw@gilawa.com>
Date: Tue May 7 16:14:46 2024 +0000
sipcapture: fix default DB URL docs
(cherry picked from commit aeeeb0c2f46c2575639dd725bef78fac64219a07)
commit c3f424bd6c0f8b9a2557cd58a3e3f5ac586d8c99
Author: Kamailio Dev <kamailio.dev@kamailio.org>
Date: Tue May 7 19:46:19 2024 +0200
modules: readme files regenerated - modules ... [skip ci]
commit 383a81bb9d81e06ab9da99cdaa3def3b63028040
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue May 7 19:32:39 2024 +0200
tcpops: note about execution of event routes by TCP main process
(cherry picked from commit be9af338e3afdab1045cdd7c30a72a9ecddcb680)
commit 1ee553a6f406af5eb4838a8c46a992c4099dd30b
Author: Kamailio Dev <kamailio.dev@kamailio.org>
Date: Tue May 7 17:31:19 2024 +0200
modules: readme files regenerated - modules ... [skip ci]
commit b5eb4f5ca037239f2ec1d99a16a71af0383f737e
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue May 7 16:55:24 2024 +0200
ctl: info log on ECONNRESET (connection reset by peer)
- not a type of error that can be controlled by kamailio
(cherry picked from commit 446c75e0e2194b6e42d768d2e3c79b5f0222905f)
commit 24e43d27544bdfa1acfce7ebb8b6e3ba7841fc13
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue May 7 16:49:49 2024 +0200
ctl: removed level and function names from log messages
(cherry picked from commit 65bafaffd6bcfebc508b774cfbb78120e68bb3f0)
commit 11f0cfec4d2fc6043d282cdb2258520559f0fcd1
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Sat May 4 20:18:18 2024 +0200
core: parse/contact: jump to error on too many contacts
(cherry picked from commit f69b22d44cb5abc803c2b58790dd33f2310c1c59)
commit d75dba611808322356fc8d1ebc9f8c30b4124a15
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri May 3 14:57:47 2024 +0200
core: parser/contact - basic validation tests for contact uri
(cherry picked from commit fc52a54370c085d6fa951da876eee99580677922)
commit 5b97d29f1bbac2656eba506c7fd94b412dfb9b7f
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri May 3 14:36:29 2024 +0200
core: parser/contact - add limit for max number of contacts
- defined to 256
(cherry picked from commit d6b0beb5a219ae57a62e9e7201a6ec1fe66e5a96)
commit 244319c67a191cf1f093b2220fa1a8579179d734
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu May 2 09:27:41 2024 +0200
pua: check if local requests are dropped and free the param
(cherry picked from commit 53e1a29c265df1489c9bd91deddc0719f8ca2092)
commit 46c8e1a5b0e11162eee2c0b201bb535529397a0a
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed May 1 07:00:58 2024 +0200
uac: check if local requests are dropped and free the param
(cherry picked from commit 00aac8d48370fac356eecff535835d918c631cc5)
commit 965a02ba4aca9283e4f43f8153ebeb81721835f1
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed May 1 06:20:43 2024 +0200
presence: check if the local notify was dropped in event route
- free tm cb parameter on drop
- related to GH #3403
(cherry picked from commit d12fc31056cb37aac347ec05f9ada7bafa5f52de)
commit e54b03fc41bc55486430b09d9a4839bcd52278fa
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed May 1 06:08:28 2024 +0200
pv_headers: print also the new TMCB_LOCAL_REQUEST_DROP in debug function
(cherry picked from commit 68624c2da093ab789d4e8d35df65ef1bce024bca)
commit a86d7d2bad119fc4cccf5c19719b4457ab066a04
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed May 1 06:07:26 2024 +0200
tm: cb_flags made unsigned for uac_req
(cherry picked from commit ebd1c6c75a1b832ce85d576aad134b99d47b5738)
commit f9ca6854d88e4fcc161e1083a953f47142fca90d
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed May 1 05:57:46 2024 +0200
tm: cb flag to mark local uac on request drop
(cherry picked from commit f5da773c5fa29edbf9d0e65a83a62f495928ddec)
commit fc54fdcd67e244ad075c54b5f24bb6442998b4cb
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed May 1 05:28:18 2024 +0200
tm: free new buffer on drop for local requests
- GH #3403
(cherry picked from commit ee06666c43d96029315dae7618e10d381265a85a)
commit 3aac0c7379577480fb09902bfb31b9aed49e7f88
Author: Jannik <40364587+volkland@users.noreply.github.com>
Date: Tue Apr 30 12:28:20 2024 +0200
sipcapture: docs - fix default value for parameter
(cherry picked from commit 265c948286f2df5136179c95fbb1d7f1255e4c71)
commit 4e98a4ae06ec0bbff408af211680c97e1f41ca11
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Apr 30 10:19:35 2024 +0200
ims_ipsec_pcscf: cascade on options to get the uri for fill_contact()
(cherry picked from commit 60d2ab6464657abf38136a771c297c6f5536e27a)
commit 4b3620d0f0d7d636bf1d9e4c2b19bf50b8ac9da0
Author: Alexander Couzens <lynxis@fe80.eu>
Date: Mon Mar 4 17:33:50 2024 +0100
ims_registrar_scscf: free_uint_fixup: fix memleak/freeing the wrong parameter
The free_uint_fixup() freed the wrong parameter in the past.
(cherry picked from commit c3e6c1edc7531406208efe2965243e6e81506127)
commit 569662043b656063be97d0ea0e22dd8f6082320e
Author: Alexander Couzens <lynxis@fe80.eu>
Date: Mon Mar 4 17:32:00 2024 +0100
ims_registrar_scscf: fix typo in function name uint_fixup
(cherry picked from commit 6f908f05d4691abcb1b3a745048d3cc2a9996676)
commit 8bb9f0601eb94597f3bfab4ede97971de83cc1e7
Author: Alexander Couzens <lynxis@fe80.eu>
Date: Mon Mar 4 17:21:25 2024 +0100
ims_registrar_scscf: refactor save_fixup4
Rename function to match argument number.
Use assign_save_fixup3_async instead of the code copy
(cherry picked from commit 82a6d7ea6edbaca60879a38c5e74e40920e89342)
commit 4aa0920b2e573661959d5c9149ee04177cae8264
Author: Alexander Couzens <lynxis@fe80.eu>
Date: Fri Mar 1 17:38:21 2024 +0100
ims_registrar_scscf: fix uninitialized arguments in save()
The script "save" command can be used with different arguments:
2, 3 and 4.
But internally for all save() calls the exact same function is use, w_save().
When calling save("PRE_REG_SAR_REPLY","location"); as given by the examples,
kamailio will call w_save().
Because the command code will cast the function pointer, the w_save() function
is called with 2 uninitialized arguments *mode, *c_flags.
mode is unused, seems a legacy argument. c_flags is referenced resulting in a crash
if not null.
Use separate wrapper functions to handle different argument number.
Fixes: a627c9a04a74 ("ims_registrar_scscf: Extend save() with optional flag")
(cherry picked from commit 20a75004d53a06da0f22b11804a4d83496ad8919)
commit 00f51e28875c209cbf25a47c96e60c9f73add952
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon Apr 29 10:08:29 2024 +0200
ims_ipsec_pcscf: handle tls for replies
(cherry picked from commit 48dab490965fa7f2f7200d95edd7dbb1407b2536)
commit 9493dc0c895d1dde50239c903fd976c8c6e0325f
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon Apr 29 06:49:47 2024 +0200
ims_ipsec_pcscf: updated comments for ipsec_forward() flags
(cherry picked from commit f7f93828993b5975dfe5f26ad63ba6c489aa69f7)
commit 7e202ec38593462559e81db7b0f97e46567f379d
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon Apr 29 06:46:56 2024 +0200
ims_ipsec_pcscf: docs updated for ipsec_forward() flags
(cherry picked from commit 575b17d23cd5fa060f775bc56b42c735048bc849)
commit 1387c32dfa601496c38f9c10d554c490c867d4d7
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon Apr 29 06:32:07 2024 +0200
ims_ipsec_pcscf: decouple IPSEC_FORWARD_USEVIA and IPSEC_TCPPORT_UEC for requests
- both flags should be avaible for use at the same time in
ipsec_forward()
- for request IPSEC_FORWARD_USEVIA gets the protocol from the next hop
address
(cherry picked from commit ab261540d656ed456bac8876f77f940457a9baf6)
commit 8af0605ade36566597ff691a2adc1e524081a6fa
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Sun Apr 28 23:28:38 2024 +0200
ims_registrar_scscf: init variable to fix analyzer warning
(cherry picked from commit 8558947034f16b162c15eda39d18f5f5df4ef562)
commit 89343b6031f186c59ecd6707109bd0269762075f
Author: Ostap <ostap_mal@hotmail.com>
Date: Mon Apr 29 00:15:28 2024 +0300
modules/statsd: ensure statsd failures do not stop execution (#3819)
* modules/statsd: avoid stopping flow when sending statsd metric fails
Currently statsd functions return bool: `true` or `false` depending when
the function succeeds or fails respectively.
This value gets implicitly converted to `int`: `true` -> `1`, `false` ->
`0`.
For Kamailio `1` means succesfull execution, but `0` means to stop
processing messages, which is not what we want as statsd should not impact
flow execution. Instead we want to return `-1` which signifies error,
but the flow continues.
* modules/statsd: do not fail module initilization when statsd init fails
statsd_init executes `statsd_connect` which tries to connect to statd
server.
If connection fails then kamailio fails to start.
This is not the desired behaviour as:
1. Kamailio should continue working even if statsd server is down,
metrics should not impact runtime.
2. `statsd_connect` is also re-executed each time we try to send the metric https://github.com/salemove/kamailio/blame/master/src/modules/statsd/lib_statsd.c#L76,
so it's initial result is not essential.
Note, that before 5.8 the result of init was already ignored due to
implicit conversion of `false` to `0`
until after
https://github.com/kamailio/kamailio/commit/0186246fce8f0e4bb46b30c05174983cd957a3ba
was introduced (which could be considered a breaking change even if it
seemingly fixes a bug in conversion).
(cherry picked from commit 5e66ba23851f115bcb88d7e3f71f78ab33fc1e30)
commit 620aa3f2a0faf3a4d54908bac0aa3ffcd8376ab5
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri Apr 26 14:35:22 2024 +0200
ims_usrloc_scscf: enclose examples in dotted lines for better visibility
(cherry picked from commit 8506a6fe781e6e0b0b1418f4087db50480db6b57)
commit 1dd7c4038eb9a0c7eec506994a58a56d04e6cee5
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri Apr 26 14:24:16 2024 +0200
ims_usrloc_scscf: reformat exported structures
(cherry picked from commit 15d859e1e96552fca2708cf56047021beae29711)
commit b2352bc1c6f3eff3aba85a087107f4ca29cedc22
Author: Henning Westerholt <hw@gilawa.com>
Date: Fri Apr 26 05:54:27 2024 +0000
uid_auth_db: spelling fix in documentation
(cherry picked from commit 9f28450312749dfbc021a8cbc23472c8a39d3fef)
commit 0bf03aa1987b9cff2fc0d776605620e26c163609
Author: Henning Westerholt <hw@gilawa.com>
Date: Fri Apr 26 05:53:30 2024 +0000
core: spelling fix in comment and log message
(cherry picked from commit db176a4918c0b500f5f051cad16fd8d442450ab7)
commit cafe437dcb637b0e571a2d2ffd04d911584404d9
Author: S-P Chan <shihping.chan@gmail.com>
Date: Mon Apr 29 09:24:16 2024 +0200
tls: clear thread-local variables up to tls_pthreads_key_mark
- other libraries may set thread-locals via pthread_setspecific
- assume that tls_pthreads_key_mark demarcates libssl's values
- only clean thread-local values up to tls_pthreads_key_mark
Currently only used by app_python[s]
(cherry picked from commit fe6f4fcde2fa06a3c00479cef169c27dc32ae490)
commit 03ff5051b640d2478dd68ea89ad74d516752ab0f
Author: Kamailio Dev <kamailio.dev@kamailio.org>
Date: Thu Apr 25 14:01:16 2024 +0200
modules: readme files regenerated - modules ... [skip ci]
commit e76d755de6482e51c9ddac5bba3834cb58ad79b2
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Apr 25 13:49:58 2024 +0200
tcpops: removed unused variable introduced recently
(cherry picked from commit fe8f052c29528b656062927626f9784b32b7c8f6)
commit 3ff024fd0057d3a9d045d3f20df5d1d7f7c9c7aa
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Apr 24 21:34:28 2024 +0200
regex: reformat exported structures
(cherry picked from commit 0ebfddd20b43396d602b4c68a88f7c2bc58ed211)
commit c8f685359c411ac43000dd77cbc2e4f95b6cb3f4
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Apr 23 12:08:30 2024 +0200
regex: allocate pcres array
- GH #3812
(cherry picked from commit 2cc62133db4f6875f55e73e044f37dafbb2274c2)
commit eaacc171adbcd84fb2b95b4c182cd1e954624e2b
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Apr 23 11:49:23 2024 +0200
regex: init globals for safer shutdown on failure
(cherry picked from commit 84517c14ca38a8371c67b858077a42019c2217a8)
commit 794c2edeaffe059bf8de6ab1d3df5db003ed4cb0
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Apr 23 11:19:30 2024 +0200
core: fmsg - parse loopback ip when initializing faked msg structure
- GH #3817
(cherry picked from commit 66b3c04a9653425b1602c82dd2456a7eb7cf59d1)
commit 7e987d8937349246f2abfa041679f568344ff402
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Apr 23 10:42:02 2024 +0200
pv: use global tcp connection callback for event route on $conid
(cherry picked from commit f5c05a68ae72881ab0691bb8488112356fc67c79)
commit 069de99576b5f8bff002176331ed2f545afe8158
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Apr 23 10:36:35 2024 +0200
core: tcp - set a global shortcut to tcp connection for event route
(cherry picked from commit d114d11724dc4157e7e5809504531d26da6bcc57)
commit c9fe59d6cd73179aa75e21b3b215bc0465b182aa
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Apr 23 10:21:20 2024 +0200
tcpops: reworked some debug messages
(cherry picked from commit 27e3b7f3f82957c6dc80f2ff89c40bdd87cecb81)
commit db2e96ec2aacde1bd50b65ea6357388bad39e86f
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Apr 23 10:19:29 2024 +0200
core: tcp - keep connection id on event route cb structure
(cherry picked from commit 11e7d71e5c2ee9428298658ed3b9a0f625d40f00)
commit 28bbcd5a50f45b8217125481706180a76323dc44
Author: Rick Barenthin <rick@ng-voice.com>
Date: Wed Apr 17 13:02:02 2024 +0200
usrloc: check on db delete the return value of memchr
When inserting into the database the AOR is split at the @ sign and
if there is no @ sign in the AOR only the domain part is filled and the
user part is left empty.
But for deleting this is not done and the query failed to be executed
and the AOR is not deleted. This PR add this behaviour of only comparing against the
domain part if the AOR doesn't contain a @ sign.
(cherry picked from commit 49276a1f43b1a3bf4a8d681888df964000360c79)
commit 3052565e3ce14d5d3c45d790877a562185085548
Author: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com>
Date: Wed Apr 10 11:14:45 2024 +0000
tcp_main: Match wss protocol
(cherry picked from commit 175d755c40bc50b78b2cf4f18ad22429289af90d)
commit 7d103cf3887401fca32d95f7ea7ee10f28e9e127
Author: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com>
Date: Wed Apr 10 11:13:32 2024 +0000
core/forward: Match protocol when forwarding
(cherry picked from commit d81e5113884b933251499630d112ec5b1150b8a4)
commit a19e6e0e49d9881ab990d23ad31a95773fe1a00b
Author: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com>
Date: Mon Apr 8 09:42:49 2024 +0000
tcp_main: Update comment docs
(cherry picked from commit 0a28a93c6e060081267dc686e342d45ef03358e7)
commit 0c070443b585c597d2d6249ac6ac32490d9c7f48
Author: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com>
Date: Mon Apr 8 09:29:57 2024 +0000
tcp_main: Add proto argument to tcpconn_exists function
(cherry picked from commit 6779efd430178adff0ae438d178e38c003e4e05c)
commit 2661594bf7f31558e6ac7524f33ebb358aefce21
Author: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com>
Date: Fri Apr 5 13:23:56 2024 +0000
tcp_main: Add protocol argument for searching tcp/tls connections
(cherry picked from commit 4a40b16d4f9bef9bc75d3272c83878e6348aa0b8)
commit d2cf78f5c70977639f3b7f66b852350b764e4b13
Author: vijay kumar <vijay.kumar@exotel.in>
Date: Sat Apr 13 01:26:13 2024 +0530
rtpengine: fix pkg mem leak in send_rtpp_command()
- freed request.s after sending request to websocket
(cherry picked from commit b4753ae4216b0c960ac094f4be8232fb4d0147b0)
commit 595d3f472179402dce7a51672c2dbfbcf3b54bd5
Author: Xenofon Karamanos <22965395+xkaraman@users.noreply.github.com>
Date: Thu Apr 11 10:47:11 2024 +0000
corex: Fix unknown af in list_sockets
(cherry picked from commit 8bc64a9e6820243336387d9cd9acf81f24d89993)
commit 800ed174b9402d1b253b2cb4ab04b5fb7030dc8d
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri Apr 5 21:41:21 2024 +0200
ims_ipsec_pcscf: log error message made info
(cherry picked from commit 92d3573b500374d100639484e5a84cb640dc6b1d)
commit 8d312ded02559b325cdd691bde61c54148b077a5
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri Apr 5 16:19:42 2024 +0200
siputils: tel2sip2() - memset to 0 pkg allocs and recompute len of new uri
(cherry picked from commit d1118064d04bb77c818540e68edf1766db1d560a)
commit 7295607e680ad1dd5290b15dab7fed77c65bfb88
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri Apr 5 07:54:12 2024 +0200
core: parser/sdp - rename parameter to suggest better its role
(cherry picked from commit b03ec73589c12e566b11ce2c653401daa915c805)
commit 855c76780c4399d6d9881ce3c525a7df56e111c4
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Apr 4 13:40:13 2024 +0200
sdpops: reformat the codecs map
(cherry picked from commit 359a442e14a156b0bcf60dc5b2580cbc57924e34)
commit f337f13cdbc7e8805c0130dbae3befaf4b684c7c
Author: Jannik Volkland <volkland@sipgate.de>
Date: Thu Apr 4 11:06:10 2024 +0200
ndb_redis: docs - refine docs regarding client certificates [skip ci]
The created ssl context does not use client certificates [1,2] which is against the default in current Redis configurations [3]. The used Redis server therefore needs to be configured to not use tls-auth-clients [3].
There is also a small typo in "ac_path" which was fixed to "ca_path".
[1]: https://github.com/kamailio/kamailio/blob/8047c958b42ea5af2e8f9ede0152f892ac0eea3a/src/modules/db_redis/redis_connection.c#L168
[2]: https://github.com/kamailio/kamailio/blob/8047c958b42ea5af2e8f9ede0152f892ac0eea3a/src/modules/db_redis/redis_connection.c#L212
[3]: https://redis.io/docs/management/security/encryption/#client-certificate-authentication
(cherry picked from commit 6faa180661e799187eff3a498f8b13e96719fa92)
commit bb48da13adfe36716c3d958ed1d9c410424f4d19
Author: Jannik Volkland <volkland@sipgate.de>
Date: Thu Apr 4 11:03:32 2024 +0200
db_redis: docs - refine docs regarding client certificates [skip ci]
The created ssl context does not use client certificates [1,2] which is against the default in current Redis configurations [3]. The used Redis server therefore needs to be configured to not use tls-auth-clients [3].
There is also a small typo in "ac_path" which was fixed to "ca_path".
[1]: https://github.com/kamailio/kamailio/blob/8047c958b42ea5af2e8f9ede0152f892ac0eea3a/src/modules/db_redis/redis_connection.c#L168
[2]: https://github.com/kamailio/kamailio/blob/8047c958b42ea5af2e8f9ede0152f892ac0eea3a/src/modules/db_redis/redis_connection.c#L212
[3]: https://redis.io/docs/management/security/encryption/#client-certificate-authentication
(cherry picked from commit 40a50243f0bae782b7acd97cf0a9b1138185068b)
commit 215af59832efc6e485563b55e3af9d209121d0c5
Author: Stefan-Cristian Mititelu <stefan-cristian.mititelu@1and1.ro>
Date: Mon Apr 8 11:35:38 2024 +0300
pdb server: allow carrier id 0
(cherry-picked from commit 60ded00a3b574a08457a696334d11d668595cc0b)
===================== 2024-04-03 Version 5.8.1 Released =====================
===================== Changes Since Version 5.8.0 ===========================

@ -4,7 +4,7 @@
# Maintainer: Nathan Angelacos <nangel@alpinelinux.org>
pkgname=kamailio
pkgver=5.8.1
pkgver=5.8.2
pkgrel=0
# If building from a git snapshot, specify the gitcommit

@ -1,3 +1,9 @@
kamailio (5.8.2) unstable; urgency=medium
* version set 5.8.2
-- Victor Seva <vseva@debian.org> Wed, 12 Jun 2024 09:00:17 +0200
kamailio (5.8.1) unstable; urgency=medium
* version set 5.8.1

@ -1,3 +1,9 @@
kamailio (5.8.2) unstable; urgency=medium
* version set 5.8.2
-- Victor Seva <vseva@debian.org> Wed, 12 Jun 2024 09:00:17 +0200
kamailio (5.8.1) unstable; urgency=medium
* version set 5.8.1

@ -1,3 +1,9 @@
kamailio (5.8.2) unstable; urgency=medium
* version set 5.8.2
-- Victor Seva <vseva@debian.org> Wed, 12 Jun 2024 09:00:17 +0200
kamailio (5.8.1) unstable; urgency=medium
* version set 5.8.1

@ -1,3 +1,9 @@
kamailio (5.8.2) unstable; urgency=medium
* version set 5.8.2
-- Victor Seva <vseva@debian.org> Wed, 12 Jun 2024 09:00:17 +0200
kamailio (5.8.1) unstable; urgency=medium
* version set 5.8.1

@ -1,3 +1,9 @@
kamailio (5.8.2) unstable; urgency=medium
* version set 5.8.2
-- Victor Seva <vseva@debian.org> Wed, 12 Jun 2024 09:00:17 +0200
kamailio (5.8.1) unstable; urgency=medium
* version set 5.8.1

@ -1,3 +1,9 @@
kamailio (5.8.2) unstable; urgency=medium
* version set 5.8.2
-- Victor Seva <vseva@debian.org> Wed, 12 Jun 2024 09:00:17 +0200
kamailio (5.8.1) unstable; urgency=medium
* version set 5.8.1

@ -1,3 +1,9 @@
kamailio (5.8.2) unstable; urgency=medium
* version set 5.8.2
-- Victor Seva <vseva@debian.org> Wed, 12 Jun 2024 09:00:17 +0200
kamailio (5.8.1) unstable; urgency=medium
* version set 5.8.1

@ -1,3 +1,9 @@
kamailio (5.8.2) unstable; urgency=medium
* version set 5.8.2
-- Victor Seva <vseva@debian.org> Wed, 12 Jun 2024 09:00:17 +0200
kamailio (5.8.1) unstable; urgency=medium
* version set 5.8.1

@ -1,3 +1,9 @@
kamailio (5.8.2) unstable; urgency=medium
* version set 5.8.2
-- Victor Seva <vseva@debian.org> Wed, 12 Jun 2024 09:00:17 +0200
kamailio (5.8.1) unstable; urgency=medium
* version set 5.8.1

@ -1,3 +1,9 @@
kamailio (5.8.2) unstable; urgency=medium
* version set 5.8.2
-- Victor Seva <vseva@debian.org> Wed, 12 Jun 2024 09:00:17 +0200
kamailio (5.8.1) unstable; urgency=medium
* version set 5.8.1

@ -1,3 +1,9 @@
kamailio (5.8.2) unstable; urgency=medium
* version set 5.8.2
-- Victor Seva <vseva@debian.org> Wed, 12 Jun 2024 09:00:17 +0200
kamailio (5.8.1) unstable; urgency=medium
* version set 5.8.1

@ -1,3 +1,9 @@
kamailio (5.8.2) unstable; urgency=medium
* version set 5.8.2
-- Victor Seva <vseva@debian.org> Wed, 12 Jun 2024 09:00:17 +0200
kamailio (5.8.1) unstable; urgency=medium
* version set 5.8.1

@ -1,3 +1,9 @@
kamailio (5.8.2) unstable; urgency=medium
* version set 5.8.2
-- Victor Seva <vseva@debian.org> Wed, 12 Jun 2024 09:00:17 +0200
kamailio (5.8.1) unstable; urgency=medium
* version set 5.8.1

@ -1,3 +1,9 @@
kamailio (5.8.2) unstable; urgency=medium
* version set 5.8.2
-- Victor Seva <vseva@debian.org> Wed, 12 Jun 2024 09:00:17 +0200
kamailio (5.8.1) unstable; urgency=medium
* version set 5.8.1

@ -1,5 +1,5 @@
%define name kamailio
%define ver 5.8.1
%define ver 5.8.2
%define rel dev1.0%{dist}
%if 0%{?fedora}

@ -106,7 +106,7 @@ INSTALL_FLAVOUR=$(FLAVOUR)
# version number
VERSION = 5
PATCHLEVEL = 8
SUBLEVEL = 1
SUBLEVEL = 2
EXTRAVERSION =
# memory manager switcher

@ -2,6 +2,6 @@
* DO NOT EDIT IT
*/
#define REPO_VER "384843"
#define REPO_HASH "384843"
#define REPO_VER "3fa5f4"
#define REPO_HASH "3fa5f4"
#define REPO_STATE ""

@ -25,6 +25,7 @@
#include "dprint.h"
#include "globals.h"
#include "dset.h"
#include "resolve.h"
#include "fmsg.h"
@ -57,6 +58,8 @@ static void faked_msg_buf_init(void)
static int faked_msg_init_new(sip_msg_t *fmsg)
{
str loip = str_init("127.0.0.1");
faked_msg_buf_init();
/* init faked sip msg */
@ -75,13 +78,9 @@ static int faked_msg_init_new(sip_msg_t *fmsg)
fmsg->rcv.proto = PROTO_UDP;
fmsg->rcv.src_port = 5060;
fmsg->rcv.src_ip.u.addr32[0] = 0x7f000001;
fmsg->rcv.src_ip.af = AF_INET;
fmsg->rcv.src_ip.len = 4;
str2ipbuf(&loip, &fmsg->rcv.src_ip);
fmsg->rcv.dst_port = 5060;
fmsg->rcv.dst_ip.u.addr32[0] = 0x7f000001;
fmsg->rcv.dst_ip.af = AF_INET;
fmsg->rcv.dst_ip.len = 4;
str2ipbuf(&loip, &fmsg->rcv.dst_ip);
return 0;
}

@ -188,7 +188,8 @@ static inline int msg_send_buffer(
su2ip_addr(&ip, &dst->to);
if(tcp_connection_match == TCPCONN_MATCH_STRICT) {
con = tcpconn_lookup(dst->id, &ip, port, from,
(dst->send_sock) ? dst->send_sock->port_no : 0, 0);
(dst->send_sock) ? dst->send_sock->port_no : 0, 0,
dst->proto);
} else {
con = tcpconn_get(dst->id, &ip, port, from, 0);
}

@ -221,6 +221,8 @@ static inline void contact_append(contact_t **head, contact_t *node)
ptr->next = node;
}
#define KSR_MAX_CONTACTS 256
/*
* Parse contacts in a Contact HF
*/
@ -229,9 +231,13 @@ int parse_contacts(str *_s, contact_t **_c)
contact_t *c;
param_hooks_t hooks;
str sv;
int n;
int star;
sv = *_s;
n = 0;
star = 0;
while(1) {
/* Allocate and clear contact structure */
c = (contact_t *)pkg_malloc(sizeof(contact_t));
@ -273,6 +279,24 @@ int parse_contacts(str *_s, contact_t **_c)
LM_ERR("invalid contact uri\n");
goto error;
}
if(c->uri.len == 1) {
if(c->uri.s[0] == '*') {
if(star == 1) {
LM_ERR("too many star contacts - index %d\n", n);
goto error;
} else {
star = 1;
}
} else {
LM_ERR("contact uri size 1 is too short - index %d\n", n);
goto error;
}
} else if(c->uri.len < 3) {
/* minimum length 's:a' (s - schema; a - address) */
LM_ERR("contact uri size %d is too short - index %d\n", n,
c->uri.len);
goto error;
}
if(_s->len == 0)
goto ok;
@ -312,7 +336,12 @@ int parse_contacts(str *_s, contact_t **_c)
contact_append(_c, c);
c = NULL;
n++;
if(n > KSR_MAX_CONTACTS) {
LM_ERR("too many contacts: %d\n", n);
goto error;
}
if(_s->len == 0) {
LM_ERR("text after comma missing\n");
goto error;

@ -735,14 +735,13 @@ int extract_sess_version(str *oline, str *sess_version)
* Auxiliary for some functions.
* Returns pointer to first character of found line, or NULL if no such line.
*/
char *find_sdp_line(char *p, char *plimit, char linechar)
char *find_sdp_line(char *pstart, char *plimit, char linechar)
{
static char linehead[3] = "x=";
char *cp, *cp1;
linehead[0] = linechar;
/* Iterate through body */
cp = p;
cp = pstart;
for(;;) {
if(cp >= plimit)
return NULL;
@ -767,13 +766,14 @@ char *find_sdp_line(char *p, char *plimit, char linechar)
}
/* This function assumes p points to a line of requested type. */
char *find_next_sdp_line(char *p, char *plimit, char linechar, char *defptr)
/* This function assumes pstart points to a line of requested type. */
char *find_next_sdp_line(
char *pstart, char *plimit, char linechar, char *defptr)
{
char *t;
if(p >= plimit || plimit - p < 3)
if(pstart >= plimit || plimit - pstart < 3)
return defptr;
t = find_sdp_line(p + 2, plimit, linechar);
t = find_sdp_line(pstart + 2, plimit, linechar);
return t ? t : defptr;
}

@ -1623,7 +1623,11 @@ struct hostent *no_naptr_srv_sip_resolvehost(
srv_name.s = tmp_srv;
srv_name.len = strlen(tmp_srv);
#ifdef USE_DNS_CACHE
he = dns_srv_get_he(&srv_name, port, dns_flags);
if(dns_cache_init) {
he = dns_srv_get_he(&srv_name, port, dns_flags);
} else {
he = srv_sip_resolvehost(&srv_name, 0, port, proto, 1, 0);
}
#else
he = srv_sip_resolvehost(&srv_name, 0, port, proto, 1, 0);
#endif
@ -1660,6 +1664,7 @@ struct hostent *naptr_sip_resolvehost(
struct rdata *naptr_head;
char n_proto;
str srv_name;
str *name_copy = 0;
naptr_bmp_t tried_bmp; /* tried bitmap */
char origproto = PROTO_NONE;
@ -1704,7 +1709,15 @@ struct hostent *naptr_sip_resolvehost(
he = no_naptr_srv_sip_resolvehost(name, port, proto);
/* fallback all the way down to A/AAAA */
if(he == 0) {
he = dns_get_he(name, dns_flags);
if(dns_cache_init) {
he = dns_get_he(name, dns_flags);
} else {
/* We need a zero terminated char* */
name_copy = shm_malloc(name->len + 1);
shm_str_dup(name_copy, name);
he = resolvehost(name_copy->s);
shm_free(name_copy);
}
}
end:
if(naptr_head)
@ -1833,6 +1846,45 @@ ip_addr_t *str2ip(str *st)
return ipb;
}
/*
* Resolve a host name to a hostent.
* @param[in] name: the host name to resolve
* @return the hostent structure or NULL on error
*
* @note
* This function is a wrapper to choose between the DNS cache and the
* system resolver. If the DNS cache is enabled, it will use the DNS cache
* to resolve the host name. Otherwise, it will use the system resolver.
*/
struct hostent *__resolvehost(char *name)
{
if(dns_cache_init) {
return dns_resolvehost(name);
} else {
return _resolvehost(name);
}
}
/*
* Resolve a host name to a hostent.
* @param[in] name: the host name to resolve
* @param[in] port: the port number
* @param[in] proto: the protocol
* @return the hostent structure or NULL on error
*
* @note
* This function is a wrapper to choose between the DNS cache and the
* system resolver. If the DNS cache is enabled, it will use the DNS cache
* to resolve the host name. Otherwise, it will use the system resolver.
*/
struct hostent *__sip_resolvehost(str *name, unsigned short *port, char *proto)
{
if(dns_cache_init) {
return dns_sip_resolvehost(name, port, proto);
} else {
return _sip_resolvehost(name, port, proto);
}
}
/* converts a str to an ipv6 address struct stored in ipb
* - ipb must be already allocated
* - return 0 on success; <0 on failure */

@ -329,14 +329,14 @@ int sip_hostport2su(
union sockaddr_union *su, str *host, unsigned short port, char *proto);
/* Wrapper functions that check for dns_cache_init */
struct hostent *__resolvehost(char *name);
struct hostent *__sip_resolvehost(str *name, unsigned short *port, char *proto);
/* wrappers */
#ifdef USE_DNS_CACHE
#define resolvehost dns_resolvehost
#define sip_resolvehost dns_sip_resolvehost
#else
#define resolvehost _resolvehost
#define sip_resolvehost _sip_resolvehost
#endif
#define resolvehost __resolvehost
#define sip_resolvehost __sip_resolvehost
#ifdef USE_NAPTR

@ -203,7 +203,7 @@ int fix_switch(struct action *t)
return E_BUG;
}
if(rval_expr_eval_long(0, 0, &c->label.match_int, c->ct_rve) < 0) {
LM_ERR("case expression (%d,%d) has non-interger type\n",
LM_ERR("case expression (%d,%d) has non-integer type\n",
c->ct_rve->fpos.s_line, c->ct_rve->fpos.s_col);
return E_BUG;
}

@ -407,7 +407,8 @@ struct tcp_connection *tcpconn_get(int id, struct ip_addr *ip, int port,
union sockaddr_union *local_addr, ticks_t timeout);
struct tcp_connection *tcpconn_lookup(int id, struct ip_addr *ip, int port,
union sockaddr_union *local_addr, int try_local_port, ticks_t timeout);
union sockaddr_union *local_addr, int try_local_port, ticks_t timeout,
sip_protos_t proto);
typedef struct tcp_event_info
{
@ -421,6 +422,7 @@ typedef struct tcp_event_info
typedef struct tcp_closed_event_info
{
enum tcp_closed_reason reason;
int id;
struct tcp_connection *con;
} tcp_closed_event_info_t;
@ -432,4 +434,6 @@ typedef struct ws_event_info
int id;
} ws_event_info_t;
tcp_connection_t *ksr_tcpcon_evcb_get(void);
#endif

@ -1697,12 +1697,12 @@ void tcpconn_rm(struct tcp_connection *c)
/* finds a connection, if id=0 uses the ip addr, port, local_ip and local port
* (host byte order) and tries to find the connection that matches all of
* them. Wild cards can be used for local_ip and local_port (a 0 filled
* ip address and/or a 0 local port).
* them. Wild cards can be used for local_ip, local_port and proto (a 0 filled
* ip address and/or a 0 local port and/or PROTO_NONE).
* WARNING: unprotected (locks) use tcpconn_get unless you really
* know what you are doing */
struct tcp_connection *_tcpconn_find(
int id, struct ip_addr *ip, int port, struct ip_addr *l_ip, int l_port)
struct tcp_connection *_tcpconn_find(int id, struct ip_addr *ip, int port,
struct ip_addr *l_ip, int l_port, sip_protos_t proto)
{
struct tcp_connection *c;
@ -1741,7 +1741,8 @@ struct tcp_connection *_tcpconn_find(
&& (ip_addr_cmp(ip, &a->parent->rcv.src_ip))
&& (is_local_ip_any
|| ip_addr_cmp(l_ip, &a->parent->rcv.dst_ip)
|| ip_addr_cmp(l_ip, &a->parent->cinfo.dst_ip))) {
|| ip_addr_cmp(l_ip, &a->parent->cinfo.dst_ip))
&& (proto == PROTO_NONE || a->parent->rcv.proto == proto)) {
LM_DBG("found connection by peer address (id: %d)\n",
a->parent->id);
return a->parent;
@ -1753,16 +1754,16 @@ struct tcp_connection *_tcpconn_find(
/**
* find if a tcp connection exits by id or remote+local address/port
* find if a tcp connection exits by id or remote+local address/port and protocol
* - return: 1 if found; 0 if not found
*/
int tcpconn_exists(int conn_id, ip_addr_t *peer_ip, int peer_port,
ip_addr_t *local_ip, int local_port)
ip_addr_t *local_ip, int local_port, sip_protos_t proto)
{
tcp_connection_t *c;
TCPCONN_LOCK;
c = _tcpconn_find(conn_id, peer_ip, peer_port, local_ip, local_port);
c = _tcpconn_find(conn_id, peer_ip, peer_port, local_ip, local_port, proto);
TCPCONN_UNLOCK;
if(c) {
return 1;
@ -1773,12 +1774,14 @@ int tcpconn_exists(int conn_id, ip_addr_t *peer_ip, int peer_port,
/* TCP connection find with locks and timeout
* - local_addr contains the desired local ip:port. If null any local address
* will be used. IN*ADDR_ANY or 0 port are wild cards.
* - proto is the protocol to match (PROTO_NONE for any)
* - try_local_port makes the search use it first, instead of port from local_addr
* If found, the connection's reference counter will be incremented, you might
* want to decrement it after use.
*/
struct tcp_connection *tcpconn_lookup(int id, struct ip_addr *ip, int port,
union sockaddr_union *local_addr, int try_local_port, ticks_t timeout)
union sockaddr_union *local_addr, int try_local_port, ticks_t timeout,
sip_protos_t proto)
{
struct tcp_connection *c;
struct ip_addr local_ip;
@ -1797,10 +1800,10 @@ struct tcp_connection *tcpconn_lookup(int id, struct ip_addr *ip, int port,
}
TCPCONN_LOCK;
if(likely(try_local_port != 0) && likely(local_port == 0)) {
c = _tcpconn_find(id, ip, port, &local_ip, try_local_port);
c = _tcpconn_find(id, ip, port, &local_ip, try_local_port, proto);
}
if(unlikely(c == NULL)) {
c = _tcpconn_find(id, ip, port, &local_ip, local_port);
c = _tcpconn_find(id, ip, port, &local_ip, local_port, proto);
}
if(likely(c)) {
atomic_inc(&c->refcnt);
@ -1825,7 +1828,7 @@ struct tcp_connection *tcpconn_lookup(int id, struct ip_addr *ip, int port,
struct tcp_connection *tcpconn_get(int id, struct ip_addr *ip, int port,
union sockaddr_union *local_addr, ticks_t timeout)
{
return tcpconn_lookup(id, ip, port, local_addr, 0, timeout);
return tcpconn_lookup(id, ip, port, local_addr, 0, timeout, PROTO_NONE);
}
@ -1951,7 +1954,7 @@ int tcpconn_add_alias(int id, int port, int proto)
port = port ? port : ((proto == PROTO_TLS) ? SIPS_PORT : SIP_PORT);
TCPCONN_LOCK;
/* check if alias already exists */
c = _tcpconn_find(id, 0, 0, 0, 0);
c = _tcpconn_find(id, 0, 0, 0, 0, PROTO_NONE);
if(likely(c)) {
ip_addr_mk_any(c->rcv.src_ip.af, &zero_ip);
alias_flags = cfg_get(tcp, tcp_cfg, alias_flags);
@ -2092,8 +2095,8 @@ int tcp_send(struct dest_info *dst, union sockaddr_union *from, const char *buf,
if(likely(port)) {
su2ip_addr(&ip, &dst->to);
if(tcp_connection_match == TCPCONN_MATCH_STRICT) {
c = tcpconn_lookup(
dst->id, &ip, port, from, try_local_port, con_lifetime);
c = tcpconn_lookup(dst->id, &ip, port, from, try_local_port,
con_lifetime, dst->proto);
} else {
c = tcpconn_get(dst->id, &ip, port, from, con_lifetime);
}
@ -2109,8 +2112,8 @@ int tcp_send(struct dest_info *dst, union sockaddr_union *from, const char *buf,
if(likely(port)) {
/* try again w/o id */
if(tcp_connection_match == TCPCONN_MATCH_STRICT) {
c = tcpconn_lookup(
0, &ip, port, from, try_local_port, con_lifetime);
c = tcpconn_lookup(0, &ip, port, from, try_local_port,
con_lifetime, dst->proto);
} else {
c = tcpconn_get(0, &ip, port, from, con_lifetime);
}
@ -3667,6 +3670,12 @@ again:
return n;
}
static tcp_connection_t *_ksr_tcpcon_evcb = NULL;
tcp_connection_t *ksr_tcpcon_evcb_get(void)
{
return _ksr_tcpcon_evcb;
}
static int tcp_emit_closed_event(struct tcp_connection *con)
{
@ -3686,9 +3695,12 @@ static int tcp_emit_closed_event(struct tcp_connection *con)
if(likely(sr_event_enabled(SREV_TCP_CLOSED))) {
memset(&tev, 0, sizeof(tcp_closed_event_info_t));
tev.reason = reason;
tev.id = con->id;
tev.con = con;
evp.data = (void *)(&tev);
_ksr_tcpcon_evcb = con;
ret = sr_event_exec(SREV_TCP_CLOSED, &evp);
_ksr_tcpcon_evcb = NULL;
} else {
LM_DBG("no callback registering for handling TCP closed event\n");
}
@ -4494,7 +4506,8 @@ static inline int handle_new_connect(struct socket_info *si)
if(likely(tcpconn)) {
if(tcp_accept_unique) {
if(tcpconn_exists(0, &tcpconn->rcv.dst_ip, tcpconn->rcv.dst_port,
&tcpconn->rcv.src_ip, tcpconn->rcv.src_port)) {
&tcpconn->rcv.src_ip, tcpconn->rcv.src_port,
si->proto)) {
LM_ERR("duplicated connection by local and remote addresses\n");
_tcpconn_free(tcpconn);
tcp_safe_close(new_sock);
@ -5430,7 +5443,8 @@ int wss_send(dest_info_t *dst, const char *buf, unsigned len)
su2ip_addr(&ip, &dst->to);
if(tcp_connection_match == TCPCONN_MATCH_STRICT) {
con = tcpconn_lookup(dst->id, &ip, port, from,
(dst->send_sock) ? dst->send_sock->port_no : 0, 0);
(dst->send_sock) ? dst->send_sock->port_no : 0, 0,
dst->proto);
} else {
con = tcpconn_get(dst->id, &ip, port, from, 0);
}

@ -315,7 +315,7 @@ static inline char *int2strbuf(unsigned long l, char *r, int r_size, int *len)
}
extern char ut_buf_int2str[INT2STR_MAX_LEN];
/** interger(long) to string conversion.
/** integer(long) to string conversion.
* This version uses a static buffer (shared with sint2str()).
* WARNING: other function calls might overwrite the static buffer, so
* either always save the result immediately or use int2strbuf(...).

@ -61,8 +61,8 @@ static void corex_rpc_list_sockets(rpc_t *rpc, void *ctx)
return;
}
if(rpc->struct_add(th, "sss{", "af", get_af_name(proto), "proto",
get_valid_proto_name(proto), "name", si->name.s,
if(rpc->struct_add(th, "sss{", "af", get_af_name(si->address.af),
"proto", get_valid_proto_name(proto), "name", si->name.s,
"addrlist", &ih)
< 0) {
rpc->fault(ctx, 500, "Internal error address list structure");

@ -204,16 +204,14 @@ void io_listen_loop(int fd_no, struct ctrl_socket *cs_lst)
if(poll_err || (poll_method == 0)) {
poll_method = choose_poll_method();
if(poll_err) {
LOG(L_ERR, "ERROR: io_listen_loop: %s, using %s instead\n",
poll_err, poll_method_name(poll_method));
LOG(L_ERR, "%s, using %s instead\n", poll_err,
poll_method_name(poll_method));
} else {
LOG(L_INFO,
"io_listen_loop: using %s as the io watch method"
" (auto detected)\n",
LOG(L_INFO, "using %s as the io watch method (auto detected)\n",
poll_method_name(poll_method));
}
} else {
LOG(L_INFO, "io_listen_loop: using %s io watch method (config)\n",
LOG(L_INFO, "using %s io watch method (config)\n",
poll_method_name(poll_method));
}
@ -236,24 +234,20 @@ void io_listen_loop(int fd_no, struct ctrl_socket *cs_lst)
cs->data =
s_conn_new(cs->fd, cs, &cs->u); /* reuse stream conn */
if(cs->data == 0) {
LOG(L_ERR, "ERROR: io_listen_loop: out of memory\n");
LOG(L_ERR, "out of memory\n");
goto error;
}
break;
#endif
case UNKNOWN_SOCK:
LOG(L_CRIT,
"BUG: io_listen_loop: bad control socket transport"
" %d\n",
LOG(L_CRIT, "BUG: bad control socket transport %d\n",
cs->transport);
goto error;
}
DBG("io_listen_loop: adding socket %d, type %d, transport"
" %d (%s)\n",
cs->fd, type, cs->transport, cs->name);
DBG("adding socket %d, type %d, transport %d (%s)\n", cs->fd, type,
cs->transport, cs->name);
if(io_watch_add(&ctl_io_h, cs->fd, POLLIN, type, cs) < 0) {
LOG(L_CRIT, "ERROR: io_listen_loop: init: failed to add"
"listen socket to the fd list\n");
LOG(L_CRIT, "init: failed to add listen socket to the fd list\n");
goto error;
}
}
@ -310,16 +304,14 @@ void io_listen_loop(int fd_no, struct ctrl_socket *cs_lst)
break;
#endif
default:
LOG(L_CRIT,
"BUG: io_listen_loop: no support for poll method "
" %s (%d)\n",
LOG(L_CRIT, "BUG: no support for poll method %s (%d)\n",
poll_method_name(ctl_io_h.poll_method),
ctl_io_h.poll_method);
goto error;
}
/* should never reach this point under normal (non-error) circumstances */
error:
LOG(L_CRIT, "ERROR: io_listen_loop exiting ...\n");
LOG(L_CRIT, "exiting ...\n");
}
@ -363,11 +355,11 @@ again:
} else if(errno == EINTR) {
goto again;
}
LOG(L_ERR, "ERROR; handle_ctrl_dgram: recvfrom on %s: [%d] %s\n",
cs->name, errno, strerror(errno));
LOG(L_ERR, "recvfrom on %s: [%d] %s\n", cs->name, errno,
strerror(errno));
goto error;
}
DBG("handle_ctrl_dgram: new packet on %s\n", cs->name);
DBG("new packet on %s\n", cs->name);
ret = 1;
#ifdef USE_FIFO
if(cs->p_proto == P_FIFO)
@ -416,24 +408,19 @@ again:
} else if(errno == EINTR) {
goto again;
}
LOG(L_ERR,
"ERROR: io_listen: handle_new_connect:"
" error while accepting connection on %s: [%d] %s\n",
LOG(L_ERR, " error while accepting connection on %s: [%d] %s\n",
cs->name, errno, strerror(errno));
goto error;
}
ret = 1;
if(io_read_connections >= MAX_IO_READ_CONNECTIONS) {
LOG(L_ERR,
"ERROR: io listen: maximum number of connections"
" exceeded: %d/%d\n",
LOG(L_ERR, "maximum number of connections exceeded: %d/%d\n",
io_read_connections, MAX_IO_READ_CONNECTIONS);
close(new_sock);
goto skip; /* success because accept was successful */
}
if(init_sock_opt(new_sock, cs->transport) < 0) {
LOG(L_ERR, "ERROR: io listen: handle_new_connect:"
" init_sock_opt failed\n");
LOG(L_ERR, "init_sock_opt failed\n");
close(new_sock);
goto skip;
}
@ -443,14 +430,12 @@ again:
s_conn_add(s_conn);
io_watch_add(&ctl_io_h, s_conn->fd, POLLIN, F_T_READ_STREAM, s_conn);
} else {
LOG(L_ERR, "ERROR: io listen: handle_new_connect:"
" s_conn_new failed\n");
LOG(L_ERR, "s_conn_new failed\n");
close(new_sock);
goto skip;
}
io_read_connections++;
DBG("handle_stream read: new connection (%d) on %s\n", io_read_connections,
cs->name);
DBG("new connection (%d) on %s\n", io_read_connections, cs->name);
skip:
return ret;
error:
@ -490,7 +475,7 @@ static int handle_stream_read(struct stream_connection *s_c, int idx)
bytes_free = STREAM_BUF_SIZE - (int)(r->end - r->buf);
log_prefix_set(NULL);
if(bytes_free == 0) {
LOG(L_ERR, "ERROR: handle_stream_read: buffer overrun\n");
LOG(L_ERR, "buffer overrun\n");
goto close_connection;
}
again:
@ -498,10 +483,14 @@ again:
if(bytes_read == -1) {
if((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
goto no_read; /* nothing has been read */
} else if(errno == EINTR)
} else if(errno == EINTR) {
goto again;
LOG(L_ERR, "ERROR: handle_stream_read: error reading: %s [%d]\n",
strerror(errno), errno);
}
if(errno == ECONNRESET) {
LOG(L_INFO, "error reading: %s [%d]\n", strerror(errno), errno);
} else {
LOG(L_ERR, "error reading: %s [%d]\n", strerror(errno), errno);
}
goto error_read;
} else if(bytes_read == 0) { /* eof */
DBG("handle_stream read: eof on %s\n", s_c->parent->name);
@ -533,7 +522,7 @@ again:
r->bytes_to_go = bytes_needed;
if(bytes_needed > 0) {
if(bytes_read == 0) { /*want more bytes, but we have eof*/
LOG(L_ERR, "ERROR: handle_stream_read: unexpected EOF\n");
LOG(L_ERR, "unexpected EOF\n");
goto close_connection;
}
break; /* no more read bytes ready for processing */
@ -607,7 +596,7 @@ static int handle_fifo_read(struct ctrl_socket *cs, int idx)
r = &(sc->req);
bytes_free = STREAM_BUF_SIZE - (int)(r->end - r->buf);
if(bytes_free == 0) {
LOG(L_ERR, "ERROR: handle_stream_read: buffer overrun\n");
LOG(L_ERR, "buffer overrun\n");
goto error;
}
again:
@ -617,11 +606,14 @@ again:
goto no_read; /* nothing has been read */
} else if(errno == EINTR)
goto again;
LOG(L_ERR, "ERROR: handle_fifo_read: error reading: %s [%d]\n",
strerror(errno), errno);
if(errno == ECONNRESET) {
LOG(L_INFO, "error reading: %s [%d]\n", strerror(errno), errno);
} else {
LOG(L_ERR, "error reading: %s [%d]\n", strerror(errno), errno);
}
goto error_read;
} else if(bytes_read == 0) { /* eof */
DBG("handle_fifo_read: eof on %s\n", cs->name);
DBG("eof on %s\n", cs->name);
}
r->end += bytes_read;
if(bytes_read && (bytes_read < r->bytes_to_go)) {
@ -640,7 +632,7 @@ again:
r->bytes_to_go = bytes_needed;
if(bytes_needed > 0) {
if(bytes_read == 0) { /*want more bytes, but we have eof*/
LOG(L_ERR, "ERROR: handle_fifo_read: unexpected EOF\n");
LOG(L_ERR, "unexpected EOF\n");
goto discard; /* discard buffered contents */
}
break; /* no more read bytes ready for processing */
@ -650,7 +642,7 @@ again:
if(bytes_processed == 0) {
/* nothing processed, nothing needed, no error - looks like
* a bug */
LOG(L_ERR, "ERROR: handle_fifo_read: unexpected return\n");
LOG(L_ERR, "unexpected return\n");
goto discard;
}
} while(r->proc < r->end);
@ -725,11 +717,10 @@ inline static int handle_io(struct fd_map *fm, short events, int idx)
break;
#endif
case F_T_RESERVED:
LOG(L_CRIT, "BUG: io listen handle_io: empty fd map\n");
LOG(L_CRIT, "empty fd map\n");
goto error;
default:
LOG(L_CRIT, "BUG: io listen handle_io: unknown fd type %d\n",
fm->type);
LOG(L_CRIT, "unknown fd type %d\n", fm->type);
goto error;
}
return ret;

@ -72,9 +72,12 @@ extern int dbcl_max_query_length;
cls->usedcon = cls->rlist[i].clist[j]; \
return 0; \
} else { \
LM_DBG("serial operation - failure on cluster" \
" [%.*s] (%d/%d)\n", \
cls->name.len, cls->name.s, i, j); \
LM_WARN("serial operation - failure on " \
"cluster" \
" [%.*s] (%d/%d) [%.*s]\n", \
cls->name.len, cls->name.s, i, j, \
cls->rlist[i].clist[j]->name.len, \
cls->rlist[i].clist[j]->name.s); \
sec = get_ticks() - sec; \
if(sec >= dbcl_max_query_length) { \
dbcl_inactive_con(cls->rlist[i].clist[j]); \
@ -106,10 +109,12 @@ extern int dbcl_max_query_length;
(j + 1) % cls->rlist[i].clen; \
return 0; \
} else { \
LM_DBG("round robin operation - failure on " \
"cluster" \
" [%.*s] (%d/%d)\n", \
cls->name.len, cls->name.s, i, j); \
LM_WARN("round robin operation - failure on " \
"cluster" \
" [%.*s] (%d/%d) [%.*s]\n", \
cls->name.len, cls->name.s, i, j, \
cls->rlist[i].clist[j]->name.len, \
cls->rlist[i].clist[j]->name.s); \
sec = get_ticks() - sec; \
if(sec >= dbcl_max_query_length) { \
dbcl_inactive_con(cls->rlist[i].clist[j]); \
@ -124,7 +129,7 @@ extern int dbcl_max_query_length;
return -1; \
} \
} \
LM_DBG("no successful read on cluster [%.*s]\n", cls->name.len, \
LM_ERR("no successful read on cluster [%.*s]\n", cls->name.len, \
cls->name.s); \
return ret; \
} while(0)
@ -167,9 +172,12 @@ extern int dbcl_max_query_length;
cls->usedcon = cls->wlist[i].clist[j]; \
return 0; \
} else { \
LM_DBG("serial operation - failure on cluster" \
" [%.*s] (%d/%d)\n", \
cls->name.len, cls->name.s, i, j); \
LM_WARN("serial operation - failure on " \
"cluster" \
" [%.*s] (%d/%d) [%.*s]\n", \
cls->name.len, cls->name.s, i, j, \
cls->rlist[i].clist[j]->name.len, \
cls->rlist[i].clist[j]->name.s); \
sec = get_ticks() - sec; \
if(sec >= dbcl_max_query_length) { \
dbcl_inactive_con(cls->wlist[i].clist[j]); \
@ -201,10 +209,12 @@ extern int dbcl_max_query_length;
(j + 1) % cls->wlist[i].clen; \
return 0; \
} else { \
LM_DBG("round robin operation - failure on " \
"cluster" \
" [%.*s] (%d/%d)\n", \
cls->name.len, cls->name.s, i, j); \
LM_WARN("round robin operation - failure on " \
"cluster" \
" [%.*s] (%d/%d) [%.*s]\n", \
cls->name.len, cls->name.s, i, j, \
cls->rlist[i].clist[j]->name.len, \
cls->rlist[i].clist[j]->name.s); \
sec = get_ticks() - sec; \
if(sec >= dbcl_max_query_length) { \
dbcl_inactive_con(cls->wlist[i].clist[j]); \
@ -232,10 +242,12 @@ extern int dbcl_max_query_length;
cls->usedcon = cls->wlist[i].clist[j]; \
rok = 1; \
} else { \
LM_DBG("parallel operation - failure on " \
"cluster" \
" [%.*s] (%d/%d)\n", \
cls->name.len, cls->name.s, i, j); \
LM_WARN("parallel operation - failure on " \
"cluster" \
" [%.*s] (%d/%d) [%.*s]\n", \
cls->name.len, cls->name.s, i, j, \
cls->rlist[i].clist[j]->name.len, \
cls->rlist[i].clist[j]->name.s); \
sec = get_ticks() - sec; \
if(sec >= dbcl_max_query_length) { \
dbcl_inactive_con(cls->wlist[i].clist[j]); \
@ -253,7 +265,7 @@ extern int dbcl_max_query_length;
return -1; \
} \
} \
LM_DBG("no successful write on cluster [%.*s]\n", cls->name.len, \
LM_ERR("no successful write on cluster [%.*s]\n", cls->name.len, \
cls->name.s); \
return ret; \
} while(0)
@ -303,9 +315,12 @@ extern int dbcl_max_query_length;
cls->usedcon = cls->wlist[i].clist[j]; \
return 0; \
} else { \
LM_DBG("serial operation - failure on cluster" \
" [%.*s] (%d/%d)\n", \
cls->name.len, cls->name.s, i, j); \
LM_WARN("serial operation - failure on " \
"cluster" \
" [%.*s] (%d/%d) [%.*s]\n", \
cls->name.len, cls->name.s, i, j, \
cls->rlist[i].clist[j]->name.len, \
cls->rlist[i].clist[j]->name.s); \
sec = get_ticks() - sec; \
if(sec >= dbcl_max_query_length) { \
dbcl_inactive_con(cls->wlist[i].clist[j]); \
@ -343,10 +358,12 @@ extern int dbcl_max_query_length;
(j + 1) % cls->wlist[i].clen; \
return 0; \
} else { \
LM_DBG("round robin operation - failure on " \
"cluster" \
" [%.*s] (%d/%d)\n", \
cls->name.len, cls->name.s, i, j); \
LM_WARN("round robin operation - failure on " \
"cluster" \
" [%.*s] (%d/%d) [%.*s]\n", \
cls->name.len, cls->name.s, i, j, \
cls->rlist[i].clist[j]->name.len, \
cls->rlist[i].clist[j]->name.s); \
sec = get_ticks() - sec; \
if(sec >= dbcl_max_query_length) { \
dbcl_inactive_con(cls->wlist[i].clist[j]); \
@ -380,10 +397,12 @@ extern int dbcl_max_query_length;
cls->usedcon = cls->wlist[i].clist[j]; \
rok = 1; \
} else { \
LM_DBG("parallel operation - failure on " \
"cluster" \
" [%.*s] (%d/%d)\n", \
cls->name.len, cls->name.s, i, j); \
LM_WARN("parallel operation - failure on " \
"cluster" \
" [%.*s] (%d/%d) [%.*s]\n", \
cls->name.len, cls->name.s, i, j, \
cls->rlist[i].clist[j]->name.len, \
cls->rlist[i].clist[j]->name.s); \
sec = get_ticks() - sec; \
if(sec >= dbcl_max_query_length) { \
dbcl_inactive_con(cls->wlist[i].clist[j]); \
@ -401,7 +420,7 @@ extern int dbcl_max_query_length;
return -1; \
} \
} \
LM_DBG("no successful write on cluster [%.*s]\n", cls->name.len, \
LM_ERR("no successful write on cluster [%.*s]\n", cls->name.len, \
cls->name.s); \
return ret; \
} while(0)

@ -178,9 +178,16 @@ struct my_con *db_mysql_new_connection(const struct db_id *id)
}
#endif /* MYSQL_VERSION_ID */
#endif /* MARIADB_BASE_VERSION */
#ifdef MYSQL_OPT_SSL_CA
if(db_mysql_opt_ssl_ca)
mysql_options(
ptr->con, MYSQL_OPT_SSL_CA, (const void *)db_mysql_opt_ssl_ca);
#else
LM_WARN("opt_ssl_ca option not supported by mysql version (value %s) - "
"ignoring\n",
db_mysql_opt_ssl_ca);
#endif /* MYSQL_OPT_SSL_CA */
#ifdef KSR_MYSQL_OPT_RECONNECT
/* set reconnect flag if enabled */

@ -39,7 +39,7 @@ Joel Centelles Martin
4.3. verbosity (int)
4.4. opt_tls (int)
4.5. db_pass (string)
4.6. ac_path (string)
4.6. ca_path (string)
5. Usage
6. Module Specific Considerations
@ -75,7 +75,7 @@ Chapter 1. Admin Guide
4.3. verbosity (int)
4.4. opt_tls (int)
4.5. db_pass (string)
4.6. ac_path (string)
4.6. ca_path (string)
5. Usage
6. Module Specific Considerations
@ -203,7 +203,7 @@ allid,time_hires&cid:callid
4.3. verbosity (int)
4.4. opt_tls (int)
4.5. db_pass (string)
4.6. ac_path (string)
4.6. ca_path (string)
4.1. schema_path (string)
@ -247,6 +247,12 @@ modparam("db_redis", "verbosity", 0)
Controls TLS usage while connecting to a remote DB. If set to 1, TLS is
used to connect to the DB.
If TLS is enabled, the module will validate the Redis server
certificate against the ca_path. There is currently no way to connect
with a specified client certificate, the corresponding configuration to
check client certificates in the Redis server must therefore be turned
off.
Default value: 0.
Example 1.4. Enabling TLS connection
@ -265,9 +271,10 @@ modparam("db_redis", "opt_tls", 1)
modparam("db_redis", "db_pass", "r3d1sPass")
...
4.6. ac_path (string)
4.6. ca_path (string)
Sets the path where Certificates Authorities certs are stored.
Sets the path where Certificates Authorities certs for the Redis server
certificate are stored.
Default value: "" (empty).

@ -224,6 +224,12 @@ modparam("db_redis", "verbosity", 0)
Controls TLS usage while connecting to a remote DB.
If set to 1, TLS is used to connect to the DB.
</para>
<para>
If TLS is enabled, the module will validate the Redis server certificate against the
ca_path. There is currently no way to connect with a specified client certificate, the
<ulink url="https://redis.io/docs/management/security/encryption/#client-certificate-authentication">corresponding configuration</ulink>
to check client certificates in the Redis server must therefore be turned off.
</para>
<para>
Default value: 0.
</para>
@ -256,9 +262,9 @@ modparam("db_redis", "db_pass", "r3d1sPass")
</section>
<section id="db_redis.p.ca_path">
<title><varname>ac_path</varname> (string)</title>
<title><varname>ca_path</varname> (string)</title>
<para>
Sets the path where Certificates Authorities certs are stored.
Sets the path where Certificates Authorities certs for the Redis server certificate are stored.
</para>
<para>
Default value: "" (empty).

@ -648,7 +648,8 @@ search_rule:
LM_DBG("match check skipped: [%.*s] %d\n",
re_list->expr.len, re_list->expr.s, rez);
rt = re_list->next;
pcre2_match_data_free(pcre_md);
if(pcre_md)
pcre2_match_data_free(pcre_md);
pcre2_code_free(re_list->re);
pkg_free(re_list);
re_list = rt;

@ -48,29 +48,33 @@ usrloc_api_t dmq_ul;
MODULE_VERSION
static param_export_t params[] = {{"enable", INT_PARAM, &dmq_usrloc_enable},
{"sync", INT_PARAM, &_dmq_usrloc_sync},
{"replicate_socket_info", INT_PARAM,
&_dmq_usrloc_replicate_socket_info},
{"batch_msg_contacts", INT_PARAM, &_dmq_usrloc_batch_msg_contacts},
{"batch_msg_size", INT_PARAM, &_dmq_usrloc_batch_msg_size},
{"batch_size", INT_PARAM, &_dmq_usrloc_batch_size},
{"batch_usleep", INT_PARAM, &_dmq_usrloc_batch_usleep},
{"usrloc_domain", PARAM_STR, &_dmq_usrloc_domain},
{"usrloc_delete", INT_PARAM, &_dmq_usrloc_delete}, {0, 0, 0}};
/* clang-format off */
static param_export_t params[] = {
{"enable", INT_PARAM, &dmq_usrloc_enable},
{"sync", INT_PARAM, &_dmq_usrloc_sync},
{"replicate_socket_info", INT_PARAM, &_dmq_usrloc_replicate_socket_info},
{"batch_msg_contacts", INT_PARAM, &_dmq_usrloc_batch_msg_contacts},
{"batch_msg_size", INT_PARAM, &_dmq_usrloc_batch_msg_size},
{"batch_size", INT_PARAM, &_dmq_usrloc_batch_size},
{"batch_usleep", INT_PARAM, &_dmq_usrloc_batch_usleep},
{"usrloc_domain", PARAM_STR, &_dmq_usrloc_domain},
{"usrloc_delete", INT_PARAM, &_dmq_usrloc_delete},
{0, 0, 0}
};
struct module_exports exports = {
"dmq_usrloc", /* module name */
DEFAULT_DLFLAGS, /* dlopen flags */
0, /* 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 */
0 /* module destroy function */
"dmq_usrloc", /* module name */
DEFAULT_DLFLAGS, /* dlopen flags */
0, /* 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 */
0 /* module destroy function */
};
/* clang-format on */
static int mod_init(void)

@ -50,7 +50,8 @@ static int geoip2_rpc_init(void);
static int w_geoip2_match(struct sip_msg *msg, char *str1, char *str2);
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);
static int w_geoip2_distance(
struct sip_msg *msg, char *str1, char *str2, char *str3);
/* clang-format off */
static pv_export_t mod_pvs[] = {
@ -138,6 +139,7 @@ static int geoip2_resid_param(modparam_t type, void *val)
static int ki_geoip2_match(sip_msg_t *msg, str *tomatch, str *pvclass)
{
geoip2_pv_reset(pvclass);
geoip2_reload_pv(geoip2_path);
return geoip2_update_pv(tomatch, pvclass);
}
@ -164,7 +166,8 @@ static int w_geoip2_match(sip_msg_t *msg, char *target, char *pvname)
return ki_geoip2_match(msg, &tomatch, &pvclass);
}
static int geoip2_distance(sip_msg_t *msg, str *_ip_addr, double lat, double lon)
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;
@ -253,7 +256,8 @@ static int geoip2_distance(sip_msg_t *msg, str *_ip_addr, double lat, double lon
return dist;
}
static int ki_geoip2_distance(sip_msg_t *msg, str *_ipaddr, str *_lat, str *_lon)
static int ki_geoip2_distance(
sip_msg_t *msg, str *_ipaddr, str *_lat, str *_lon)
{
double lat = 0;
double lon = 0;
@ -262,8 +266,7 @@ static int ki_geoip2_distance(sip_msg_t *msg, str *_ipaddr, str *_lat, str *_lon
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);
LM_ERR("cannot convert string to double: %.*s\n", _lat->len, _lat->s);
return -1;
}
@ -271,17 +274,17 @@ static int ki_geoip2_distance(sip_msg_t *msg, str *_ipaddr, str *_lat, str *_lon
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);
LM_ERR("cannot convert string to double: %.*s\n", _lon->len, _lon->s);
return -1;
}
return geoip2_distance(msg, _ipaddr, lat, lon);
geoip2_reload_pv(geoip2_path);
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)
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;
@ -304,7 +307,7 @@ static int w_geoip2_distance(sip_msg_t *msg, char *ip_addr_param, char *lat_para
static void geoip2_rpc_reload(rpc_t *rpc, void *ctx)
{
if(geoip2_reload_pv(geoip2_path) != 0) {
if(geoip2_reload_set() < 0) {
rpc->fault(ctx, 500, "Reload failed");
return;
}

@ -65,11 +65,14 @@ typedef struct _geoip2_pv
int type;
} geoip2_pv_t;
static MMDB_s *_handle_GeoIP;
static gen_lock_t *lock = NULL;
static MMDB_s *_handle_GeoIP = NULL;
static gen_lock_t *_sr_geoip2_lock = NULL;
static sr_geoip2_item_t *_sr_geoip2_list = NULL;
static int *_sr_geoip2_reloadG = NULL;
static int _sr_geoip2_reloadL = 0;
MMDB_s *get_geoip_handle(void)
{
return _handle_GeoIP;
@ -77,7 +80,7 @@ MMDB_s *get_geoip_handle(void)
gen_lock_t *get_gen_lock(void)
{
return lock;
return _sr_geoip2_lock;
}
sr_geoip2_record_t *sr_geoip2_get_record(str *name)
@ -264,9 +267,9 @@ static int get_mmdb_value2(MMDB_entry_s *entry, MMDB_entry_data_s *data,
{
int status = 0;
lock_get(lock);
lock_get(_sr_geoip2_lock);
status = MMDB_get_value(entry, data, first, second, NULL);
lock_release(lock);
lock_release(_sr_geoip2_lock);
return status;
}
@ -276,9 +279,9 @@ static int get_mmdb_value3(MMDB_entry_s *entry, MMDB_entry_data_s *data,
{
int status = 0;
lock_get(lock);
lock_get(_sr_geoip2_lock);
status = MMDB_get_value(entry, data, first, second, third, NULL);
lock_release(lock);
lock_release(_sr_geoip2_lock);
return status;
}
@ -289,9 +292,9 @@ static int get_mmdb_value4(MMDB_entry_s *entry, MMDB_entry_data_s *data,
{
int status = 0;
lock_get(lock);
lock_get(_sr_geoip2_lock);
status = MMDB_get_value(entry, data, first, second, third, fourth, NULL);
lock_release(lock);
lock_release(_sr_geoip2_lock);
return status;
}
@ -493,12 +496,18 @@ int pv_get_geoip2(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
static int init_shmlock(void)
{
lock = lock_alloc();
if(!lock) {
_sr_geoip2_reloadG = (int *)shm_malloc(sizeof(int));
if(_sr_geoip2_reloadG == NULL) {
LM_CRIT("cannot allocate memory for reload step\n");
return -1;
}
*_sr_geoip2_reloadG = 1;
_sr_geoip2_lock = lock_alloc();
if(!_sr_geoip2_lock) {
LM_CRIT("cannot allocate memory for lock\n");
return -1;
}
if(lock_init(lock) == 0) {
if(lock_init(_sr_geoip2_lock) == 0) {
LM_CRIT("cannot initialize lock\n");
return -1;
}
@ -508,24 +517,28 @@ static int init_shmlock(void)
static void destroy_shmlock(void)
{
if(lock) {
lock_destroy(lock);
lock_dealloc((void *)lock);
lock = NULL;
if(_sr_geoip2_lock) {
lock_destroy(_sr_geoip2_lock);
lock_dealloc((void *)_sr_geoip2_lock);
_sr_geoip2_lock = NULL;
}
if(_sr_geoip2_reloadG != NULL) {
shm_free(_sr_geoip2_reloadG);
_sr_geoip2_reloadG = NULL;
}
}
int geoip2_init_pv(char *path)
{
int status;
_handle_GeoIP = shm_malloc(sizeof(struct MMDB_s));
memset(_handle_GeoIP, 0, sizeof(struct MMDB_s));
_handle_GeoIP = (struct MMDB_s *)malloc(sizeof(struct MMDB_s));
if(_handle_GeoIP == NULL) {
SHM_MEM_ERROR;
SYS_MEM_ERROR;
return -1;
}
memset(_handle_GeoIP, 0, sizeof(struct MMDB_s));
status = MMDB_open(path, MMDB_MODE_MMAP, _handle_GeoIP);
if(MMDB_SUCCESS != status) {
@ -540,20 +553,37 @@ int geoip2_init_pv(char *path)
return 0;
}
int geoip2_reload_set(void)
{
if(_sr_geoip2_reloadG == NULL) {
LM_ERR("not initialized\n");
return -1;
}
lock_get(_sr_geoip2_lock);
*_sr_geoip2_reloadG = *_sr_geoip2_reloadG + 1;
lock_release(_sr_geoip2_lock);
return 0;
}
int geoip2_reload_pv(char *path)
{
int status = 0;
lock_get(lock);
lock_get(_sr_geoip2_lock);
if(*_sr_geoip2_reloadG == _sr_geoip2_reloadL) {
lock_release(_sr_geoip2_lock);
return MMDB_SUCCESS;
}
MMDB_close(_handle_GeoIP);
status = MMDB_open(path, MMDB_MODE_MMAP, _handle_GeoIP);
if(MMDB_SUCCESS != status) {
LM_ERR("cannot reload GeoIP database file at: %s\n", path);
} else {
LM_INFO("reloaded GeoIP database file at: %s\n", path);
_sr_geoip2_reloadL = *_sr_geoip2_reloadG;
}
lock_release(lock);
lock_release(_sr_geoip2_lock);
return status;
}
@ -564,9 +594,6 @@ void geoip2_destroy_list(void)
void geoip2_destroy_pv(void)
{
MMDB_close(_handle_GeoIP);
shm_free(_handle_GeoIP);
_handle_GeoIP = NULL;
destroy_shmlock();
}
@ -599,10 +626,10 @@ int geoip2_update_pv(str *tomatch, str *name)
strncpy(gr->tomatch, tomatch->s, tomatch->len);
tomatch->s[tomatch->len] = '\0';
lock_get(lock);
lock_get(_sr_geoip2_lock);
gr->record = MMDB_lookup_string(
_handle_GeoIP, (const char *)gr->tomatch, &gai_error, &mmdb_error);
lock_release(lock);
lock_release(_sr_geoip2_lock);
LM_DBG("attempt to match: %s\n", gr->tomatch);
if(gai_error || MMDB_SUCCESS != mmdb_error || !gr->record.found_entry) {
LM_DBG("no match for: %s\n", gr->tomatch);

@ -37,5 +37,6 @@ 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);
int geoip2_reload_set(void);
#endif

@ -37,8 +37,11 @@ int pv_get_ht_cell(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
if(hpv->ht == NULL) {
hpv->ht = ht_get_table(&hpv->htname);
if(hpv->ht == NULL)
if(hpv->ht == NULL) {
LM_ERR("htable not found for getting $sht(%.*s=>%.*s)\n",
hpv->htname.len, hpv->htname.s, htname.len, htname.s);
return pv_get_null(msg, param, res);
}
}
if(pv_printf_s(msg, hpv->pve, &htname) != 0) {
LM_ERR("cannot get $sht name\n");
@ -73,8 +76,11 @@ int pv_set_ht_cell(
if(hpv->ht == NULL)
hpv->ht = ht_get_table(&hpv->htname);
if(hpv->ht == NULL)
if(hpv->ht == NULL) {
LM_ERR("htable not found for setting $sht(%.*s=>%.*s)\n",
hpv->htname.len, hpv->htname.s, htname.len, htname.s);
return -1;
}
if(pv_printf_s(msg, hpv->pve, &htname) != 0) {
LM_ERR("cannot get $sht name\n");

@ -308,7 +308,7 @@ ipsec_create("location", "1");
then this must be name of the table which stores the contacts.
flags - bitwise flag:
+ 0x01 (1) - set force socket for request messages. Useful for
ipsec and TCP.
ipsec and TCP/TLS.
+ 0x02 (2) - reverse search for a contact in the memory. Useful
when contact alias is disabled.
+ 0x04 (4) - use destination URI for IPSec tunnel search. Useful
@ -317,12 +317,13 @@ ipsec_create("location", "1");
+ 0x10 (16) - do not look for alias parameter to set received
details.
+ 0x20 (32) - do not reset the destination URI.
+ 0x40 (64) - use user equipment client port as target for TCP
requests.
+ 0x40 (64) - use user equipment client port as target for
TCP/TLS requests (try to reuse the UE client connection).
+ 0x80 (128) - set transport parameter in the new dst uri for
TCP requests.
TCP/TLS requests.
+ 0x100 (256) - use Via attributes (port and protocol) for
routing UDP reply.
routing UDP reply, and protocol from next hop address for
request (otherwise it taken from saved contact).
+ 0x200 (512) - try TCP if corresponding UDP socket is not
found.
This is an optional parameter, default value - 0.
@ -360,7 +361,7 @@ ipsec_destroy("location");
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
The last three parameters have to be string values and can contain
variables.
Example 1.14. ipsec_destroy_by_contact()

@ -88,11 +88,12 @@ extern struct tm_binds tmb;
#define IPSEC_NOALIAS_SEARCH (1 << 4)
/* if set - do not reset dst uri for IPsec forward */
#define IPSEC_NODSTURI_RESET (1 << 5)
/* if set - use user equipment client port as target for requests over TCP */
/* if set - use user equipment client port as target for requests over TCP/TLS */
#define IPSEC_TCPPORT_UEC (1 << 6)
/* if set - build new dst uri with transport parameter for TCP */
/* if set - build new dst uri with transport parameter for TCP/TLS */
#define IPSEC_SETDSTURI_FULL (1 << 7)
/* if set - use Via attributes for routing reply */
/* if set - use Via attributes for routing reply
* and protocol from next hop address for request */
#define IPSEC_FORWARD_USEVIA (1 << 8)
/* if set - try TCP if corresponding UDP socket is not found */
#define IPSEC_FORWARD_TRYTCP (1 << 9)
@ -186,7 +187,7 @@ static int fill_contact(
if(m->first_line.type == SIP_REQUEST) {
char *alias_start;
struct sip_uri uri;
str suri;
str suri = STR_NULL;
memset(&uri, 0, sizeof(struct sip_uri));
@ -195,17 +196,20 @@ static int fill_contact(
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) {
}
if((sflags & IPSEC_DSTADDR_SEARCH) && suri.s == NULL
&& 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);
} else if((sflags & IPSEC_RURIADDR_SEARCH) && m->new_uri.s != NULL
&& m->new_uri.len > 0) {
}
if((sflags & IPSEC_RURIADDR_SEARCH) && suri.s == NULL
&& m->new_uri.s != NULL && m->new_uri.len > 0) {
suri = m->new_uri;
LM_DBG("using new r-uri for contact filling: %.*s\n", suri.len,
suri.s);
} else {
}
if(suri.s == NULL) {
suri = m->first_line.u.request.uri;
LM_DBG("using original uri for contact filling: %.*s\n", suri.len,
suri.s);
@ -942,6 +946,37 @@ cleanup:
return ret;
}
/**
*
*/
int ims_ipsec_get_forward_proto(sip_msg_t *msg)
{
struct sip_uri parsed_uri;
str uri;
if(msg == NULL) {
LM_ERR("no message structure - fallback to UDP\n");
return PROTO_UDP;
}
if(msg->dst_uri.s != NULL && msg->dst_uri.len > 0) {
uri = msg->dst_uri;
} else {
if(msg->new_uri.s != NULL && msg->new_uri.len > 0) {
uri = msg->new_uri;
} else {
uri = msg->first_line.u.request.uri;
}
}
if(parse_uri(uri.s, uri.len, &parsed_uri) != 0) {
LM_ERR("failed to parse next hop uri [%.*s]\n", uri.len, uri.s);
return PROTO_UDP;
}
if(parsed_uri.proto == PROTO_NONE || parsed_uri.proto == PROTO_OTHER) {
return PROTO_UDP;
}
return parsed_uri.proto;
}
int ipsec_forward(struct sip_msg *m, udomain_t *d, int _cflags)
{
@ -1021,13 +1056,15 @@ int ipsec_forward(struct sip_msg *m, udomain_t *d, int _cflags)
}
if(m->first_line.type == SIP_REPLY) {
/* reply handling */
if(_cflags & IPSEC_FORWARD_USEVIA) {
/* req - corresponding request from transaction */
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) {
if(dst_proto == PROTO_TCP || dst_proto == PROTO_TLS) {
src_port = req->rcv.dst_port;
dst_port = req->rcv.src_port;
} else {
@ -1041,63 +1078,53 @@ int ipsec_forward(struct sip_msg *m, udomain_t *d, int _cflags)
}
}
} else {
// for Reply get the dest proto from the received request
// dest proto from the corresponding request from transaction
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(dst_proto == PROTO_TCP || dst_proto == PROTO_TLS) {
// for TCP/TLS send from P-CSCF server port
src_port = s->port_ps;
// 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 TCP/TLS send to UE client port
dst_port = s->port_uc;
} else {
// for UDP send from P-CSCF client port
src_port = s->port_pc;
// Check send socket
// for UDP send to UE server port
dst_port = s->port_us;
}
// find 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) {
/* fallback: P-CSCF client port to UE server port */
src_port = s->port_pc;
dst_port = s->port_us;
}
}
} else {
/* request handling */
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;
}
}
// 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;
dst_proto = ims_ipsec_get_forward_proto(m);
} else {
// for Request get the dest proto from the saved contact
dst_proto = pcontact->received_proto;
}
if((_cflags & IPSEC_TCPPORT_UEC)
&& ((dst_proto == PROTO_TCP) || (dst_proto == PROTO_TLS))) {
// TCP/TLS send from P-CSCF server port, UDP sends from P-CSCF client port
src_port = s->port_ps;
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;
// for TCP/TLS sends to UE client port, for UDP sends to UE server port
dst_port = s->port_uc;
} else {
// for Request sends from P-CSCF client port
src_port = s->port_pc;
} else {
// send from P-CSCF client port
src_port = s->port_pc;
// for Request sends to UE server port
dst_port = s->port_us;
}
// send to UE server port
dst_port = s->port_us;
}
}
@ -1126,7 +1153,8 @@ 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)) {
} 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);
@ -1143,7 +1171,7 @@ int ipsec_forward(struct sip_msg *m, udomain_t *d, int _cflags)
memcpy(m->dst_uri.s, buf, buf_len);
m->dst_uri.len = buf_len;
m->dst_uri.s[m->dst_uri.len] = '\0';
LM_ERR("new destination URI: %.*s\n", m->dst_uri.len, m->dst_uri.s);
LM_INFO("new destination URI: %.*s\n", m->dst_uri.len, m->dst_uri.s);
}
// Set send socket

@ -284,7 +284,7 @@ ipsec_create("location", "1");
<itemizedlist>
<listitem>
<para>
<emphasis>0x01</emphasis> (1) - set force socket for request messages. Useful for ipsec and TCP.
<emphasis>0x01</emphasis> (1) - set force socket for request messages. Useful for ipsec and TCP/TLS.
</para>
</listitem>
<listitem>
@ -316,17 +316,19 @@ ipsec_create("location", "1");
</listitem>
<listitem>
<para>
<emphasis>0x40</emphasis> (64) - use user equipment client port as target for TCP requests.
<emphasis>0x40</emphasis> (64) - use user equipment client port as target for TCP/TLS requests
(try to reuse the UE client connection).
</para>
</listitem>
<listitem>
<para>
<emphasis>0x80</emphasis> (128) - set transport parameter in the new dst uri for TCP requests.
<emphasis>0x80</emphasis> (128) - set transport parameter in the new dst uri for TCP/TLS requests.
</para>
</listitem>
<listitem>
<para>
<emphasis>0x100</emphasis> (256) - use Via attributes (port and protocol) for routing UDP reply.
<emphasis>0x100</emphasis> (256) - use Via attributes (port and protocol) for routing UDP reply,
and protocol from next hop address for request (otherwise it taken from saved contact).
</para>
</listitem>
<listitem>
@ -403,7 +405,7 @@ ipsec_destroy("location");
</para>
</listitem>
</itemizedlist>
<para>The last three parameters have to be string valies and can contain
<para>The last three parameters have to be string values and can contain
variables.</para>
<example>
<title>ipsec_destroy_by_contact()</title>

@ -131,7 +131,9 @@ struct _pv_req_data _pv_treq;
static int mod_init(void);
static int child_init(int);
static void mod_destroy(void);
static int w_save(
static int w_save2(struct sip_msg *_m, char *_route, char *_d);
static int w_save3(struct sip_msg *_m, char *_route, char *_d, char *mode);
static int w_save4(
struct sip_msg *_m, char *_route, char *_d, char *mode, char *_cflags);
static int w_assign_server_unreg(
struct sip_msg *_m, char *_route, char *_d, char *_direction);
@ -143,7 +145,7 @@ static int w_lookup_path_to_contact(struct sip_msg *_m, char *contact_uri);
static int domain_fixup(void **param, int param_no);
static int assign_save_fixup3_async(void **param, int param_no);
static int free_uint_fixup(void **param, int param_no);
static int save_fixup3(void **param, int param_no);
static int save_fixup4(void **param, int param_no);
static int unreg_fixup(void **param, int param_no);
static int fetchc_fixup(void **param, int param_no);
/*! \brief Functions */
@ -231,11 +233,11 @@ static pv_export_t mod_pvs[] = {
* Exported functions
*/
static cmd_export_t cmds[] = {
{"save", (cmd_function)w_save, 2, assign_save_fixup3_async, 0,
{"save", (cmd_function)w_save2, 2, assign_save_fixup3_async, 0,
REQUEST_ROUTE | ONREPLY_ROUTE},
{"save", (cmd_function)w_save, 3, assign_save_fixup3_async, 0,
{"save", (cmd_function)w_save3, 3, assign_save_fixup3_async, 0,
REQUEST_ROUTE | ONREPLY_ROUTE},
{"save", (cmd_function)w_save, 4, save_fixup3, free_uint_fixup,
{"save", (cmd_function)w_save4, 4, save_fixup4, free_uint_fixup,
REQUEST_ROUTE | ONREPLY_ROUTE},
{"lookup", (cmd_function)w_lookup, 1, domain_fixup, 0,
REQUEST_ROUTE | FAILURE_ROUTE},
@ -677,9 +679,21 @@ AAAMessage *callback_cdp_request(AAAMessage *request, void *param)
/*! \brief
* Wrapper to save(location)
*/
static int w_save(
static int w_save2(struct sip_msg *_m, char *_route, char *_d)
{
return save(_m, _d, _route, 0);
}
static int w_save3(struct sip_msg *_m, char *_route, char *_d, char *_mode)
{
/* mode is unsed. Docs says legacy parameter? Maybe to be compatible with registrar/save? */
return save(_m, _d, _route, 0);
}
static int w_save4(
struct sip_msg *_m, char *_route, char *_d, char *mode, char *_cflags)
{
/* mode is unsed. Docs says legacy parameter? Maybe to be compatible with registrar/save? */
if(_cflags) {
return save(_m, _d, _route, ((int)(*_cflags)));
}
@ -772,7 +786,7 @@ static int assign_save_fixup3_async(void **param, int param_no)
return 0;
}
static int unit_fixup(void **param, int param_no)
static int uint_fixup(void **param, int param_no)
{
str s;
unsigned int *num;
@ -800,36 +814,19 @@ static int unit_fixup(void **param, int param_no)
static int free_uint_fixup(void **param, int param_no)
{
if(*param && param_no == 2) {
if(*param && param_no == 4) {
pkg_free(*param);
*param = 0;
}
return 0;
}
static int save_fixup3(void **param, int param_no)
static int save_fixup4(void **param, int param_no)
{
if(strlen((char *)*param) <= 0) {
LM_ERR("empty parameter %d not allowed\n", param_no);
return -1;
}
if(param_no == 1) { //route name - static or dynamic string (config vars)
if(fixup_spve_null(param, param_no) < 0)
return -1;
return 0;
} else if(param_no == 2) {
udomain_t *d;
if(ul.register_udomain((char *)*param, &d) < 0) {
LM_ERR("Error doing fixup on save");
return -1;
}
*param = (void *)d;
} else if(param_no == 3) {
return 0;
if(param_no < 4) {
return assign_save_fixup3_async(param, param_no);
} else if(param_no == 4) {
return unit_fixup(param, param_no);
return uint_fixup(param, param_no);
}
return 0;

@ -334,7 +334,7 @@ int term_impu_has_contact(struct sip_msg *_m, udomain_t *_d, char *_s)
str aor, uri;
ucontact_t *ptr = 0;
int res;
int ret;
int ret = -1;
impu_contact_t *impucontact;

@ -40,6 +40,11 @@
*
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "../../core/parser/parse_uri.h"
#include "userdata_parser.h"
#include "../../core/parser/parse_hname2.h"

@ -173,8 +173,10 @@ Chapter 1. Admin Guide
database URL for storing impu/contacts records
Example 1.1. Set db_url parameter
...
modparam("ims_usrloc_scscf", "db_url", "mysql//username:password@localho
st/scscf")
...
3.2. db_mode (string)
@ -191,6 +193,7 @@ st/scscf")
Example 1.2. Set db_mode parameter
...
modparam("ims_usrloc_scscf", "db_mode", 1)
...
3.3. maxcontact (int)
@ -201,6 +204,7 @@ st/scscf")
Example 1.3. Set maxcontact parameter
...
modparam("ims_usrloc_scscf", "maxcontact", 10)
...
3.4. maxcontact_3gpp (int)
@ -212,6 +216,7 @@ st/scscf")
Example 1.4. Set maxcontact_3gpp parameter
...
modparam("ims_usrloc_scscf", "maxcontact_3gpp", 0)
...
3.5. maxcontact_behaviour (int)
@ -225,6 +230,7 @@ st/scscf")
Example 1.5. Set maxcontact_behaviour parameter
...
modparam("ims_usrloc_scscf", "maxcontact_behaviour", 2)
...
3.6. max_subscribes(int)
@ -235,6 +241,7 @@ st/scscf")
Example 1.6. Set max_subscribes parameter
...
modparam("ims_usrloc_scscf", "max_subscribes", 2)
...
3.7. sub_dialog_hash_size(int)
@ -245,6 +252,7 @@ st/scscf")
Example 1.7. Set sub_dialog_hash_size parameter
...
modparam("ims_usrloc_scscf", "sub_dialog_hash_size", 512)
...
3.8. timer_procs(int)
@ -255,6 +263,7 @@ st/scscf")
Example 1.8. Set timer_procs parameter
...
modparam("ims_usrloc_scscf", "timer_procs", 5)
...
3.9. timer_interval (int)
@ -267,6 +276,7 @@ st/scscf")
Example 1.9. Set timer_interval parameter
...
modparam("ims_usrloc_scscf", "timer_interval", 120)
...
3.10. desc_time_order (int)
@ -278,6 +288,7 @@ st/scscf")
Example 1.10. Set desc_time_order parameter
...
modparam("ims_usrloc_scscf", "desc_time_order", 1)
...
3.11. matching_mode (int)
@ -292,6 +303,7 @@ st/scscf")
Example 1.11. Set matching_mode parameter
...
modparam("ims_usrloc_scscf", "matching_mode", 0)
...
3.12. cseq_delay (int)
@ -303,6 +315,7 @@ st/scscf")
Example 1.12. Set cseq_delay parameter
...
modparam("ims_usrloc_scscf", "cseq_delay", 20)
...
3.13. fetch_rows(int)
@ -314,6 +327,7 @@ st/scscf")
Example 1.13. Set fetch_rows parameter
...
modparam("ims_usrloc_scscf", "fetch_rows", 3000)
...
3.14. hash_size (int)
@ -324,6 +338,7 @@ st/scscf")
Example 1.14. Set hash_size parameter
...
modparam("ims_usrloc_scscf", "hash_size", 512)
...
3.15. subs_hash_size (int)
@ -335,6 +350,7 @@ st/scscf")
Example 1.15. Set subs_hash_size parameter
...
modparam("ims_usrloc_scscf", "subs_hash_size", 512)
...
3.16. contacts_hash_size (integer)
@ -346,6 +362,7 @@ st/scscf")
Example 1.16. Set contacts_hash_size parameter
...
modparam("ims_usrloc_scscf", "contacts_hash_size", 512)
...
3.17. nat_bflag (integer)
@ -354,7 +371,9 @@ st/scscf")
Default value is 0
Example 1.17. Set nat_bflag parameter
...
modparam("ims_usrloc_scscf", "nat_bflag", 3)
...
3.18. contact_delete_delay (int)
@ -364,7 +383,9 @@ st/scscf")
Default value is 30
Example 1.18. Set contact_delete_delayparameter
...
modparam("ims_usrloc_scscf", "contact_delete_delay", 32)
...
3.19. support_wildcardPSI (int)
@ -383,22 +404,28 @@ st/scscf")
Default value is 1800
Example 1.20. Set unreg_validity parameter
...
modparam("ims_usrloc_scscf", "unreg_validity", 0)
...
3.21. user_data_xsd (string)
Default value is 1800
Example 1.21. Set unreg_validity parameter
...
modparam("ims_usrloc_scscf", "user_data_xsd", "/usr/local/etc/kamailio/C
xDataType_Rel6.xsd")
...
3.22. realm (string)
Default value is NULL
Example 1.22. Set realm parameter
...
modparam("ims_usrloc_scscf", "realm", "kamailio-ims.org")
...
3.23. skip_realm (int)
@ -408,7 +435,9 @@ xDataType_Rel6.xsd")
Default value is 0
Example 1.23. Set skip_realm parameter
...
modparam("ims_usrloc_scscf", "skip_realm", 1)
...
4. RPC Commands

@ -11,7 +11,9 @@
<section>
<title>Overview</title>
<para>This module serves as a storage engine for SCSCF contacts, much like the standard Kamailio module that is usrloc, is a storage engine for standard SIP contacts.</para>
<para>This module serves as a storage engine for SCSCF contacts, much like
the standard Kamailio module that is usrloc, is a storage engine
for standard SIP contacts.</para>
</section>
<section>
<title>Dependencies</title>
@ -40,14 +42,17 @@
<example>
<title>Set <varname>db_url</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("ims_usrloc_scscf", "db_url", "mysql//username:password@localhost/scscf")
</programlisting>
...
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.db_mode">
<title><varname>db_mode</varname> (string)</title>
<para>This is the database mode to be used for the SCSCF usrloc data persistent storage. Currently this module supports the Write-Back scheme only.</para>
<para>This is the database mode to be used for the SCSCF usrloc data persistent
storage. Currently this module supports the Write-Back scheme only.</para>
<itemizedlist>
<listitem>
<para>
@ -57,16 +62,19 @@
</listitem>
<listitem>
<para>
1 - Write-Backend scheme. All changes are made to memory and database synchronization is done in the timer
1 - Write-Backend scheme. All changes are made to memory and database
synchronization is done in the timer
</para>
</listitem>
</itemizedlist>
<para><emphasis> Default value is 0. </emphasis></para>
<example>
<title>Set <varname>db_mode</varname> parameter</title>
<programlisting format="linespecific">...
<programlisting format="linespecific">
...
modparam("ims_usrloc_scscf", "db_mode", 1)
</programlisting>
...
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.maxcontact">
@ -75,9 +83,11 @@
<para><emphasis>Default value is 0(max)</emphasis></para>
<example>
<title>Set <varname>maxcontact</varname> parameter</title>
<programlisting format="linespecific">...
<programlisting format="linespecific">
...
modparam("ims_usrloc_scscf", "maxcontact", 10)
</programlisting>
...
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.maxcontact_3gpp">
@ -86,9 +96,11 @@
<para><emphasis> Default value is 0.(max) </emphasis></para>
<example>
<title>Set <varname>maxcontact_3gpp</varname> parameter</title>
<programlisting format="linespecific">...
<programlisting format="linespecific">
...
modparam("ims_usrloc_scscf", "maxcontact_3gpp", 0)
</programlisting>
...
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.maxcontact_behaviour">
@ -114,9 +126,11 @@
<para><emphasis> Default value is 0. </emphasis></para>
<example>
<title>Set <varname>maxcontact_behaviour</varname> parameter</title>
<programlisting format="linespecific">...
<programlisting format="linespecific">
...
modparam("ims_usrloc_scscf", "maxcontact_behaviour", 2)
</programlisting>
...
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.max_subscribes">
@ -125,9 +139,11 @@
<para><emphasis> Default value is 0. </emphasis></para>
<example>
<title>Set <varname>max_subscribes</varname> parameter</title>
<programlisting format="linespecific">...
<programlisting format="linespecific">
...
modparam("ims_usrloc_scscf", "max_subscribes", 2)
</programlisting>
...
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.sub_dialog_hash_size">
@ -136,9 +152,11 @@
<para><emphasis> Default value is 10. </emphasis></para>
<example>
<title>Set <varname>sub_dialog_hash_size</varname> parameter</title>
<programlisting format="linespecific">...
<programlisting format="linespecific">
...
modparam("ims_usrloc_scscf", "sub_dialog_hash_size", 512)
</programlisting>
...
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.timer_procs">
@ -147,9 +165,11 @@
<para><emphasis> Default value is 0 </emphasis></para>
<example>
<title>Set <varname>timer_procs</varname> parameter</title>
<programlisting format="linespecific">...
<programlisting format="linespecific">
...
modparam("ims_usrloc_scscf", "timer_procs", 5)
</programlisting>
...
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.timer_interval">
@ -159,19 +179,24 @@
<para><emphasis> Default value is 90 </emphasis></para>
<example>
<title>Set <varname>timer_interval</varname> parameter</title>
<programlisting format="linespecific">...
<programlisting format="linespecific">
...
modparam("ims_usrloc_scscf", "timer_interval", 120)
</programlisting>
...
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.desc_time_order">
<title>desc_time_order (int)</title>
<para>If the user's contacts should be kept timestamp ordered; otherwise the contact will be ordered based on q value. Non 0 value means true.</para>
<para>If the user's contacts should be kept timestamp ordered; otherwise the contact
will be ordered based on q value. Non 0 value means true.</para>
<para><emphasis> Default value is timestamp ordering not enabled </emphasis></para>
<example>
<title>Set <varname>desc_time_order</varname> parameter</title>
<programlisting format="linespecific">...
<programlisting format="linespecific">
...
modparam("ims_usrloc_scscf", "desc_time_order", 1)
...
</programlisting>
</example>
</section>
@ -203,9 +228,11 @@
<para><emphasis> Default value is 0. </emphasis></para>
<example>
<title>Set <varname>matching_mode</varname> parameter</title>
<programlisting format="linespecific">...
<programlisting format="linespecific">
...
modparam("ims_usrloc_scscf", "matching_mode", 0)
</programlisting>
...
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.cseq_delay">
@ -214,9 +241,11 @@
<para><emphasis> Default value is 20. </emphasis></para>
<example>
<title>Set <varname>cseq_delay</varname> parameter</title>
<programlisting format="linespecific">...
<programlisting format="linespecific">
...
modparam("ims_usrloc_scscf", "cseq_delay", 20)
</programlisting>
...
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.fetch_rows">
@ -225,9 +254,11 @@
<para><emphasis> Default value is 2000. </emphasis></para>
<example>
<title>Set <varname>fetch_rows</varname> parameter</title>
<programlisting format="linespecific">...
<programlisting format="linespecific">
...
modparam("ims_usrloc_scscf", "fetch_rows", 3000)
</programlisting>
...
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.hash_size">
@ -236,9 +267,11 @@
<para><emphasis> Default value 512</emphasis></para>
<example>
<title>Set <varname>hash_size</varname> parameter</title>
<programlisting format="linespecific">...
<programlisting format="linespecific">
...
modparam("ims_usrloc_scscf", "hash_size", 512)
</programlisting>
...
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.subs_hash_size">
@ -247,9 +280,11 @@
<para><emphasis> Default value 512</emphasis></para>
<example>
<title>Set <varname>subs_hash_size</varname> parameter</title>
<programlisting format="linespecific">...
<programlisting format="linespecific">
...
modparam("ims_usrloc_scscf", "subs_hash_size", 512)
</programlisting>
...
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.contacts_hash_size">
@ -258,9 +293,11 @@
<para><emphasis> Default value is 512</emphasis></para>
<example>
<title>Set <varname>contacts_hash_size</varname> parameter</title>
<programlisting format="linespecific">...
<programlisting format="linespecific">
...
modparam("ims_usrloc_scscf", "contacts_hash_size", 512)
</programlisting>
...
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.nat_bflag">
@ -270,8 +307,10 @@
<example>
<title>Set <varname>nat_bflag</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("ims_usrloc_scscf", "nat_bflag", 3)
</programlisting>
...
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.contact_delete_delay">
@ -281,8 +320,10 @@
<example>
<title>Set <varname>contact_delete_delay</varname>parameter</title>
<programlisting format="linespecific">
...
modparam("ims_usrloc_scscf", "contact_delete_delay", 32)
</programlisting>
...
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.support_wildcardPSI">
@ -303,8 +344,10 @@
<example>
<title>Set <varname>unreg_validity</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("ims_usrloc_scscf", "unreg_validity", 0)
</programlisting>
...
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.user_data_xsd">
@ -314,8 +357,10 @@
<example>
<title>Set <varname>unreg_validity</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("ims_usrloc_scscf", "user_data_xsd", "/usr/local/etc/kamailio/CxDataType_Rel6.xsd")
</programlisting>
...
</programlisting>
</example>
</section>
@ -326,8 +371,10 @@
<example>
<title>Set <varname>realm</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("ims_usrloc_scscf", "realm", "kamailio-ims.org")
</programlisting>
...
</programlisting>
</example>
</section>
@ -338,8 +385,10 @@
<example>
<title>Set <varname>skip_realm</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("ims_usrloc_scscf", "skip_realm", 1)
</programlisting>
...
</programlisting>
</example>
</section>
</section>

@ -143,55 +143,61 @@ delete_shtable_t pres_delete_shtable;
destroy_shtable_t pres_destroy_shtable;
extract_sdialog_info_t pres_extract_sdialog_info;
/* clang-format off */
/*! \brief
* Exported functions
*/
static cmd_export_t cmds[] = {
{"ul_bind_usrloc", (cmd_function)bind_usrloc, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 0}};
{"ul_bind_usrloc", (cmd_function)bind_usrloc, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 0}
};
/*! \brief
* Exported parameters
*/
static param_export_t params[] = {
{"timer_interval", INT_PARAM, &timer_interval},
{"desc_time_order", INT_PARAM, &desc_time_order},
{"matching_mode", INT_PARAM, &matching_mode},
{"cseq_delay", INT_PARAM, &cseq_delay},
{"fetch_rows", INT_PARAM, &ul_fetch_rows},
{"hash_size", INT_PARAM, &ul_hash_size},
{"subs_hash_size", INT_PARAM, &subs_hash_size},
{"contacts_hash_size", INT_PARAM, &contacts_hash_size},
{"nat_bflag", INT_PARAM, &nat_bflag},
{"contact_delete_delay", INT_PARAM, &contact_delete_delay},
{"usrloc_debug_file", PARAM_STR, &usrloc_debug_file},
{"enable_debug_file", INT_PARAM, &usrloc_debug},
{"user_data_dtd", PARAM_STRING, &scscf_user_data_dtd},
{"user_data_xsd", PARAM_STRING, &scscf_user_data_xsd},
{"support_wildcardPSI", INT_PARAM, &scscf_support_wildcardPSI},
{"unreg_validity", INT_PARAM, &unreg_validity},
{"maxcontact_behaviour", INT_PARAM, &maxcontact_behaviour},
{"maxcontact", INT_PARAM, &maxcontact},
{"maxcontact_3gpp", INT_PARAM, &maxcontact_3gpp},
{"max_subscribes", INT_PARAM, &max_subscribes},
{"sub_dialog_hash_size", INT_PARAM, &sub_dialog_hash_size},
{"db_mode", INT_PARAM, &db_mode}, {"db_url", PARAM_STR, &db_url},
{"timer_procs", INT_PARAM, &ul_timer_procs},
{"realm", PARAM_STRING, &cscf_realm},
{"skip_realm", INT_PARAM, &skip_cscf_realm}, {0, 0, 0}};
{"timer_interval", INT_PARAM, &timer_interval},
{"desc_time_order", INT_PARAM, &desc_time_order},
{"matching_mode", INT_PARAM, &matching_mode},
{"cseq_delay", INT_PARAM, &cseq_delay},
{"fetch_rows", INT_PARAM, &ul_fetch_rows},
{"hash_size", INT_PARAM, &ul_hash_size},
{"subs_hash_size", INT_PARAM, &subs_hash_size},
{"contacts_hash_size", INT_PARAM, &contacts_hash_size},
{"nat_bflag", INT_PARAM, &nat_bflag},
{"contact_delete_delay", INT_PARAM, &contact_delete_delay},
{"usrloc_debug_file", PARAM_STR, &usrloc_debug_file},
{"enable_debug_file", INT_PARAM, &usrloc_debug},
{"user_data_dtd", PARAM_STRING, &scscf_user_data_dtd},
{"user_data_xsd", PARAM_STRING, &scscf_user_data_xsd},
{"support_wildcardPSI", INT_PARAM, &scscf_support_wildcardPSI},
{"unreg_validity", INT_PARAM, &unreg_validity},
{"maxcontact_behaviour", INT_PARAM, &maxcontact_behaviour},
{"maxcontact", INT_PARAM, &maxcontact},
{"maxcontact_3gpp", INT_PARAM, &maxcontact_3gpp},
{"max_subscribes", INT_PARAM, &max_subscribes},
{"sub_dialog_hash_size", INT_PARAM, &sub_dialog_hash_size},
{"db_mode", INT_PARAM, &db_mode}, {"db_url", PARAM_STR, &db_url},
{"timer_procs", INT_PARAM, &ul_timer_procs},
{"realm", PARAM_STRING, &cscf_realm},
{"skip_realm", INT_PARAM, &skip_cscf_realm},
{0, 0, 0}
};
struct module_exports exports = {
"ims_usrloc_scscf", DEFAULT_DLFLAGS, /*!< dlopen flags */
cmds, /*!< Exported functions */
params, /*!< Export parameters */
0, /*!< exported RPC methods */
0, /*!< exported pseudo-variables */
0, /*!< Response function */
mod_init, /*!< Module initialization function */
child_init, /*!< Child initialization function */
destroy /*!< Destroy function */
"ims_usrloc_scscf",
DEFAULT_DLFLAGS, /*!< dlopen flags */
cmds, /*!< Exported functions */
params, /*!< Export parameters */
0, /*!< exported RPC methods */
0, /*!< exported pseudo-variables */
0, /*!< Response function */
mod_init, /*!< Module initialization function */
child_init, /*!< Child initialization function */
destroy /*!< Destroy function */
};
/* clang-format on */
/*! \brief

@ -1153,15 +1153,13 @@ static int ki_handle_ruri_alias_mode(struct sip_msg *msg, int mode)
}
start = NULL;
/* locate last alias parameter */
while(rest_len > _ksr_contact_alias.len + 4) {
while(rest_len > _ksr_contact_alias.len) {
if(strncmp(rest, _ksr_contact_alias.s, _ksr_contact_alias.len) == 0) {
start = rest;
if(mode == 0) {
/* use first alias parameter */
break;
}
rest = rest + _ksr_contact_alias.len;
rest_len = rest_len - _ksr_contact_alias.len;
}
sep = memchr(rest, 59 /* ; */, rest_len);
if(sep == NULL) {

@ -55,7 +55,7 @@ Joel Centelles Martin
3.8. flush_on_reconnect (integer)
3.9. allow_dynamic_nodes (integer)
3.10. debug (integer)
3.11. ac_path (string)
3.11. ca_path (string)
4. Functions
@ -103,7 +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)
3.11. ca_path (string)
4. Functions
@ -149,7 +149,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)
3.11. ca_path (string)
3.1. server (str)
@ -168,6 +168,12 @@ Chapter 1. Admin Guide
many REDIS servers, just give different attributes and use the specific
server name when querying the REDIS instance.
If tls is enabled, the module will validate the REDIS server
certificate against the ca_path. There is currently no way to connect
with a specified client certificate, the corresponding configuration to
check client certificates in the REDIS server must therefore be turned
off.
Default value is NULL.
Example 1.1. Set server parameter
@ -346,9 +352,10 @@ modparam("ndb_redis", "allow_dynamic_nodes", 1)
modparam("ndb_redis", "debug", 1)
...
3.11. ac_path (string)
3.11. ca_path (string)
Sets the path where Certificates Authorities certs are stored.
Sets the path where Certificates Authorities certs for the REDIS server
certificate are stored.
Default value: "" (empty).

@ -75,6 +75,12 @@
many REDIS servers, just give different attributes and use the specific
server name when querying the REDIS instance.
</para>
<para>
If tls is enabled, the module will validate the REDIS server certificate against the
ca_path. There is currently no way to connect with a specified client certificate, the
<ulink url="https://redis.io/docs/management/security/encryption/#client-certificate-authentication">corresponding configuration</ulink>
to check client certificates in the REDIS server must therefore be turned off.
</para>
<para>
<emphasis>
Default value is NULL.
@ -330,9 +336,9 @@ modparam("ndb_redis", "debug", 1)
</example>
</section>
<section id="ndb_redis.p.ca_path">
<title><varname>ac_path</varname> (string)</title>
<title><varname>ca_path</varname> (string)</title>
<para>
Sets the path where Certificates Authorities certs are stored.
Sets the path where Certificates Authorities certs for the REDIS server certificate are stored.
</para>
<para>
Default value: "" (empty).

@ -1736,6 +1736,10 @@ jump_over_body:
shm_free(cb_param);
goto error;
}
if(uac_r.cb_flags & TMCB_LOCAL_REQUEST_DROP) {
shm_free(cb_param);
goto done;
}
LM_GEN2(pres_local_log_facility, pres_local_log_level,
"NOTIFY %.*s via %.*s on behalf of %.*s for event %.*s : %.*s\n",
@ -1744,6 +1748,7 @@ jump_over_body:
subs->event->name.len, subs->event->name.s, subs->callid.len,
subs->callid.s);
done:
ps_free_tm_dlg(td);
if(str_hdr.s)

@ -700,6 +700,11 @@ int update_pua(ua_pres_t *p)
ret_code = -1;
goto done;
}
if(uac_r.cb_flags & TMCB_LOCAL_REQUEST_DROP) {
shm_free(cb_param);
ret_code = 0;
goto done;
}
} else {
str met = {"SUBSCRIBE", 9};
ua_pres_t *cb_param = NULL;

@ -624,6 +624,9 @@ send_publish:
LM_ERR("in t_request tm module function\n");
goto error;
}
if(uac_r.cb_flags & TMCB_LOCAL_REQUEST_DROP) {
shm_free(cb_param);
}
done:
ret = 0;

@ -838,6 +838,7 @@ struct dlginfo_cell *get_dialog_data(struct dlg_cell *dlg, int type,
}
memset(dlginfo->pubruris_caller, 0, sizeof(struct str_list));
dlginfo->pubruris_caller->s.s = shm_str2char_dup(&dlginfo->from_uri);
dlginfo->pubruris_caller->s.len = dlginfo->from_uri.len;
if(!dlginfo->pubruris_caller->s.s) {
free_dlginfo_cell(dlginfo);
return NULL;

@ -2939,6 +2939,13 @@ int pv_get_tcpconn_id(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
if(msg == NULL)
return -1;
/* use first the connection set for event_route[tcp:...] */
con = ksr_tcpcon_evcb_get();
if(con != NULL) {
return pv_get_sintval(msg, param, res, con->id);
}
/* find connection from sip message structure */
if((con = tcpconn_get(msg->rcv.proto_reserved1, 0, 0, 0, 0)) == NULL)
return pv_get_null(msg, param, res);

@ -479,6 +479,8 @@ static inline char *tm_type_to_string(int type)
return "TMCB_ON_BRANCH_FAILURE";
case TMCB_ON_BRANCH_FAILURE_RO:
return "TMCB_ON_BRANCH_FAILURE_RO";
case TMCB_LOCAL_REQUEST_DROP:
return "TMCB_LOCAL_REQUEST_DROP";
case TMCB_MAX:
return "TMCB_MAX";
}

@ -68,7 +68,7 @@ gen_lock_t *reload_lock;
/*
* Module exported parameter variables
*/
static char *file;
static char *file = NULL;
static int max_groups = MAX_GROUPS;
static int group_max_size = GROUP_MAX_SIZE;
static int pcre_caseless = 0;
@ -83,9 +83,9 @@ static int pcre_extended = 0;
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 pcre2_code **pcres = NULL;
static pcre2_code ***pcres_addr = NULL;
static int *num_pcres = NULL;
static int pcre_options = 0x00000000;
@ -113,48 +113,54 @@ static int w_pcre_match_group(struct sip_msg *_msg, char *_s1, char *_s2);
/*
* Exported functions
*/
/* clang-format off */
static cmd_export_t cmds[] = {
{"pcre_match", (cmd_function)w_pcre_match, 2, fixup_spve_spve, 0,
REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE
| LOCAL_ROUTE},
{"pcre_match_group", (cmd_function)w_pcre_match_group, 2,
fixup_spve_spve, 0,
REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE
| LOCAL_ROUTE},
{"pcre_match_group", (cmd_function)w_pcre_match_group, 1,
fixup_spve_null, 0,
REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE
| LOCAL_ROUTE},
{0, 0, 0, 0, 0, 0}};
{"pcre_match", (cmd_function)w_pcre_match, 2, fixup_spve_spve, 0,
REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE
| LOCAL_ROUTE},
{"pcre_match_group", (cmd_function)w_pcre_match_group, 2,
fixup_spve_spve, 0,
REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE
| LOCAL_ROUTE},
{"pcre_match_group", (cmd_function)w_pcre_match_group, 1,
fixup_spve_null, 0,
REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE
| LOCAL_ROUTE},
{0, 0, 0, 0, 0, 0}
};
/*
* Exported parameters
*/
static param_export_t params[] = {{"file", PARAM_STRING, &file},
{"max_groups", INT_PARAM, &max_groups},
{"group_max_size", INT_PARAM, &group_max_size},
{"pcre_caseless", INT_PARAM, &pcre_caseless},
{"pcre_multiline", INT_PARAM, &pcre_multiline},
{"pcre_dotall", INT_PARAM, &pcre_dotall},
{"pcre_extended", INT_PARAM, &pcre_extended}, {0, 0, 0}};
static param_export_t params[] = {
{"file", PARAM_STRING, &file},
{"max_groups", INT_PARAM, &max_groups},
{"group_max_size", INT_PARAM, &group_max_size},
{"pcre_caseless", INT_PARAM, &pcre_caseless},
{"pcre_multiline", INT_PARAM, &pcre_multiline},
{"pcre_dotall", INT_PARAM, &pcre_dotall},
{"pcre_extended", INT_PARAM, &pcre_extended},
{0, 0, 0}
};
/*
* Module interface
*/
struct module_exports exports = {
"regex", /*!< 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 */
0, /*!< per-child init function */
destroy /*!< destroy function */
"regex", /*!< 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 */
0, /*!< per-child init function */
destroy /*!< destroy function */
};
/* clang-format on */
static void *pcre2_malloc(size_t size, void *ext)
@ -421,7 +427,7 @@ static int load_pcres(int action)
}
/* Temporal pointer of pcres */
if((pcres_tmp = pkg_malloc(sizeof(pcre2_code *) * num_pcres_tmp)) == 0) {
if((pcres_tmp = shm_malloc(sizeof(pcre2_code *) * num_pcres_tmp)) == 0) {
LM_ERR("no more memory for pcres_tmp\n");
goto err;
}
@ -462,11 +468,11 @@ static int load_pcres(int action)
}
shm_free(pcres);
}
*num_pcres = num_pcres_tmp;
*pcres = *pcres_tmp;
pcres = pcres_tmp;
*pcres_addr = pcres;
pkg_free(pcres_tmp);
/* Free allocated slots for unused patterns */
for(i = num_pcres_tmp; i < max_groups; i++) {
pkg_free(patterns[i]);

@ -2206,8 +2206,10 @@ static int mod_init(void)
}
}
register_procs(1);
cfg_register_child(1);
if(rtpengine_dtmf_event_sock.len > 0) {
register_procs(1);
cfg_register_child(1);
}
}
return 0;
@ -3517,6 +3519,7 @@ static char *send_rtpp_command(
len = _rtpe_lwscb.request(&node->rn_url, (str *)&rtpe_proto, &request,
&response, rtpengine_tout_ms * 1000);
pkg_free(request.s);
if(len < 0) {
LM_ERR("failed to do websocket request\n");

@ -91,19 +91,29 @@ Registration Procedures: Standards Action Process or expert approval
*/
typedef struct _codecsmap
{
/* clang-format off */
typedef struct _codecsmap {
str name;
str ids;
} codecsmap_t;
codecsmap_t sdpops_codecsmap_table[] = {{{"PCMU", 4}, {"0", 1}},
{{"GSM", 3}, {"3", 1}}, {{"G723", 4}, {"4", 1}},
{{"DVI4", 4}, {"5,6,16,17", 9}}, {{"LPC", 3}, {"7", 1}},
{{"PCMA", 4}, {"8", 1}}, {{"G722", 4}, {"9", 1}},
{{"L16", 3}, {"10,11", 5}}, {{"QCELP", 5}, {"12", 2}},
{{"CN", 2}, {"13", 5}}, {{"MPA", 3}, {"14", 2}},
{{"G728", 4}, {"15", 2}}, {{"G729", 4}, {"18", 2}}, {{0, 0}, {0, 0}}};
codecsmap_t sdpops_codecsmap_table[] = {
{{"PCMU", 4}, {"0", 1}},
{{"GSM", 3}, {"3", 1}},
{{"G723", 4}, {"4", 1}},
{{"DVI4", 4}, {"5,6,16,17", 9}},
{{"LPC", 3}, {"7", 1}},
{{"PCMA", 4}, {"8", 1}},
{{"G722", 4}, {"9", 1}},
{{"L16", 3}, {"10,11", 5}},
{{"QCELP", 5}, {"12", 2}},
{{"CN", 2}, {"13", 5}},
{{"MPA", 3}, {"14", 2}},
{{"G728", 4}, {"15", 2}},
{{"G729", 4}, {"18", 2}},
{{0, 0}, {0, 0}}
};
/* clang-format on */
/**
* set the string with the IDs mapped to codec name

@ -218,11 +218,12 @@ Chapter 1. Admin Guide
Database URL.
Default value is "".
Default value is “mysql://kamailio:kamailiorw@localhost/kamailio”.
Example 1.1. Set db_url parameter
...
modparam("sipcapture", "db_url", "mysql://user:passwd@host/dbname")
modparam("sipcapture", "db_url", "mysql://kamailio:kamailiorw@localhost/kamailio
")
...
3.2. table_name (str)

@ -89,14 +89,14 @@
</para>
<para>
<emphasis>
Default value is "".
Default value is <quote>&defaultdb;</quote>.
</emphasis>
</para>
<example>
<title>Set <varname>db_url</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("sipcapture", "db_url", "mysql://user:passwd@host/dbname")
modparam("sipcapture", "db_url", "&defaultdb;")
...
</programlisting>
</example>

@ -264,6 +264,8 @@ int parsing_hepv3_message(char *buf, unsigned int len)
int totelem = 0;
int chunk_vendor = 0, chunk_type = 0, chunk_length = 0;
int total_length = 0;
static char ipbuf1[IP_ADDR_MAX_STR_SIZE];
static char portbuf1[INT2STR_MAX_LEN];
hg = (struct hep_generic_recv *)pkg_malloc(sizeof(struct hep_generic_recv));
@ -484,13 +486,14 @@ int parsing_hepv3_message(char *buf, unsigned int len)
si->flags = 0;
si->addr_info_lst = 0;
si->address_str.s = ip_addr2a(&si->address);
si->address_str.len =
ip_addr2sbuf(&si->address, ipbuf1, sizeof(ipbuf1) - 1);
ipbuf1[si->address_str.len] = 0;
si->address_str.s = ipbuf1;
si->address_str.len = strlen(si->address_str.s);
si->port_no_str.s = int2str(si->port_no, &tmp_len);
si->port_no_str.s =
int2strbuf(si->port_no, portbuf1, INT2STR_MAX_LEN, &tmp_len);
si->port_no_str.len = tmp_len;
si->address_str.len = strlen(si->address_str.s);
si->name.len = si->address_str.len;
si->name.s = si->address_str.s;

@ -780,7 +780,7 @@ int tel2sip2(struct sip_msg *_msg, char *_uri, char *_hostpart, char *_res)
return 1;
/* reserve memory for clean tel uri */
tel_uri.s = pkg_malloc(uri.len + 1);
tel_uri.s = pkg_mallocxz(uri.len + 1);
if(tel_uri.s == 0) {
LM_ERR("no more pkg memory\n");
return -1;
@ -839,7 +839,7 @@ int tel2sip2(struct sip_msg *_msg, char *_uri, char *_hostpart, char *_res)
/* 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);
sip_uri.s = pkg_mallocxz(sip_uri.len + 1);
if(sip_uri.s == 0) {
LM_ERR("no more pkg memory\n");
pkg_free(tel_uri.s);
@ -873,6 +873,8 @@ int tel2sip2(struct sip_msg *_msg, char *_uri, char *_hostpart, char *_res)
/* tel_uri is not needed anymore */
pkg_free(tel_uri.s);
sip_uri.len = strlen(sip_uri.s);
/* set result pv value and write sip uri to result pv */
res_val.rs = sip_uri;
res_val.flags = PV_VAL_STR;
@ -1163,6 +1165,7 @@ int get_uri_param(struct sip_msg *_msg, char *_param, char *_value)
pv_value_t val;
param_hooks_t hooks;
param_t *plist = NULL;
param_t *params;
param = (str *)_param;
@ -1175,11 +1178,12 @@ int get_uri_param(struct sip_msg *_msg, char *_param, char *_value)
t = _msg->parsed_uri.params;
if(parse_params(&t, CLASS_ANY, &hooks, &params) < 0) {
if(parse_params(&t, CLASS_ANY, &hooks, &plist) < 0) {
LM_ERR("ruri parameter parsing failed\n");
return -1;
}
params = plist;
while(params) {
if((params->name.len == param->len)
&& (strncmp(params->name.s, param->s, param->len) == 0)) {
@ -1194,11 +1198,11 @@ int get_uri_param(struct sip_msg *_msg, char *_param, char *_value)
}
}
free_params(params);
free_params(plist);
return -1;
found:
free_params(params);
free_params(plist);
return 1;
}

@ -50,6 +50,7 @@ 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 int convert_result(bool result);
static char *get_milliseconds(char *dst);
typedef struct StatsdParams
@ -115,7 +116,6 @@ static int mod_init(void)
rc = statsd_init(statsd_params.ip, statsd_params.port);
if(rc == false) {
LM_ERR("Statsd connection failed (ERROR_CODE: %i)\n", rc);
return -1;
} else {
LM_INFO("Statsd: success connection to statsd server\n");
}
@ -133,69 +133,69 @@ void mod_destroy(void)
static int func_gauge(struct sip_msg *msg, char *key, char *val)
{
return statsd_gauge(key, val, NULL);
return convert_result(statsd_gauge(key, val, NULL));
}
static int func_gauge_with_labels(
struct sip_msg *msg, char *key, char *val, char *labels)
{
return statsd_gauge(key, val, labels);
return convert_result(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, NULL);
return convert_result(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);
return convert_result(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);
return convert_result(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);
return convert_result(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, NULL);
return convert_result(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);
return convert_result(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, NULL);
return convert_result(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);
return convert_result(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, NULL);
return convert_result(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);
return convert_result(statsd_set(key->s, val->s, labels->s));
}
static int func_time_start(struct sip_msg *msg, char *key)
@ -278,42 +278,51 @@ static int ki_statsd_stop_with_labels(sip_msg_t *msg, str *key, str *labels)
static int func_incr(struct sip_msg *msg, char *key)
{
return statsd_count(key, "+1", NULL);
return convert_result(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);
return convert_result(statsd_count(key, "+1", labels));
}
static int ki_statsd_incr(sip_msg_t *msg, str *key)
{
return statsd_count(key->s, "+1", NULL);
return convert_result(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);
return convert_result(statsd_count(key->s, "+1", labels->s));
}
static int func_decr(struct sip_msg *msg, char *key)
{
return statsd_count(key, "-1", NULL);
return convert_result(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);
return convert_result(statsd_count(key, "-1", labels));
}
static int ki_statsd_decr(sip_msg_t *msg, str *key)
{
return statsd_count(key->s, "-1", NULL);
return convert_result(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);
return convert_result(statsd_count(key->s, "-1", labels->s));
}
static int convert_result(bool result)
{
if(result == false) {
return -1;
}
return 1;
}
char *get_milliseconds(char *dst)

@ -437,6 +437,14 @@ event_route[tcp:closed] {
Whether these routes are always called, never, or on a per socket basis
is controlled by the closed_event parameter.
Note that the event routes can be executed by TCP main process, which
manages the TCP connections but does not hande the SIP traffic over
them. It is very important not do do any time consuming operations
inside the event routes. Also, many resources might not be available in
the TCP main process (e.g., database connections), consider using async
module with async_task_data(...) or async_task_group_data() functions
for delegating task execution to async workers.
4.1. tcp:closed
Called for each "normal" TCP socket closure by the other side

@ -31,6 +31,16 @@
<emphasis>closed_event</emphasis>
parameter.
</para>
<para>
Note that the event routes can be executed by TCP main process,
which manages the TCP connections but does not hande the SIP traffic
over them. It is very important not do do any time consuming
operations inside the event routes. Also, many resources might not
be available in the TCP main process (e.g., database connections),
consider using async module with async_task_data(...) or
async_task_group_data() functions for delegating task execution
to async workers.
</para>
<section>
<title>
<function moreinfo="none">tcp:closed</function>

@ -249,6 +249,7 @@ static void tcpops_tcp_closed_run_route(tcp_closed_event_info_t *tev)
sr_kemi_eng_t *keng = NULL;
str *evname;
LM_DBG("event reason id: %d\n", tev->reason);
if(tcpops_event_callback.len > 0) {
rt = -1;
keng = sr_kemi_eng_get();
@ -258,9 +259,10 @@ static void tcpops_tcp_closed_run_route(tcp_closed_event_info_t *tev)
}
} else {
rt = tcp_closed_routes[tev->reason];
LM_DBG("event reason id: %d rt: %d\n", tev->reason, rt);
if(rt == -1)
if(rt == -1) {
LM_DBG("event reason id: %d - event route not set\n", tev->reason);
return;
}
}
if(faked_msg_init() < 0) {

@ -72,66 +72,71 @@ str tcpops_event_callback = STR_NULL;
static int pv_get_tcp(sip_msg_t *msg, pv_param_t *param, pv_value_t *res);
static int pv_parse_tcp_name(pv_spec_p sp, str *in);
/* clang-format off */
static pv_export_t mod_pvs[] = {
{{"tcp", (sizeof("tcp") - 1)}, PVT_CONTEXT, pv_get_tcp, 0,
pv_parse_tcp_name, 0, 0, 0},
{{"tcp", (sizeof("tcp") - 1)}, PVT_CONTEXT, pv_get_tcp, 0,
pv_parse_tcp_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[] = {
{"tcp_keepalive_enable", (cmd_function)w_tcp_keepalive_enable4, 4,
fixup_igp_all, fixup_free_igp_all, ANY_ROUTE},
{"tcp_keepalive_enable", (cmd_function)w_tcp_keepalive_enable3, 3,
fixup_igp_all, fixup_free_igp_all,
REQUEST_ROUTE | ONREPLY_ROUTE},
{"tcp_keepalive_disable", (cmd_function)w_tcp_keepalive_disable1, 1,
fixup_igp_all, fixup_free_igp_all, ANY_ROUTE},
{"tcp_keepalive_disable", (cmd_function)w_tcp_keepalive_disable0, 0, 0,
0, REQUEST_ROUTE | ONREPLY_ROUTE},
{"tcp_set_connection_lifetime",
(cmd_function)w_tcpops_set_connection_lifetime2, 2,
fixup_igp_all, fixup_free_igp_all, ANY_ROUTE},
{"tcp_set_connection_lifetime",
(cmd_function)w_tcpops_set_connection_lifetime1, 1,
fixup_igp_all, fixup_free_igp_all,
REQUEST_ROUTE | ONREPLY_ROUTE},
{"tcp_enable_closed_event", (cmd_function)w_tcpops_enable_closed_event1,
1, fixup_igp_all, fixup_free_igp_all, ANY_ROUTE},
{"tcp_enable_closed_event", (cmd_function)w_tcpops_enable_closed_event0,
0, 0, 0, REQUEST_ROUTE | ONREPLY_ROUTE},
{"tcp_conid_state", (cmd_function)w_tcp_conid_state, 1, fixup_igp_all,
fixup_free_igp_all, ANY_ROUTE},
{"tcp_get_conid", (cmd_function)w_tcp_get_conid, 2, fixup_spve_pvar,
fixup_free_spve_pvar, ANY_ROUTE},
{"tcp_conid_alive", (cmd_function)w_tcp_conid_alive, 1, fixup_igp_all,
fixup_free_igp_all, ANY_ROUTE},
{"tcp_set_otcpid", (cmd_function)w_tcp_set_otcpid, 1, fixup_igp_all,
fixup_free_igp_all, ANY_ROUTE},
{"tcp_set_otcpid_flag", (cmd_function)w_tcp_set_otcpid_flag, 1,
fixup_igp_all, fixup_free_igp_all, ANY_ROUTE},
{"tcp_close_connection", (cmd_function)w_tcp_close_connection, 0, 0, 0,
ANY_ROUTE},
{"tcp_close_connection", (cmd_function)w_tcp_close_connection_id, 1,
fixup_igp_all, fixup_free_igp_all, ANY_ROUTE},
{0, 0, 0, 0, 0, 0}};
{"tcp_keepalive_enable", (cmd_function)w_tcp_keepalive_enable4, 4,
fixup_igp_all, fixup_free_igp_all, ANY_ROUTE},
{"tcp_keepalive_enable", (cmd_function)w_tcp_keepalive_enable3, 3,
fixup_igp_all, fixup_free_igp_all,
REQUEST_ROUTE | ONREPLY_ROUTE},
{"tcp_keepalive_disable", (cmd_function)w_tcp_keepalive_disable1, 1,
fixup_igp_all, fixup_free_igp_all, ANY_ROUTE},
{"tcp_keepalive_disable", (cmd_function)w_tcp_keepalive_disable0, 0, 0,
0, REQUEST_ROUTE | ONREPLY_ROUTE},
{"tcp_set_connection_lifetime",
(cmd_function)w_tcpops_set_connection_lifetime2, 2,
fixup_igp_all, fixup_free_igp_all, ANY_ROUTE},
{"tcp_set_connection_lifetime",
(cmd_function)w_tcpops_set_connection_lifetime1, 1,
fixup_igp_all, fixup_free_igp_all, REQUEST_ROUTE | ONREPLY_ROUTE},
{"tcp_enable_closed_event", (cmd_function)w_tcpops_enable_closed_event1,
1, fixup_igp_all, fixup_free_igp_all, ANY_ROUTE},
{"tcp_enable_closed_event", (cmd_function)w_tcpops_enable_closed_event0,
0, 0, 0, REQUEST_ROUTE | ONREPLY_ROUTE},
{"tcp_conid_state", (cmd_function)w_tcp_conid_state, 1, fixup_igp_all,
fixup_free_igp_all, ANY_ROUTE},
{"tcp_get_conid", (cmd_function)w_tcp_get_conid, 2, fixup_spve_pvar,
fixup_free_spve_pvar, ANY_ROUTE},
{"tcp_conid_alive", (cmd_function)w_tcp_conid_alive, 1, fixup_igp_all,
fixup_free_igp_all, ANY_ROUTE},
{"tcp_set_otcpid", (cmd_function)w_tcp_set_otcpid, 1, fixup_igp_all,
fixup_free_igp_all, ANY_ROUTE},
{"tcp_set_otcpid_flag", (cmd_function)w_tcp_set_otcpid_flag, 1,
fixup_igp_all, fixup_free_igp_all, ANY_ROUTE},
{"tcp_close_connection", (cmd_function)w_tcp_close_connection, 0, 0, 0,
ANY_ROUTE},
{"tcp_close_connection", (cmd_function)w_tcp_close_connection_id, 1,
fixup_igp_all, fixup_free_igp_all, ANY_ROUTE},
{0, 0, 0, 0, 0, 0}
};
static param_export_t params[] = {
{"closed_event", PARAM_INT, &tcp_closed_event},
{"event_callback", PARAM_STR, &tcpops_event_callback}, {0, 0, 0}};
{"closed_event", PARAM_INT, &tcp_closed_event},
{"event_callback", PARAM_STR, &tcpops_event_callback},
{0, 0, 0}
};
struct module_exports exports = {
"tcpops", /* module name */
DEFAULT_DLFLAGS, /* dlopen flags */
cmds, /* exported functions to config */
params, /* exported parameters to config */
0, /* RPC method exports */
mod_pvs, /* exported pseudo-variables */
0, /* response function */
mod_init, /* module initialization function */
child_init, /* per child init function */
mod_destroy /* destroy function */
"tcpops", /* module name */
DEFAULT_DLFLAGS, /* dlopen flags */
cmds, /* exported functions to config */
params, /* exported parameters to config */
0, /* RPC method exports */
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 */
/**
@ -783,7 +788,7 @@ static int pv_get_tcp(sip_msg_t *msg, pv_param_t *param, pv_value_t *res)
ival = con->cinfo.src_port;
tcpconn_put(con);
return pv_get_sintval(msg, param, res, ival);
case 3: /* ac_si */
case 3: /* ac_si */
if(con == NULL) {
return pv_get_null(msg, param, res);
}
@ -791,14 +796,14 @@ static int pv_get_tcp(sip_msg_t *msg, pv_param_t *param, pv_value_t *res)
tcpconn_put(con);
sval.len = strlen(sval.s);
return pv_get_strval(msg, param, res, &sval);
case 4: /* ac_sp */
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 */
case 5: /* aconid */
if(con == NULL) {
return pv_get_null(msg, param, res);
}

@ -343,10 +343,11 @@ static tls_domains_cfg_t* tls_use_modparams(void)
* is < 10
*
*/
static int tls_pthreads_key_mark;
static void fork_child(void)
{
int k = 0;
for(k = 0; k < 16; k++) {
int k;
for(k = 0; k < tls_pthreads_key_mark; k++) {
if(pthread_getspecific(k) != 0)
pthread_setspecific(k, 0x0);
}
@ -356,6 +357,8 @@ static int mod_init(void)
{
int method;
int verify_client;
unsigned char rand_buf[32];
int k;
if(tls_disable) {
LM_WARN("tls support is disabled "
@ -464,6 +467,23 @@ static int mod_init(void)
if(ksr_tls_threads_mode == 2) {
pthread_atfork(NULL, NULL, &fork_child);
}
#if OPENSSL_VERSION_NUMBER >= 0x010101000L
/*
* force creation of all thread-locals now so that other libraries
* that use pthread_key_create(), e.g. python,
* will have larger key values
*/
if(ksr_tls_threads_mode > 0) {
ERR_clear_error();
RAND_bytes(rand_buf, sizeof(rand_buf));
for(k = 0; k < 32; k++) {
if(pthread_getspecific(k))
tls_pthreads_key_mark = k + 1;
}
LM_WARN("set maximum pthreads key to %d\n", tls_pthreads_key_mark);
}
#endif
return 0;
error:
tls_h_mod_destroy_f();
@ -500,6 +520,7 @@ static int mod_child_hook(int *rank, void *dummy)
if(tls_fix_domains_cfg(*tls_domains_cfg, &mod_params, &mod_params) < 0)
return -1;
}
return 0;
}
@ -509,17 +530,26 @@ static OSSL_LIB_CTX *new_ctx;
#endif
static int mod_child(int rank)
{
int k;
if(tls_disable || (tls_domains_cfg == 0))
return 0;
/*
* 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
*/
* 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_INIT) {
return run_thread4PP((_thread_proto4PP)mod_child_hook, &rank, NULL);
}
if(ksr_tls_threads_mode == 1 && rank && rank != PROC_INIT
&& rank != PROC_POSTCHILDINIT) {
for(k = 0; k < tls_pthreads_key_mark; k++)
pthread_setspecific(k, 0x0);
LM_WARN("clean-up of thread-locals key < %d\n", tls_pthreads_key_mark);
}
#ifdef KSR_SSL_COMMON
/*
* after the child is fork()ed we go through the TLS domains

@ -21,10 +21,10 @@
#define _TLS_RAND_H_
#include <openssl/ssl.h>
#include <openssl/rand.h>
#if OPENSSL_VERSION_NUMBER >= 0x10100000L \
&& OPENSSL_VERSION_NUMBER < 0x030000000L
#include <openssl/rand.h>
const RAND_METHOD *RAND_ksr_krand_method(void);
const RAND_METHOD *RAND_ksr_fastrand_method(void);

@ -59,7 +59,8 @@ struct cell;
#define TMCB_RESPONSE_SENT_N 23
#define TMCB_ON_BRANCH_FAILURE_RO_N 24
#define TMCB_ON_BRANCH_FAILURE_N 25
#define TMCB_MAX_N 25
#define TMCB_LOCAL_REQUEST_DROP_N 26
#define TMCB_MAX_N 26
#define TMCB_REQUEST_IN (1 << TMCB_REQUEST_IN_N)
@ -88,6 +89,7 @@ struct cell;
#define TMCB_RESPONSE_SENT (1 << TMCB_RESPONSE_SENT_N)
#define TMCB_ON_BRANCH_FAILURE (1 << TMCB_ON_BRANCH_FAILURE_N)
#define TMCB_ON_BRANCH_FAILURE_RO (1 << TMCB_ON_BRANCH_FAILURE_RO_N)
#define TMCB_LOCAL_REQUEST_DROP (1 << TMCB_LOCAL_REQUEST_DROP_N)
#define TMCB_MAX ((1 << (TMCB_MAX_N + 1)) - 1)

@ -1246,7 +1246,8 @@ char *build_dlg_ack(struct sip_msg *rpl, struct cell *Trans,
/* headers */
*len += Trans->from_hdr.len + Trans->callid_hdr.len + to->len
+ Trans->cseq_hdr_n.len + 1 + ACK_LEN + CRLF_LEN;
+ Trans->cseq_hdr_n.len + 1 + ACK_LEN + +MAXFWD_HEADER_LEN
+ CRLF_LEN;
/* copy'n'paste Route headers */
@ -1291,6 +1292,8 @@ char *build_dlg_ack(struct sip_msg *rpl, struct cell *Trans,
append_str(p, Trans->callid_hdr.s, Trans->callid_hdr.len);
append_str(p, to->s, to->len);
append_str(p, MAXFWD_HEADER, MAXFWD_HEADER_LEN);
append_str(p, Trans->cseq_hdr_n.s, Trans->cseq_hdr_n.len);
append_str(p, " ", 1);
append_str(p, ACK, ACK_LEN);

@ -559,6 +559,7 @@ static inline int t_uac_prepare(
refresh_shortcuts =
t_run_local_req(&buf, &buf_len, uac_r, new_cell, request);
if(unlikely(refresh_shortcuts == E_DROP)) {
shm_free(buf);
ret = E_DROP;
goto error1;
}
@ -679,6 +680,7 @@ send:
ret = t_uac_prepare(uac_r, dst_req, 0);
if(unlikely(ret < 0 && ret == E_DROP)) {
uac_r->cb_flags |= TMCB_LOCAL_REQUEST_DROP;
ret = 0;
}
@ -774,6 +776,7 @@ int t_uac_with_ids(
if(ret < 0) {
if(unlikely(ret == E_DROP)) {
uac_r->cb_flags |= TMCB_LOCAL_REQUEST_DROP;
ret = 0;
}
return ret;

@ -47,7 +47,7 @@ typedef struct uac_req
str *ssock;
str *ssockname;
dlg_t *dialog;
int cb_flags;
unsigned int cb_flags;
transaction_cb *cb;
void *cbp;
str *callid;

@ -974,6 +974,10 @@ void uac_reg_tm_callback(struct cell *t, int type, struct tmcb_params *ps)
ri->l_uuid.len, ri->l_uuid.s);
goto error;
}
if(uac_r.cb_flags & TMCB_LOCAL_REQUEST_DROP) {
shm_free(uuid);
*ps->param = NULL;
}
ri->flags |= UAC_REG_AUTHSENT;
lock_release(ri->lock);
@ -1130,6 +1134,9 @@ int uac_reg_send(reg_uac_t *reg, time_t tn)
reg->flags &= ~UAC_REG_ONGOING;
return -1;
}
if(uac_r.cb_flags & TMCB_LOCAL_REQUEST_DROP) {
shm_free(uuid);
}
return 0;
}

@ -794,6 +794,11 @@ void uac_send_tm_callback(struct cell *t, int type, struct tmcb_params *ps)
LM_ERR("failed to send request with authentication\n");
goto error;
}
if(uac_r.cb_flags & TMCB_LOCAL_REQUEST_DROP) {
shm_free(tp);
*ps->param = NULL;
tp = NULL;
}
if(tp->evroute != 0) {
return;
@ -871,6 +876,10 @@ int uac_req_send(void)
shm_free(tp);
return -1;
}
if(uac_r.cb_flags & TMCB_LOCAL_REQUEST_DROP) {
if(tp != NULL)
shm_free(tp);
}
return 1;
}

@ -66,7 +66,7 @@
the <serdoc:module>textops</serdoc:module> module.
</para>
<para>
The reason for the failure can be determined from the interger
The reason for the failure can be determined from the integer
return value stored in the <varname>$?</varname> attribute.
A value of <literal>-3</literal> indicates that it was impossible
to retrieve credentials from the request. A 400 (Bad Request)

@ -1784,9 +1784,11 @@ int uldb_delete_attrs(str *_dname, str *_user, str *_domain, str *_ruid)
str tname;
db_key_t keys[3];
db_val_t vals[3];
int n = 0;
if(ul_db_ops_ruid == 1)
if(ul_db_ops_ruid == 1 && _ruid) {
return uldb_delete_attrs_ruid(_dname, _ruid);
}
LM_DBG("trying to delete location attributes\n");
@ -1805,22 +1807,26 @@ int uldb_delete_attrs(str *_dname, str *_user, str *_domain, str *_ruid)
tname.s = tname_buf;
tname.len = _dname->len + 6;
keys[0] = &ulattrs_user_col;
keys[1] = &ulattrs_ruid_col;
keys[2] = &ulattrs_domain_col;
vals[0].type = DB1_STR;
vals[0].nul = 0;
vals[0].val.str_val = *_user;
keys[n] = &ulattrs_user_col;
vals[n].type = DB1_STR;
vals[n].nul = 0;
vals[n].val.str_val = *_user;
n++;
vals[1].type = DB1_STR;
vals[1].nul = 0;
vals[1].val.str_val = *_ruid;
if(_ruid) {
keys[n] = &ulattrs_ruid_col;
vals[n].type = DB1_STR;
vals[n].nul = 0;
vals[n].val.str_val = *_ruid;
n++;
}
if(ul_use_domain) {
vals[2].type = DB1_STR;
vals[2].nul = 0;
vals[2].val.str_val = *_domain;
keys[n] = &ulattrs_domain_col;
vals[n].type = DB1_STR;
vals[n].nul = 0;
vals[n].val.str_val = *_domain;
n++;
}
if(ul_dbf.use_table(ul_dbh, &tname) < 0) {
@ -1828,7 +1834,7 @@ int uldb_delete_attrs(str *_dname, str *_user, str *_domain, str *_ruid)
return -1;
}
if(ul_dbf.delete(ul_dbh, keys, 0, vals, (ul_use_domain) ? (3) : (2)) < 0) {
if(ul_dbf.delete(ul_dbh, keys, 0, vals, n) < 0) {
LM_ERR("deleting from database failed\n");
return -1;
}

@ -491,13 +491,21 @@ int db_delete_urecord(urecord_t *_r)
vals[0].val.str_val.len = _r->aor.len;
if(ul_use_domain) {
dom = memchr(_r->aor.s, '@', _r->aor.len);
vals[0].val.str_val.len = dom - _r->aor.s;
vals[1].type = DB1_STR;
vals[1].nul = 0;
vals[1].val.str_val.s = dom + 1;
vals[1].val.str_val.len = _r->aor.s + _r->aor.len - dom - 1;
dom = memchr(_r->aor.s, '@', _r->aor.len);
if(dom == 0) {
vals[0].val.str_val.len = 0;
vals[1].val.str_val = _r->aor;
} else {
vals[0].val.str_val.len = dom - _r->aor.s;
vals[1].val.str_val.s = dom + 1;
vals[1].val.str_val.len = _r->aor.s + _r->aor.len - dom - 1;
}
uldb_delete_attrs(
_r->domain, &vals[0].val.str_val, &vals[1].val.str_val, NULL);
} else {
uldb_delete_attrs(_r->domain, &vals[0].val.str_val, NULL, NULL);
}
if(ul_dbf.use_table(ul_dbh, _r->domain) < 0) {

@ -36,7 +36,7 @@
-1000..-1 used in dtm to indicate a carrier id and that no more nodes will follow (leaf node compression).
-1001 used in dtm to mark a pointer to a child node as NULL.
*/
#define MIN_PDB_CARRIERID 1
#define MIN_PDB_CARRIERID 0
#define MAX_PDB_CARRIERID 999
#define OTHER_CARRIERID 1000
#define MAX_CARRIERID 1000

Loading…
Cancel
Save