The TOUCH_MIXMONITOR_OPTIONS channel variable can now be used to configure the options used by the mixmonitor application when it is started via automixmon. If both TOUCH_MIXMONITOR_OPTIONS and TOUCH_MIXMONITOR_BEEP are set, TOUCH_MIXMONITOR_BEEP is ignored with a warning.
There is no longer a requirement to play silence or otherwise have a stream of audio being sent to a hooked channel for whispered frames to be heard.
Bundled pjproject: It's now possible to override some of the pjproject
build options contained in ./third-party/pjproject/patches/config_site.h by
adding PJPROJECT_CFLAGS to your Asterisk ./configure command line. For example:
./configure ... PJPROJECT_CFLAGS='-DPJ_OPT1=8192 -DPJ_OPT2=512'
Any option in config_site.h that's wrapped in a #ifndef block can be overridden
and many of the PJSIP options displayed by pjproject show buildopts can be
set. WARNING: Adjusting these options without understanding their effect can
cripple your Asterisk instances. You shouldn't adjust them unless you need
to solve a specific issue.
Resolves: #2011
The "manager show eventq" CLI command has been removed as there is no longer a single event queue to display.
A new pjsip.conf transport option 'external_signaling_hostname' has been added. When set, this value will be used in SIP Contact and Via headers instead of the automatically determined IP address. This option is mutually exclusive with 'external_signaling_address'.
Forward/outbound proxies can now be specified for outbound websockets. See the websocket_client.conf.sample file for configuration information. TCP-level or WebSocket PING/PONG keepalives can now be enabled on
ast_openstream should stop at the first compatible fileSTOP_MEDIA_BUFFERINGformat_cap: guard against NULL src in *_from_cap helpers
res_pjsip: Add external_signaling_hostname transport option
func_strings: Fix syntax error in STRBETWEEN documentation example
Logger: Don't discard WARNING or ERROR messages.
WebSocket Enhancements: Proxies and Keepalives for ARI and Media Outbound Websockets.
file.c: Ensure opening a stream opens at most one file
extension_state: Add new extension state API.
res_pjsip_session: Bound delayed BYE behind UAC INVITE
app_mixmonitor: Fix duplex recording for non 8K codecs
chan_local: Update chan_local references for Local channels.
bridging: Add support for TOUCH_MIXMONITOR_OPTIONS
configs: Comment out values setting to avoid parse error
jansson: Upgrade version to jansson 2.15.1
chan_websocket: Fix NULL requestor dereference in webchan_request.
res_http_websocket: Unref session when it fails to establish.
values setting to avoid parse errorAuthor: Mike Bradeen Date: 2026-08-05
A reINVITE that changed the offered codec set (e.g. ulaw+alaw -> alaw only) could lead to call teardown when a bridge write still using the old format occurred during the re-negotiation.
This change avoids the termination by making the following changes.
First, Asterisk now holds the lock across both the tx payload update and the channel format update so they commit atomically.
Second, when processing the sdp on the new incoming offer, merge the new offer with the old until the negotiation is complete.
Also adds unit tests for the sdp merge
Fixes: #2059
Author: Sven Kube Date: 2026-08-05
Two log statements in webchan_request() passed requestor straight to
ast_channel_name(), which dereferences the channel with no NULL check.
requestor is NULL whenever no originator channel is supplied: ARI POST
/channels/externalMedia always passes NULL, and POST /channels/create
passes NULL when originator is omitted.
Author: Naveen Albert Date: 2026-08-04
stdbool.h is needed now that we use the bool type directly instead of bfd_boolean. See also 1d95b744c06974f0a00c143c6e0fc979af930908.
Resolves: #2061
Author: aabolfazl Date: 2026-08-02
local_ast_moh_start() returns -1 from the answeredonly check without releasing the mohclass reference it holds, unlike every other exit path in the function. Nothing else ever releases that reference, so moh_class_destructor() never runs for the object. With realtime music on hold and cachertclasses disabled, each suppressed request leaks the class object, its monitor thread, the external application process and two file descriptors for the lifetime of Asterisk. For static classes the stale references prevent the class from ever being destroyed after it is replaced by a reload.
Release the reference before returning, matching the other exit paths.
Fixes: #2051
Author: Naveen Albert Date: 2026-08-03
bfd_boolean has been deprecated for some time and has now been removed in gdb, so use bool directly instead.
See: https://github.com/gnutools/binutils-gdb/commit/1d95b744c06974f0a00c143c6e0fc979af930908
Resolves: #2054
Author: Sean Bright Date: 2026-08-02
A pointer to new is passed to inboxcount(...) which increments the
pointed-to value.
Author: Mike Bradeen Date: 2026-08-03
Disable building the pjsua test application when any of the SANITIZER flags are set.
Fixes: #2056
Author: George Joseph Date: 2026-08-04
Author: Mehrdad Seifzadeh Date: 2026-06-05
Outgoing PJSIP channels did not have transport information stored in their session datastore when CHANNEL(pjsip,local_addr) or CHANNEL(pjsip,remote_addr) was read. As a result, the address fields were empty on B-leg channels even though other dialog fields such as call-id and URIs were available.
Store the selected local transport address and destination address for outgoing UAC session requests once the request is transmitted and the transport information is known.
Fixes: #871
Author: aabolfazl Date: 2026-07-29
The FIELDNUM description misspelled "occurred" as "occured". This text is user-visible: it is rendered on docs.asterisk.org and printed by "core show function FIELDNUM".
Author: Sean Bright Date: 2026-07-28
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 chan_sip. The fixes can be broken down into the following:
Author: Jeremy Lainé Date: 2026-07-23
handle_tcptls_connection() marks the current thread as inhibiting privilege escalations and as an external user interface so that dialplan functions considered 'dangerous' (STAT, SHELL, ...) cannot be executed on behalf of an external protocol.
This is correct for inbound (server) connections, each of which runs on its own dedicated worker thread. However, the outbound (client) path calls handle_tcptls_connection() synchronously on the caller's own thread. When that caller is a channel/PBX thread, the thread-local flags are set and never cleared, permanently tainting the dialplan thread.
Examples:
Outbound connections are initiated by Asterisk itself and are not external user interfaces, so the flags should not be set for them. Gate the flag-setting on tcptls_session->client so it applies only to inbound connections.
Resolves: #2038
Author: Mike Bradeen Date: 2026-06-26
Fixes two related instance, group lock inversion deadlocks.
When writing the RTP stream via rtp_sendto, the RTP instance was only unlocked before being passed to pj project when the instance was un-bundled (ie video was not bundled onto the audio stream's ICE transport.)
The first change unlocks the instance whether bundled or unbundled to avoid the deadlock, then re-checks the bundled status upon return to know wether or not the transport should be used.
For the second change, when an incoming RTCP NACK record was recieved, the parent (transport) and child (instance) locks were both held before the call to rtp_sendto, which is only able to release the child lock. Now in the un-bundled case the parent and child will be unlocked and re-locked in the correct order via a new helper function before and after the call to send_to.
Fixes: #1946
Author: Stanislav Abramenkov Date: 2026-07-21
UpgradeNote: jansson has been upgraded to 2.15.1. For more information visit jansson Github page: https://github.com/akheron/jansson/releases/tag/v2.15.1
Resolves: #2033
Author: Jeremy Lainé Date: 2025-12-03
The functions used to stream files eventually end up calling into
filehelper(.., ACTION_OPEN) which takes care of iterating over
supported extensions and opening the first existing file.
To do this, filehelper uses two nested loops:
We need to break out of both loops as soon as a file was successfully
opened. Otherwise if a file exists in multiple formats (e.g foo.wav
and foo.alaw) both files will be opened successively.
Resolves: #1625
Author: Joshua C. Colp Date: 2026-07-15
When placing outbound calls each call would get its own taskprocessor for things related to the call. In practice this is overkill as few things actually occur. Inbound calls on the other hand already use one of the fixed number of distributor taskprocessors. This also occurred for OPTIONS requests with each AOR having its own taskprocessor.
This change moves both to using a distributor taskprocessor instead.
Author: Roel van Meer Date: 2026-06-29
This channel variable can be used to override the default automixmon
options (which are 'b' or 'bB(
Fixes: #1981
UserNote: The TOUCH_MIXMONITOR_OPTIONS channel variable can now be used to configure the options used by the mixmonitor application when it is started via automixmon. If both TOUCH_MIXMONITOR_OPTIONS and TOUCH_MIXMONITOR_BEEP are set, TOUCH_MIXMONITOR_BEEP is ignored with a warning.
Author: George Joseph Date: 2026-07-01
When an attended transfer is controlled by ARI using PJSIP_TRANSFER_HANDLING()=ari-only, and a REFER request is received with a Refer-Sub: false header to suppress the automatic progress subscription, a segfault occurs in res_pjsip_refer:refer_incoming_ari_request().
However, even if the segfault were prevented, there's another issue... Suppressing the subscription and NOTIFYs to the referer also prevents the ARI app from getting any progress events for the transfer which it's controlling.
So...
Resolves: #2021
Author: Mike Bradeen Date: 2026-07-14
pjsua and it's python bindings were removed as part of PR 1854. Testing for RTT requires the pjsua application be re-added to the third pary build process. This applies to the pjsua application ONLY and not the associated python bindings.
Resolves: #2024
Author: Naveen Albert Date: 2026-07-14
The 'none' value can be used to disable DSP processing for DTMF on PJSIP channels and is sometimes necessary for this reason, and already exists in the code, but is not documented. Add it to the documentation enum.
Resolves: #2026
Author: Mike Bradeen Date: 2026-06-02
Audiohook whispers work by mixing audio with the current stream of frames being written to the hooked channel. Prior to this change if there were no audio frames being written to the channel outside of the audiohook, then any whisper audio has nothing to mix with and so is not heard on the hooked channel.
This change removes that requirement by creating a framehook driven timer on the channel that creates silent frames the whispered frames can be mixed into.
The framehook is automatically added with the first attached whisper audiohook and is removed when the last one is detached. If there are no attached streams being written to the channel, the timer is used to generate a default one. If a stream is attached; the timer is ignored until the stream stops. This stop and start is automatically triggered by the presence of a written stream and does not require any external action.
Resolves: #1966
UserNote: There is no longer a requirement to play silence or otherwise have a stream of audio being sent to a hooked channel for whispered frames to be heard.
Author: Ben Ford Date: 2026-06-01
When the logger reaches it's threshold for messages, don't discard the WARNING or ERROR messages up to a certain amount. If THAT threshold reaches its maximum, start discarding the oldest non-WARNING/ERROR messages until we only have WARNING and ERROR messages left. Everything will be discarded after that until we have room again for more.
Also added a test that limits the queue sizes and logs many messages to see the queues hitting their maximums and discarding the appropriate messages.
Fixes: #1882
Author: Aqeel Abbas Date: 2026-07-12
The STRBETWEEN function documentation example was missing a closing brace in the SendDTMF call. Corrected the syntax to ensure the dialplan example is functional.
Author: Mehrdad Seifzadeh Date: 2026-06-10
When an inbound REGISTER is matched to an endpoint using an identification method such as IP, header, or request URI, the endpoint can be identified and authenticated successfully while registrar AOR resolution still fails.
find_registrar_aor() only resolved AOR names for username and auth_username identify methods. A header-only endpoint therefore left aor_name unset and failed registration with "AOR '' not found" even when the REGISTER To URI matched one of the endpoint's configured AORs.
Resolve the REGISTER AOR from the To URI for endpoint identification methods that do not directly provide an AOR name, while still constraining the match to the already-identified endpoint's configured AOR list.
Fixes: #1398
Author: Thomas Guebels Date: 2026-07-09
Two error paths in res_http_websocket could leak an ast_websocket session by failing to drop a reference after the session had been allocated.
The first occurs when session ID generation fails. While this is largely theoretical, as it would require an out-of-memory condition, the session reference should still be released correctly.
The second occurs when the ast_websocket_pre_callback session_attempted callback returns an error. This path is reachable through ari_websockets, which implements this callback and can legitimately fail under certain conditions.
Fixes: #2020
Author: George Joseph Date: 2026-07-02
Bundled pjproject uses ./third-party/pjproject/patches/config_site.h to set many pjproject build options like PJ_IOQUEUE_MAX_HANDLES, PJSIP_MAX_URL_SIZE, etc. Editing that file however, causes the git tree to become dirty which is inconvenient. So...
Updated the Asterisk configure scripts to pass the PJPROJECT_CFLAGS variable down to the pjproject configure scripts. See the UserNote below for details.
Updated ./third-party/pjproject/patches/config_site.h to allow the following options to be overridden: PJ_MAX_HOSTNAME, PJSIP_MAX_URL_SIZE, PJ_IOQUEUE_MAX_HANDLES. Other options in config_site.h are not overridable because they can have a bad effect on the overall operation of pjproject. This may be revisited in the future. Options not already set in config_site.h can still be set.
Fixed an issue where if the Linux epoll facility is used (which it is by
default) the default PJ_IOQUEUE_MAX_HANDLES and PJSIP_MAX_TRANSPORTS were
being left at 1024 instead of being icnreased to 5000.
The pjproject show buildopts CLI command previously only showed options from
the top level PJ pjproject layer but now also shows many from the PJSIP
layer. Many of these, such as PJSIP_MAX_TRANSPORTS, can be set using
PJPROJECT_CFLAGS provided they're not already unconditionally set in
config_site.h.
The pjsip dump endpt CLI command previously required that the pjproject
log level be already set to at least 3 or no output would be produced. The
command now does that automatically then sets it back to whatever it was.
This isn't strictly related to this PR but was just nagging me.
UserNote: Bundled pjproject: It's now possible to override some of the pjproject
build options contained in ./third-party/pjproject/patches/config_site.h by
adding PJPROJECT_CFLAGS to your Asterisk ./configure command line. For example:
./configure ... PJPROJECT_CFLAGS='-DPJ_OPT1=8192 -DPJ_OPT2=512'
Any option in config_site.h that's wrapped in a #ifndef block can be overridden
and many of the PJSIP options displayed by pjproject show buildopts can be
set. WARNING: Adjusting these options without understanding their effect can
cripple your Asterisk instances. You shouldn't adjust them unless you need
to solve a specific issue.
Resolves: #2011
Author: Joshua C. Colp Date: 2026-06-20
This is a module which is only built when TEST_FRAMEWORK is enabled and provides CLI commands for testing performance of certain things on the system they are invoked on. The first CLI commands added cover the most common container usage: storage of objects with a lookup based on a string key. These commands take various arguments and allow you to see how they perform. There is also an "all" command named "performance test container_key_lookup_all" that will execute all of these container tests and pass through the given arguments, which makes it easy to run all of the tests for given usage.
To facilitate a vector bsearch test a new AST_VECTOR_BSEARCH macro has been added that allows more efficient searching of sorted vectors.
Author: Joshua C. Colp Date: 2026-05-15
This change moves manager away from a shared linked list for events to a per-session vector of pending events. This allows early filtering of events which eliminates the need to wake up threads for events that they have no interest in.
TCP based connections have also been moved to an alert pipe based wakeup mechanism to reduce locking and simplify usage.
UserNote: The "manager show eventq" CLI command has been removed as there is no longer a single event queue to display.
Author: George Joseph Date: 2026-06-29
When the 20ms channel timer fires but there are no frames available in the queue, we now check for leftover data in the buffer and if there is any, we create a frame with it and send it to the core. This resolves an issue with the leftover data being delayed if a STOP_MEDIA_BUFFERING command is delayed. Some existing comments were also clarified to account for the new behavior.
Resolves: #2006
Author: Mehrdad Seifzadeh Date: 2026-06-06
When a confirmed session is being terminated while an outgoing in-dialog INVITE transaction is still outstanding, the BYE is delayed until the outstanding transaction terminates.
If that INVITE has already received a provisional response and the final response is malformed and rejected before transaction processing, the transaction can remain outstanding and the delayed BYE can keep the session, media state, RTP instance, and PJPROJECT pools referenced after the channels are gone.
When a BYE is delayed behind an outstanding UAC INVITE, set a PJPROJECT transaction timeout on that INVITE so the delayed cleanup path has a bounded wait. If PJPROJECT terminates the dialog as a result of the timeout, discard the delayed BYE instead of sending a duplicate BYE.
Fixes: #1965
Author: Alexandre Fournier Date: 2026-06-23
ast_format_cap_append_from_cap() and ast_format_cap_replace_from_cap() dereference 'src' (src->preference_order) without checking it for NULL.
A dummy channel allocated with ast_dummy_channel_alloc() never sets a native-format capability, so ast_channel_nativeformats() returns NULL on such channels. When CHANNEL(audionativeformat) / CHANNEL(videonativeformat) is evaluated against a dummy channel (e.g. via ARI channelvars during a Stasis VarSet event raised while app_voicemail builds the notification email on a dummy channel), func_channel_read() passes that NULL straight into ast_format_cap_append_from_cap(), causing a NULL dereference at offset 0x28 and a SIGSEGV.
Guard both helpers against a NULL source. A NULL source simply means "no formats to copy", so appending/replacing nothing is the correct no-op behaviour. This also protects all other callers.
Fixes https://github.com/asterisk/asterisk/issues/1992
AI disclosure: this was generated using Claude Opus 4.8, tested to fix the issue. Not sure if it is the right way to do it.
values setting to avoid parse errorAuthor: Sean Bright Date: 2026-06-23
Fixes the following after a make samples:
config.c:2281 process_text_line: parse error: No category context for line 64 of ...
Author: Mike Bradeen Date: 2026-06-10
The native sampling of duplex recording is set to match the raw 8K output format. If one or more of the streams being recorded is above 8K, the frame size coming into the mixmonitor is too large and needs to be translated to 8K before being mixed into the stereo frame to avoid garbled and mistimed audio
Fixes: #1779
Author: George Joseph Date: 2026-06-09
The websocket client proxy and server handshakes use ast_iostream_gets which are blocking calls. If the outgoing connection succeeds at the TCP or TLS layer but the proxy (if configured) or the websocket server fails to respond to the CONNECT or GET requests, the process can hang indefinitely and escalate to a deadlock. To address this, the handshakes are now guarded with calls to ast_iostream_set_timeout_sequence() with the timeout set to the client's (connection_timeout * 2) milliseconds.
In order to use ast_iostream_set_timeout_sequence(), the iostream has to be set to non-blocking with ast_iostream_nonblock() but there was no way to reset the stream back to blocking mode so a new API ast_iostream_blocking() was added for it.
Tracing was also enabled in the websocket_client_handshake function for future troubleshooting.
Resolves: #1979
Author: Joshua C. Colp Date: 2026-02-10
Extension state to this point has been an API implemented inside the PBX core resulting in its state being intermingled with that of the dialplan. This increased the complexity of the PBX core and made it difficult to enact improvements.
This change adds a new separate extension state API which receives updates from the PBX core as configuration changes but maintains its own separate state. The API is also written to fully take advantage of modern APIs in a more selective manner by subscribing each extension state to only the devices it is interested in, ultimately reducing resource consumption during updates. Presence state updates being infrequently done use a single shared subscription that goes through the extension states to find and update ones that the update is applicable to.
Legacy API support is provided by reimplementing the API as wrappers over the new extension state API. This improves the legacy API by making it multithreaded, with each callback being individually subscribed.
Autohints support is maintained but has been separated out into a self contained new implementation.
Synchronous subscription support has also been added to Stasis to remove the overhead of asynchronous publishing when the handling of published messages is small and fast.
Author: Alexis Chenard Date: 2026-06-01
Adds a new transport option 'external_signaling_hostname' which allows a hostname or FQDN to be used in SIP Contact and Via headers instead of the automatically determined IP address. This is useful when a remote SIP endpoint requires a fully qualified domain name in these headers.
The option is mutually exclusive with 'external_signaling_address' and an error is raised at transport load time if both are set simultaneously.
Resolves: #1749
UserNote: A new pjsip.conf transport option 'external_signaling_hostname' has been added. When set, this value will be used in SIP Contact and Via headers instead of the automatically determined IP address. This option is mutually exclusive with 'external_signaling_address'.
Author: George Joseph Date: 2026-05-12
See the notes below for high-level descriptions of the new features.
Outbound/forward HTTP proxies are now supported and configurable in websocket_client.conf. You can specify a host:port plus optional proxy_username and proxy_password. Because WebSockets aren't consistently supported among proxies (specifically passing through UPGRADEs), the CONNECT method is always used to establish a TCP tunnel through the proxy. This is required if a TLS session is to be established with the WebSocket server anyway. It's important to understand that that negotiation with the proxy is ALWAYS unsecured. Once the proxy establishes the tunnel, the TLS session will be negotiated directly with the remote WebSocket server via the tunnel.
Both TCP-level and WebSocket PING/PONG keepalives can be configured and are available with either the curl or tcptls client implementations. The TCP keepalives are handled entirely by the operating system and require no resources from Asterisk but by their very nature, they can't traverse proxies. WebSocket PING/PONGs are implemented in the Asterisk websocket code and require a scheduler thread to keep track of them so they're a bit more complicated but they do traverse proxies. Which one is used is completely up to the admin. You could use both.
A few changes were needed to res/ari/ari_websockets and res/res_aeap/transport_websocket to add explicit calls to ast_websocket_close. They had been assuming that the websocket session destructor would close the websocket when it unreffed it but the keepalive process now holds a reference so the destructor wouldn't actually run without the call to ast_websocket_close to stop the keepalives.
A few new methods were added to tcptls.c to allow switching an existing connection from unsecured to TLS. These were required because the initial connection and handshake with a proxy is always unsecured but then needs to be switched to TLS if required for the remote WebSocket server.
There was a bug in sorcery.h where the ast_sorcery_register_uint macro was referencing _stringify (which doesn't exist) instead of _sorcery_stringify.
Resolves: #1881 Resolves: #1933
UserNote: Forward/outbound proxies can now be specified for outbound websockets. See the websocket_client.conf.sample file for configuration information.
UserNote: TCP-level or WebSocket PING/PONG keepalives can now be enabled on outbound websockets. They can help detect network failures even when a persistent connection is idle. See the websocket_client.conf.sample file for configuration information.
DeveloperNote: The addition of the proxy and keepalive configuration parameters pushed the websocket client parameter count over 32. This necessitated changing the size of the ast_ws_client_fields enum from a 32 bit bitfield to a 64-bit bitfield with a corresponding change to the ast_websocket_client structure.
Author: Naveen Albert Date: 2026-04-01
chan_local no longer exists since Local channels are built into the core (core_local), but there are still comments which reference it, including in the configs. Update these to avoid confusion.
Resolves: #1849