diff options
author | George Joseph <gjoseph@digium.com> | 2017-02-07 12:17:12 -0700 |
---|---|---|
committer | George Joseph <gjoseph@digium.com> | 2017-02-15 13:11:46 -0600 |
commit | 4bdf5d329fb10d90d3ba53188834c58f54a5324c (patch) | |
tree | 1fa70b8698d938da159efd69350ff19551ff4988 /third-party/pjproject/patches/0010-evsub-Add-pjsip_evsub_set_uas_timeout.patch | |
parent | 0b5a17082be78be17c5191d86f806936dcdc7d61 (diff) |
res_pjsip_pubsub: Correctly implement persisted subscriptions
This patch fixes 2 original issues and more that those 2 exposed.
* When we send a NOTIFY, and the client either doesn't respond or
responds with a non OK, pjproject only calls our
pubsub_on_evsub_state callback, no others. Since
pubsub_on_evsub_state (which does the sub_tree cleanup) does not
expect to be called back without the other callbacks being called
first, it just returns leaving the sub_tree orphaned. Now
pubsub_on_evsub_state checks the event for PJSIP_EVENT_TSX_STATE
which is what pjproject will set to tell us that it was the
transaction that timed out or failed and not the subscription
itself timing our or being terminated by the client. If is
TSX_STATE, pubsub_on_evsub_state now does the proper cleanup
regardless of the state of the subscription.
* When a client renews a subscription, we don't update the
persisted subscription with the new expires timestamp. This causes
subscription_persistence_recreate to prune the subscription if/when
asterisk restarts. Now, pubsub_on_rx_refresh calls
subscription_persistence_update to apply the new expires timestamp.
This exposed other issues however...
* When creating a dialog from rdata (which sub_persistence_recreate
does from the packet buffer) there must NOT be a tag on the To
header (which there will be when a client refreshes a
subscription). If there is one, pjsip_dlg_create_uas will fail.
To address this, subscription_persistence_update now accepts a flag
that indicates that the original packet buffer must not be updated.
New subscribes don't set the flag and renews do. This makes sure
that when the rdata is recreated on asterisk startup, it's done
from the original subscribe packet which won't have the tag on To.
* When creating a dialog from rdata, we were setting the dialog's
remote (SUBSCRIBE) cseq to be the same as the local (NOTIFY) cseq.
When the client tried to resubscribe after a restart with the
correct cseq, we'd reject the request with an Invalid CSeq error.
* The acts of creating a dialog and evsub by themselves when
recreating a subscription does NOT restart pjproject's subscription
timer. The result was that even if we did correctly recreate the
subscription, we never removed it if the client happened to go away
or send a non-OK response to a NOTIFY. However, there is no
pjproject function exposed to just set the timer on an evsub that
wasn't created by an incoming subscribe request. To address this,
we create our own timer using ast_sip_schedule_task. This timer is
used only for re-establishing subscriptions after a restart.
An earlier approach was to add support for setting pjproject's
timer (via a pjproject patch) and while that patch is still included
here, we don't use that call at the moment.
While addressing these issues, additional debugging was added and
some existing messages made more useful. A few formatting changes
were also made to 'pjsip show scheduled tasks' to make displaying
the subscription timers a little more friendly.
ASTERISK-26696
ASTERISK-26756
Change-Id: I8c605fc1e3923f466a74db087d5ab6f90abce68e
Diffstat (limited to 'third-party/pjproject/patches/0010-evsub-Add-pjsip_evsub_set_uas_timeout.patch')
-rw-r--r-- | third-party/pjproject/patches/0010-evsub-Add-pjsip_evsub_set_uas_timeout.patch | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/third-party/pjproject/patches/0010-evsub-Add-pjsip_evsub_set_uas_timeout.patch b/third-party/pjproject/patches/0010-evsub-Add-pjsip_evsub_set_uas_timeout.patch new file mode 100644 index 000000000..a55aa0013 --- /dev/null +++ b/third-party/pjproject/patches/0010-evsub-Add-pjsip_evsub_set_uas_timeout.patch @@ -0,0 +1,84 @@ +From b7af9e6639f29feb4db6d0866c98e552b025ec96 Mon Sep 17 00:00:00 2001 +From: George Joseph <gjoseph@digium.com> +Date: Mon, 6 Feb 2017 15:39:29 -0700 +Subject: [PATCH] evsub: Add pjsip_evsub_set_uas_timeout. + +A UAS which needs to recreate incoming subscriptions from a persistent +store can call pjsip_dlg_create_uas_and_inc_lock and +pjsip_evsub_create_uas as long as they've persisted the +correct data but since the timer is triggered by an incoming subscribe, +it's never set and the subscription never expires. + +* Add pjsip_evsub_set_uas_timeout which is just a wrapper around + evsub.c:set_timeout(sub, TIMER_TYPE_UAS_TIMEOUT, seconds) + +* Also, fixed copy-paste error in pjsip_sub_state_hdr_print when + printing retry-after parameter. +--- + pjsip/include/pjsip-simple/evsub.h | 14 ++++++++++++++ + pjsip/src/pjsip-simple/evsub.c | 10 ++++++++++ + pjsip/src/pjsip-simple/evsub_msg.c | 2 +- + 3 files changed, 25 insertions(+), 1 deletion(-) + +diff --git a/pjsip/include/pjsip-simple/evsub.h b/pjsip/include/pjsip-simple/evsub.h +index 82e0a7c..45e6411 100644 +--- a/pjsip/include/pjsip-simple/evsub.h ++++ b/pjsip/include/pjsip-simple/evsub.h +@@ -511,6 +511,20 @@ PJ_DEF(pj_status_t) pjsip_evsub_add_ref(pjsip_evsub *sub); + PJ_DEF(pj_status_t) pjsip_evsub_dec_ref(pjsip_evsub *sub); + + ++/** ++ * Sets, resets or cancels the UAS subscription timeout. ++ * ++ * If there is an existing timer, it is cancelled before any ++ * other action. ++ * ++ * A timeout of 0 is ignored except that any existing timer ++ * is cancelled. ++ * ++ * @param sub The server subscription instance. ++ * @param seconds The new timeout. ++ */ ++PJ_DEF(void) pjsip_evsub_set_uas_timeout(pjsip_evsub *sub, pj_int32_t seconds); ++ + + PJ_END_DECL + +diff --git a/pjsip/src/pjsip-simple/evsub.c b/pjsip/src/pjsip-simple/evsub.c +index 3fe4b49..6918a8c 100644 +--- a/pjsip/src/pjsip-simple/evsub.c ++++ b/pjsip/src/pjsip-simple/evsub.c +@@ -530,6 +530,16 @@ static void set_timer( pjsip_evsub *sub, int timer_id, + + + /* ++ * Set event subscription UAS timout. ++ */ ++PJ_DEF(void) pjsip_evsub_set_uas_timeout(pjsip_evsub *sub, pj_int32_t seconds) ++{ ++ PJ_ASSERT_RETURN(sub != NULL, PJ_EINVAL); ++ set_timer(sub, TIMER_TYPE_UAS_TIMEOUT, seconds); ++} ++ ++ ++/* + * Destructor. + */ + static void evsub_on_destroy(void *obj) +diff --git a/pjsip/src/pjsip-simple/evsub_msg.c b/pjsip/src/pjsip-simple/evsub_msg.c +index b44a715..b37db1c 100644 +--- a/pjsip/src/pjsip-simple/evsub_msg.c ++++ b/pjsip/src/pjsip-simple/evsub_msg.c +@@ -179,7 +179,7 @@ static int pjsip_sub_state_hdr_print(pjsip_sub_state_hdr *hdr, + } + if (hdr->retry_after >= 0) { + pj_memcpy(p, ";retry-after=", 13); +- p += 9; ++ p += 13; + printed = pj_utoa(hdr->retry_after, p); + p += printed; + } +-- +2.9.3 + |