Commit Graph

34410 Commits

Author SHA1 Message Date
Mike Bradeen fbaabcaaa2 manager: Use remote address in user error logging
To avoid a potential null dereference use the remote address
in error logging when there is no user or the user acl fails.

Resolves: #GHSA-3rhj-hhw7-m6fw
2026-06-25 08:21:35 -06:00
Mike Bradeen 70b0abcd03 ooh323: Prevent potential buffer overflow in trace logging
Replace a call to vsprintf with a call to ast_vasprintf to
prevent a possible buffer overflow.

Resolves: #GHSA-x348-j6c9-77f3
2026-06-25 08:21:35 -06:00
Pengpeng Hou 9724288770 app_sms: Bound protocol 1 SMS unpacking to fixed-size buffers
The protocol 1 unpack helpers trusted externally controlled lengths and wrote
 them directly into fixed-size buffers in sms_t. Clamp the address, header,
 and body copies to the destination array sizes so malformed messages cannot
 overwrite adjacent state.

Resolves: #GHSA-q9fr-m7g8-6ph5
2026-06-25 08:21:35 -06:00
Milan Kyselica 8bcf6b79f8 res_xmpp: Fix stack buffer overflow in namespace prefix handling
The snprintf size parameter in xmpp_action_hook() is computed from
the attacker-controlled namespace prefix length and is not bounded
by the 256-byte stack buffer size. When a remote XMPP peer sends a
stanza with a child element whose namespace prefix exceeds 249
characters, snprintf writes past the buffer boundary.

Use sizeof(attr) as the snprintf size limit and %.*s precision to
extract only the prefix portion of the element name, preserving
the original truncation behavior for valid inputs.

Resolves: #GHSA-mxgm-8c6f-5p8f
2026-06-25 08:21:35 -06:00
Milan Kyselica 2121ff8ef6 res_pjsip_pubsub: Add width limit to sscanf in MWI NOTIFY parser
The parse_simple_message_summary() function uses sscanf with an
unbounded %s format specifier to parse the Message-Account field
from incoming SIP NOTIFY bodies into a fixed-size 512-byte stack
buffer (PJSIP_MAX_URL_SIZE). A single unauthenticated SIP NOTIFY
with a Message-Account value exceeding 512 bytes overflows the
buffer, corrupting adjacent stack data and permanently disabling
the PJSIP transport layer without crashing the process.

Add a width specifier (%511s) to limit the sscanf write to
PJSIP_MAX_URL_SIZE - 1 bytes plus the NUL terminator, matching
the destination buffer size.

Resolves: #GHSA-589g-qgf8-m6mx
2026-06-25 08:21:35 -06:00
Milan Kyselica 56deaaa063 res_config_ldap: Escape LDAP filter values per RFC 4515
The LDAP realtime driver constructs search filters by directly
concatenating user-supplied values without RFC 4515 escaping.
When LDAP is used as a realtime backend for endpoint
identification, characters with special meaning in LDAP filters
(*, (, ), \) can be injected via the SIP From header username.

Add ldap_filter_escape_value() that escapes RFC 4515 special
characters to their \HH hex representation, and apply it to
non-LIKE query values. The LIKE query path preserves the existing
wildcard conversion behavior with a note for maintainers.

Resolves: #GHSA-r6c2-hwc2-j4mp
2026-06-25 08:21:35 -06:00
Milan Kyselica 8f51e97808 cel_pgsql, cel_tds: Escape eventtype field to prevent SQL injection
The eventtype column handler in cel_pgsql.c inserts
record.user_defined_name directly into the SQL query without
calling PQescapeStringConn(), while all other string fields in
the same function are properly escaped. Similarly, cel_tds.c
passes the raw user_defined_name into the SQL INSERT without
routing it through anti_injection(), while all other fields are
processed through that function.

For cel_pgsql.c, escape the eventtype value using
PQescapeStringConn(), matching the existing pattern used for all
other string fields at lines 308-331 of the same function.

For cel_tds.c, route the eventtype value through
anti_injection() consistent with how all other fields are handled
in the same function.

Resolves: #GHSA-ph27-3m5q-mj5m
2026-06-25 08:21:35 -06:00
Milan Kyselica 98f50c235e http: Escape error page text to prevent reflected XSS
The text parameter in ast_http_create_response() is inserted into
the HTML body without escaping, while the server name on the same
page is properly escaped via ast_xml_escape(). When res_phoneprov
passes the decoded request URI as the text of a 404 response, HTML
metacharacters in the URI are rendered by the browser.

Apply ast_xml_escape() to the text parameter before inserting it
into the HTML template, using the same function already used for
the server name.

Resolves: #GHSA-4pgv-j3mr-3rcp
2026-06-25 08:21:35 -06:00
Milan Kyselica 7a8d4975fe codec_codec2: Only process complete Codec2 frames in decoder
The codec2_samples() function uses floor division (160 * datalen/6)
to compute expected output samples, but the decode loop condition
(x < datalen) iterates with ceiling behavior when datalen is not a
multiple of CODEC2_FRAME_LEN. This mismatch causes the loop to
decode one extra frame beyond what the framework bounds check
budgeted for, leading to an out-of-bounds write on the output buffer.

Change the loop condition to only process complete frames, matching
the floor-division behavior of codec2_samples(). This also prevents
an out-of-bounds read on the input side when fewer than
CODEC2_FRAME_LEN bytes remain.

Resolves: #GHSA-qf8j-jp7h-c5hx
2026-06-25 08:21:35 -06:00
Milan Kyselica 2f38860a5a format_ogg_speex: Add bounds check to prevent heap buffer overflow
The ogg_speex_read() function copies OGG packet data via memcpy()
without validating the packet size against the destination buffer
(BUF_SIZE = 200 bytes). A crafted .spx file with an oversized OGG
audio packet causes a heap buffer overflow that corrupts the
adjacent speex_desc structure containing libogg heap pointers,
leading to a crash (SIGSEGV) on playback.

Add a bounds check for both negative and oversized values before
the memcpy, consistent with how format_ogg_vorbis bounds its reads
via ov_read().

Resolves: #GHSA-8jhw-m2hg-vp3h
2026-06-25 08:21:35 -06:00
Sean Bright 28e7566f88 configs: Comment out values setting to avoid parse error
Fixes the following after a `make samples`:

```
config.c:2281 process_text_line: parse error: No category context for line 64 of ...
```
2026-06-24 14:49:44 +00:00
Mike Bradeen 3bd8695703 app_mixmonitor: Fix duplex recording for non 8K codecs
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
2026-06-16 14:19:02 +00:00
George Joseph 9173b0f526 res_http_websocket: Add timeout to client handshakes.
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
2026-06-16 14:17:41 +00:00
Joshua C. Colp d40369adc3 extension_state: Add new extension state API.
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.
2026-06-11 18:30:55 +00:00
Alexis Chenard 052409f4b6 res_pjsip: Add external_signaling_hostname transport option
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'.
2026-06-09 14:57:20 +00:00
George Joseph d8df207318 WebSocket Enhancements: Proxies and Keepalives for ARI and Media Outbound Websockets.
See the notes below for high-level descriptions of the new features.

* Proxies

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.

* Keepalives

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.

* Other Changes

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.
2026-06-09 14:22:56 +00:00
Naveen Albert 922e31b107 chan_local: Update chan_local references for Local channels.
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
2026-06-05 13:36:44 +00:00
George Joseph e3c0b816ea res_ari: Add res_ari_model as an optional_module.
Under certain timing/load conditions, res_ari_model may not load until after
res_ari on startup or it might unload before res_ari on shutdown. This can
cause a segfault when DEVMODE is enabled and there are persistent outbound
websocket connections because DEVMODE forces validation of outgoing events
against the models.  To prevent this, res_ari_model has been added as an
"optional_module" to res_ari's NODULE_INFO.  This will enforce load/unload
order but not make res_ari dependent on res_ari_model.  However, if
Asterisk is configured with --enable-dev-mode, res_ari will fail to
load if res_ari_model isn't available.

Resolves: #1970
2026-06-04 12:32:55 +00:00
Mike Bradeen 45198e9af0 res ari: Add attachable states to Channels and Bridges
Adds the ability to attach multiple states to both Channels and Bridges in the form
of variables that are included in all events on the associated object.

First, this adds an optional boolean field to channel variables 'report_events'
that causes the variable to automatically be included in all events on that channel.

To allow this, variables can now be either name value pairs (the current format):
`<variable_name>: '<value_string>'`
 - or -
`<variable_name>: {value: '<value_string>', report_events: [true|false]}`

If the old format is used or 'report_events' is not included, it will default to
false and retain current behavior.

Second, this extends both reported and unreported variables to Bridges so they too
may have stateful information.

Resolves: #1910

UserNote: Bridge variables now can be set and retrieved via the following paths:
`/bridges/{bridgeId}/variable`
`/bridges/{bridgeId}/variables`
Both Bridge and Channel variables can now be set with an optional 'report_events'
boolean flag that will cause those variables to be included on all events on that
object. The 'report_events' flag will default to False if not set to maintain
backwards capability.
To allow this, variables can now be either name value pairs (the current format):
`<variable_name>: '<value_string>'`
 - or -
`<variable_name>: {value: '<value_string>', report_events: [true|false]}`
2026-06-03 22:54:43 +00:00
Ben Ford 6888844375 ARI: Added paths to get and set multiple channel variables.
Two new paths exist for ARI to get and set multiple channel variables at
the same time. This is done via GET and POST like the single get and set
variable equivalents. Leading and trailing whitespace will be stripped
from the variable names for both paths. When setting variables, the
values will be read as-is, whitespace included. GET takes in a single
string with comma-separated values, while POST takes in a dictionary of
key value pairs. The code follows the same paths as when setting
multiple variables when originating a channel via ARI.

UserNote: Added new ARI paths for getting and setting multiple channel
variables at a time. For GET, this takes in a single string of
comma-separated variable names, while POST takes in a dictionary of key
value pairs. The behavior is the same as passing in variables when
originating a channel.
2026-06-03 22:54:42 +00:00
Bernd Kuhls ba98ceae97 res_stir_shaken: avoid direct ASN1_STRING accesses
https://github.com/openssl/openssl/issues/29117

Signed-off-by: Bernd Kuhls <bernd@kuhls.net>

Resolves: #1952
2026-06-02 16:15:28 +00:00
Bernd Kuhls 9d608b50c1 tcptls.c: fix build with OpenSSL 4
tcptls.c: In function '__ssl_setup':
tcptls.c:417:52: error: implicit declaration of function 'SSLv3_client_method';
 did you mean 'SSLv23_client_method'? [-Wimplicit-function-declaration]
  417 |                         cfg->ssl_ctx = SSL_CTX_new(SSLv3_client_method());

SSLv3_client_method was removed from OpenSSL 4.0.0:
https://github.com/openssl/openssl/blob/openssl-4.0.0/doc/man7/ossl-removed-api.pod?plain=1#L440

Signed-off-by: Bernd Kuhls <bernd@kuhls.net>

Resolves: #1952
2026-06-02 16:15:27 +00:00
mikhail_grishak b94728ece7 res_calendar: Fix build with libical 4.X
libical 4.0 removed the icaltime_add() function in favor of icaltime_adjust(). Additionally, the callback signature for icalcomponent_foreach_recurrence() was updated to use a const pointer for the icaltime_span argument.

This commit adds conditional compilation using ICAL_MAJOR_VERSION to support both libical 3.X and the new 4.X API, ensuring backward compatibility.

Fixes: #1957
2026-06-01 16:41:04 +00:00
UpBeta 82ca1727c7 app_record: Fix hangup handling during beep playback
When a hangup occurs while app_record is playing the initial beep,
the application does not detect the hangup and continues running
until the maxduration timeout expires.

Replace the manual ast_streamfile() + ast_waitstream() sequence with
ast_stream_and_wait(), which properly detects hangup and returns
non-zero, allowing the application to exit immediately with
RECORD_STATUS set to HANGUP.

Resolves: #1950
2026-06-01 16:40:26 +00:00
smtcbn b4d609a045 odbc: Don't use prepared statements for distinct SQL statements
Avoids unnecessary prepare for simple INSERT statements that cause
issues with ProxySQL (prepared statement counter overflow).

Resolves: #1217
2026-06-01 16:10:25 +00:00
Alexander Bakker 4cd84e4b48 abstract_jb.c: Remove timerfd from channel when disabling jitter buffer
Previously, the lingering timerfd would cause a tight loop if the
channel enters a BridgeWait after the jitter buffer was disabled.

Fixes: #1762
2026-06-01 16:07:53 +00:00
Sean Bright ca7709c2f6 res_pjsip: Don't allow a leading period when wildcard matching
The reference identifier (what the client provides - in this case a
hostname) must start with a domain label, not a `.`.

The current implementation will match `.seanbright.com` against
`*.seanbright.com` which is incorrect.
2026-06-01 15:36:19 +00:00
George Joseph 3f0ddb0f3a Ensure channel locks aren't held while calling ast_set_variables.
If the channel is locked when calling ast_set_variables and any of the
variables contained dialplan functions, there's a possiblilty of a deadlock.
To prevent this, either the explicit locks were removed or the call to
ast_set_variables moved out of the lock scope.  A warning to not hold
channel locks is also added to the documentation for ast_set_variables.

Resolves: #1936
2026-06-01 15:30:10 +00:00
smtcbn be57e60baf app_queue: fix double increment of member->calls with shared_lastcall
Under high concurrency, update_queue() may be invoked multiple times
for the same call, causing member->calls and queue-level counters to
be incremented more than once.

The existing starttime check is not atomic and allows concurrent
execution paths to pass. Treat member->starttime as a single-use token
and consume it via CAS to ensure the call is counted exactly once.

This also prevents incorrect call distribution when using strategies
such as fewestcalls.

Observed as a regression after upgrading to 20.17.

Resolves: #1736
2026-06-01 15:23:18 +00:00
George Joseph 5dca413f9b chan_dahdi: Fix set but not used in mfcr2_show_links_of().
When openr2 is installed mfcr2_show_links_of() is no longer ifdeffed out
which makes gcc-16 complain with 'variable ‘x’ set but not used'.

Resolves: #1947
2026-06-01 14:48:10 +00:00
Sebastian Jennen ef7dc45b77 tests: add tests/test_codec_translations.c
This tests checks [slin -> codec -> slin] and then compares slin in vs out
regarding signal noise ratio and delay.

Near-lossless codecs (ulaw, alaw) are checked with a maximum per-sample
error bound.  Lossy codecs are checked with a per-codec SNR threshold.
Cross-correlation alignment compensates for algorithmic delay in codecs
like speex and opus.

Covered codecs: ulaw, alaw, adpcm, g726, g726aal2, gsm, speex,
speex16, speex32, ilbc, codec2, lpc10, g722, opus.

Resolves: #1812
2026-05-22 16:16:43 +00:00
Sean Bright f1d1332c9b install_prereq: Add a 'minimal' mode for basic build dependencies 2026-05-21 17:35:58 +00:00
George Joseph d077cf14b1 chan_websocket: Handle incoming CONTINUATION frames.
chan_websocket now tells res_http_websocket to accumulate incoming CONTINUATION
frames into 1024 byte TEXT or BINARY frames.

Resolves: #1941
2026-05-21 17:27:39 +00:00
George Joseph a22baf5350 res_rtp_asterisk: Fix incorrect reference in ast_rtp_get_stat().
```
AST_RTP_STAT_SET(AST_RTP_INSTANCE_STAT_LOCAL_STDEVMES, \
AST_RTP_INSTANCE_STAT_COMBINED_MES, stats->local_stdevmes, \
rtp->rtcp->stdev_rxjitter);
```

Should have been

```
AST_RTP_STAT_SET(AST_RTP_INSTANCE_STAT_LOCAL_STDEVMES, \
AST_RTP_INSTANCE_STAT_COMBINED_MES, stats->local_stdevmes, \
rtp->rtcp->stdev_rxmes);
```

Note the last macro parameter name.

Resolves: #1938
2026-05-20 13:15:15 +00:00
Stanislav Abramenkov 81a65a6458 jansson: Upgrade version to jansson 2.15.0
UpgradeNote: jansson has been upgraded to 2.15.0. For more
information visit jansson Github page: https://github.com/akheron/jansson/releases/tag/v2.15.0

Resolves: #1931
2026-05-20 12:09:28 +00:00
George Joseph 1afa20d018 channel.c: Move setting RTP stats from ast_softhangup to ast_ari_channels_hangup.
The original trigger for setting the RTP stats in ast_softhangup() came from
an ARI issue where stats weren't being set in time to be reported on STASIS_END
events. The thought was that setting them in a common place like ast_softhangup()
would ensure the stats were set in possibly other scenarios.  Unfortunately,
setting the RTP stats variables in ast_softhangup() broke ABI as it required
that no channel locks be held which was not the case earlier.

Given that the original issue was ARI, we can move setting the stats to
ast_ari_channels_hangup() in resource_channels just before it calls
ast_softhangup().  This might not catch all cases of the stats not being set,
but it won't break ABI or deadlock either.

Resolves: #1928
2026-05-19 21:12:29 +00:00
George Joseph 3754a93e9c res_rtp_asterisk: Add option to control stun host resolution when TTL = 0
If a hostname is specified for stunaddr in rtp.conf, periodic DNS resolution
is enabled based on the TTL returned in the DNS results.  If the TTL returned
is 0, it means that the next time the IP address is needed, it must be
looked up again.  I.E.  Don't cache.  Historically (and incorrectly) however,
res_rtp_asterisk stopped the periodic resolution and never re-resolved the
hostname again.

Besides what's mentioned in the user notes...
* Additional debugging was added in various STUN/DNS functions.
* The `rtp show settings` CLI command shows more detailed STUN info.
* Some debugging was added to dns_core.c and dns_recurring.c.

UserNote: A new `stunaddr_reresolve_ttl_0` parameter has been added to rtp.conf
that allows control over what happens when a STUN server hostname lookup
returns a TTL of 0.  The values can be set as follows:
- 'no': This is the historical (and current default) behavior of not doing
any further lookups and continuing to use the last successful result until
Asterisk is restarted or rtp.conf is reloaded.
- 'yes': Use the last cached result for the current call but trigger
re-resolution in the background for the benefit of future calls.
If the result of the background lookup is a ttl > 0, periodic resolution
will be restarted otherwise the next call will use the new cached value
and will trigger a background lookup again.

UserNote: A new CLI command `rtp resolve stun hostname` has been added
that will force a resolution of the STUN hostname and (re)start periodic
resolution if the result has a TTL > 0.

Resolves: #1858
2026-05-19 21:11:24 +00:00
Jaco Kroon c522e05fc8 pjsip_configuration: Show actual dtls_verify config.
Rather than merely showing

dtls_verify : Yes/No

in pjsip show endpoint xxx it will now be shown what exactly is being
checked, ie, one of:

dtls_verify : No
dtls_verify : Fingerprint
dtls_verify : Certificate
dtls_verify : Yes

Where Yes implies both Fingerprint and Certificate.

Signed-off-by: Jaco Kroon <jaco@uls.co.za>
2026-05-18 13:04:06 +00:00
Naveen Albert fe149119af app_dial: Properly handle callee hangup while sending digits.
If we are sending digits (either DTMF, MF, or SF) to the called channel
after receiving progress or a wink, and the callee hangs up before we
have finished sending it digits, there are several problems that can ensue:

* If the callee hung up without answering, the calling channel would
  hang up and not continue in the dialplan.
* If the callee *did* answer before hanging up, the answer was never
  passed through to the caller, since this gets "eaten" by the various
  digit streaming functions and is never processed by app_dial.

This is generally an edge case that occurs due to some kind of signaling
failure, but to better handle this:

* Set to_answer to 0 to prevent hangup on the exit path, just like other
  parts of wait_for_answer.
* Better document this usage of to_answer.
* If the channel did answer while it was receiving digits, manually
  answer the calling channel before we abort. The call would not continue
  in the dialplan anyways (either before or after this fix), but technically
  the call was answered, so the CDRs should probably reflect that, and this
  mirrors the behavior of calls which normally do not continue.

Resolves: #1915

UserNote: If a called channel sends progress or wink and the caller begins
sending digits but the callee answers and then hangs up before digit
sending can finish, the call is now answered before being disconnected.
If the callee hangs up without answering, the call now continues in
the dialplan.
2026-05-12 16:31:11 +00:00
Maximilian Fridrich 6ed90d4180 res_pjsip_messaging: Update To URI only if it is a SIP(S) URI
When a message is sent via ARI, the ARI endpoint only provides a To
field which is also used as destination field. This means that the To
field might not necessarily contain a SIP URI but might instead specify
an Asterisk endpoint (in MessageDestinationInfo format). This led to
many warnings even though the message was sent correctly.

The fix is to only call `ast_sip_update_to_uri` if the To field starts
with the sip: or sips: scheme.

Resolves: #1357
2026-05-12 16:27:41 +00:00
Stanislav Abramenkov 08a5097569 Upgrade bundled pjproject to 2.17.
Resolves: #1888

UserNote: Bundled pjproject has been upgraded to 2.17. For more
information about what is included in this release, see the
pjproject Github page: https://github.com/pjsip/pjproject/releases/tag/2.17
2026-05-12 16:26:59 +00:00
Mike Bradeen 7c26efb32a res_stir_shaken: fix memory free crash when Asterisk is built with malloc_debug
crypto_utils uses ast_asprintf to allocate the search string when checking the
certificate subject, but was not using ast_free to free it. This caused a crash
when Asterisk was built with malloc_debug

Resolves: #1921
2026-05-11 15:01:27 +00:00
Joshua C. Colp 191b7a81a5 manager: Eliminate unnecessary code, simplify sessions in stasis callbacks
Due to stasis filtering the stasis callback for AMI type messages is
guaranteed to only receive messages that can be turned into AMI events,
so remove the check done in the callback.

The sessions container usage for the stasis callbacks has also been
simplified by having a reference on the message router subscription
instead of having to acquire the sessions from the global object each
time.
2026-05-11 12:53:07 +00:00
Peter Krall 9565568505 res_stasis/resource_bridges: Split bridge playback control and wrapper cleanup
Modified the bridge playback teardown so the worker thread removes only the
playback control, while the after-bridge callback removes the playback
wrapper once the announcer has actually left the bridge.

This avoids a stale window where a new playback request could create a
replacement announcer before the old announcer had fully exited the holding
bridge.

Also replaced the flexible trailing bridge_id storage in the shared worker
thread data with an optional bridge_id pointer, since recording paths use the
same structure without a bridge id.

Fixes: #1861
2026-05-07 18:55:26 +00:00
Sebastian Denz 9bad7ee2fc res_pjsip_outbound_publish.c: Add more verbose documentation for outbound_proxy usage 2026-05-07 15:40:23 +00:00
George Joseph a55c028c8d channel.c: Don't lock the channel in ast_softhangup while setting rtp instance vars
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
2026-05-06 12:29:34 +00:00
Charles Langlois 307802c5c5 chan_pjsip: Fix deadlock when endpoint set_var uses PJSIP_HEADER
When a PJSIP endpoint is configured with set_var invoking a dialplan
function (e.g. PJSIP_HEADER(add,...)), chan_pjsip_new() calls
pbx_builtin_setvar_helper() while holding the channel lock.
For function-style variables, this dispatches to ast_func_write()
which, in the case of PJSIP_HEADER, calls
ast_sip_push_task_wait_serializer() -- blocking synchronously while
the channel lock is held.

If a concurrent operation (ARI, AMI, rtp_check_timeout) traverses
the channels container via ast_channel_get_by_name(), it acquires
the container lock then tries to lock individual channels in the
iteration callback (by_uniqueid_cb/by_name_cb). When the serializer
thread also needs the container lock, a circular dependency forms:

  channel_lock -> serializer_wait -> container_lock -> channel_lock

This causes a complete Asterisk freeze. In the observed case, 36
threads were blocked on the container lock until res_freeze_check
triggered SIGABRT after its 30-second timeout.

Unlock the channel before iterating endpoint channel_vars so that
dialplan functions can block without holding the channel lock. Re-lock
the channel for ast_channel_stage_snapshot_done() so the batched
snapshot is published under lock and captures the full channel state
including the variables set during the loop.

Fixes: #1872
2026-04-29 19:29:18 +00:00
mattia aee2b7da29 res_pjsip: Add per-endpoint RTP port range configuration
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.
2026-04-28 17:45:52 +00:00
phoneben ec9c0deff6 app_queue: Fix raise_respect_min lost in copy_rules() breaking rN queue rules
app_queue: Fix raise_respect_min not copied in copy_rules() causing rN rules to be ignored.

`copy_rules()` never copied `raise_respect_min` into the per-call rule list, so the flag was always 0 when a timed penaltychange rule fired, making `rN` behave like plain `N` and raising members below `min_penalty` that should have been excluded.

Also fixes `update_qe_rule()` not propagating the flag from `qe->pr` to `qe`, and dropping the `r` prefix when saving back to `QUEUE_RAISE_PENALTY`.

Resolves: #1901
2026-04-28 16:28:17 +00:00
phoneben ed83ec1863 app_voicemail_odbc: fix msgnum race and crash on failed STORE
app_voicemail_odbc: fix msgnum race and crash on failed STORE

Two concurrent callers leaving voicemail to the same mailbox could be
assigned the same msgnum because ast_unlock_path() was called before
STORE(), allowing a second thread to read the same LAST_MSG_INDEX()
before the first INSERT committed. The losing thread got a duplicate
key error, but execution continued into notify_new_message() ->
RETRIEVE() because the STORE() return value was not checked.
RETRIEVE() then fetched the winning thread's DB row, mmap'd its blob
size against the locally truncated file, and crashed with SIGBUS.

Hold the path lock through STORE() and bail out on failure.

Fixes: #1653
2026-04-28 16:26:22 +00:00