Commit Graph

243 Commits

Author SHA1 Message Date
Maximilian Fridrich
a998c0d78a res_pjsip_session: Reset pending_media_state->read_callbacks
In handle_negotiated_sdp the pending_media_state->read_callbacks must be
reset before they are added in the SDP handlers in
handle_negotiated_sdp_session_media. Otherwise, old callbacks for
removed streams and file descriptors could be added to the channel and
Asterisk would poll on non-existing file descriptors.

Resolves: #611
(cherry picked from commit f626af8e13)
2024-05-09 13:47:40 +00:00
George Joseph
c5f1bf2ab0 Stir/Shaken Refactor
Why do we need a refactor?

The original stir/shaken implementation was started over 3 years ago
when little was understood about practical implementation.  The
result was an implementation that wouldn't actually interoperate
with any other stir-shaken implementations.

There were also a number of stir-shaken features and RFC
requirements that were never implemented such as TNAuthList
certificate validation, sending Reason headers in SIP responses
when verification failed but we wished to continue the call, and
the ability to send Media Key(mky) grants in the Identity header
when the call involved DTLS.

Finally, there were some performance concerns around outgoing
calls and selection of the correct certificate and private key.
The configuration was keyed by an arbitrary name which meant that
for every outgoing call, we had to scan the entire list of
configured TNs to find the correct cert to use.  With only a few
TNs configured, this wasn't an issue but if you have a thousand,
it could be.

What's changed?

* Configuration objects have been refactored to be clearer about
  their uses and to fix issues.
    * The "general" object was renamed to "verification" since it
      contains parameters specific to the incoming verification
      process.  It also never handled ca_path and crl_path
      correctly.
    * A new "attestation" object was added that controls the
      outgoing attestation process.  It sets default certificates,
      keys, etc.
    * The "certificate" object was renamed to "tn" and had it's key
      change to telephone number since outgoing call attestation
      needs to look up certificates by telephone number.
    * The "profile" object had more parameters added to it that can
      override default parameters specified in the "attestation"
      and "verification" objects.
    * The "store" object was removed altogther as it was never
      implemented.

* We now use libjwt to create outgoing Identity headers and to
  parse and validate signatures on incoming Identiy headers.  Our
  previous custom implementation was much of the source of the
  interoperability issues.

* General code cleanup and refactor.
    * Moved things to better places.
    * Separated some of the complex functions to smaller ones.
    * Using context objects rather than passing tons of parameters
      in function calls.
    * Removed some complexity and unneeded encapsuation from the
      config objects.

Resolves: #351
Resolves: #46

UserNote: Asterisk's stir-shaken feature has been refactored to
correct interoperability, RFC compliance, and performance issues.
See https://docs.asterisk.org/Deployment/STIR-SHAKEN for more
information.

UpgradeNote: The stir-shaken refactor is a breaking change but since
it's not working now we don't think it matters. The
stir_shaken.conf file has changed significantly which means that
existing ones WILL need to be changed.  The stir_shaken.conf.sample
file in configs/samples/ has quite a bit more information.  This is
also an ABI breaking change since some of the existing objects
needed to be changed or removed, and new ones added.  Additionally,
if res_stir_shaken is enabled in menuselect, you'll need to either
have the development package for libjwt v1.15.3 installed or use
the --with-libjwt-bundled option with ./configure.

(cherry picked from commit 181edcc3a3)
2024-03-07 14:16:38 +00:00
Sean Bright
c9c2c575b8 res_pjsip_session.c: Correctly format SDP connection addresses.
Resolves a regression identified by @justinludwig involving the
rendering of IPv6 addresses in outgoing SDP.

Also updates `media_address` on PJSIP endpoints so that if we are able
to parse the configured value as an IP we store it in a format that we
can directly use later. Based on my reading of the code it appeared
that one could configure `media_address` as:

```
[foo]
type = endpoint
...
media_address = [2001:db8::]
```

And that value would be blindly copied into the outgoing SDP without
regard to its format.

Fixes #541

(cherry picked from commit 72523f19a9)
2024-03-07 14:16:38 +00:00
George Joseph
67f98056da Revert "core & res_pjsip: Improve topology change handling."
This reverts commit 315eb551db.

Over the past year, we've had several reports of "topology storms"
occurring where 2 external facing channels connected by one or more
local channels and bridges will get themselves in a state where
they continually send each other topology change requests.  This
usually manifests itself in no-audio calls and a flood of
"Exceptionally long queue length" messages.  It appears that this
commit is the cause so we're reverting it for now until we can
determine a more appropriate solution.

Resolves: #530
(cherry picked from commit b71e338eea)
2024-01-12 18:21:33 +00:00
Bastian Triller
9b1071f259 res_pjsip_session: Send Session Interval too small response
Handle session interval lower than endpoint's configured minimum timer
when sending first answer. Timer setting is checked during this step and
needs to handled appropriately.
Before this change, no response was sent at all. After this change a
response with 422 Session Interval too small is sent to UAC.

(cherry picked from commit 98665a14b3)
2023-09-06 16:46:46 +00:00
Ben Ford
7fdff94861 res_pjsip_session: Added new function calls to avoid ABI issues.
Added two new functions (ast_sip_session_get_dialog and
ast_sip_session_get_pjsip_inv_state) that retrieve the dialog and the
pjsip_inv_state respectively from the pjsip_inv_session on the
ast_sip_session struct. This is due to pjproject adding a new field to
the pjsip_inv_session struct that caused crashes when trying to access
fields that were no longer where they were expected to be if a module
was compiled against a different version of pjproject.

Resolves: #145
(cherry picked from commit 23c4d21d1b)
2023-07-10 11:49:31 +00:00
Henning Westerholt
ebee6f38f0 chan_pjsip: also return all codecs on empty re-INVITE for late offers
We should also return all codecs on an re-INVITE without SDP for a
call that used late offer (e.g. no SDP in the initial INVITE, SDP
in the ACK). Bugfix for feature introduced in ASTERISK-30193
(https://issues.asterisk.org/jira/browse/ASTERISK-30193)

Migration from previous gerrit change that was not merged.

(cherry picked from commit 8711c84e3c)
2023-05-08 17:55:17 +00:00
Naveen Albert
ec0ca7dcbc res_pjsip_session: Add overlap_context option.
Adds the overlap_context option, which can be used
to explicitly specify a context to use for overlap
dialing extension matches, rather than forcibly
using the context configured for the endpoint.

ASTERISK-30262 #close

Change-Id: Ibbcd4a8b11402428a187fb56b8d4e7408774a0db
2023-01-30 08:45:57 -06:00
Naveen Albert
40ed776c40 res_pjsip_session: Use Caller ID for extension matching.
Currently, there is no Caller ID available to us when
checking for an extension match when handling INVITEs.
As a result, extension patterns that depend on the Caller ID
are not matched and calls may be incorrectly rejected.

The Caller ID is not available because the supplement that
adds Caller ID to the session does not execute until after
this check. Supplement callbacks cannot yet be executed
at this point since the session is not yet in the appropriate
state.

To fix this without impacting existing behavior, the Caller ID
number is now retrieved before attempting to pattern match.
This ensures pattern matching works correctly and there is
no behavior change to the way supplements are called.

ASTERISK-28767 #close

Change-Id: Iec7f5a3b90e51b65ccf74342f96bf80314b7cfc7
2022-12-20 09:55:16 -06:00
Michael Kuron
d73f22268f res_pjsip_aoc: New module for sending advice-of-charge with chan_pjsip
chan_sip supported sending AOC-D and AOC-E information in SIP INFO
messages in an "AOC" header in a format that was originally defined by
Snom. In the meantime, ETSI TS 124 647 introduced an XML-based AOC
format that is supported by devices from multiple vendors, including
Snom phones with firmware >= 8.4.2 (released in 2010).

This commit adds a new res_pjsip_aoc module that inserts AOC information
into outgoing messages or sends SIP INFO messages as described below.
It also fixes a small issue in res_pjsip_session which didn't always
call session supplements on outgoing_response.

* AOC-S in the 180/183/200 responses to an INVITE request
* AOC-S in SIP INFO (if a 200 response has already been sent or if the
  INVITE was sent by Asterisk)
* AOC-D in SIP INFO
* AOC-D in the 200 response to a BYE request (if the client hangs up)
* AOC-D in a BYE request (if Asterisk hangs up)
* AOC-E in the 200 response to a BYE request (if the client hangs up)
* AOC-E in a BYE request (if Asterisk hangs up)

The specification defines one more, AOC-S in an INVITE request, which
is not implemented here because it is not currently possible in
Asterisk to have AOC data ready at this point in call setup. Once
specifying AOC-S via the dialplan or passing it through from another
SIP channel's INVITE is possible, that might be added.

The SIP INFO requests are sent out immediately when the AOC indication
is received. The others are inserted into an appropriate outgoing
message whenever that is ready to be sent. In the latter case, the XML
is stored in a channel variable at the time the AOC indication is
received. Depending on where the AOC indications are coming from (e.g.
PRI or AMI), it may not always be possible to guarantee that the AOC-E
is available in time for the BYE.

Successfully tested AOC-D and both variants of AOC-E with a Snom D735
running firmware 10.1.127.10. It does not appear to properly support
AOC-S however, so that could only be tested by inspecting SIP traces.

ASTERISK-21502 #close
Reported-by: Matt Jordan <mjordan@digium.com>

Change-Id: Iebb7ad0d5f88526bc6629d3a1f9f11665434d333
2022-12-09 07:55:05 -06:00
Naveen Albert
833f2af3da res_pjsip_session.c: Map empty extensions in INVITEs to s.
Some SIP devices use an empty extension for PLAR functionality.

Rather than rejecting these empty extensions, we now use the s
extension for such calls to mirror the existing PLAR functionality
in Asterisk (e.g. chan_dahdi).

ASTERISK-30265 #close

Change-Id: I0861a405cd49bbbf532b52f7b47f0e2810832590
2022-12-09 07:53:46 -06:00
Maximilian Fridrich
37b0727288 core & res_pjsip: Improve topology change handling.
This PR contains two relatively separate changes in channel.c and
res_pjsip_session.c which ensure that topology changes are not ignored
in cases where they should be handled.

For channel.c:

The function ast_channel_request_stream_topology_change only triggers a
stream topology request change indication, if the channel's topology
does not equal the requested topology. However, a channel could be in a
state where it is currently "negotiating" a new topology but hasn't
updated it yet, so the topology request change would be lost. Channels
need to be able to handle such situations internally and stream
topology requests should therefore always be passed on.

In the case of chan_pjsip for example, it queues a session refresh
(re-INVITE) if it is currently in the middle of a transaction or has
pending requests (among other reasons).

Now, ast_channel_request_stream_topology_change always indicates a
stream topology request change even if the requested topology equals the
channel's topology.

For res_pjsip_session.c:

The function resolve_refresh_media_states does not process stream state
changes if the delayed active state differs from the current active
state. I.e. if the currently active stream state has changed between the
time the sip session refresh request was queued and the time it is being
processed, the session refresh is ignored. However, res_pjsip_session
contains logic that ensures that session refreshes are queued and
re-queued correctly if a session refresh is currently not possible. So
this check is not necessary and led to some session refreshes being
lost.

Now, a session refresh is done even if the delayed active state differs
from the current active state and it is checked whether the delayed
pending state differs from the current active - because that means a
refresh is necessary.

Further, the unit test of resolve_refresh_media_states was adapted to
reflect the new behavior. I.e. the changes to delayed pending are
prioritized over the changes to current active because we want to
preserve the original intention of the pending state.

ASTERISK-30184

Change-Id: Icd0703295271089057717006730b555b9a1d4e5a
2022-11-29 16:35:37 -06:00
Henning Westerholt
093593a7c8 res_pjsip: return all codecs on a re-INVITE without SDP
Currently chan_pjsip on receiving a re-INVITE without SDP will only
return the codecs that are previously negotiated and not offering
all enabled codecs.

This causes interoperability issues with different equipment (e.g.
from Cisco) for some of our customers and probably also in other
scenarios involving 3PCC infrastructure.

According to RFC 3261, section 14.2 we SHOULD return all codecs
on a re-INVITE without SDP

The PR proposes a new parameter to configure this behaviour:
all_codecs_on_empty_reinvite. It includes the code, documentation,
alembic migrations, CHANGES file and example configuration additions.

ASTERISK-30193 #close

Change-Id: I69763708d5039d512f391e296ee8a4d43a1e2148
2022-10-27 14:46:16 -05:00
Maximilian Fridrich
675bed5f2c res_pjsip: Add mediasec capabilities.
This patch adds support for mediasec SIP headers and SDP attributes.
These are defined in RFC 3329, 3GPP TS 24.229 and
draft-dawes-sipcore-mediasec-parameter. The new features are
implemented so that a backbone for RFC 3329 is present to streamline
future work on RFC 3329.

With this patch, Asterisk can communicate with Deutsche Telekom trunks
which require these fields.

ASTERISK-30032

Change-Id: Ia7f5b5ba42db18074fdd5428c4e1838728586be2
2022-10-03 08:01:23 -05:00
Maximilian Fridrich
479ce16eba res_pjsip: Add 100rel option "peer_supported".
This patch adds a new option to the 100rel parameter for pjsip
endpoints called "peer_supported". When an endpoint with this option
receives an incoming request and the request indicated support for the
100rel extension, then Asterisk will send 1xx responses reliably. If
the request did not indicate 100rel support, Asterisk sends 1xx
responses normally.

ASTERISK-30158

Change-Id: Id6d95ffa8f00dab118e0b386146e99f254f287ad
2022-09-22 18:39:16 -05:00
Ben Ford
1f685d6969 res_pjsip: Add TEL URI support for basic calls.
This change allows TEL URI requests to come through for basic calls. The
allowed requests are INVITE, ACK, BYE, and CANCEL. The From and To
headers will now allow TEL URIs, as well as the request URI.

Support is only for TEL URIs present in traffic from a remote party.
Asterisk does not generate any TEL URIs on its own.

ASTERISK-26894

Change-Id: If5729e6cd583be7acf666373bf9f1b9d653ec29a
2022-09-13 04:51:41 -05:00
George Joseph
f55886a72c res_pjsip: Make message_filter and session multipart aware
Neither pjsip_message_filter's filter_on_tx_message() nor
res_pjsip_session's session_outgoing_nat_hook() were multipart
aware and just assumed that an SDP would be the only thing in
a message body.  Both were changed to use the new
pjsip_get_sdp_info() function which searches for an sdp in
both single- and multi- part message bodies.

ASTERISK-29813

Change-Id: I8f5b8cfdc27f1d4bd3e7491ea9090951a4525c56
2022-01-17 11:19:54 -06:00
George Joseph
59cf9f0047 res_pjsip: Add utils for checking media types
Added two new functions to assist checking media types...

* ast_sip_are_media_types_equal compares two pjsip_media_types.
* ast_sip_is_media_type_in tests if one media type is in a list
  of others.

Added static definitions for commonly used media types to
res_pjsip.h.

Changed several modules to use the new functions and static
definitions.

ASTERISK_29813
(not ready to close)

Change-Id: Ief77675235bd3bf00a6b095d4673fd878d0801b9
2022-01-17 09:40:23 -06:00
Alexander Traud
178cb0ffe4 res: Fix for Doxygen.
These are the remaining issues found in /res.

ASTERISK-29761

Change-Id: I572e6019c422780dde5ce8448b6c85c77af6046d
2021-12-03 12:12:02 -06:00
Alexander Traud
bae495601a res_pjsip: Fix for Doxygen.
ASTERISK-29747

Change-Id: Ic7a1e9453f805a6264fe86c96b7d18b87b376084
2021-11-18 12:46:12 -06:00
Josh Soref
dcf492e7b6 res: Spelling fixes
Correct typos of the following word families:

identifying
structures
actcount
initializer
attributes
statement
enough
locking
declaration
userevent
provides
unregister
session
execute
searches
verification
suppressed
prepared
passwords
recipients
event
because
brief
unidentified
redundancy
character
the
module
reload
operation
backslashes
accurate
incorrect
collision
initializing
instance
interpreted
buddies
omitted
manually
requires
queries
generator
scheduler
configuration has
owner
resource
performed
masquerade
apparently
routable

ASTERISK-29714

Change-Id: I88485116d2c59b776aa2e1f8b4ce8239a21decda
2021-11-15 15:41:51 -06:00
Ben Ford
2e55c0fded STIR/SHAKEN: Option split and response codes.
The stir_shaken configuration option now has 4 different choices to pick
from: off, attest, verify, and on. Off and on behave the same way they
do now. Attest will only perform attestation on the endpoint, and verify
will only perform verification on the endpoint.

Certain responses are required to be sent based on certain conditions
for STIR/SHAKEN. For example, if we get a Date header that is outside of
the time range that is considered valid, a 403 Stale Date response
should be sent. This and several other responses have been added.

Change-Id: I4ac1ecf652cd0e336006b0ca638dc826b5b1ebf7
2021-10-27 08:45:27 -05:00
Joshua C. Colp
523a795289 AST-2021-007 - res_pjsip_session: Don't offer if no channel exists.
If a re-INVITE is received after we have sent a BYE request then it
is possible for no channel to be present on the session. If this
occurs we allow PJSIP to produce the offer instead. Since the call
is being hung up if it produces an incorrect offer it doesn't
actually matter. This also ensures that code which produces SDP
does not need to handle if a channel is not present.

ASTERISK-29381

Change-Id: I673cb88c432f38f69b2e0851d55cc57a62236042
2021-07-22 13:27:02 -05:00
George Joseph
c78d0ce429 res_pjsip_session: Make reschedule_reinvite check for NULL topologies
When the check for equal topologies was added to reschedule_reinvite()
it was assumed that both the pending and active media states would
actually have non-NULL topologies.  We since discovered this isn't
the case.

We now only test for equal topologies if both media states have
non-NULL topologies.  The logic had to be rearranged a bit to make
sure that we cloned the media states if their topologies were
non-NULL but weren't equal.

ASTERISK-29215

Change-Id: I61313cca7fc571144338aac826091791b87b6e17
2021-03-22 09:40:13 -05:00
Ben Ford
83b0f5963f res_pjsip_session.c: Check topology on re-invite.
Removes an unnecessary check for the conditional that compares the
stream topologies to see if they are equal to suppress re-invites. This
was a problem when a Digium phone received an INVITE that offered codecs
different than what it supported, causing Asterisk to send the
re-invite.

ASTERISK-29303

Change-Id: I04dc91befb2387904e28a9aaeaa3bcdbcaa7fa63
2021-02-25 08:46:33 -06:00
Joshua C. Colp
1af2a84c8b res_pjsip_session: Always produce offer on re-INVITE without SDP.
When PJSIP receives a re-INVITE without an SDP offer the INVITE
session library will first call the on_create_offer callback and
if unavailable then use the active negotiated SDP as the offer.

In some cases this would result in a different SDP then was
previously used without an incremented SDP version number. The two
known cases are:

1. Sending an initial INVITE with a set of codecs and having the
remote side answer with a subset. The active negotiated SDP would
have the pruned list but would not have an incremented SDP version
number.

2. Using re-INVITE for unhold. We would modify the active negotiated
SDP but would not increment the SDP version.

To solve these, and potential other unknown cases, the on_create_offer
callback has now been implemented which produces a fresh offer with
incremented SDP version number. This better fits within the model
provided by the INVITE session library.

ASTERISK-28452

Change-Id: I2d81048d54edcb80fe38fdbb954a86f0a58281a1
2021-02-25 08:42:07 -06:00
Kevin Harwell
fad0cf12e6 AST-2021-002: Remote crash possible when negotiating T.38
When an endpoint requests to re-negotiate for fax and the incoming
re-invite is received prior to Asterisk sending out the 200 OK for
the initial invite the re-invite gets delayed. When Asterisk does
finally send the re-inivite the SDP includes streams for both audio
and T.38.

This happens because when the pending topology and active topologies
differ (pending stream is not in the active) in the delayed scenario
the pending stream is appended to the active topology. However, in
the fax case the pending stream should replace the active.

This patch makes it so when a delay occurs during fax negotiation,
to or from, the audio stream is replaced by the T.38 stream, or vice
versa instead of being appended.

Further when Asterisk sent the re-invite with both audio and T.38,
and the endpoint responded with a declined T.38 stream then Asterisk
would crash when attempting to change the T.38 state.

This patch also puts in a check that ensures the media state has a
valid fax session (associated udptl object) before changing the
T.38 state internally.

ASTERISK-29203 #close

Change-Id: I407f4fa58651255b6a9030d34fd6578cf65ccf09
2021-02-18 10:38:03 -06:00
Robert Cripps
017e09b40a res/res_pjsip_session.c: Check that media type matches in
function ast_sip_session_media_state_add.

Check ast_media_type matches when a ast_sip_session_media is found
otherwise when transitioning from say image to audio, the wrong
session is returned in the first if statement.

ASTERISK-29220 #close

Change-Id: I6f6efa9b821ebe8881bb4c8c957f8802ddcb4b5d
2021-01-18 11:30:26 -06:00
Alexander Traud
3f119192bb res_pjsip_session: Avoid sometimes-uninitialized warning with Clang.
ASTERISK-29248

Change-Id: I2b17bd5ffb246bc64c463402c9831413da78a556
2021-01-18 10:36:30 -06:00
Ivan Poddubnyi
c3fad2fd01 chan_pjsip: Assign SIPDOMAIN after creating a channel
session->channel doesn't exist until chan_pjsip creates it, so intead of
setting a channel variable every new incoming call sets one and the same
global variable.

This patch moves the code to chan_pjsip so that SIPDOMAIN is set on
a newly created channel, it also removes a misleading reference to
channel->session used to fetch call pickup configuraion.

ASTERISK-29240

Change-Id: I90c9bbbed01f5d8863585631a29322ae4e046755
2021-01-13 08:28:30 -06:00
Richard Mudgett
027f4e3a21 res_pjsip_session.c: Fix compiler warnings.
AST_VECTOR_SIZE() returns a size_t.  This is not always equivalent to an
unsigned long on all machines.

Change-Id: I0a4189a104e6e3a2e2273de06620eaef19df9338
2020-12-28 08:26:35 -06:00
Sungtae Kim
d8b7a6f599 res_pjsip_session: Fixed NULL active media topology handle
Added NULL pointer check to prevent Asterisk crash.

ASTERISK-29215

Change-Id: If07e50ea8d78cb610af9195fc13b5dca4bfcef95
2020-12-23 07:45:48 -06:00
Joshua C. Colp
5b4e71fa0a pjsip: Match lifetime of INVITE session to our session.
In some circumstances it was possible for an INVITE
session to be destroyed while we were still using it.
This occurred due to the reference on the INVITE session
being released internally as a result of its state
changing to DISCONNECTED.

This change adds a reference to the INVITE session
which is released when our own session is destroyed,
ensuring that the INVITE session remains valid for
the lifetime of our session.

ASTERISK-29022

Change-Id: I300c6d9005ff0e6efbe1132daefc7e47ca6228c9
2020-12-09 13:06:32 -06:00
Kevin Harwell
6baa4b53be AST-2020-001 - res_pjsip: Return dialog locked and referenced
pjproject returns the dialog locked and with a reference. However,
in Asterisk the method that handles this decrements the reference
and removes the lock prior to returning. This makes it possible,
under some circumstances, for another thread to free said dialog
before the thread that created it attempts to use it again. Of
course when the thread that created it tries to use a freed dialog
a crash can occur.

This patch makes it so Asterisk now returns the newly created
dialog both locked, and with an added reference. This allows the
caller to de-reference, and unlock the dialog when it is safe to
do so.

In the case of a new SIP Invite the lock, and reference are now
held for the entirety of the new invite handling process.
Otherwise it's possible for the dialog, or its dependent objects,
like the transaction, to disappear. For example if there is a TCP
transport error.

ASTERISK-29057 #close

Change-Id: I5ef645a47829596f402cf383dc02c629c618969e
2020-11-05 11:52:28 -06:00
Ben Ford
82325ba58b AST-2020-002 - res_pjsip: Stop sending INVITEs after challenge limit.
If Asterisk sends out and INVITE and receives a challenge with a
different nonce value each time, it will continually send out INVITEs,
even if the call is hung up. The endpoint must be configured for
outbound authentication in order for this to occur. A limit has been set
on outbound INVITEs so that, once reached, Asterisk will stop sending
INVITEs and the transaction will terminate.

ASTERISK-29013

Change-Id: I2d001ca745b00ca8aa12030f2240cd72363b46f7
2020-11-05 10:42:29 -06:00
Kevin Harwell
439f7bb848 res_pjsip, res_pjsip_session: initialize local variables
This patch initializes a couple of local variables to some default values.
Interestingly, in the 'pj_status_t dlg_status' case the value not being
initialized caused memory to grow, and not be recovered, in the off nominal
path (at least on my machine).

Change-Id: I22ee65e1e1bff8efacea8a167c6c8428898523f7
2020-10-28 09:51:08 -05:00
Nick French
f041763e3b res_pjsip_session: Restore calls to ast_sip_message_apply_transport()
Commit 44bb0858cb ("debugging: Add enough
to choke a mule") accidentally removed calls to
ast_sip_message_apply_transport when it was attempting to just add
debugging code.

The kiss of death was saying that there were no functional changes in
the commit comment.

This makes outbound calls that use the 'flow' transport mechanism fail,
since this call is used to relay headers into the outbound INVITE
requests.

ASTERISK-29124 #close

Change-Id: I0f3e32c2e8ac415e30b1d29966d75a1546f0526a
2020-10-28 08:37:32 -05:00
Joshua C. Colp
9eeb40af33 res_pjsip_session: Fix stream name memory leak.
When constructing a stream name based on the media type
and position the allocated name was not being freed
causing a leak.

Change-Id: I52510863b24a2f531f0a55b440bb2c81844029de
2020-09-23 10:58:20 -05:00
Joshua C. Colp
957aff751d res_pjsip_session: Fix session reference leak.
The ast_sip_dialog_get_session function returns the session
with reference count increased. This was not taken into
account and was causing sessions to remain around when they
should not be.

ASTERISK-29089

Change-Id: I430fa721b0a824311a59effec6056e9ec528e3e8
2020-09-23 10:02:30 -05:00
Sean Bright
6f32c254be res_pjsip_session.c: Fix build when TEST_FRAMEWORK is not defined
Change-Id: Id4852c26e9c412af8e37b5dd3c15da9453ad3276
2020-09-16 09:09:23 -05:00
George Joseph
cc71be0078 res_pjsip_session: Fix issue with COLP and 491
The recent 491 changes introduced a check to determine if the active
and pending topologies were equal and to suppress the re-invite if they
were. When a re-invite is sent for a COLP-only change, the pending
topology is NULL so that check doesn't happen and the re-invite is
correctly sent. Of course, sending the re-invite sets the pending
topology.  If a 491 is received, when we resend the re-invite, the
pending topology is set and since we didn't request a change to the
topology in the first place, pending and active topologies are equal so
the topologies-equal check causes the re-invite to be erroneously
suppressed.

This change checks if the topologies are equal before we run the media
state resolver (which recreates the pending topology) so that when we
do the final topologies-equal check we know if this was a topology
change request.  If it wasn't a change request, we don't suppress
the re-invite even though the topologies are equal.

ASTERISK-29014

Change-Id: Iffd7dd0500301156a566119ebde528d1a9573314
2020-09-14 09:40:14 -06:00
George Joseph
ad4f2a8c99 debugging: Add enough to choke a mule
Added to:
 * bridges/bridge_softmix.c
 * channels/chan_pjsip.c
 * include/asterisk/res_pjsip_session.h
 * main/channel.c
 * res/res_pjsip_session.c

There NO functional changes in this commit.

Change-Id: I06af034d1ff3ea1feb56596fd7bd6d7939dfdcc3
2020-09-11 10:41:15 -06:00
George Joseph
d4f3b17dd3 res_pjsip_session: Handle multi-stream re-invites better
When both Asterisk and a UA send re-invites at the same time, both
send 491 "Transaction in progress" responses to each other and back
off a specified amount of time before retrying. When Asterisk
prepares to send its re-invite, it sets up the session's pending
media state with the new topology it wants, then sends the
re-invite.  Unfortunately, when it received the re-invite from the
UA, it partially processed the media in the re-invite and reset
the pending media state before sending the 491 losing the state it
set in its own re-invite.

Asterisk also was not tracking re-invites received while an existing
re-invite was queued resulting in sending stale SDP with missing
or duplicated streams, or no re-invite at all because we erroneously
determined that a re-invite wasn't needed.

There was also an issue in bridge_softmix where we were using a stream
from the wrong topology to determine if a stream was added.  This also
caused us to erroneously determine that a re-invite wasn't needed.

Regardless of how the delayed re-invite was triggered, we need to
reconcile the topology that was active at the time the delayed
request was queued, the pending topology of the queued request,
and the topology currently active on the session.  To do this we
need a topology resolver AND we need to make stream named unique
so we can accurately tell what a stream has been added or removed
and if we can re-use a slot in the topology.

Summary of changes:

 * bridge_softmix:
   * We no longer reset the stream name to "removed" in
     remove_all_original_streams().  That was causing  multiple streams
     to have the same name and wrecked the checks for duplicate streams.

   * softmix_bridge_stream_sources_update() was checking the old_stream
     to see if it had the softmix prefix and not considering the stream
     as "new" if it did.  If the stream in that slot has something in it
     because another re-invite happened, then that slot in old might
     have a softmix stream but the same stream in new might actually
     be a new one.  Now we check the new_stream's name instead of
     the old_stream's.

 * stream:
   * Instead of using plain media type name ("audio", "video", etc) as
     the default stream name, we now append the stream position to it
     to make it unique.  We need to do this so we can distinguish multiple
     streams of the same type from each other.

   * When we set a stream's state to REMOVED, we no longer reset its
     name to "removed" or destroy its metadata.  Again, we need to
     do this so we can distinguish multiple streams of the same
     type from each other.

 * res_pjsip_session:
   * Added resolve_refresh_media_states() that takes in 3 media states
     and creates an up-to-date pending media state that includes the changes
     that might have happened while a delayed session refresh was in the
     delayed queue.

   * Added is_media_state_valid() that checks the consistency of
     a media state and returns a true/false value. A valid state has:
     * The same number of stream entries as media session entries.
         Some media session entries can be NULL however.
     * No duplicate streams.
     * A valid stream for each non-NULL media session.
     * A stream that matches each media session's stream_num
       and media type.

   * Updated handle_incoming_sdp() to set the stream name to include the
     stream position number in the name to make it unique.

   * Updated the ast_sip_session_delayed_request structure to include both
     the pending and active media states and updated the associated delay
     functions to process them.

   * Updated sip_session_refresh() to accept both the pending and active
     media states that were in effect when the request was originally queued
     and to pass them on should the request need to be delayed again.

   * Updated sip_session_refresh() to call resolve_refresh_media_states()
     and substitute its results for the pending state passed in.

   * Updated sip_session_refresh() with additional debugging.

   * Updated session_reinvite_on_rx_request() to simply return PJ_FALSE
     to pjproject if a transaction is in progress.  This stops us from
     creating a partial pending media state that would be invalid later on.

   * Updated reschedule_reinvite() to clone both the current pending and
     active media states and pass them to delay_request() so the resolver
     can tell what the original intention of the re-invite was.

   * Added a large unit test for the resolver.

ASTERISK-29014

Change-Id: Id3440972943c611a15f652c6c569fa0e4536bfcb
2020-09-11 10:41:15 -06:00
Patrick Verzele
5a49757e40 res_pjsip_session: Deferred re-INVITE without SDP send a=sendrecv instead of a=sendonly
Building on ASTERISK-25854. When the device requests hold by sending SDP with attribute recvonly, asterisk places the session in sendonly mode. When the device later requests to resume the call by using a re-INVITE excluding SDP, asterisk needs to change the sendonly mode to sendrecv again.

Change-Id: I60341ce3d87f95869f3bc6dc358bd3e8286477a6
2020-09-03 08:15:14 -05:00
Joshua C. Colp
3c074038fe res_pjsip_session: Don't aggressively terminate on failed re-INVITE.
Per the RFC when an outgoing re-INVITE is done we should
only terminate the dialog if a 481 or 408 is received.

ASTERISK-29033

Change-Id: I6c3ff513aa41005d02de0396ba820083e9b18503
2020-08-25 13:24:29 -05:00
George Joseph
71446b68fc res_pjsip_session: Ensure reused streams have correct bundle group
When a bundled stream is removed, its bundle_group is reset to -1.
If that stream is later reused, the bundle parameters on session
media need to be reset correctly it could mistakenly be rebundled
with a stream that was removed and never reused.  Since the removed
stream has no rtp instance, a crash will result.

Change-Id: Ie2b792220f9291587ab5f9fd123145559dba96d7
2020-07-28 12:12:55 -05:00
George Joseph
e88beedd08 res_pjsip_session: Fix segv in session_on_rx_response
session_on_rx_response wasn't checking for a NULL dialog before
attempting to get the invite session from it.

Change-Id: Id13534375966cc2eb7f2b55717c9813c63c10065
2020-07-09 08:56:50 -06:00
George Joseph
9bd1d686a1 ACN: Add tracing to existing code
Prior to making any modifications to the pjsip infrastructure
for ACN, I've added the tracing functions to the existing code.
This should make the final commit easier to review, but we can also
now run a "before and after" trace.

No functional changes were made with this commit.

Change-Id: Ia83a1a2687ccb96f2bc8a2a3928a5214c4be775c
2020-07-08 09:24:42 -05:00
Kevin Harwell
4eba6b9eb2 PJSIP_MEDIA_OFFER: override configuration on refresh
When using the PSJIP_MEDIA_OFFER dialplan function it was not
overriding an endpoint's configured codecs on refresh unless
they had a shared codec between the two.

This patch makes it so whatever is set using PJSIP_MEDIA_OFFER
is used when creating the SDP for a refresh no matter what.

ASTERISK-28878 #close

Change-Id: I0f7dc86fd0fb607c308e6f98ede303c54d1eacb6
2020-07-06 09:05:41 -05:00
Joshua C. Colp
ee8ea9275f res_pjsip_session: Preserve label on incoming re-INVITE.
When a re-INVITE is received we create a new set of
streams that are then swapped in as the active streams.
We did not preserve the SDP label from the previous
streams, resulting in the label getting lost.

This change ensures that if an SDP label is present
on the previous stream then it is set on the new stream.

ASTERISK-28953

Change-Id: I9dd63b88b562fe96ce5c791a3dae5bcaca258445
2020-06-19 04:42:22 -05:00