|
|
|
@ -127,6 +127,11 @@
|
|
|
|
|
<configOption name="contact_uri">
|
|
|
|
|
<synopsis>The Contact URI of the dialog for the subscription</synopsis>
|
|
|
|
|
</configOption>
|
|
|
|
|
<configOption name="prune_on_boot">
|
|
|
|
|
<synopsis>If set, indicates that the contact used a reliable transport
|
|
|
|
|
and therefore the subscription must be deleted after an asterisk restart.
|
|
|
|
|
</synopsis>
|
|
|
|
|
</configOption>
|
|
|
|
|
</configObject>
|
|
|
|
|
<configObject name="resource_list">
|
|
|
|
|
<synopsis>Resource list configuration parameters.</synopsis>
|
|
|
|
@ -382,6 +387,8 @@ struct subscription_persistence {
|
|
|
|
|
struct timeval expires;
|
|
|
|
|
/*! Contact URI */
|
|
|
|
|
char contact_uri[PJSIP_MAX_URL_SIZE];
|
|
|
|
|
/*! Prune subscription on restart */
|
|
|
|
|
int prune_on_boot;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
@ -446,6 +453,10 @@ struct sip_subscription_tree {
|
|
|
|
|
* capable of restarting the timer.
|
|
|
|
|
*/
|
|
|
|
|
struct ast_sip_sched_task *expiration_task;
|
|
|
|
|
/*! The transport the subscription was received on.
|
|
|
|
|
* Only used for reliable transports.
|
|
|
|
|
*/
|
|
|
|
|
pjsip_transport *transport;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
@ -549,6 +560,17 @@ static void *publication_resource_alloc(const char *name)
|
|
|
|
|
return ast_sorcery_generic_alloc(sizeof(struct ast_sip_publication_resource), publication_resource_destroy);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void sub_tree_transport_cb(void *data) {
|
|
|
|
|
struct sip_subscription_tree *sub_tree = data;
|
|
|
|
|
|
|
|
|
|
ast_debug(3, "Transport destroyed. Removing subscription '%s->%s' prune on restart: %d\n",
|
|
|
|
|
sub_tree->persistence->endpoint, sub_tree->root->resource,
|
|
|
|
|
sub_tree->persistence->prune_on_boot);
|
|
|
|
|
|
|
|
|
|
sub_tree->state = SIP_SUB_TREE_TERMINATE_IN_PROGRESS;
|
|
|
|
|
pjsip_evsub_terminate(sub_tree->evsub, PJ_TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*! \brief Destructor for subscription persistence */
|
|
|
|
|
static void subscription_persistence_destroy(void *obj)
|
|
|
|
|
{
|
|
|
|
@ -599,8 +621,9 @@ static void subscription_persistence_update(struct sip_subscription_tree *sub_tr
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ast_debug(3, "Updating persistence for '%s->%s'\n", sub_tree->persistence->endpoint,
|
|
|
|
|
sub_tree->root->resource);
|
|
|
|
|
ast_debug(3, "Updating persistence for '%s->%s' prune on restart: %s\n",
|
|
|
|
|
sub_tree->persistence->endpoint, sub_tree->root->resource,
|
|
|
|
|
sub_tree->persistence->prune_on_boot ? "yes" : "no");
|
|
|
|
|
|
|
|
|
|
dlg = sub_tree->dlg;
|
|
|
|
|
sub_tree->persistence->cseq = dlg->local.cseq;
|
|
|
|
@ -614,6 +637,28 @@ static void subscription_persistence_update(struct sip_subscription_tree *sub_tr
|
|
|
|
|
sub_tree->persistence->expires = ast_tvadd(ast_tvnow(), ast_samp2tv(expires, 1));
|
|
|
|
|
|
|
|
|
|
if (contact_hdr) {
|
|
|
|
|
if (contact_hdr) {
|
|
|
|
|
if (type == SUBSCRIPTION_PERSISTENCE_CREATED) {
|
|
|
|
|
sub_tree->persistence->prune_on_boot =
|
|
|
|
|
!ast_sip_will_uri_survive_restart(
|
|
|
|
|
(pjsip_sip_uri *)pjsip_uri_get_uri(contact_hdr->uri),
|
|
|
|
|
sub_tree->endpoint, rdata);
|
|
|
|
|
|
|
|
|
|
if (sub_tree->persistence->prune_on_boot) {
|
|
|
|
|
ast_debug(3, "adding transport monitor on %s for '%s->%s' prune on restart: %d\n",
|
|
|
|
|
rdata->tp_info.transport->obj_name,
|
|
|
|
|
sub_tree->persistence->endpoint, sub_tree->root->resource,
|
|
|
|
|
sub_tree->persistence->prune_on_boot);
|
|
|
|
|
sub_tree->transport = rdata->tp_info.transport;
|
|
|
|
|
ast_sip_transport_monitor_register(rdata->tp_info.transport,
|
|
|
|
|
sub_tree_transport_cb, sub_tree);
|
|
|
|
|
/*
|
|
|
|
|
* FYI: ast_sip_transport_monitor_register holds a reference to the sub_tree
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, contact_hdr->uri,
|
|
|
|
|
sub_tree->persistence->contact_uri, sizeof(sub_tree->persistence->contact_uri));
|
|
|
|
|
} else {
|
|
|
|
@ -656,6 +701,15 @@ static void subscription_persistence_remove(struct sip_subscription_tree *sub_tr
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sub_tree->persistence->prune_on_boot && sub_tree->transport) {
|
|
|
|
|
ast_debug(3, "Unregistering transport monitor on %s '%s->%s'\n",
|
|
|
|
|
sub_tree->transport->obj_name,
|
|
|
|
|
sub_tree->endpoint ? ast_sorcery_object_get_id(sub_tree->endpoint) : "Unknown",
|
|
|
|
|
sub_tree->root ? sub_tree->root->resource : "Unknown");
|
|
|
|
|
ast_sip_transport_monitor_unregister(sub_tree->transport,
|
|
|
|
|
sub_tree_transport_cb, sub_tree, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ast_sorcery_delete(ast_sip_get_sorcery(), sub_tree->persistence);
|
|
|
|
|
ao2_ref(sub_tree->persistence, -1);
|
|
|
|
|
sub_tree->persistence = NULL;
|
|
|
|
@ -1564,6 +1618,14 @@ static int subscription_persistence_recreate(void *obj, void *arg, int flags)
|
|
|
|
|
pjsip_rx_data rdata;
|
|
|
|
|
struct persistence_recreate_data recreate_data;
|
|
|
|
|
|
|
|
|
|
/* If this subscription used a reliable transport it can't be reestablished so remove it */
|
|
|
|
|
if (persistence->prune_on_boot) {
|
|
|
|
|
ast_debug(3, "Deleting subscription marked as 'prune' from persistent store '%s' %s\n",
|
|
|
|
|
persistence->endpoint, persistence->tag);
|
|
|
|
|
ast_sorcery_delete(ast_sip_get_sorcery(), persistence);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If this subscription has already expired remove it */
|
|
|
|
|
if (ast_tvdiff_ms(persistence->expires, ast_tvnow()) <= 0) {
|
|
|
|
|
ast_debug(3, "Expired subscription retrived from persistent store '%s' %s\n",
|
|
|
|
@ -5416,6 +5478,8 @@ static int load_module(void)
|
|
|
|
|
persistence_expires_str2struct, persistence_expires_struct2str, NULL, 0, 0);
|
|
|
|
|
ast_sorcery_object_field_register(sorcery, "subscription_persistence", "contact_uri", "", OPT_CHAR_ARRAY_T, 0,
|
|
|
|
|
CHARFLDSET(struct subscription_persistence, contact_uri));
|
|
|
|
|
ast_sorcery_object_field_register(sorcery, "subscription_persistence", "prune_on_boot", "0", OPT_UINT_T, 0,
|
|
|
|
|
FLDSET(struct subscription_persistence, prune_on_boot));
|
|
|
|
|
|
|
|
|
|
if (apply_list_configuration(sorcery)) {
|
|
|
|
|
ast_sched_context_destroy(sched);
|
|
|
|
@ -5492,6 +5556,8 @@ static int unload_module(void)
|
|
|
|
|
AST_TEST_UNREGISTER(loop);
|
|
|
|
|
AST_TEST_UNREGISTER(bad_event);
|
|
|
|
|
|
|
|
|
|
ast_sip_transport_monitor_unregister_all(sub_tree_transport_cb, NULL, NULL);
|
|
|
|
|
|
|
|
|
|
ast_cli_unregister_multiple(cli_commands, ARRAY_LEN(cli_commands));
|
|
|
|
|
|
|
|
|
|
ast_manager_unregister(AMI_SHOW_SUBSCRIPTIONS_OUTBOUND);
|
|
|
|
|