res_pjsip_pubsub: Fix persistent subscriptions not surviving graceful shutdown
authorGeorge Joseph <george.joseph@fairview5.com>
Thu, 8 Jan 2015 21:41:02 +0000 (21:41 +0000)
committerGeorge Joseph <george.joseph@fairview5.com>
Thu, 8 Jan 2015 21:41:02 +0000 (21:41 +0000)
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/
........

Merged revisions 430397 from http://svn.asterisk.org/svn/asterisk/branches/13

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@430398 65c4cc65-6c06-0410-ace0-fbb531ad65f3

res/res_pjsip_pubsub.c

index 490f694..23f04bb 100644 (file)
@@ -2060,6 +2060,12 @@ static int send_notify(struct sip_subscription_tree *sub_tree, unsigned int forc
        pjsip_evsub *evsub = sub_tree->evsub;
        pjsip_tx_data *tdata;
 
+       if (ast_shutting_down()
+               && sub_tree->root->subscription_state == PJSIP_EVSUB_STATE_TERMINATED
+               && sub_tree->persistence) {
+               return 0;
+       }
+
        if (pjsip_evsub_notify(evsub, sub_tree->root->subscription_state,
                                NULL, NULL, &tdata) != PJ_SUCCESS) {
                return -1;