ast_softhangup() was locking the channel before calling ast_rtp_instance_set_stats_vars()
which, if the channel was in a bridge, then locked the bridge peer channel. If another
thread attempted to set bridge variables on the peer, it would lock that channel first,
then this channel causing a lock inversion. ast_softhangup() now holds the channel lock
while retrieving the rtp instance, then unlocks it before calling
ast_rtp_instance_set_stats_vars(), then locks it again after it returns.
Resolves: #1907
Add rtp_port_start and rtp_port_end options to PJSIP endpoint
configuration, allowing each endpoint to use a dedicated RTP port
range instead of the global rtp.conf setting.
This is useful for scenarios where different endpoints need isolated
port ranges, such as firewall rules per trunk, multi-tenant systems,
or network QoS policies tied to port ranges.
The implementation adds ast_rtp_instance_new_with_port_range() to the
RTP engine API, which sets the port range on the instance before the
engine allocates the transport. The default RTP engine
(res_rtp_asterisk) checks for per-instance overrides in
rtp_allocate_transport() and falls back to the global range when
none is set.
Both options must be set together, with values >= 1024 and
rtp_port_end > rtp_port_start. Setting both to 0 (the default)
preserves existing behavior.
Resolves: https://github.com/asterisk/asterisk-feature-requests/issues/71
UserNote: PJSIP endpoints now support rtp_port_start and
rtp_port_end options to configure a dedicated RTP port range per
endpoint, overriding the global rtp.conf setting.
UpgradeNote: An alembic database migration has been added to add
the rtp_port_start and rtp_port_end columns to the ps_endpoints
table. Run "alembic upgrade head" to apply the schema change.
DeveloperNote: New public API: ast_rtp_instance_new_with_port_range()
creates an RTP instance with a per-instance port range.
ast_rtp_instance_get_port_start() and ast_rtp_instance_get_port_end()
allow RTP engines to query the override. Third-party RTP engines can
use these getters to support per-instance port ranges.
Line 2729 has `#if HAVE_LIBEDIT_IS_UNICODE` instead if `#ifdef`. Since
macros defined by autoconf are either set to `1` or not set at all,
older distros where libedit isn't unicode won't have that macro defined
and will fail to compile.
Resolves: #1896
The default (codec) still uses the codec provided samples. Additionally
different sample_types can be used with eg: `translate sampletype speech`
and then running `core show translation comp 10` to measure performance
of different audio scenarios.
Resolves: #1807
Before ast_func_read and ast_func_write call their respective read and write
callbacks for registered dialplan functions, they use the module pointer in
the registered ast_custom_function structure to increment the module use
count. They then decrement the usecount when the callback returns. This
prevents the providing module from being unloaded while there's a call using
the function.
Some modules, notably func_odbc, create and destroy dialplan functions based
on the contents of a config file. Since the ast_custom_function structure is
dynamically allocated, it could be destroyed on reload which means when the
module's read or write callback returns to the ast_func calls it would try to
decrement the usecount using the module pointer from an ast_custom_function
structure that has already been freed. Proper locking or reference counting
by the module can reduce the possibility of this happening but it can't
prevent it because it doesn't have control after its read or write callback
has returned to ast_func_read or ast_func_write.
To address this, ast_func_read, ast_func_read2 and ast_func_write save the
module pointer to a local variable before calling the module's callback,
then use the saved pointer to decrement the use count. The module
pointer will always be valid if the module is loaded regardless of the
state of the ast_custom_function structure.
Resolves: #1818
The pjsua Python module and the pjsua/pjsystest apps were used by the
Asterisk Test Suite for SIP simulation in dev mode builds. They are now
fully obsolete for three independent reasons:
1. **pjsua Python bindings officially deprecated upstream.** The pjproject
maintainers added `pjsip-apps/src/python/DEPRECATED.txt` directing
users to the PJSUA2 SWIG binding instead. A build-fix PR
(https://github.com/pjsip/pjproject/pull/4892) was closed by the
maintainer explicitly citing this deprecation.
2. **Removed from the Asterisk Test Suite.** As confirmed by @mbradeen:
> *"We had to get rid of pjsua when we went to Python3 because it would
> hang due to a conflict between async calls within pjsua and twisted.
> There are still some old references to tests we couldn't fully convert
> to sipp, but those are skipped."*
3. **Broken and unmaintained.** Building with Python 2.7 (the only version
`configure.ac` searched for) fails with:
```
_pjsua.c: error: 'INIT_RETURN' undeclared (first use in this function)
```
due to a bug in pjproject 2.16's `python3_compat.h` that upstream
declined to fix.
This PR removes all pjsua-related build artifacts from Asterisk's bundled
pjproject build: the pjsua and pjsystest application binaries, the deprecated
Python (`_pjsua.so`) bindings, the `asterisk_malloc_debug.c` stubs, and the
`PYTHONDEV` detection from `configure.ac`. Also removes `libpjsua` from
Asterisk's main linker flags.
DeveloperNote: The pjsua and pjsystest application binaries, the deprecated
Python pjsua bindings (`_pjsua.so`), and the `asterisk_malloc_debug.c` stub
implementations are no longer built or installed as part of the bundled
pjproject dev mode build. The `PYTHONDEV` (python2.7-dev) build dependency
is also removed. Developers who relied on the pjsua binary for Test Suite
SIP simulation should use SIPp instead, which is the current Asterisk Test
Suite standard.
Fixes: #1840
Change rawdata buffer from char to unsigned char to prevent
sign-extension of TLV length bytes >= 0x80. On signed-char
platforms (all Asterisk builds due to -fsigned-char in
configure.ac), these values become negative when assigned to
int, bypass the `if (res > 32)` bounds check, and reach
memcpy as size_t producing a ~18 EB read that immediately
crashes with SIGSEGV.
Affects DAHDI analog (FXO) channels only. Not reachable
via SIP, PRI/BRI, or DTMF-based Caller ID.
Fixes: #1839
ast_channel_datastore_find() and ast_channel_datastore_add() must only be
called while the channel is locked (see channel.h). raise_exception() and the
EXCEPTION dialplan function read path accessed the exception datastore without
holding ast_channel_lock, which could corrupt the per-channel datastore list
under concurrency and lead to crashes during teardown (e.g. double free in
ast_datastore_free).
Resolves: #1831
manager.c: Fix CLI event display
- `manager show events`: fix event names being truncated at 20 characters, widen column to 28 to accommodate the longest registered event name
- `manager show events`: skip duplicate entries caused by multiple modules registering the same event name, list is already sorted so adjacent name comparison is sufficient
Redirects initiated by 302 response codes weren't handled correctly
when setting the hangup cause code and tech cause code on the responding
channel. They're now set to 23 (REDIRECTED_TO_NEW_DESTINATION) and
302 (Moved permanently). Other non-2XX response codes also had issues.
A new API ast_channel_dialed_causes_iterator() was added to retrieve
the hangup cause codes for a channel.
chan_pjsip_session_end() in chan_pjsip has been refactored to set the
correct cause codes on a channel based on the cause codes added by
chan_pjsip_incoming_response_update_cause(). Copious amounts of
debugging and comments were also added.
Resolves: #1819
If a channel in Stasis/ARI is hung up by the channel driver, the RTPAUDIOQOS
variables are set before the channel leaves Stasis and are therefore
available to the ARI app via ChannelVarset events. If the channel is hung up
by ARI however, the channel leaves Stasis before the RTPAUDIOQOS variables
are set so the app may not get the ChannelVarset events.
We now set the RTPAUDIOQOS variables when ast_softhangup() is called as well
as when the channel driver hangs up a channel. Since ARI hangups call
ast_softhangup(), the variables will be set before the channel leaves Stasis
and the app should get the ChannelVarset events.
ast_rtp_instance_set_stats_vars(), which actually sets the variables, now
checks to see if the variables are already set before attempting to set them.
This prevents double messages from being generated.
Resolves: #1816
Description:
When Asterisk is running without a timing module, attempting to process DTMF
triggers a segmentation fault. This occurs because the system
attempts to access a null timing file descriptor when setting up the
DTMF emulation timer.
This fix ensures that the system checks for a valid timing source before
attempting to start the DTMF emulation timer. If no timing module is
present, it logs a warning and skips the emulation instead of crashing
the process.
Changes:
- Modified main/channel.c to add a safety check within the __ast_read function.
- Implemented a graceful return path when no timing source is available
- Added a LOG_WARNING to inform the administrator that DTMF emulation
was skipped due to missing timing modules.
Testing:
- Disabled all timing_ modules in modules.conf and confirmed with
'timing test'.
- Reproduced the crash by modifying the dialplan with:
exten => 707,1,NoOp(Starting DTMF - No Timing Mode)
same => n,Answer()
same => n,Background(demo-congrats)
same => n,WaitExten(10)
same => n,Hangup()
And calling 707 followed by 1
- Verified that with the fix applied, the system logs "No timing module
loaded; skipping DTMF timer" and continues dialplan
execution without crashing.
- Confirmed stability during concurrent media sessions and DTMF input.
Fixes: #566
Add uri prefix based acl support to the built in http server.
This allows an acl to be added per uri prefix (ie '/metrics'
or '/ws') to restrict access.
Add user based acl support for ARI. This adds new acl options
to the user section of ari.conf to restrict access on a per
user basis.
resolves: #1799
UserNote: A new section, type=restriction has been added to http.conf
to allow an uri prefix based acl to be configured. See
http.conf.sample for examples and more information.
The user section of ari.conf can now contain an acl configuration
to restrict users access. See ari.conf.sample for examples and more
information
Extend the existing DTMF/MF tone detection support by adding support
for R2 tones, another variant of MF (R1) signaling. Both forward
and backward signaling are supported.
Resolves: #1804
For application, function, manager, managerEvent, managerEventInstance
and info XML documentation nodes, the make_xml_documentation script will
add a "module" attribute if not already present. For XML in separate
"*_doc.xml" files, the script figures out the correct module name. For
documentation in the "main" directory, the module name is set to "builtin".
The CLI handlers for "core show application", "core show function",
"manager show command" and "manager show event", have been updated to
show the following after the Synopsis...
```
[Provided By]
<modulename>
```
For modules that provide additional "info" elements (like the technologies
do for Dial), the providing module has also been added.
```
Technology: WebSocket Provided by: chan_websocket
WebSocket Dial Strings:
...
```
UserNote: The CLI help for applications, functions, manager commands and
manager events now shows the module that provides its functionality.
There is a LOT of work in this commit but the TL;DR is that it takes
CEL processing from using 38% of the CPU instructions used by a call,
which is more than that used by the call processing itself, down to less
than 10% of the instructions.
So here's the deal... cdr_custom, cdr_sqlite3_custom, cel_custom
and cel_sqlite3_custom all shared one ugly trait...they all used
ast_str_substitute_variables() or pbx_substitute_variables_helper()
to resolve the dialplan functions used in their config files. Not only
are they both extraordinarily expensive, they both require a dummy
channel to be allocated and destroyed for each record written. For CDRs,
that's not too bad because we only write one CDR per call. For CELs however,
it's a disaster.
As far as source code goes, the modules basically all did the same thing.
Unfortunately, they did it badly. The config files simply contained long
opaque strings which were intepreted by ast_str_substitute_variables() or
pbx_substitute_variables_helper(), the very functions that ate all the
instructions. This meant introducing a new "advanced" config format much
like the advanced manager event filtering added to manager.conf in 2024.
Fortunately however, if the legacy config was recognizable, we were able to
parse it as an advanced config and gain the benefit. If not, then it
goes the legacy, and very expensive, route.
Given the commonality among the modules, instead of making the same
improvements to 4 modules then trying to maintain them over time, a single
module "res_cdrel_custom" was created that contains all of the common code.
A few bonuses became possible in the process...
* The cdr_custom and cel_custom modules now support JSON formatted output.
* The cdr_sqlite_custom and cel_sqlite3_custom modules no longer have
to share an Sqlite3 database.
Summary of changes:
A new module "res/res_cdrel_custom.c" has been created and the existing
cdr_custom, cdr_sqlite3_custom, cel_custom and cel_sqlite3_custom modules
are now just stubs that call the code in res_cdrel_custom.
res_cdrel_custom contains:
* A common configuration facility.
* Getters for both CDR and CEL fields that share the same abstraction.
* Formatters for all data types found in the ast_cdr and ast_event
structures that share the same abstraction.
* Common writers for the text file and database backends that, you guessed it,
share the same abstraction.
The result is that while there is certainly a net increase in the number of
lines in the code base, most of it is in the configuration handling at
load-time. The run-time instruction path length is now significanty shorter.
```
Scenario Instructions Latency
=====================================================
CEL pre changes 38.49% 37.51%
CEL Advanced 9.68% 6.06%
CEL Legacy (auto-conv to adv) 9.95% 6.13%
CEL Sqlite3 pre changes 39.41% 39.90%
CEL Sqlite3 Advanced 25.68% 24.24%
CEL Sqlite3 Legacy (auto conv) 25.88% 24.53%
CDR pre changes 4.79% 2.95%
CDR Advanced 0.79% 0.47%
CDR Legacy (auto conv to adv) 0.86% 0.51%
CDR Sqlite3 pre changes 4.47% 2.89%
CEL Sqlite3 Advanced 2.16% 1.29%
CEL Sqlite3 Legacy (auto conv) 2.19% 1.30%
```
Notes:
* We only write one CDR per call but every little bit helps.
* Sqlite3 still takes a fair amount of resources but the new config
makes a decent improvement.
* Legacy configs that we can't auto convert will still take the
"pre changes" path.
If you're interested in more implementation details, see the comments
at the top of the res_cdrel_custom.c file.
One minor fix to CEL is also included...Although TenantID was added to the
ast_event structure, it was always rendered as an empty string. It's now
properly rendered.
UserNote: Significant performance improvements have been made to the
cdr_custom, cdr_sqlite3_custom, cel_custom and cel_sqlite3_custom modules.
See the new sample config files for those modules to see how to benefit
from them.
GCC 15.2.1 pays attention to the discarding of the const
qualifier when strchr, strrchr, memchr, or memrchr are now
used. This change fixes numerous errors with this throughout
the tree. The fixes can be broken down into the following:
1. The return value should be considered const.
2. The value passed to strchr or strrchr can be cast as it is
expected and allowed to be modified.
3. The pointer passed to strchr or strrchr is not meant to be
modified and so the contents must be duplicated.
4. It was declared const and never should have been.
This change adds an API call to allow direct access to the latest
snapshot of an ast_endpoint. This is then used by chan_pjsip when
calculating device state, eliminating the need to access the cache
which would incur a container find and access.
To address potential security issues, the httpstatus page is now disabled
by default and the echoed query string and cookie output is html-escaped.
Resolves: #GHSA-v6hp-wh3r-cwxh
UpgradeNote: To prevent possible security issues, the `/httpstatus` page
served by the internal web server is now disabled by default. To explicitly
enable it, set `enable_status=yes` in http.conf.
The xmlReadFile XML_PARSE_NOENT flag, which allows parsing of external
entities, could allow a potential XXE injection attack. Replacing it with
XML_PARSE_NONET, which prevents network access, is safer.
Resolves: #GHSA-85x7-54wr-vh42
stasis.c: Fix deadlock in stasis_topic_pool_get_topic during module load.
Deadlock occurs when res_manager_devicestate loads concurrently with
device state operations due to lock ordering violation:
Thread 1: Holds pool lock → needs topic lock (in stasis_forward_all)
Thread 2: Holds topic lock → needs pool lock (in stasis_topic_pool_get_topic)
Fix: Release pool lock before calling stasis_topic_create() and
stasis_forward_all(). Re-acquire only for insertion with race check.
Preserves borrowed reference semantics while breaking the deadlock cycle.
Fixes: #1611
With this new feature, users who speak these languages can now benefit from the
text-to-speech functionality provided by asterisk. This will make the platform
more accessible and useful to a wider range of users, particularly those in
regions where Pashto and Dari are spoken. This contribution will help to improve
the overall usability and inclusivity of the asterisk platform.
Fixes: #1724
This extends 'channel request hangup' to accept multiple channel
names, a POSIX Extended Regular Expression, a glob-like pattern, or a
combination of all of them.
UserNote: The 'channel request hangup' CLI command now accepts
multiple channel names, POSIX Extended Regular Expressions, glob-like
patterns, or a combination of all of them. See the CLI command 'core
show help channel request hangup' for full details.
Versions of libedit that support Unicode expect that the
EL_GETCFN (the function that does character I/O) will fill in a
`wchar_t` with a character, which may be multi-byte. The built-in
function that libedit provides, but does not expose with a public API,
does properly handle multi-byte sequences.
Due to the design of Asterisk's console processing loop, Asterisk
provides its own implementation which does not handle multi-byte
characters. Changing Asterisk to use libedit's built-in function would
be ideal, but would also require changing some fundamental things
about console processing which could be fairly disruptive.
Instead, we bring in libedit's `read_char` implementation and modify
it to suit our specific needs.
Resolves: #60
When dial attempts timeout in the core dialing API, the channel's hangup
cause was not being set before hanging up. Only the ast_dial_channel
structure's internal cause field was updated, but the actual ast_channel
hangup cause remained unset.
This resulted in incorrect or missing hangup cause information being
reported through CDRs, AMI events, and other mechanisms that read the
channel's hangup cause when dial timeouts occurred via applications
using the dialing API (FollowMe, Page, etc.).
The fix adds proper channel locking and sets AST_CAUSE_NO_ANSWER on
the channel before calling ast_hangup(), ensuring consistent hangup
cause reporting across all interfaces.
Resolves: #1660
This change moves the PJSIP module from the threadpool API
to the taskpool API. PJSIP-specific implementations for
task usage have been removed and replaced with calls to
the optimized taskpool implementations instead. The need
for a pool of serializers has also been removed as
taskpool inherently provides this. The default settings
have also been changed to be more realistic for common
usage.
UpgradeNote: The threadpool_* options in pjsip.conf have now
been deprecated though they continue to be read and used.
They have been replaced with taskpool options that give greater
control over the underlying taskpool used for PJSIP. An alembic
upgrade script has been added to add these options to realtime
as well.
Commit 26795be introduced a memory leak of ast_endpoint when
ast_endpoint_shutdown() was called. The leak occurs only if a configuration
change removes an endpoint and isn't related to call volume or the length of
time asterisk has been running. An ao2_ref(-1) has been added to
ast_endpoint_shutdown() to plug the leak.
Resolves: #1635
This change makes some small changes to improve log readability in
addition to the following changes:
Modified 'core show taskprocessors' to now show Low time and High time
for task execution.
New command 'core show taskprocessor name <taskprocessor-name>' to dump
taskprocessor info and current queue.
Addionally, a new test was added to demonstrate the 'show taskprocessor
name' functionality:
test execute category /main/taskprocessor/ name taskprocessor_cli_show
Setting 'core set debug 3 taskprocessor.c' will now log pushed tasks.
(Warning this is will cause extremely high levels of logging at even
low traffic levels.)
Resolves: #1566
UserNote: New CLI command has been added -
core show taskprocessor name <taskprocessor-name>
While this check is technically unnecessary, it also was not harmful.
The 2 other items mentioned in the linked issue are false positives
and require no action.
Resolves: #1417
callback returned the last iterated channel when no match existed, causing invalid channel references and potential double frees. Updated to correctly return NULL when there is no match.
Resolves: #1609
The Call Completion Supplementary Service feature is rarely used but many of
it's functions are called by app_dial and channel.c "just in case". These
functions lock and unlock the channel just to see if CCSS is enabled on it,
which it isn't 99.99% of the time.
UserNote: A new "enabled" parameter has been added to ccss.conf. It defaults
to "yes" to preserve backwards compatibility but CCSS is rarely used so
setting "enabled = no" in the "general" section can save some unneeded channel
locking operations and log message spam. Disabling ccss will also prevent
the func_callcompletion and chan_dahdi modules from loading.
DeveloperNote: A new API ast_is_cc_enabled() has been added. It should be
used to ensure that CCSS is enabled before making any other ast_cc_* calls.
When running "dialplan reload", the number of contexts reported
is initially wrong, as it is the old context count. Running
"dialplan reload" a second time returns the correct number of
contexts that are loaded. This can confuse users into thinking
that the reload didn't work successfully the first time.
This counter is currently only incremented when iterating the
old contexts prior to the context merge; at the very end, get
the current number of elements in the context hash table and
report that instead. This way, the count is correct immediately
whenever a reload occurs.
Resolves: #1599
After p->chan = NULL, ast still points to the valid channel object,
using ast safely accesses the channel's DIALSTATUS variable before it's fully destroyed
Resolves: #1590
After PR #1498 added read locking to channelstorage_cpp_map_name_id, if ARI
channels/externalMedia was called with a custom channel id AND the
cpp_map_name_id channel storage backend is in use, a deadlock can occur when
hanging up the channel. It's actually triggered in
channel.c:__ast_channel_alloc_ap() when it gets a write lock on the
channelstorage driver then subsequently does a lookup for channel uniqueid
which now does a read lock. This is an invalid operation and causes the lock
state to get "bad". When the channels try to hang up, a write lock is
attempted again which hangs and causes the deadlock.
Now instead of the cpp_map_name_id channelstorage driver "get" APIs
automatically performing a read lock, they take a "lock" parameter which
allows a caller who already has a write lock to indicate that the "get" API
must not attempt its own lock. This prevents the state from getting mesed up.
The ao2_legacy driver uses the ao2 container's recursive mutex so doesn't
have this issue but since it also implements the common channelstorage API,
it needed its "get" implementations updated to take the lock parameter. They
just don't use it.
Resolves: #1578
The TCP three-way handshake completes, but if the server is under a TLS handshake attack, asterisk will get stuck at SSL_do_handshake().
In this case, a timeout mechanism should be set for the SSL/TLS handshake process to prevent indefinite waiting during the SSL handshake.
Resolves: #1559
This change moves the PJSIP module from the threadpool API
to the taskpool API. PJSIP-specific implementations for
task usage have been removed and replaced with calls to
the optimized taskpool implementations instead. The need
for a pool of serializers has also been removed as
taskpool inherently provides this. The default settings
have also been changed to be more realistic for common
usage.
UpgradeNote: The threadpool_* options in pjsip.conf have now
been deprecated though they continue to be read and used.
They have been replaced with taskpool options that give greater
control over the underlying taskpool used for PJSIP. An alembic
upgrade script has been added to add these options to realtime
as well.
When publishing device state check the local cache for the
existing device state. If the new device state is unchanged
from the prior one, don't bother publishing the update. This
can reduce the work done by consumers of device state, such
as hints and app_queue, by not publishing a message to them.
These messages would most often occur with devices that are
seeing numerous simultaneous channels. The underlying device
state would remain as in use throughout, but an update would
be published as channels are created and hung up.