pjsip: Rewrite OPTIONS support with new eyes.

The OPTIONS support in PJSIP has organically grown, like many things in
Asterisk.  It has been tweaked, changed, and adapted based on situations
run into.  Unfortunately this has taken its toll.  Configuration file
based objects have poor performance and even dynamic ones aren't that
great.

This change scraps the existing code and starts fresh with new eyes.  It
leverages all of the APIs made available such as sorcery observers and
serializers to provide a better implementation.

1.  The state of contacts, AORs, and endpoints relevant to the qualify
process is maintained.  This state can be updated by external forces (such
as a device registering/unregistering) and also the reload process.  This
state also includes the association between endpoints and AORs.

2.  AORs are scheduled and not contacts.  This reduces the amount of work
spent juggling scheduled items.

3.  Manipulation of which AORs are being qualified and the endpoint states
all occur within a serializer to reduce the conflict that can occur with
multiple threads attempting to modify things.

4.  Operations regarding an AOR use a serializer specific to that AOR.

5.  AORs and endpoint state act as state compositors.  They take input
from lower level objects (contacts feed AORs, AORs feed endpoint state)
and determine if a sufficient enough change has occurred to be fed further
up the chain.

6.  Realtime is supported by using observers to know when a contact has
been registered.  If state does not exist for the associated AOR then it
is retrieved and becomes active as appropriate.

The end result of all of this is best shown with a configuration file of
3000 endpoints each with an AOR that has a static contact.  In the old
code it would take over a minute to load and use all 8 of my cores.  This
new code takes 2-3 seconds and barely touches the CPU even while dealing
with all of the OPTIONS requests.

ASTERISK-26806

Change-Id: I6a5ebbfca9001dfe933eaeac4d3babd8d2e6f082
This commit is contained in:
Joshua Colp
2017-12-11 18:34:53 +00:00
committed by Richard Mudgett
parent 9c430569d4
commit 882e79b77e
7 changed files with 2442 additions and 1431 deletions

View File

@@ -283,8 +283,6 @@ struct ast_sip_contact {
int prune_on_boot;
};
#define CONTACT_STATUS "contact_status"
/*!
* \brief Status type for a contact.
*/
@@ -307,23 +305,20 @@ enum ast_sip_contact_status_type {
* if available.
*/
struct ast_sip_contact_status {
SORCERY_OBJECT(details);
AST_DECLARE_STRING_FIELDS(
/*! The original contact's URI */
AST_STRING_FIELD(uri);
/*! The name of the aor this contact_status belongs to */
AST_STRING_FIELD(aor);
);
/*! Current status for a contact (default - unavailable) */
enum ast_sip_contact_status_type status;
/*! The round trip start time set before sending a qualify request */
struct timeval rtt_start;
/*! The round trip time in microseconds */
int64_t rtt;
/*! Current status for a contact (default - unavailable) */
enum ast_sip_contact_status_type status;
/*! Last status for a contact (default - unavailable) */
enum ast_sip_contact_status_type last_status;
/*! TRUE if the contact was refreshed. e.g., re-registered */
unsigned int refresh:1;
/*! Name of the contact */
char name[0];
};
/*!
@@ -1061,13 +1056,33 @@ void *ast_sip_endpoint_alloc(const char *name);
/*!
* \brief Change state of a persistent endpoint.
*
* \param endpoint The SIP endpoint name to change state.
* \param endpoint_name The SIP endpoint name to change state.
* \param state The new state
* \retval 0 Success
* \retval -1 Endpoint not found
*/
int ast_sip_persistent_endpoint_update_state(const char *endpoint_name, enum ast_endpoint_state state);
/*!
* \brief Publish the change of state for a contact.
*
* \param endpoint_name The SIP endpoint name.
* \param contact_status The contact status.
*/
void ast_sip_persistent_endpoint_publish_contact_state(const char *endpoint_name, const struct ast_sip_contact_status *contact_status);
/*!
* \brief Retrieve the current status for a contact.
*
* \param contact The contact.
*
* \retval non-NULL Success
* \retval NULL Status information not found
*
* \note The returned contact status object is immutable.
*/
struct ast_sip_contact_status *ast_sip_get_contact_status(const struct ast_sip_contact *contact);
/*!
* \brief Get a pointer to the PJSIP endpoint.
*