Commit Graph

84 Commits

Author SHA1 Message Date
Richard Mudgett
30af92e78d res_pjsip: Add ignore_uri_user_options option.
This implements the chan_sip legacy_useroption_parsing option but with a
better name.

* Made the caller-id number and redirecting number strings obtained from
incoming SIP URI user fields always truncated at the first semicolon.
People don't care about anything after the semicolon showing up on their
displays even though the RFC allows the semicolon.

ASTERISK-26316 #close
Reported by: Kevin Harwell

Change-Id: Ib42b0e940dd34d84c7b14bc2e90d1ba392624f62
2016-09-09 17:09:54 -05:00
Alexei Gradinari
5997ec7c9e res_pjsip_pubsub: fixed a bug when pjsip_tx_data_dec_ref is called twice.
This patch removed call of pjsip_tx_data_dec_ref in send_notify
if send_request failed.
The pjsip_dlg_send_request deletes the message on error by itself.

It seems this patch fixes next issues:
ASTERISK-26199
ASTERISK-26166
ASTERISK-26174

Change-Id: I8b05917c93d993f95d604c042ace5f1a5500f59a
2016-07-21 11:21:05 -04:00
Matt Jordan
9dd0aeeb44 res/res_pjsip_pubsub: Add additional debug statements
When something very sad and wrong occurs, it's challenging sometimes to
figure out why. This patch adds some additional debug statements on
off-nominal paths to try and make debugging easier.

Change-Id: I7bffb73cc733b6f80193a23340881db4a102b640
2016-07-06 07:22:47 -05:00
George Joseph
6a568bcc66 res_pjsip_pubsub: Address SEGV when attempting to terminate a subscription
Occasionally under load we'll attempt to send a final NOTIFY on a
subscription that's already been terminated and a SEGV will occur
down in pjproject's evsub_destroy function.  This is a result of a
race condition between all the paths that can generate a notify
and/or destroy the underlying pjproject evsub object:

 * The client can send a SUBSCRIBE with Expires: 0.
 * The client can send a SUBSCRIBE/refresh.
 * The subscription timer can expire.
 * An extension state can change.
 * An MWI event can be generated.
 * The pjproject transaction timer (timer_b) can expire.

Normally when our pubsub_on_evsub_state is called with a terminate,
we push a task to the serializer and return at which point the dialog
is unlocked.  This is usually not a problem because the task runs
immediately and locks the dialog again.  When the system is heavily
loaded though, there may be a delay between the unlock and relock
during which another event may occur such as the subscription timer
or timer_b expiring, an extension state change, etc.  These may also
cause a terminate to be processed and if so, we could cause pjproject
to try to destroy the evsub structure twice.  There's no way for us to
tell that the evsub was already destroyed and the evsub's group lock
can't tolerate this and SEGVs.

The remedy is twofold.

 * A patch has been submitted to Teluu and added to the bundled
   pjproject which adds add/decrement operations on evsub's group lock.

 * In res_pjsip_pubsub:
   * configure.ac and pjproject-bundled's configure.m4 were updated
     to check for the new evsub group lock APIs.
   * We now add a reference to the evsub group lock when we create
     the subscription and remove the reference when we clean up the
     subscription.  This prevents evsub from being destroyed before
     we're done with it.
   * A state has been added to the subscription tree structure so
     termination progress can be tracked through the asyncronous tasks.
   * The pubsub_on_evsub_state callback has been split so it's not doing
     double duty.  It now only handles the final cleanup of the
     subscription tree.  pubsub_on_rx_refresh now handles both client
     refreshes and client terminates.  It was always being called for
     both anyway.
   * The serialized_on_server_timeout task was removed since
     serialized_pubsub_on_rx_refresh was almost identical.
   * Missing state checks and ao2_cleanups were added.
   * Some debug levels were adjusted to make seeing only off-nominal
     things at level 1 and nominal or progress things at level 2+.

ASTERISK-26099 #close
Reported-by: Ross Beer.

Change-Id: I779d11802cf672a51392e62a74a1216596075ba1
2016-06-21 12:47:36 -06:00
Richard Mudgett
ceb1007ed7 res_pjsip_pubsub.c: Recreate subscriptions using distributor serializer.
* Resolves potential reentrancy problems if system restarted in the middle
of subscription message transactions.

* Fixes memory leak recreating persistent subscriptions when the
subscription resource tree could not be created.

ASTERISK-26088
Reported by:  Richard Mudgett

Change-Id: I71e34d7ae8ed35a694f1030e820e2548c48697be
2016-06-07 13:16:19 -05:00
Richard Mudgett
27bafc3a8b res_pjsip_pubsub.c: Use distributor serializer for incoming subscriptions.
We must continue using the serializer that the original SUBSCRIBE came in
on for the dialog.  There may be retransmissions already enqueued in the
original serializer that can result in reentrancy and message sequencing
problems.  The "sip_transaction Unable to register SUBSCRIBE transaction
(key exists)" message is a notable symptom of this issue.

Outgoing subscriptions still create the pjsip/pubsub/<endpoint>
serializers for their dialogs.

ASTERISK-26088
Reported by:  Richard Mudgett

Change-Id: I18b00bb74a56747b2c8c29543a82440b110bf0b0
2016-06-07 13:16:19 -05:00
zuul
3e5666eadc Merge "res_pjsip_pubsub.c: Fix body generator registration race." into 13 2016-04-29 13:06:27 -05:00
Richard Mudgett
5dc0e082b2 res_pjsip_pubsub.c: Add useful information to some messages.
Change-Id: Ia0b2e15773894c599e5c5748bbc70e99f434192a
2016-04-28 17:06:01 -05:00
Richard Mudgett
f9e416f053 res_pjsip_pubsub.c: Fix body generator registration race.
Change-Id: Id8752073ef06472a2fd96080f4009fac42843e67
2016-04-28 17:03:07 -05:00
George Joseph
d8f0bc3572 res_pjsip_mwi: Add voicemail extension and mwi_subscribe_replaces_unsolicited
res_pjsip_mwi was missing the chan_sip "vmexten" functionality which adds
the Message-Account header to the MWI NOTIFY.  Also, specifying mailboxes
on endpoints for unsolicited mwi and on aors for subscriptions required
that the admin know in advance which the client wanted.  If you specified
mailboxes on the endpoint, subscriptions were rejected even if you also
specified mailboxes on the aor.

Voicemail extension:
* Added a global default_voicemail_extension which defaults to "".
* Added voicemail_extension to both endpoint and aor.
* Added ast_sip_subscription_get_dialog for support.
* Added ast_sip_subscription_get_sip_uri for support.

When an unsolicited NOTIFY is constructed, the From header is parsed, the
voicemail extension from the endpoint is substituted for the user, and the
result placed in the Message-Account field in the body.

When a subscribed NOTIFY is constructed, the subscription dialog local uri
is parsed, the voicemail_extension from the aor (looked up from the
subscription resource name) is substituted for the user, and the result
placed in the Message-Account field in the body.

If no voicemail extension was defined, the Message-Account field is not added
to the NOTIFY body.

mwi_subscribe_replaces_unsolicited:
* Added mwi_subscribe_replaces_unsolicited to endpoint.

The previous behavior was to reject a subscribe if a previous internal
subscription for unsolicited MWI was found for the mailbox.  That remains the
default.  However, if there are mailboxes also set on the aor and the client
subscribes and mwi_subscribe_replaces_unsolicited is set, the existing internal
subscription is removed and replaced with the external subscription.  This
allows an admin to configure mailboxes on both the endpoint and aor and allows
the client to select which to use.

ASTERISK-25865 #close
Reported-by: Ross Beer

Change-Id: Ic15a9415091760539c7134a5ba3dc4a6a1217cea
2016-03-30 12:17:29 -06:00
George Joseph
530cff5f5f res_pjsip: Strip spaces from items parsed from comma-separated lists
Configurations like "aors = a, b, c" were either ignoring everything after "a"
or trying to look up " b".  Same for mailboxes,  ciphers, contacts and a few
others.

To fix, all the strsep(&copy, ",") calls have been wrapped in ast_strip.  To
facilitate this, ast_strip, ast_skip_blanks and ast_skip_nonblanks were
updated to handle null pointers.

In some cases, an ast_strlen_zero() test was added to skip consecutive commas.

There was also an attempt to ast_free an ast_strdupa'd string in
ast_sip_for_each_aor which was causing a SEGV.  I removed it.

Although this issue was reported for realtime, the issue was in the res_pjsip
modules so all config mechanisms were affected.

ASTERISK-25829 #close
Reported-by: Mateusz Kowalski

Change-Id: I0b22a2cf22a7c1c50d4ecacbfa540155bec0e7a2
2016-03-07 12:15:58 -07:00
George Joseph
d2a1457e0b res_pjsip/config_transport: Allow reloading transports.
The 'reload' mechanism actually involves closing the underlying
socket and calling the appropriate udp, tcp or tls start functions
again.  Only outbound_registration, pubsub and session needed work
to reset the transport before sending requests to insure that the
pjsip transport didn't get pulled out from under them.

In my testing, no calls were dropped when a transport was changed
for any of the 3 transport types even if ip addresses or ports were
changed. To be on the safe side however, a new transport option was
added (allow_reload) which defaults to 'no'.  Unless it's explicitly
set to 'yes' for a transport, changes to that transport will be ignored
on a reload of res_pjsip.  This should preserve the current behavior.

Change-Id: I5e759850e25958117d4c02f62ceb7244d7ec9edf
2016-02-19 17:56:27 -07:00
Joshua Colp
1c4f2a920d res_pjsip_pubsub: Move where the subscription is stored to after initialized.
A problem arose when testing the AMI subscription listing actions where it
was possible for a subscription that had not been fully initialized to be
listed. This was problematic as the underlying listing code would crash.

This change makes it so the subscription tree is fully set up before it is
added to the list of subscriptions. This ensures that when the listing actions
get the subscription it is valid.

ASTERISK-25738 #close

Change-Id: Iace2b13641c31bbcc0d43a39f99aba1f340c0f48
2016-02-15 14:52:22 -04:00
Mark Michelson
8261bda1bf res_pjsip_pubsub: Prevent crash from AMI command on freed subscription.
A test recently uncovered that running an ill-timed AMI command to show
inbound subscriptions could cause a crash since Asterisk will try to
operate on a freed subscription.

The fix for this is to remove the subscription tree from the list of
subscriptions at the time that we are sending our final NOTIFY request
out. This way, as the subscription is in the process of dying, it is
inaccessible from AMI.

Change-Id: Ic0239003d8d73e04c47c12dd2a7e23867e5b5b23
2016-01-25 16:51:25 -06:00
Richard Mudgett
cf8e7a580b res_pjsip: Create human friendly serializer names.
PJSIP name formats:
pjsip/aor/<aor>-<seq> -- registrar thread pool serializer
pjsip/default-<seq> -- default thread pool serializer
pjsip/messaging -- messaging thread pool serializer
pjsip/outreg/<registration>-<seq> -- outbound registration thread pool
serializer
pjsip/pubsub/<endpoint>-<seq> -- pubsub thread pool serializer
pjsip/refer/<endpoint>-<seq> -- REFER thread pool serializer
pjsip/session/<endpoint>-<seq> -- session thread pool serializer
pjsip/websocket-<seq> -- websocket thread pool serializer

Change-Id: Iff9df8da3ddae1132cb2ef65f64df0c465c5e084
2016-01-08 22:08:35 -06:00
Joshua Colp
9a021a42ad res_pjsip_pubsub: Fix assertion when UAS dialog creation fails.
When compiled with assertions enabled one will occur when destroying
the subscription tree when UAS dialog creation fails. This is because
the code assumes that a dialog will always exist on a subscription
tree when in reality during this specific scenario it won't.

This change makes it so a dialog is not removed from the subscription
tree if it is not present.

ASTERISK-25505 #close

Change-Id: Id5c182b055aacc5e66c80546c64804ce19218dee
2015-10-29 10:28:33 -03:00
Mark Michelson
3b19efefef res_pjsip_pubsub: Prevent sending NOTIFY on destroyed dialog.
A certain situation can result in our attempting to send a NOTIFY on a
destroyed dialog. Say we attempt to send a NOTIFY to a subscriber, but
that subscriber has dropped off the network. We end up retransmitting
that NOTIFY until the appropriate SIP timer says to destroy the NOTIFY
transaction. When the pjsip evsub code is told that the transaction has
been terminated, it responds in kind by alerting us that the
subscription has been terminated, destroying the subscription, and then
removing its reference to the dialog, thus destroying the dialog.

The problem is that when we get told that the subscription is being
terminated, we detect that we have not sent a terminating NOTIFY
request, so we queue up such a NOTIFY to be sent out. By the time that
queued NOTIFY gets sent, the dialog has been destroyed, so attempting to
send that NOTIFY can result in a crash.

The fix being introduced here is actually a reintroduction of something
the pubsub code used to employ. We hold a reference to the dialog and
wait to decrement our reference to the dialog until our subscription
tree object is destroyed. This way, we can send messages on the dialog
even if the PJSIP evsub code wants to terminate earlier than we would
like.

In doing this, some NULL checks for subscription tree dialogs have been
removed since NULL dialogs are no longer actually possible.

Change-Id: I013f43cddd9408bb2a31b77f5db87a7972bfe1e5
2015-10-22 16:16:57 -05:00
Mark Michelson
0a346f095f res_pjsip_pubsub: Ensure dialog lock balance.
When sending a NOTIFY, we lock the dialog and then unlock the dialog
when finished. A recent change made it so that the subscription tree's
dialog pointer will be set NULL when sending the final NOTIFY request
out. This means that when we attempt to unlock the dialog, we pass a
NULL pointer to pjsip_dlg_dec_lock(). The result is that the dialog
remains locked after we think we have unlocked it. When a response to
the NOTIFY arrives, the monitor thread attempts to lock the dialog, but
it cannot because we never released the dialog lock. This results in
Asterisk being unable to process incoming SIP traffic any longer.

The fix in this patch is to use a local pointer to save off the pointer
value of the subscription tree's dialog when locking and unlocking the
dialog. This way, if the subscription tree's dialog pointer is NULLed
out, the local pointer will still have point to the proper place and the
dialog lock will be unlocked as we expect.

Change-Id: I7ddb3eaed7276cceb9a65daca701c3d5e728e63a
2015-10-22 16:16:56 -05:00
Mark Michelson
ad39508095 res_pjsip_pubsub: Prevent crashes on final NOTIFY.
The SIP dialog is removed from the subscription tree when the final
NOTIFY is sent. However, after the final NOTIFY is sent, the persistence
update function still attempts to access the cseq from the dialog,
resulting in a crash.

This fix removes the subscription persistence at the same time that the
dialog is removed from the subscription tree. This way, there is no
attempt to update persistence when the subscription is being destroyed.

Change-Id: Ibb46977a6cef9c51dc95f40f43446e3d11eed5bb
2015-10-22 16:16:56 -05:00
Mark Michelson
067f408760 res_pjsip_pubsub: Remove serializer when sending final NOTIFY.
There have been crashes seen where a taskprocessor's listener is NULL
unexpectedly.

Looking at backtraces, the problem was specifically seen in PJSIP
serializers.

Subscriptions make the mistake of removing a serializer from a dialog
during subscription tree destruction. Since subscription trees are
reference-counted, guaranteeing the circumstances behind the destruction
are not possible. This makes it so that the dialog serializer can be
removed while not holding the dialog lock. This makes it possible for
the distributor to get a pointer to the dialog serializer and have that
serializer get freed out from under it.

The fix for this is to remove the serializer from a subscription dialog
when sending the final NOTIFY. This guarantees that the serializer is
removed with the dialog lock held. By doing this, we guarantee that if
the distributor gains access to the dialog's serializer, it will not be
possible for the serializer to get freed by another thread.

Change-Id: I21f5dac33529f65cec45679bdace60670800ff66
2015-10-22 16:16:29 -05:00
Mark Michelson
1bcc592765 res_pjsip_pubsub: Fix crash on destruction of empty subscription tree.
If an old persistent subscription is recreated but then immediately
destroyed because it is out of date, the subscription tree will have no
leaf subscriptions on it. This was resulting in a crash when attempting
to destroy the subscription tree.

A simple NULL check fixes this problem.

Change-Id: I85570b9e2bcc7260a3fe0ad85904b2a9bf36d2ac
2015-10-22 15:07:41 -05:00
Mark Michelson
b3cc2bd7df res_pjsip_pubsub: Solidify lifetime and ownership of objects.
There have been crashes and general instability seen in the pubsub code,
so this patch introduces three changes to increase the stability.

First, the ownership model for subscriptions has been modified. Due to
RLS, subscriptions are stored in memory as a tree structure. Prior to my
patch, the PJSIP subscription was the owner of the subscription tree.
When the PJSIP subscription told us that it was terminating, we started
destroying the subscription tree along with all of the individual leaf
subscriptions that belong to the tree. The problem with this model is
that the two actors in play here, the PJSIP subscription and the
individual leaf subscriptions, need to have joint ownership of the
subscription tree. So now, the PJSIP subscription and the individual
leaf subscriptions each have a reference to the subscription tree. This
way, we will not actually free memory until no players are left that
care. The PJSIP subscription is a bigger stakeholder, in that if the
PJSIP subscription's reference to the subscription tree is removed, the
subscription tree instructs the leaf subscriptions to shut down and drop
their references to the subscription tree when possible. The individual
leaf subscriptions, upon being told to shut down, can drop their stasis
subscriptions or whatever they use to learn of new state, and then drop
their reference to the subscription tree once they are ready to die.

Second, the lifetime of a PJSIP subscription's reference to our
subscription tree has been altered. As I learned from doing a deep dive,
the PJSIP evsub code can tell Asterisk multiple times that the
subscription has been terminated, and not all of these times
are especially helpful. I have altered the message flow that we use for
SIP subscriptions such that we will always drop the PJSIP subscription's
reference to the subscription tree when we send the NOTIFY that
terminates a SIP subscription. This also means that we will now queue
NOTIFY requests to be sent after responding to incoming SUBSCRIBEs so
that we can have predictable state changes from the PJSIP evsub code.

Third, the synchronization of operations has been improved. PJSIP can
call into our code from a serializer thread (e.g. upon receiving an
incoming request) or from the monitor thread (e.g. when a subscription
times out). Because of this, there is the possibility of competing
threads stepping on each other. PJSIP attempts to do some
synchronization on its own by always keeping the dialog lock held when
it calls into us. However, since we end up pushing tasks into the
serializer, the result was that serialized operations were not grabbing
the dialog lock and could, as a result, step on something that was being
attempted by a different thread. Now we ensure that serialized
operations grab the dialog lock, then check for extenuating
circumstances, then proceed with their operation if they can.

Change-Id: Iff2990c40178dad9cc5f6a5c7f76932ec644b2e5
2015-10-22 15:07:41 -05:00
Mark Michelson
fe5077b1f8 res_pjsip_pubsub: Eliminate race during initial NOTIFY.
There is a slim chance of a race condition occurring where two threads
can both attempt to manipulate the same area.

Thread A can be handling an incoming initial SUBSCRIBE request. Thread A
lets the specific subscription handler know that the subscription has
been established.

At this point, Thread B may detect a state change on the subscribed
resource and queue up a notification task on Thread C, the subscription
serializer thread.

Now Thread A attempts to generate the initial NOTIFY request to send to
the subscriber at the same time that Thread C attempts to generate a
state change NOTIFY request to send to the subscriber.

The result is that Threads A and C can step on the same memory area,
resulting in a crash. The crash has been observed as happening when
attempting to allocate more space to hold the body for the NOTIFY.

The solution presented here is to queue the subscription establishment
and initial NOTIFY generation onto the subscription serializer thread
(Thread C in the above scenario). This way, there is no way that a state
change notification can occur before the initial NOTIFY is sent, and if
there is a quick succession of NOTIFYs, we can guarantee that the two
NOTIFY requests will be sent in succession.

Change-Id: I5a89a77b5f2717928c54d6efb9955e5f6f5cf815
2015-09-17 11:03:13 -05:00
Richard Mudgett
e75aff53e6 res_pjsip_pubsub.c: Mark ast_sip_create_subscription() as not used.
Change-Id: I2b8db18eac36c01a5c7eb9467699124e203fd093
2015-09-10 13:13:39 -05:00
Richard Mudgett
4d91d01df1 res_pjsip_pubsub.c: Add some notification comments.
Change-Id: Ie62ff1f4b7adc1a12fa0303f53926af249b25e20
2015-09-10 13:13:38 -05:00
Richard Mudgett
f36a9d1221 res_pjsip_pubsub.c: Set dlg_status code instead of sending SIP response.
We should not try to send a SIP response message because we may be
restoring a persistent subscription where we are not responding to a SIP
request.

Change-Id: Id89167ef90320c5563f37e632db0dda6cb9e7dec
2015-09-10 13:13:38 -05:00
Richard Mudgett
94582f8fab res_pjsip_pubsub.c: Fix off-nominal memory leak.
Fix off-nominal visited vector leak in build_resource_tree().

Change-Id: If0399c7941c9c0b1038bcfb7b9a371760977831c
2015-09-10 13:13:25 -05:00
Richard Mudgett
8b3ed52239 res_pjsip_pubsub.c: Fix one byte buffer overrun error.
ast_sip_pubsub_register_body_generator() did not account for the null
terminator set by sprintf() in the allocated output buffer.

Change-Id: I388688a132e479bca6ad1c19275eae0070969ae2
2015-09-10 13:10:20 -05:00
Richard Mudgett
4329bd1e4c res_pjsip_pubsub.c: Use ast_alloca() instead of alloca().
Change-Id: Ia396096b4fedc2874649ca11137612c3f55e83e3
2015-09-10 13:10:20 -05:00
Richard Mudgett
a456a20ecf res_pjsip_pubsub.c: Add missing error return in load_module().
Change-Id: I15debd0f717f16ee2f78e7f56151c3b3b97b72fc
2015-09-10 13:10:20 -05:00
Mark Michelson
d58c8d73af res_pjsip_pubsub: re-re-fix persistent subscription storage.
A recent change to res_pjsip_pubsub switched to using pjsip_msg_print as
a means of writing an appropriate packet to persistent storage. While
this partially solved the issue, it had its own problems.
pjsip_msg_print will always add a Content-Length header to the message
it prints. Frequent restarts of Asterisk can result in persistent
subscriptions being written with five or more Content-Length headers. In
addition, sometimes some apparent corruption of individual headers could
be seen.

This aims to fix the problem by not running a parsed message through an
interpreter but rather by taking the raw message and saving it. The
logic for what to save is going to be different depending on whether a
SUBSCRIBE was received from the wire or if it was pulled from
persistence. When receiving a packet from the wire, when using a
streaming transport, the rdata->pkt_info.packet may contain multiple SIP
messages or fragments. However, the rdata->msg_info.msg_buf will always
contain the current SIP message to be processed. When pulling from
persistence, though, the rdata->msg_info.msg_buf will be NULL since no
transport actually handled the packet. However, since we know that we
will always ever pull one SIP message from persistence, we are free to
save directly from rdata->pkt_info.packet instead.

ASTERISK-25365 #close
Reported by Mark Michelson

Change-Id: I33153b10d0b4dc8e3801aaaee2f48173b867855b
2015-09-01 09:38:06 -05:00
Joshua Colp
7c4d0c3506 res_pjsip_pubsub: On recreated notify fail deleted sub_tree is referenced
When recreating a subscription it is possible for a freed sub_tree
to be referenced when the initial NOTIFY fails to be created.

Change-Id: I681c215309aad01b21d611c2de47b3b0a6022788
2015-08-24 13:06:09 -03:00
Mark Michelson
e25569ef95 res_pjsip_pubsub: More accurately persist packet.
The pjsip_rx_data structure has a pkt_info.packet field on it that is
the packet that was read from the transport. For datagram transports,
the packet read from the transport will correspond to the SIP message
that arrived. For streamed transports, however, it is possible to read
multiple SIP messages in one packet.

In a recent case, Asterisk crashed on a system where TCP was being used.
This is because at some point, a read from the TCP socket resulted in a
200 OK response as well as an incoming SUBSCRIBE request being stored in
rdata->pkt_info.packet. When the SUBSCRIBE was processed, the
combination 200 OK and SUBSCRIBE was saved in persistent storage. Later,
a restart of Asterisk resulted in the crash because the persistent
subscription recreation code ended up building the 200 OK response
instead of a SUBSCRIBE request, and we attempted to access
request-specific data.

The fix here is to use the pjsip_msg_print() function in order to
persist SUBSCRIBE requests. This way, rather than using the raw socket
data, we use the parsed SIP message that PJSIP has given us. If we
receive multiple SIP messages from a single read, we will be sure only
to save off the relevant SIP message. There also is a safeguard put in
place to make sure that if we do end up reconstructing a SIP response,
it will not cause a crash.

ASTERISK-25306 #close
Reported by Mark Michelson

Change-Id: I4bf16f7b76a2541d10b55de82bcd14c6e542afb2
2015-08-06 13:13:29 -05:00
Richard Mudgett
0422433f47 PJSIP XML, XPIDF: Fix buffer size overwrite memory corruption error.
When res_pjsip body generator modules were generating XML or XPIDF
response bodies, there was a chance that the generated body would be the
exact size of the supplied buffer.  Adding the nul string terminator would
then write beyond the end of the buffer and potentially corrupt memory.

* Fix MALLOC_DEBUG high fence violations caused by adding a nul string
terminator on the end of a buffer for XML or XPIDF response bodies.

* Made calls to pj_xml_print() safer if the XML prolog is requested.  Due
to a bug in pjproject, the return value could be -1 _or_
AST_PJSIP_XML_PROLOG_LEN if the supplied buffer is not large enough.

* Updated the doxygen comment of AST_PJSIP_XML_PROLOG_LEN to describe the
return value of pj_xml_print() when the supplied buffer is not large
enough.

ASTERISK-25168
Reported by: Carl Fortin

Change-Id: Id70e1d373a6a2b2bd9e678b5cbc5e55b308981de
2015-07-06 15:38:15 -05:00
Matt Jordan
51ffed5e61 res/res_pjsip_pubsub: Note that 'dialog' is also a valid event type for RLS
In addition to specifying lists of 'presence' and 'message-summary',
users can also create lists of type 'dialog'. These should be treated in
the same fashion as 'presence'.

Change-Id: I583bb69cd9f88b0b29bf09ddaddeac4e84189f6e
2015-05-22 12:22:39 -05:00
Joshua Colp
d649d682c4 res_pjsip_exten_state: Fix race condition between sending NOTIFY and termination
The res_pjsip_exten_state module currently has a race condition between
processing the extension state callback from the PBX core and processing
the subscription shutdown callback from res_pjsip_pubsub. There is currently
no synchronization between the two. This can present a problem as while
the SIP subscription will remain valid the tree it points to may not.
This is in particular a problem as a task to send a NOTIFY may get queued
which will try to use the tree that may no longer be valid.

This change does the following to fix this problem:

1. All access to the subscription tree is done within the task that
sends the NOTIFY to ensure that no other thread is modifying or
destroying the tree. This task executes on the serializer for the
subscriptions.

2. A reference to the subscription serializer is kept to ensure it
remains valid for the lifetime of the extension state subscription.

3. The NOTIFY task has been changed so it will no longer attempt
to send a NOTIFY if the subscription has already been terminated.

ASTERISK-25057 #close
Reported by: Matt Jordan

Change-Id: I0b3cd2fac5be8d9b3dc5e693aaa79846eeaf5643
2015-05-07 09:32:58 -03:00
Mark Michelson
3327560cb2 res_pjsip_pubsub: Set the endpoint on SUBSCRIBE dialogs.
When SUBSCRIBE dialogs were established, we never associated
the endpoint that created the subscription with the dialog
we end up creating. In most cases, this ended up not causing
any problems.

The actual bug that was observed was that when a device that
was behind NAT established a subscription with Asterisk, Asterisk
would end up sending in-dialog NOTIFY requests to the device's
private IP addres instead of the public address of the NAT router.

When Asterisk receives the initial SUBSCRIBE from the device,
res_pjsip_nat rewrites the contact to the public address on which the
SUBSCRIBE was received. This allows for the dialog to have its target
address set to the proper public address. Asterisk then would send a 200
OK response to the SUBSCRIBE, then a NOTIFY with the initial
subscription state. The device would then send a 200 OK response to
Asterisk's NOTIFY.

Here's where things went wrong. When the 200 OK arrived, res_pjsip_nat
did not rewrite the address in the Contact header. Then, when the PJSIP
dialog layer processed the 200 OK, PJSIP would perform a comparison
between the IP address in the Contact header and its saved target
address for the dialog. Since they differed, PJSIP would update the
target dialog address to be the address in the Contact header. From this
point, if Asterisk needed to send a NOTIFY to the device, the result was
that the NOTIFY would be sent to the private address that the device
placed in the Contact header.

The reason why res_pjsip_nat did not rewrite the address when it
received the 200 OK response was that it could not associate the
incoming response with a configured endpoint. This is because on a
response, the only way to associate the response to an endpoint is by
finding the dialog that the response is associated with and then finding
the endpoint that is associated with that dialog. We do not perform
endpoint lookups on responses. res_pjsip_pubsub skipped the step of
associating the endpoint with the dialog we created, so res_pjsip_nat
could not find the associated endpoint and therefore couldn't rewrite
the contact.

This commit message is like 50x longer than the actual fix.

ASTERISK 24981 #close
Reported by Mark Michelson

Change-Id: I2b963c58c063bae293e038406f7d044a8a5377cd
2015-04-21 05:01:43 -05:00
Scott Griepentrog
8d4ce7cc2b res_pjsip_pubsub: On notify fail deleted sub_tree is then referenced
This change makes the send_notify of the sub_tree
not happen when the sub_tree has been deleted due
to the notify call failing, which avoids a crash.

ASTERISK-24970 #close

Change-Id: I1f20ffc08b192f59c457293b218025a693992cbf
2015-04-16 13:52:24 -05:00
Corey Farrell
d0df545a44 res_pjsip: Enable unload of all modules at shutdown.
* Move most of res_pjsip:module_unload to unload_pjsip to resolve crashes
  caused by running PJSIP functions from non-PJSIP threads.
* Remove call to pjsip_endpt_destroy(ast_pjsip_endpoint), it was causing
  crashes in some cases.  In theory pj_shutdown() should take care of this.
* Mark res_pjsip_keepalive and res_pjsip_session as allowed to unload at
  shutdown.
* Resolve leaked config global in res_pjsip_notify.
* Unregister pubsub pjsip service module.
* Implement cleanup for res_pjsip_session.

ASTERISK-24731 #close
Reported by: Corey Farrell
Review: https://reviewboard.asterisk.org/r/4498/


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@433469 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2015-03-26 17:46:46 +00:00
Richard Mudgett
feddab7944 HTTP: Stop accepting requests on final system shutdown.
There are three CLI commands to stop and restart Asterisk each.

1) core stop/restart now - Hangup all calls and stop or restart Asterisk.
New channels are prevented while the shutdown request is pending.

2) core stop/restart gracefully - Stop or restart Asterisk when there are
no calls remaining in the system.  New channels are prevented while the
shutdown request is pending.

3) core stop/restart when convenient - Stop or restart Asterisk when there
are no calls in the system.  New calls are not prevented while the
shutdown request is pending.

ARI has made stopping/restarting Asterisk more problematic.  While a
shutdown request is pending it is desirable to continue to process ARI
HTTP requests for current calls.  To handle the current calls while a
shutdown request is pending, a new committed to shutdown phase is needed
so ARI applications can deal with the calls until the system is fully
committed to shutdown.

* Added a new shutdown committed phase so ARI applications can deal with
calls until the final committed to shutdown phase is reached.

* Made refuse new HTTP requests when the system has reached the final
system shutdown phase.  Starting anything while the system is actively
releasing resources and unloading modules is not a good thing.

* Split the bridging framework shutdown to not cleanup the global bridging
containers when shutting down in a hurry.  This is similar to how other
modules prevent crashes on rapid system shutdown.

* Moved ast_begin_shutdown(), ast_cancel_shutdown(), and
ast_shutting_down().  You should not have to include channel.h just to
access these system functions.

ASTERISK-24752 #close
Reported by: Matthew Jordan

Review: https://reviewboard.asterisk.org/r/4399/


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@431692 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2015-02-11 17:28:13 +00:00
Kevin Harwell
630eea087d Investigate and fix memory leaks in Asterisk
Fixed memory leaks that were found in Asterisk.

ASTERISK-24693 #close
Reported by:  Kevin Harwell
Review: https://reviewboard.asterisk.org/r/4347/


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@430999 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2015-01-23 15:12:41 +00:00
Richard Mudgett
4b363688d4 AMI: Make AMI actions that generate event lists consistent.
* Made the following AMI actions use list API calls for consistency:
Agents
BridgeInfo
BridgeList
BridgeTechnologyList
ConfbridgeLIst
ConfbridgeLIstRooms
CoreShowChannels
DAHDIShowChannels
DBGet
DeviceStateList
ExtensionStateList
FAXSessions
Hangup
IAXpeerlist
IAXpeers
IAXregistry
MeetmeList
MeetmeListRooms
MWIGet
ParkedCalls
Parkinglots
PJSIPShowEndpoint
PJSIPShowEndpoints
PJSIPShowRegistrationsInbound
PJSIPShowRegistrationsOutbound
PJSIPShowResourceLists
PJSIPShowSubscriptionsInbound
PJSIPShowSubscriptionsOutbound
PresenceStateList
PRIShowSpans
QueueStatus
QueueSummary
ShowDialPlan
SIPpeers
SIPpeerstatus
SIPshowregistry
SKINNYdevices
SKINNYlines
Status
VoicemailUsersList

* Incremented the AMI version to 2.7.0.

* Changed astman_send_listack() to not use the listflag parameter and
always set the value to "Start" so the start capitalization is consistent.
i.e., The FAXSessions used "Start" while the rest of the system used
"start".  The corresponding complete event always used "Complete".

* Fixed ami_show_resource_lists() "PJSIPShowResourceLists" to output the
AMI ActionID for all of its list events.

* Fixed off-nominal AMI protocol error in manager_bridge_info(),
manager_parking_status_single_lot(), and
manager_parking_status_all_lots().  Use of astman_send_error() after
responding to the original AMI action request violates the action response
pattern by sending two responses.

* Fixed minor protocol error in action_getconfig() when no requested
categories are found.  Each line needs to be formatted as "Header: text".

* Fixed off-nominal memory leak in manager_build_parked_call_string().

* Eliminated unnecessary use of RAII_VAR() in ami_subscription_detail().

ASTERISK-24049 #close
Reported by: Jonathan Rose

Review: https://reviewboard.asterisk.org/r/4315/


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@430434 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2015-01-09 17:54:49 +00:00
George Joseph
b937438c17 res_pjsip_pubsub: Fix persistent subscriptions not surviving graceful shutdown
If you do a 'core (shutdown|restart) graceful' persistent subscriptions won't 
survive.  If you do a 'core (shutdown|restart) now' or asterisk terminates for 
some reason, they do.  Here's why...

When asterisk shuts down gracefully, it sends a 'NOTIFY/terminated' to 
subscribers for each subscription.  This not only tells the subscribers that the 
dialog/state machine is done, it also frees the last reference to the 
subscription tree which causes the persistent subscription to get deleted from 
astdb.  When asterisk restarts, nothing's left.  Just preventing the delete from 
astdb doesn't work because we already told the subscriber to terminate the 
dialog so we can't restart it even if it was still in astdb.  Everything works 
OK if asterisk terminates unexpectedly because we never send the 'terminated' 
message so on restart, the subscription is still in astdb and the subscriber is 
none the wiser.

This patch suppresses the sending of 'NOTIFY/terminated' on shutdown for 
persistent connections.

Tested-by: George Joseph

Review: https://reviewboard.asterisk.org/r/4318/





git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@430397 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2015-01-08 21:40:29 +00:00
Mark Michelson
b85f79c0c1 Activate persistent subscriptions when they are recreated.
Prior to this change, recreating persistent subscriptions would
create the subscription but would not activate it. This led to subscriptions
being listed in the "NULL" state by diagnostics and not sending NOTIFYs
when expected.

Review: https://reviewboard.asterisk.org/r/4261



git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@429571 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-12-15 15:36:57 +00:00
Matthew Jordan
d79c68d3fb main/stasis: Allow subscriptions to use a threadpool for message delivery
Prior to this patch, all Stasis subscriptions would receive a dedicated
thread for servicing published messages. In contrast, prior to r400178
(see review https://reviewboard.asterisk.org/r/2881/), the subscriptions
shared a thread pool. It was discovered during some initial work on Stasis
that, for a low subscription count with high message throughput, the
threadpool was not as performant as simply having a dedicated thread per
subscriber.

For situations where a subscriber receives a substantial number of messages
and is always present, the model of having a dedicated thread per subscriber
makes sense. While we still have plenty of subscriptions that would follow
this model, e.g., AMI, CDRs, CEL, etc., there are plenty that also fall into
the following two categories:
* Large number of subscriptions, specifically those tied to endpoints/peers.
* Low number of messages. Some subscriptions exist specifically to coordinate
  a single message - the subscription is created, a message is published, the
  delivery is synchronized, and the subscription is destroyed.
In both of the latter two cases, creating a dedicated thread is wasteful (and
in the case of a large number of peers/endpoints, harmful). In those cases,
having shared delivery threads is far more performant.

This patch adds the ability of a subscriber to Stasis to choose whether or not
their messages are dispatched on a dedicated thread or on a threadpool. The
threadpool is configurable through stasis.conf.

Review: https://reviewboard.asterisk.org/r/4193

ASTERISK-24533 #close
Reported by: xrobau
Tested by: xrobau
........

Merged revisions 428681 from http://svn.asterisk.org/svn/asterisk/branches/12


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@428687 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-12-01 17:57:12 +00:00
Mark Michelson
77c57f2b1a Fix race condition where duplicated requests may be handled by multiple threads.
This is the Asterisk 13 version of the patch. The main difference is in the pubsub
code since it was completely refactored between Asterisk 12 and 13.

Review: https://reviewboard.asterisk.org/r/4175



git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@427841 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-11-14 14:24:02 +00:00
Kinsey Moore
289830cdc6 PJSIP: Enforce module load dependencies
This enforces that res_pjsip, res_pjsip_session, and res_pjsip_pubsub
have loaded properly before attempting to load any modules that depend
on them since the module loader system is not currently capable of
resolving module dependencies on its own.

ASTERISK-24312 #close
Reported by: Dafi Ni
Review: https://reviewboard.asterisk.org/r/4062/
........

Merged revisions 425690 from http://svn.asterisk.org/svn/asterisk/branches/12


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@425691 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-10-16 14:35:00 +00:00
Matthew Jordan
9f5c73586c res/res_pjsip_pubsub: Fix typo in WARNING message
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@424713 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-10-07 14:09:19 +00:00
Matthew Jordan
f36b64f58e res/res_pjsip_pubsub: Gracefully handle errors when re-creating subscriptions
A subscription that has been persisted can - for various reasons - fail to be
re-created on startup. This patch resolves a number of crashes that occurred
when a subscription cannot be re-created on several off-nominal paths.

#SIPit31

ASTERISK-24368 #close
Reported by: Matt Jordan


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@424601 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-10-06 00:06:45 +00:00
Richard Mudgett
2a7c5208ee Simplify UUID generation in several places.
Replace code using ast_uuid_generate() with simpler and faster code using
ast_uuid_generate_str().  The new code avoids a malloc(), free(), and
copy.
........

Merged revisions 424103 from http://svn.asterisk.org/svn/asterisk/branches/12


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@424105 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-09-29 21:17:26 +00:00