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.
Although the ISDN/Q.850/Q.931 hangup cause code is already part of the ARI
and AMI hangup and channel destroyed events, it can be helpful to know what
the actual channel technology code was if the call was unsuccessful.
For PJSIP, it's the SIP response code.
* A new "tech_hangupcause" field was added to the ast_channel structure along
with ast_channel_tech_hangupcause() and ast_channel_tech_hangupcause_set()
functions. It should only be set for off-nominal terminations.
* chan_pjsip was modified to set the tech hangup cause in the
chan_pjsip_hangup() and chan_pjsip_session_end() functions. This is a bit
tricky because these two functions aren't always called in the same order.
The channel that hangs up first will get chan_pjsip_session_end() called
first which will trigger the core to call chan_pjsip_hangup() on itself,
then call chan_pjsip_hangup() on the other channel. The other channel's
chan_pjsip_session_end() function will get called last. Unfortunately,
the other channel's HangupRequest events are sent before chan_pjsip has had a
chance to set the tech hangupcause code so the HangupRequest events for that
channel won't have the cause code set. The ChannelDestroyed and Hangup
events however will have the code set for both channels.
* A new "tech_cause" field was added to the ast_channel_snapshot_hangup
structure. This is a public structure so a bit of refactoring was needed to
preserve ABI compatibility.
* The ARI ChannelHangupRequest and ChannelDestroyed events were modified to
include the "tech_cause" parameter in the JSON for off-nominal terminations.
The parameter is suppressed for nominal termination.
* The AMI SoftHangupRequest, HangupRequest and Hangup events were modified to
include the "TechCause" parameter for off-nominal terminations. Like their ARI
counterparts, the parameter is suppressed for nominal termination.
DeveloperNote: A "tech_cause" parameter has been added to the
ChannelHangupRequest and ChannelDestroyed ARI event messages and a "TechCause"
parameter has been added to the HangupRequest, SoftHangupRequest and Hangup
AMI event messages. For chan_pjsip, these will be set to the last SIP
response status code for off-nominally terminated calls. The parameter is
suppressed for nominal termination.
When an endpoint is created in the core of Asterisk a subscription
was previously created alongside it to monitor any channels being
destroyed that were related to it. This was done by receiving all
channel snapshot updates for every channel and only reacting when
it was indicated that the channel was dead.
This change removes this logic and instead provides an API call
for directly removing a channel from an endpoint. This is called
when channels are destroyed. This operation is fast, so blocking
the calling thread for a short period of time doesn't have any
noticeable impact.
Dial() already preserves the ADSI capability by copying it to the new
channel, but since Local channel pairs consist of two channels, we
also need to copy the capability to the second channel.
Resolves: #1517
As soon as SIP call may end with several Reason headers, we
want to make all of them available through the HAGUPCAUSE() function.
This implementation uses the same ao2 hash for cause codes storage
and adds a flag to make difference between last processed sip
message and content of reason headers.
UserNote: Added a new option to HANGUPCAUSE to access additional
information about hangup reason. Reason headers from pjsip
could be read using 'tech_extended' cause type.
Among the lower-quality voice codecs, some of the quality scores did
not make sense relative to each other.
For instance, quality-wise, G.729 > G.723 > PLC10.
However, current scores do not uphold these relationships.
Tweak the scores slightly to reflect more accurate relationships.
Resolves: #1501
When we retrieve a channel from a C++ map, we actually get back a wrapper
object that points to the channel then right after we retrieve it, we bump its
reference count. There's a tiny chance however that between those two
statements a delete and/or unref might happen which would cause the wrapper
object or the channel itself to become invalid resulting in a SEGV. To avoid
this we now perform a read lock on the driver around those statements.
Resolves: #1491
Commit dc8e3eeaaf improved the debug log
messages in dsp.c. This makes two minor corrections to it:
* Properly guard an added log statement in a conditional.
* Don't add one to the hit count if there was no hit (however, we do
still want to do this for the case where this is one).
Resolves: #1496
When running "config show help <module>", if no XML documentation exists
for the specified module, "Module <module> not found." is returned,
which is misleading if the module is loaded but simply has no XML
documentation for its config. Improve the message to clarify that the
module may simply have no config documentation.
Resolves: #1489
This change moves observer invocation from the use of
a threadpool to a taskpool. The taskpool options have also
been adjusted to ensure that at least one taskprocessor
remains available at all times.
Follow-on to #244 and #960 regarding how the ast_config_XXX APIs
handle template inheritance.
ast_config_text_file_save2() incorrectly suppressed variables if they
matched any ancestor template. This broke deep chains (dropping values
based on distant parents) and wide inheritance (ignoring last-wins order
across multiple parents).
The function now inspects the full template hierarchy to find the nearest
effective parent (last occurrence wins). Earlier inherited duplicates are
collapsed, explicit overrides are kept unless they exactly match the parent,
and PreserveEffectiveContext avoids writing redundant lines.
Resolves: #1451
When handling SIP transfers via ARI, the `referred_by` field in
`transfer_ari_state` may be null, since SIP REFER requests are not
required to include a `Referred-By` header. Without this check, a null
value caused the transfer to fail and triggered a NOTIFY with a 500
Internal Server Error.
This change introduces a new API called taskpool. This is a pool
of taskprocessors. It provides the following functionality:
1. Task pushing to a pool of taskprocessors
2. Synchronous tasks
3. Serializers for execution ordering of tasks
4. Growing/shrinking of number of taskprocessors in pool
This functionality already exists through the combination of
threadpool+taskprocessors but through investigating I determined
that this carries substantial overhead for short to medium duration
tasks. The threadpool uses a single queue of work, and for management
of threads it involves additional tasks.
I wrote taskpool to eliminate the extra overhead and management
as much as possible. Instead of a single queue of work each
taskprocessor has its own queue and at push time a selector chooses
the taskprocessor to queue the task to. Each taskprocessor also
has its own thread like normal. This spreads out the tasks immediately
and reduces contention on shared resources.
Using the included efficiency tests the number of tasks that can be
executed per second in a taskpool is 6-12 times more than an equivalent
threadpool+taskprocessor setup.
Stasis has been moved over to using this new API as it is a heavy consumer
of threadpool+taskprocessors and produces a lot of tasks.
UpgradeNote: The threadpool_* options in stasis.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 stasis.
DeveloperNote: The taskpool API has been added for common usage of a
pool of taskprocessors. It is suggested to use this API instead of the
threadpool+taskprocessor approach.
In a previous commit, a change was made to
ast_rtp_codecs_payload_code_tx_sample_rate to check for differing sample
rates. This ended up returning an invalid payload int for comfort noise.
A check has been added that returns early if the payload is in fact
supposed to be comfort noise.
Fixes: #1340
"dialplan eval function" has been using a dummy channel for function
evaluation, much like many of the unit tests. However, sometimes, this
can cause issues for functions that are not expecting dummy channels.
As an example, ast_channel_tech(chan) is NULL on such channels, and
ast_channel_tech(chan)->type consequently results in a NULL dereference.
Normally, functions do not worry about this since channels executing
dialplan aren't dummy channels.
While some functions are better about checking for these sorts of edge
cases, use a real channel with a dummy technology to make this CLI
command inherently safe for any dialplan function that could be evaluated
from the CLI.
Resolves: #1434
Currently, the 'd' option will play dial tone while waiting
for digits. Allow it to accept an argument for any tone from
indications.conf.
Resolves: #1396
UserNote: The tone used while waiting for digits in WaitExten
can now be overridden by specifying an argument for the 'd'
option.
This patch resolves two issues in Sorcery objectset handling with multiple
backends:
1. Prevent duplicate objects:
When an object exists in more than one backend (e.g., a contact in both
'astdb' and 'realtime'), the objectset previously returned multiple instances
of the same logical object. This caused logic failures in components like the
PJSIP registrar, where duplicate contact entries led to overcounting and
incorrect deletions, when max_contacts=1 and remove_existing=yes.
This patch ensures only one instance of an object with a given key is added
to the objectset, avoiding these duplicate-related side effects.
2. Ensure missing objects are created:
When using multiple writable backends, a temporary backend failure can lead
to objects missing permanently from that backend.
Currently, .update() silently fails if the object is not present,
and no .create() is attempted.
This results in inconsistent state across backends (e.g. astdb vs. realtime).
This patch introduces a new global option in sorcery.conf:
[general]
update_or_create_on_update_miss = yes|no
Default: no (preserves existing behavior).
When enabled: if .update() fails with no data found, .create() is attempted
in that backend. This ensures that objects missing due to temporary backend
outages are re-synchronized once the backend is available again.
Added a new CLI command:
sorcery show settings
Displays global Sorcery settings, including the current value of
update_or_create_on_update_miss.
Updated tests to validate both flag enabled/disabled behavior.
Fixes: #1289
UserNote: Users relying on Sorcery multiple writable backends configurations
(e.g., astdb + realtime) may now enable update_or_create_on_update_miss = yes
in sorcery.conf to ensure missing objects are recreated after temporary backend
failures. Default behavior remains unchanged unless explicitly enabled.
* Added a new option to the WebSocket dial string to capture the additional
URI parameters.
* Added a new API ast_uri_verify_encoded() that verifies that a string
either doesn't need URI encoding or that it has already been encoded.
* Added a new API ast_websocket_client_add_uri_params() to add the params
to the client websocket session.
* Added XML documentation that will show up with `core show application Dial`
that shows how to use it.
Resolves: #1352
UserNote: A new WebSocket channel driver option `v` has been added to the
Dial application that allows you to specify additional URI parameters on
outgoing connections. Run `core show application Dial` from the Asterisk CLI
to see how to use it.
The debug logging during DSP processing has always been kind
of overwhelming and annoying to troubleshoot. Simplify and
improve the logging in a few ways to aid DSP debugging:
* If we had a DSP hit, don't also emit the previous debug message that
was always logged. It is duplicated by the hit message, so this can
reduce the number of debug messages during detection by 50%.
* Include the hit count and required number of hits in the message so
on partial detections can be more easily troubleshot.
* Use debug level 9 for hits instead of 10, so we can focus on hits
without all the noise from the per-frame debug message.
* 1-index the hit count in the debug messages. On the first hit, it
currently logs '0', just as when we are not detecting anything,
which can be confusing.
Resolves: #1375
If you do a `core show application Dial`, you'll see it's kind of a mess.
Indents are wrong is some places, examples are printed in black which makes
them invisible on most terminals, and the lack of line breaks in some cases
makes it hard to follow.
* Fixed the rendering of examples so they are indented properly and changed
the color so they can be seen.
* There is now a line break before each option.
* Options are now printed on their own line with all option content indented
below them.
Example from Dial before fixes:
```
Example: Dial 555-1212 on first available channel in group 1, searching
from highest to lowest
Example: Ringing FXS channel 4 with ring cadence 2
Example: Dial 555-1212 on channel 3 and require answer confirmation
...
O([mode]):
mode - With <mode> either not specified or set to '1', the originator
hanging up will cause the phone to ring back immediately.
- With <mode> set to '2', when the operator flashes the trunk, it will ring
their phone back.
Enables *operator services* mode. This option only works when bridging a DAHDI
channel to another DAHDI channel only. If specified on non-DAHDI interfaces, it
will be ignored. When the destination answers (presumably an operator services
station), the originator no longer has control of their line. They may hang up,
but the switch will not release their line until the destination party (the
operator) hangs up.
p: This option enables screening mode. This is basically Privacy mode
without memory.
```
After:
```
Example: Dial 555-1212 on first available channel in group 1, searching
from highest to lowest
same => n,Dial(DAHDI/g1/5551212)
Example: Ringing FXS channel 4 with ring cadence 2
same => n,Dial(DAHDI/4r2)
Example: Dial 555-1212 on channel 3 and require answer confirmation
same => n,Dial(DAHDI/3c/5551212)
...
O([mode]):
mode - With <mode> either not specified or set to '1', the originator
hanging up will cause the phone to ring back immediately.
With <mode> set to '2', when the operator flashes the trunk, it will
ring their phone back.
Enables *operator services* mode. This option only works when bridging
a DAHDI channel to another DAHDI channel only. If specified on
non-DAHDI interfaces, it will be ignored. When the destination answers
(presumably an operator services station), the originator no longer has
control of their line. They may hang up, but the switch will not
release their line until the destination party (the operator) hangs up.
p:
This option enables screening mode. This is basically Privacy mode
without memory.
```
There are still things we can do to make this more readable but this is a
start.
If the BRIDGE_NOANSWER variable is set on a channel, it is not supposed
to answer when another channel bridges to it using Bridge(), and this is
checked when ast_bridge_call* is called. However, another path exists
(bridge_exec -> ast_bridge_add_channel) where this variable was not
checked and channels would be answered. We now check the variable there.
Resolves: #401Resolves: #1364
With `sounds_search_custom_dir = yes`, we are supposed to search for sounds
in the `AST_DATA_DIR/sounds/custom` directory before searching the normal
directories. Unfortunately, a recent change
(https://github.com/asterisk/asterisk/pull/1172) had a typo resulting in
the "custom" directory not being searched. This change restores this
expected behavior.
Resolves: #1353
Fixes: #1280
UserNote: Enabling the tracking of the
STREAM_BEGIN and the STREAM_END event
types in cel.conf will log media files and
music on hold played to each channel.
The STREAM_BEGIN event's extra field will
contain a JSON with the file details (path,
format and language), or the class name, in
case of music on hold is played. The DTMF
event's extra field will contain a JSON with
the digit and the duration in milliseconds.
Remove the deprecated 'rotatetimestamp' config option, as this
was deprecated by 'rotatestrategy' in 1.6 by commit
f5a14167f3.
Resolves: #1345
UpgradeNote: The deprecated rotatetimestamp option has been removed.
Use rotatestrategy instead.
The "no debug channel" command has been deprecated since
1.6 (commit 691363656f),
as it is replaced by "core set debug channel", which also
supports tab-completion on channels. Remove the redundant
command.
Resolves: #1343
UpgradeNote: The deprecated "no debug channel" command has
now been removed; use "core set debug channel" instead.