kuzaxak created an issue (kamailio/kamailio#4807)
### Description
Concurrent dispatcher reloads can corrupt shared memory when multiple worker
processes rebuild the dispatcher destination table.
The dispatcher module keeps two destination-set slots in shared memory
(`ds_lists[0]` and `ds_lists[1]`) and publishes the active slot through
`ds_crt_idx`/`ds_next_idx`. In `ds_load_list()` and `ds_load_db()`
(`src/modules/dispatcher/dispatch.c`), the reload path checks that no reload is
in progress, selects the inactive slot, destroys that slot, repopulates it, and
then publishes it (condensed):
```c
if((*ds_crt_idx) != (*ds_next_idx)) {
LM_WARN("load command already generated, aborting reload...\n");
return 0;
}
/* ... open the list file / query the database ... */
*ds_next_idx = (*ds_crt_idx + 1) % 2;
ds_avl_destroy(&ds_lists[*ds_next_idx]);
/* add_dest2list(), reindex_dests(), etc. */
*ds_crt_idx = *ds_next_idx;
```
That check is not atomic with the later `*ds_next_idx` write. With multiple
workers, two workers can both observe `*ds_crt_idx == *ds_next_idx`, both select
the same inactive slot, and both destroy/rebuild the same shared-memory AVL
tree. Depending on timing, q_malloc reports either explicit double-free lines or
allocator fragment corruption followed by a worker crash.
The same unprotected rebuild pattern is also present in `ds_add_dst()` and
`ds_remove_dst()`, which select and destroy the inactive slot without the
`ds_crt_idx == ds_next_idx` guard.
Expected behavior: concurrent reload/add/remove requests should not corrupt
shared memory. At most one dispatcher table rebuild should be active at a time,
or later callers should return without touching the inactive slot.
The same unguarded sequence is present on both branches checked:
- `master`: `b3a8384d9d10343317b3df83c595f5cfe570d14a`
- `6.0`: `5709418e6a47768e4f729e44530722bc42fedf1c`
### Troubleshooting
#### Reproduction
A self-contained reproducer archive is attached to this issue:
`kamailio-dispatcher-reload-race-repro-with-pcap.zip`.
It contains the runnable repro harness and captured evidence.
[kamailio-dispatcher-reload-race-repro-with-pcap.zip](https://github.com/user-attachments/files/29594512/kamailio-dispatcher-reload-race-repro-with-pcap.zip)
To reproduce from the attached archive:
```sh
unzip kamailio-dispatcher-reload-race-repro-with-pcap.zip -d
kamailio-dispatcher-reload-race-repro
cd kamailio-dispatcher-reload-race-repro
./run.sh --duration 25 --senders 32
```
The repro:
- builds unpatched `master` from `b3a8384d9d10343317b3df83c595f5cfe570d14a`
- uses a file-based dispatcher list with 4000 destinations (widens the
destroy/rebuild window)
- uses `children=16` (more workers reloading concurrently)
- sets `modparam("dispatcher", "reload_delta", 0)` (see note below)
- starts Kamailio with `-x q_malloc` (debug allocator that detects double-free
and overwritten fragments)
- calls `ds_reload()` from `request_route` on every received OPTIONS request
- sends OPTIONS from 32 parallel UDP senders for 25 seconds
This setup only makes the race window easy to hit within seconds; it does not
create the race. In particular, `reload_delta` does not close the window: the
gate in `ds_reload()` (the `LM_ERR("ongoing reload")` check on
`*ds_rpc_reload_time` in dispatcher.c) is itself a non-atomic check-then-set on
shared memory, so with the default `reload_delta` of 5 seconds two workers can
still pass it simultaneously — just as they can simultaneously pass the
`ds_crt_idx == ds_next_idx` guard shown above.
Observed on unpatched `master`:
```text
kam container state : kam exited 139
double-free lines : 0 (q_malloc 'freeing already freed pointer')
shm corruption BUG lines : 2 (q_malloc 'fragm ... overwritten')
worker signal/core lines : 2
reload-guard aborts : 16 (WARN 'load command already generated')
flooder rc : 0
```
(`exited 139` is 128+11, i.e. SIGSEGV; `flooder rc` is the exit code of the
traffic generator.)
A separate run from the same harness hit the explicit q_malloc double-free
detector:
```text
double-free lines : 4
shm corruption BUG lines : 1
worker signal/core lines : 2
reload-guard aborts : 3876
```
The existing `ds_crt_idx == ds_next_idx` guard does fire (16 and 3876
`reload-guard aborts` above), but it cannot prevent the corruption because the
check and the later index write are not atomic.
#### Debugging Data
The core below is from the main process: after child process 8 exited with
SIGSEGV (see Log Messages), the main process crashed during shutdown cleanup
while destroying the already-corrupted dispatcher table. Output of `bt full`
and `thread apply all bt` from `logs/coredump-bt-unpatched.txt`:
```text
warning: Can't open file /dev/zero (deleted) during file-backed mapping note
processing
[New LWP 1]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".
Core was generated by `/usr/local/sbin/kamailio -DD -E -x q_malloc -m 128 -M 16
-w /cores -f /etc/kamailio/kam.cfg'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x0000aaaae11bb3b0 in qm_status (qmp=0xffffb48c0000) at
core/mem/q_malloc.c:992
warning: 992 core/mem/q_malloc.c: No such file or directory
#0 0x0000aaaae11bb3b0 in qm_status (qmp=0xffffb48c0000) at
core/mem/q_malloc.c:992
qm = 0xffffb48c0000
f = 0x8
i = 4170
j = 1
h = 2060
unused = 0
memlog = 4
mem_summary = 12
__func__ = "qm_status"
__llevel = <optimized out>
__kld = <optimized out>
#1 0x0000aaaae11adf20 in qm_debug_check_frag (qm=0xffffb48c0000,
f=0xffffb67152a0, file=0xffffbc939618 "dispatcher: dispatch.c", line=5141,
efile=0xaaaae1401fb0 "core/mem/q_malloc.c", eline=569) at
core/mem/q_malloc.c:146
p = 0xbb5f1b6a0
__func__ = "qm_debug_check_frag"
#2 0x0000aaaae11b26fc in qm_free (qmp=0xffffb48c0000, p=0xffffb67152e0,
file=0xffffbc939618 "dispatcher: dispatch.c", func=0xffffbc943668 <__func__.1>
"ds_avl_destroy", line=5141, mname=0xffffbc939608 "dispatcher") at
core/mem/q_malloc.c:569
qm = 0xffffb48c0000
f = 0xffffb67152a0
size = 176
next = 0xffffbdc31430 <_IO_2_1_stderr_>
prev = 0xaaaae11c024c <qm_shm_free+92>
__func__ = "qm_free"
#3 0x0000aaaae11c023c in qm_shm_free (qmp=0xffffb48c0000, p=0xffffb67152e0,
file=0xffffbc939618 "dispatcher: dispatch.c", func=0xffffbc943668 <__func__.1>
"ds_avl_destroy", line=5141, mname=0xffffbc939608 "dispatcher") at
core/mem/q_malloc.c:1602
No locals.
#4 0x0000ffffbc9178a0 in ds_avl_destroy (node_ptr=0xffffb5a19518) at
dispatch.c:5141
node = 0xffffb5f09410
dest = 0x0
i = 2
__func__ = "ds_avl_destroy"
#5 0x0000ffffbc917754 in ds_avl_destroy (node_ptr=0xffffb49b1db8) at
dispatch.c:5128
node = 0xffffb5a19040
dest = 0x0
i = 1
__func__ = "ds_avl_destroy"
#6 0x0000ffffbc917754 in ds_avl_destroy (node_ptr=0xffffb495eda0) at
dispatch.c:5128
node = 0xffffb49b18e0
dest = 0x0
i = 1
__func__ = "ds_avl_destroy"
#7 0x0000ffffbc8ddb18 in ds_destroy_list () at dispatch.c:1731
__func__ = "ds_destroy_list"
#8 0x0000ffffbc921184 in destroy () at dispatcher.c:589
__func__ = "destroy"
#9 0x0000aaaae108be20 in destroy_modules () at core/sr_module.c:895
t = 0xffffbcb869e0
foo = 0xffffbcb862a0
__func__ = "destroy_modules"
#10 0x0000aaaae0db1d2c in cleanup (show_status=1) at main.c:606
memlog = 1747626
__func__ = "cleanup"
#11 0x0000aaaae0db3e74 in shutdown_children (sig=15, show_status=1) at
main.c:754
__func__ = "shutdown_children"
#12 0x0000aaaae0db7a38 in handle_sigs () at main.c:854
chld = 0
chld_status = 139
any_chld_stopped = 1
memlog = 65535
__func__ = "handle_sigs"
#13 0x0000aaaae0dc8370 in main_loop () at main.c:2094
i = 16
pid = 27
si = 0x0
sx = 0xaaaae0dd4290 <main+47504>
si_desc = "udp receiver child=15
sock=0.0.0.0:5060\000`\3409\341\252\252\000\000(\2518\341\252\252\000\000\340
4\327\377\377\000\000\340 4\327\377\377\000\000\260
4\327\377\377\000\000\320\377\377\377\200\377\377\377\340[\270\274\377\377\000\000\340
4\327\377\377\000\000\340 4\327\377\377\000\000\260
4\327\377\377\000\000\320\377\377\377\200\377\377\377"
nrprocs = 16
woneinit = 1
agfound = 1
__func__ = "main_loop"
#14 0x0000aaaae0dd42d8 in main (argc=13, argv=0xffffd7342508) at main.c:3439
cfg_stream = 0xaaab1d895380
c = -1
r = 0
tmp = 0xffffd7342f52 ""
tmp_len = 0
port = 5060
proto = 0
aproto = 0
ahost = 0x0
socket_name = 0x0
aport = 0
listen_field_count = 0
listen_fields = {0xffffbdd1a740 "\300\256\321\275\377\377",
0xffffbdd25000 <_rtld_global> "@f\322\275\377\377", 0xaaaae149f500
"\314\374\332\340\252\252"}
options = 0xaaaae1387fe0
":f:cm:M:dVIhEeb:B:l:L:n:vKrRDTN:W:w:t:u:g:P:G:SQ:O:a:A:x:X:Y:"
ret = -1
debug_save = 0
debug_flag = 0
dont_fork_cnt = 2
n_lst = 0xaaaae0daec00
p = 0xffffbdd1a740 "\300\256\321\275\377\377"
tbuf = 0xaaaae0dae558 "\020\004r"
tbuf_tmp = 0x0
st = {st_dev = 0, st_ino = 0, st_mode = 0, st_nlink = 0, st_uid = 0,
st_gid = 0, st_rdev = 0, __pad1 = 0, st_size = 0, st_blksize = 0, __pad2 = 0,
st_blocks = 0, st_atim = {tv_sec = 0, tv_nsec = 0}, st_mtim = {tv_sec = 0,
tv_nsec = 0}, st_ctim = {tv_sec = 0, tv_nsec = 0}, __glibc_reserved = {0, 0}}
l1 = 128
lim = {rlim_cur = 1048576, rlim_max = 1048576}
option_index = 0
long_options = {{name = 0xaaaae138a930 "help", has_arg = 0, flag = 0x0,
val = 104}, {name = 0xaaaae1385218 "version", has_arg = 0, flag = 0x0, val =
118}, {name = 0xaaaae138a938 "alias", has_arg = 1, flag = 0x0, val = 1024},
{name = 0xaaaae138a940 "domain", has_arg = 1, flag = 0x0, val = 1024}, {name =
0xaaaae138a948 "subst", has_arg = 1, flag = 0x0, val = 1025}, {name =
0xaaaae138a950 "substdef", has_arg = 1, flag = 0x0, val = 1026}, {name =
0xaaaae138a960 "substdefs", has_arg = 1, flag = 0x0, val = 1027}, {name =
0xaaaae138a970 "server-id", has_arg = 1, flag = 0x0, val = 1028}, {name =
0xaaaae138a980 "loadmodule", has_arg = 1, flag = 0x0, val = 1029}, {name =
0xaaaae138a990 "modparam", has_arg = 1, flag = 0x0, val = 1030}, {name =
0xaaaae138a9a0 "log-engine", has_arg = 1, flag = 0x0, val = 1031}, {name =
0xaaaae138a9b0 "debug", has_arg = 1, flag = 0x0, val = 1032}, {name =
0xaaaae138a9b8 "cfg-print", has_arg = 0, flag = 0x0, val = 1033}, {name =
0xaaaae138a9c8 "atexit", has_arg = 1, flag = 0x0, val = 1034}, {name =
0xaaaae138a9d0 "all-errors", has_arg = 0, flag = 0x0, val = 1035}, {name =
0xaaaae138a9e0 "iuid", has_arg = 1, flag = 0x0, val = 1036}, {name = 0x0,
has_arg = 0, flag = 0x0, val = 0}}
__func__ = "main"
==== all threads ====
Thread 1 (Thread 0xffffbdd1a020 (LWP 1)):
#0 0x0000aaaae11bb3b0 in qm_status (qmp=0xffffb48c0000) at
core/mem/q_malloc.c:992
#1 0x0000aaaae11adf20 in qm_debug_check_frag (qm=0xffffb48c0000,
f=0xffffb67152a0, file=0xffffbc939618 "dispatcher: dispatch.c", line=5141,
efile=0xaaaae1401fb0 "core/mem/q_malloc.c", eline=569) at
core/mem/q_malloc.c:146
#2 0x0000aaaae11b26fc in qm_free (qmp=0xffffb48c0000, p=0xffffb67152e0,
file=0xffffbc939618 "dispatcher: dispatch.c", func=0xffffbc943668 <__func__.1>
"ds_avl_destroy", line=5141, mname=0xffffbc939608 "dispatcher") at
core/mem/q_malloc.c:569
#3 0x0000aaaae11c023c in qm_shm_free (qmp=0xffffb48c0000, p=0xffffb67152e0,
file=0xffffbc939618 "dispatcher: dispatch.c", func=0xffffbc943668 <__func__.1>
"ds_avl_destroy", line=5141, mname=0xffffbc939608 "dispatcher") at
core/mem/q_malloc.c:1602
#4 0x0000ffffbc9178a0 in ds_avl_destroy (node_ptr=0xffffb5a19518) at
dispatch.c:5141
#5 0x0000ffffbc917754 in ds_avl_destroy (node_ptr=0xffffb49b1db8) at
dispatch.c:5128
#6 0x0000ffffbc917754 in ds_avl_destroy (node_ptr=0xffffb495eda0) at
dispatch.c:5128
#7 0x0000ffffbc8ddb18 in ds_destroy_list () at dispatch.c:1731
#8 0x0000ffffbc921184 in destroy () at dispatcher.c:589
#9 0x0000aaaae108be20 in destroy_modules () at core/sr_module.c:895
#10 0x0000aaaae0db1d2c in cleanup (show_status=1) at main.c:606
#11 0x0000aaaae0db3e74 in shutdown_children (sig=15, show_status=1) at
main.c:754
#12 0x0000aaaae0db7a38 in handle_sigs () at main.c:854
#13 0x0000aaaae0dc8370 in main_loop () at main.c:2094
#14 0x0000aaaae0dd42d8 in main (argc=13, argv=0xffffd7342508) at main.c:3439
```
#### Log Messages
Allocator corruption and crash from `logs/kam-unpatched.log`:
```text
CRITICAL: <core> [core/mem/q_malloc.c:130]: qm_debug_check_frag(): BUG: qm:
fragm. 0xffffb68bc530 (address 0xffffb68bc570) beginning overwritten (0)!
Memory allocator was called from dispatcher: dispatch.c:1201. Fragment marked
by (null):0. Exec from core/mem/q_malloc.c:439.
ALERT: <core> [main.c:824]: handle_sigs(): child process 8 exited by a signal 11
ALERT: <core> [main.c:828]: handle_sigs(): core was generated
CRITICAL: <core> [core/mem/q_malloc.c:140]: qm_debug_check_frag(): BUG: qm:
fragm. 0xffffb67152a0 (address 0xffffb67152e0) end overwritten (0, 20)! Memory
allocator was called from dispatcher: dispatch.c:5141. Fragment marked by
dispatcher: dispatch.c:1201. Exec from core/mem/q_malloc.c:569.
```
Explicit double-free form from another run of the same harness
(`logs/kam-unpatched-doublefree.log`):
```text
CRITICAL: <core> [core/mem/q_malloc.c:578]: qm_free(): BUG: freeing already
freed pointer (0xffff99c9e870), called from dispatcher: dispatch.c:
ds_avl_destroy(5136), first free dispatcher: dispatch.c: ds_set_attrs(383) -
ignoring
CRITICAL: <core> [core/mem/q_malloc.c:578]: qm_free(): BUG: freeing already
freed pointer (0xffff99c9bda0), called from dispatcher: dispatch.c:
ds_avl_destroy(5132), first free dispatcher: dispatch.c: pack_dest(647) -
ignoring
CRITICAL: <core> [core/mem/q_malloc.c:578]: qm_free(): BUG: freeing already
freed pointer (0xffff99c99360), called from dispatcher: dispatch.c:
ds_avl_destroy(5132), first free dispatcher: dispatch.c: ds_avl_destroy(5132) -
ignoring
CRITICAL: <core> [core/mem/q_malloc.c:152]: qm_debug_check_frag(): BUG: qm:
prev. fragm. tail overwritten(736e6172743b3036,
7064753d74726f70)[0xffff99c9bd60:0xffff99c9bda0]! Memory allocator was called
from dispatcher: dispatch.c:5132. Fragment marked by dispatcher:
dispatch.c:647. Exec from core/mem/q_malloc.c:569.
ALERT: <core> [main.c:824]: handle_sigs(): child process 16 exited by a signal 6
ALERT: <core> [main.c:828]: handle_sigs(): core was generated
```
#### SIP Traffic
The message content is not significant here — the flood consists of identical
plain OPTIONS requests and only the request rate matters. Captured traffic and
the generator script are in the attached repro archive:
```text
pcap/sip-unpatched.pcap (full capture, unpatched run)
pcap/sip-unpatched-sample.pcap (small sample capture, unpatched run)
pcap/sip-patched.pcap (full capture, patched run)
stress/flood.py (traffic generator)
```
### Possible Solutions
Serialize the full dispatcher rebuild critical section with a shared dispatcher
lock. The lock should cover check/select/destroy/populate/publish in:
- `ds_load_list()`
- `ds_load_db()`
- `ds_add_dst()`
- `ds_remove_dst()`
I tested this with a dispatcher-global `gen_lock_t *ds_reload_lock`, allocated
in shared memory and released on every success/error return from those paths.
The patch does not lock the request-routing hot path; normal dispatch selection
continues to read the active slot as before. The tested patch is included in
the attached archive as `build/dispatcher-reload-lock.patch`. I can submit it
as a pull request if the approach is acceptable.
```diff
--- a/src/modules/dispatcher/dispatch.c
+++ b/src/modules/dispatcher/dispatch.c
@@ -134,6 +134,7 @@ static ds_set_t **ds_lists = NULL;
static int *ds_list_nr = NULL;
static int *ds_crt_idx = NULL;
static int *ds_next_idx = NULL;
+static gen_lock_t *ds_reload_lock = NULL;
static ds_set_t *ds_strictest_node = NULL;
static int ds_strictest_idx = 0;
@@ -315,6 +316,21 @@ int ds_init_data(void)
ds_list_nr = p + 2;
*ds_crt_idx = *ds_next_idx = 0;
+ ds_reload_lock = lock_alloc();
+ if(!ds_reload_lock) {
+ shm_free(p);
+ shm_free(ds_lists);
+ SHM_MEM_ERROR;
+ return -1;
+ }
+ if(lock_init(ds_reload_lock) == 0) {
+ lock_dealloc(ds_reload_lock);
+ shm_free(p);
+ shm_free(ds_lists);
+ LM_ERR("could not initialize reload lock\n");
+ return -1;
+ }
+
return 0;
}
@@ -1016,19 +1032,23 @@ int ds_load_list(char *lfile)
str attrs;
ds_latency_stats_t *latency_stats;
+ lock_get(ds_reload_lock);
if((*ds_crt_idx) != (*ds_next_idx)) {
LM_WARN("load command already generated, aborting reload...\n");
+ lock_release(ds_reload_lock);
return 0;
}
if(lfile == NULL || strlen(lfile) <= 0) {
LM_ERR("bad list file\n");
+ lock_release(ds_reload_lock);
return -1;
}
f = fopen(lfile, "r");
if(f == NULL) {
LM_ERR("can't open list file [%s]\n", lfile);
+ lock_release(ds_reload_lock);
return -1;
}
@@ -1137,6 +1157,7 @@ int ds_load_list(char *lfile)
/* Update list - should it be sync'ed? */
_ds_list_nr = setn;
*ds_crt_idx = *ds_next_idx;
+ lock_release(ds_reload_lock);
LM_DBG("found [%d] dest sets\n", _ds_list_nr);
@@ -1148,6 +1169,7 @@ error:
fclose(f);
ds_avl_destroy(&ds_lists[*ds_next_idx]);
*ds_next_idx = *ds_crt_idx;
+ lock_release(ds_reload_lock);
return -1;
}
@@ -1286,18 +1308,22 @@ int ds_load_db(void)
}
}
+ lock_get(ds_reload_lock);
if((*ds_crt_idx) != (*ds_next_idx)) {
LM_WARN("load command already generated, aborting reload...\n");
+ lock_release(ds_reload_lock);
return 0;
}
if(ds_db_handle == NULL) {
LM_ERR("invalid DB handler\n");
+ lock_release(ds_reload_lock);
return -1;
}
if(ds_dbf.use_table(ds_db_handle, &ds_table_name) < 0) {
LM_ERR("error in use_table\n");
+ lock_release(ds_reload_lock);
return -1;
}
@@ -1307,6 +1333,7 @@ int ds_load_db(void)
if(ds_dbf.query(ds_db_handle, 0, 0, 0, query_cols, 0, nrcols, 0, &res)
< 0) {
LM_ERR("error while querying database\n");
+ lock_release(ds_reload_lock);
return -1;
}
@@ -1395,6 +1422,7 @@ int ds_load_db(void)
/* update data - should it be sync'ed? */
_ds_list_nr = setn;
*ds_crt_idx = *ds_next_idx;
+ lock_release(ds_reload_lock);
LM_DBG("found [%d] dest sets\n", _ds_list_nr);
@@ -1408,6 +1436,7 @@ err2:
ds_avl_destroy(&ds_lists[*ds_next_idx]);
ds_dbf.free_result(ds_db_handle, res);
*ds_next_idx = *ds_crt_idx;
+ lock_release(ds_reload_lock);
return -1;
}
@@ -1424,6 +1453,12 @@ int ds_destroy_list(void)
if(ds_crt_idx)
shm_free(ds_crt_idx);
+ if(ds_reload_lock) {
+ lock_destroy(ds_reload_lock);
+ lock_dealloc(ds_reload_lock);
+ ds_reload_lock = NULL;
+ }
+
return 0;
}
@@ -2890,6 +2925,7 @@ int ds_add_dst(int group, str *address, int flags, int
priority, str *attrs)
setn = _ds_list_nr;
+ lock_get(ds_reload_lock);
*ds_next_idx = (*ds_crt_idx + 1) % 2;
ds_avl_destroy(&ds_lists[*ds_next_idx]);
@@ -2914,6 +2950,7 @@ int ds_add_dst(int group, str *address, int flags, int
priority, str *attrs)
_ds_list_nr = setn;
*ds_crt_idx = *ds_next_idx;
+ lock_release(ds_reload_lock);
ds_log_sets();
return 0;
@@ -2921,6 +2958,7 @@ int ds_add_dst(int group, str *address, int flags, int
priority, str *attrs)
error:
ds_avl_destroy(&ds_lists[*ds_next_idx]);
*ds_next_idx = *ds_crt_idx;
+ lock_release(ds_reload_lock);
return -1;
}
@@ -2972,6 +3010,7 @@ int ds_remove_dst(int group, str *address)
filter_arg.dest = dp;
filter_arg.setn = &setn;
+ lock_get(ds_reload_lock);
*ds_next_idx = (*ds_crt_idx + 1) % 2;
ds_avl_destroy(&ds_lists[*ds_next_idx]);
@@ -2985,6 +3024,7 @@ int ds_remove_dst(int group, str *address)
_ds_list_nr = setn;
*ds_crt_idx = *ds_next_idx;
+ lock_release(ds_reload_lock);
ds_log_sets();
return 0;
@@ -2992,6 +3032,7 @@ int ds_remove_dst(int group, str *address)
error:
ds_avl_destroy(&ds_lists[*ds_next_idx]);
*ds_next_idx = *ds_crt_idx;
+ lock_release(ds_reload_lock);
return -1;
}
```
### Additional Information
- [x] LLM/AI Assistants were involved in discovery, analysis or submitting of
the issue
- [x] It happened in a production deployment
- [ ] It happened in a testing or development deployment
- [x] Testing or fuzzing tools were used to generate SIP traffic when it
happened
Originally occurred in prod and was later reproduced locally.
* **Kamailio Version** - output of `kamailio -v`
```text
version: kamailio 6.2.0-dev1 (aarch64/linux)
flags: USE_TCP, USE_TLS, USE_SCTP, TLS_HOOKS, USE_RAW_SOCKS, DISABLE_NAGLE,
USE_MCAST, DNS_IP_HACK, SHM_MMAP, PKG_MALLOC, MEM_JOIN_FREE, Q_MALLOC,
F_MALLOC, TLSF_MALLOC, DBG_SR_MEMORY, DBG_QM_MALLOC, DBG_F_MALLOC,
DBG_TLSF_MALLOC, USE_FUTEX, FAST_LOCK-ADAPTIVE_WAIT, USE_DNS_CACHE,
USE_DNS_FAILOVER, USE_NAPTR, USE_DST_BLOCKLIST, HAVE_RESOLV_RES,
TLS_PTHREAD_MUTEX_SHARED
ADAPTIVE_WAIT_LOOPS 1024, MAX_RECV_BUFFER_SIZE 262144, MAX_SEND_BUFFER_SIZE
262144, MAX_URI_SIZE 1024, BUF_SIZE 65535, DEFAULT PKG_SIZE 8MB
poll method support: poll, epoll_lt, epoll_et, sigio_rt, select.
id: unknown
compiled on 09:55:20 Jul 2 2026 with gcc 14.2.0
```
* **Operating System**:
```text
PRETTY_NAME="Debian GNU/Linux 13 (trixie)"
NAME="Debian GNU/Linux"
VERSION_ID="13"
VERSION="13 (trixie)"
VERSION_CODENAME=trixie
DEBIAN_VERSION_FULL=13.5
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
Linux 4d913b2b0ae0 6.10.14-linuxkit #1 SMP Thu Aug 14 19:26:13 UTC 2025 aarch64
GNU/Linux
```
--
Reply to this email directly or view it on GitHub:
https://github.com/kamailio/kamailio/issues/4807
You are receiving this because you are subscribed to this thread.
Message ID: <kamailio/kamailio/issues/[email protected]>_______________________________________________
Kamailio - Development Mailing List -- [email protected]
To unsubscribe send an email to [email protected]
Important: keep the mailing list in the recipients, do not reply only to the
sender!