diff options
author | Joshua Colp <jcolp@digium.com> | 2015-10-21 13:44:17 -0300 |
---|---|---|
committer | Joshua Colp <jcolp@digium.com> | 2015-10-21 12:36:06 -0500 |
commit | 64c172debadfb6c5d6d4e424fdefd8ad86268b3b (patch) | |
tree | 63db46984f1bd15ed59debab07973c9ed0f1f42a /res/res_pjsip/location.c | |
parent | b9bd249a85b7dcb3890fca1df8cf12558f7d82f5 (diff) |
res_pjsip: Move URI validation to use time.
In a realtime based system with a limited number of threadpool threads
it is possible for a deadlock to occur. This happens when permanent
endpoint state is updated, which will cause database queries to be done.
These queries may result in URI validation being done which is done
synchronously using a PJSIP thread. If all PJSIP threads are in use
processing traffic they themselves may be blocked waiting to get the
permanent endpoint container lock when identifying an endpoint.
This change moves URI validation to occur at use time instead of
configuration time. While this comes at a cost of not seeing a problem
until you use it it does solve the underlying deadlock problem.
ASTERISK-25486 #close
Change-Id: I2d7d167af987d23b3e8199e4a68f3359eba4c76a
Diffstat (limited to 'res/res_pjsip/location.c')
-rw-r--r-- | res/res_pjsip/location.c | 32 |
1 files changed, 0 insertions, 32 deletions
diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c index 9625f04ef..331d839a1 100644 --- a/res/res_pjsip/location.c +++ b/res/res_pjsip/location.c @@ -319,32 +319,6 @@ static int expiration_struct2str(const void *obj, const intptr_t *args, char **b return (ast_asprintf(buf, "%ld", contact->expiration_time.tv_sec) < 0) ? -1 : 0; } -/*! \brief Helper function which validates a permanent contact */ -static int permanent_contact_validate(void *data) -{ - const char *value = data; - pj_pool_t *pool; - pj_str_t contact_uri; - static const pj_str_t HCONTACT = { "Contact", 7 }; - pjsip_contact_hdr *contact_hdr; - int rc = 0; - - pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "Permanent Contact Validation", 256, 256); - if (!pool) { - return -1; - } - - pj_strdup2_with_null(pool, &contact_uri, value); - if (!(contact_hdr = pjsip_parse_hdr(pool, &HCONTACT, contact_uri.ptr, contact_uri.slen, NULL)) - || !(PJSIP_URI_SCHEME_IS_SIP(contact_hdr->uri) - || PJSIP_URI_SCHEME_IS_SIPS(contact_hdr->uri))) { - rc = -1; - } - - pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool); - return rc; -} - static int permanent_uri_sort_fn(const void *obj_left, const void *obj_right, int flags) { const struct ast_sip_contact *object_left = obj_left; @@ -393,12 +367,6 @@ static int permanent_uri_handler(const struct aco_option *opt, struct ast_variab struct ast_sip_contact_status *status; char contact_id[strlen(aor_id) + strlen(contact_uri) + 2 + 1]; - if (ast_sip_push_task_synchronous(NULL, permanent_contact_validate, contact_uri)) { - ast_log(LOG_ERROR, "Permanent URI on aor '%s' with contact '%s' failed to parse\n", - ast_sorcery_object_get_id(aor), contact_uri); - return -1; - } - if (!aor->permanent_contacts) { aor->permanent_contacts = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, permanent_uri_sort_fn, NULL); |