diff options
author | George Joseph <george.joseph@fairview5.com> | 2016-04-01 12:30:56 -0600 |
---|---|---|
committer | Joshua Colp <jcolp@digium.com> | 2016-04-11 13:00:14 -0500 |
commit | fe7e48db03de03c232cc5af28e37ce08c5ccd3d8 (patch) | |
tree | 42c7165686c2d8c4e3ae2d39a760855bfef92956 /include/asterisk/res_pjsip.h | |
parent | 736a2c303db533eff296a93a120405d0f2855e27 (diff) |
res_pjsip contact: Lock expiration/addition of contacts
Contact expiration can occur in several places: res_pjsip_registrar,
res_pjsip_registrar_expire, and automatically when anyone calls
ast_sip_location_retrieve_aor_contact. At the same time, res_pjsip_registrar
may also be attempting to renew or add a contact. Since none of this was locked
it was possible for one thread to be renewing a contact and another thread to
expire it immediately because it was working off of stale data. This was the
casue of intermittent registration/inbound/nominal/multiple_contacts test
failures.
Now, the new named lock functionality is used to lock the aor during contact
expire and add operations and res_pjsip_registrar_expire now checks the
expiration with the lock held before deleting the contact.
ASTERISK-25885 #close
Reported-by: Josh Colp
Change-Id: I83d413c46a47796f3ab052ca3b349f21cca47059
Diffstat (limited to 'include/asterisk/res_pjsip.h')
-rw-r--r-- | include/asterisk/res_pjsip.h | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index fbb9bdcbe..3a9d61e4c 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -1004,10 +1004,28 @@ struct ast_sip_contact *ast_sip_location_retrieve_first_aor_contact(const struct * * \retval NULL if no contacts available * \retval non-NULL if contacts available + * + * \warning + * Since this function prunes expired contacts before returning, it holds a named write + * lock on the aor. If you already hold the lock, call ast_sip_location_retrieve_aor_contacts_nolock instead. */ struct ao2_container *ast_sip_location_retrieve_aor_contacts(const struct ast_sip_aor *aor); /*! + * \brief Retrieve all contacts currently available for an AOR without locking the AOR + * \since 13.9.0 + * + * \param aor Pointer to the AOR + * + * \retval NULL if no contacts available + * \retval non-NULL if contacts available + * + * \warning + * This function should only be called if you already hold a named write lock on the aor. + */ +struct ao2_container *ast_sip_location_retrieve_aor_contacts_nolock(const struct ast_sip_aor *aor); + +/*! * \brief Retrieve the first bound contact from a list of AORs * * \param aor_list A comma-separated list of AOR names @@ -1057,12 +1075,37 @@ struct ast_sip_contact *ast_sip_location_retrieve_contact(const char *contact_na * * \retval -1 failure * \retval 0 success + * + * \warning + * This function holds a named write lock on the aor. If you already hold the lock + * you should call ast_sip_location_add_contact_nolock instead. */ int ast_sip_location_add_contact(struct ast_sip_aor *aor, const char *uri, struct timeval expiration_time, const char *path_info, const char *user_agent, struct ast_sip_endpoint *endpoint); /*! + * \brief Add a new contact to an AOR without locking the AOR + * \since 13.9.0 + * + * \param aor Pointer to the AOR + * \param uri Full contact URI + * \param expiration_time Optional expiration time of the contact + * \param path_info Path information + * \param user_agent User-Agent header from REGISTER request + * \param endpoint The endpoint that resulted in the contact being added + * + * \retval -1 failure + * \retval 0 success + * + * \warning + * This function should only be called if you already hold a named write lock on the aor. + */ +int ast_sip_location_add_contact_nolock(struct ast_sip_aor *aor, const char *uri, + struct timeval expiration_time, const char *path_info, const char *user_agent, + struct ast_sip_endpoint *endpoint); + +/*! * \brief Update a contact * * \param contact New contact object with details |