Setup: Asterisk 20 realtime via res_odbc → PostgreSQL (unixODBC). ~20 endpoints. Zero/low traffic. Random unauthorized REGISTER/INVITE attempts.
Symptom: Asterisk randomly stops processing SIP; pjsip/distributor taskprocessor queue fills and never drains.
What I saw:
-
GDB backtrace shows threads waiting on an ODBC/PostgreSQL connection (no timeout).
-
Happens more often when unsolicited REGISTER/INVITE arrive; almost disappears if I apply an ACL on the SIP port.
-
No logs hinting at ODBC pool exhaustion
Cause (my findings):
-
res_odbc.confhad;max_connections => 20commented. -
Default seems to be 1 connection (per DSN). With only one, a blocked DB call stalls everything and the distributor queue locks up. (found only on the source code) asterisk/res/res_odbc.c at master · asterisk/asterisk · GitHub
no hint on the documentation.
Fix/workaround:
Set max_connectionsto 20 (increase from default 1)
Open questions:
-
Is default
max_connections=1intentional? It’s not clearly documented. -
Should
res_odbcwarn on pool exhaustion and/or support an acquire timeout? -
Any best practices to avoid SIP distributor stalls from unauthorized traffic triggering realtime lookups?
-
Why asterisk is not able to drain the queue in that condition (max_connection default to 1) and I have to restart completely asterisk to recover?
This change reliably fixes the freeze for me. Curious what others think.
Thanks:
below a snip of GDB stack trace:
Thread 16 (Thread 0x76b41b7b26c0 (LWP 3513642) “asterisk”): #0 0x000076b44211b4fd in __GI___poll (fds=0x76b41b7b0298, nfds=1, timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
#1 0x000076b43f3eb9d4 in ?? () from /lib/x86_64-linux-gnu/libpq.so.5
#2 0x000076b43f3f1920 in PQgetResult () from /lib/x86_64-linux-gnu/libpq.so.5
#3 0x000076b43f3f351e in PQdescribePrepared () from /lib/x86_64-linux-gnu/libpq.so.5
#4 0x000076b436a6989b in ?? () from /usr/lib/x86_64-linux-gnu/odbc/psqlodbcw.so
#5 0x000076b436a2e041 in ?? () from /usr/lib/x86_64-linux-gnu/odbc/psqlodbcw.so
#6 0x000076b436a52f20 in ?? () from /usr/lib/x86_64-linux-gnu/odbc/psqlodbcw.so #7 0x000076b436a37592 in ?? () from /usr/lib/x86_64-linux-gnu/odbc/psqlodbcw.so
#8 0x000076b436a3c9c3 in ?? () from /usr/lib/x86_64-linux-gnu/odbc/psqlodbcw.so
#9 0x000076b436a56c10 in SQLExecute () from /usr/lib/x86_64-linux-gnu/odbc/psqlodbcw.so #10 0x000076b43f4397dd in SQLExecute () from /lib/x86_64-linux-gnu/libodbc.so.2
#11 0x000076b4422193da in ast_odbc_prepare_and_execute () from /usr/lib/x86_64-linux-gnu/asterisk/modules/res_odbc.so #12 0x000076b4419bbab5 in ?? () from /usr/lib/x86_64-linux-gnu/asterisk/modules/res_config_odbc.so
#13 0x0000584c72dcf69c in ast_load_realtime_all_fields () #14 0x0000584c72dcf8a7 in ast_load_realtime_fields ()
#15 0x000076b43c17dc7e in ?? () from /usr/lib/x86_64-linux-gnu/asterisk/modules/res_sorcery_realtime.so #16 0x000076b43c17dd96 in ?? () from /usr/lib/x86_64-linux-gnu/asterisk/modules/res_sorcery_realtime.so
#17 0x0000584c72d4ad4b in ast_sorcery_retrieve_by_id ()
#18 0x000076b436f774a9 in ?? () from /usr/lib/x86_64-linux-gnu/asterisk/modules/res_pjsip_endpoint_identifier_anonymous.so
#19 0x000076b437f16d0a in ast_sip_identify_endpoint () from /usr/lib/x86_64-linux-gnu/asterisk/modules/res_pjsip.so
#20 0x000076b437f38765 in ?? () from /usr/lib/x86_64-linux-gnu/asterisk/modules/res_pjsip.so
#21 0x000076b442e869cb in pjsip_endpt_process_rx_data () from /lib/x86_64-linux-gnu/libasteriskpj.so.2 #22 0x000076b437f37a80 in ?? () from /usr/lib/x86_64-linux-gnu/asterisk/modules/res_pjsip.so
#23 0x0000584c72d80df5 in ast_taskprocessor_execute () #24 0x0000584c72d931c0 in ?? ()
#25 0x0000584c72d80df5 in ast_taskprocessor_execute ()
#26 0x0000584c72d92c10 in ?? ()
#27 0x0000584c72da430f in ?? ()
#28 0x000076b44209caa4 in start_thread (arg=) at ./nptl/pthread_create.c:447
#29 0x000076b442129c6c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78