res_pjsip_registrar: blocked threads on reliable transport shutdown take 3

When a contact was removed by the registrar it did not always check to see if
the circumstances involved a monitored reliable transport. For instance, if the
'remove_existing' option was set to 'true' then when existing contacts were
removed due to 'max_contacts' being reached, those existing contacts being
removed did not unregister the transport monitor.

Also, it was possible to add more than one monitor on a reliable transport for
a given aor and contact.

This patch makes it so all contact removals done by the registrar also remove
any associated transport monitors if necessary. It also makes it so duplicate
monitors cannot be added for a given transport.

ASTERISK-28213

Change-Id: I94b06f9026ed177d6adfd538317c784a42c1b17a
This commit is contained in:
Kevin Harwell
2019-02-20 11:03:01 -06:00
parent e0fc663295
commit 930a7fe910
3 changed files with 133 additions and 83 deletions

View File

@@ -305,6 +305,12 @@ void ast_sip_transport_monitor_unregister(pjsip_transport *transport,
enum ast_transport_monitor_reg ast_sip_transport_monitor_register(pjsip_transport *transport,
ast_transport_monitor_shutdown_cb cb, void *ao2_data)
{
return ast_sip_transport_monitor_register_replace(transport, cb, ao2_data, NULL);
}
enum ast_transport_monitor_reg ast_sip_transport_monitor_register_replace(pjsip_transport *transport,
ast_transport_monitor_shutdown_cb cb, void *ao2_data, ast_transport_monitor_data_matcher matches)
{
struct ao2_container *transports;
struct transport_monitor *monitored;
@@ -321,6 +327,13 @@ enum ast_transport_monitor_reg ast_sip_transport_monitor_register(pjsip_transpor
monitored = ao2_find(transports, transport->obj_name, OBJ_SEARCH_KEY | OBJ_NOLOCK);
if (monitored) {
struct transport_monitor_notifier new_monitor;
struct callback_data cb_data = {
.cb = cb,
.data = ao2_data,
.matches = matches ?: ptr_matcher,
};
transport_monitor_unregister_cb(monitored, &cb_data, 0);
/* Add new monitor to vector */
new_monitor.cb = cb;