Merge "res_pjsip: improve realtime performance"

This commit is contained in:
Joshua Colp 2016-05-11 10:58:54 -05:00 committed by Gerrit Code Review
commit 87787bb889
5 changed files with 84 additions and 23 deletions

View File

@ -0,0 +1,32 @@
"""ps_contacts add authenticate_qualify
Revision ID: 6be31516058d
Revises: 81b01a191a46
Create Date: 2016-05-03 14:57:12.538179
"""
# revision identifiers, used by Alembic.
revision = '6be31516058d'
down_revision = '81b01a191a46'
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects.postgresql import ENUM
YESNO_NAME = 'yesno_values'
YESNO_VALUES = ['yes', 'no']
def upgrade():
############################# Enums ##############################
# yesno_values have already been created, so use postgres enum object
# type to get around "already created" issue - works okay with mysql
yesno_values = ENUM(*YESNO_VALUES, name=YESNO_NAME, create_type=False)
op.add_column('ps_contacts', sa.Column('authenticate_qualify', yesno_values))
def downgrade():
op.drop_column('ps_contacts', 'authenticate_qualify')

View File

@ -1095,6 +1095,13 @@
If <literal>0</literal> no timeout. Time in fractional seconds.
</para></description>
</configOption>
<configOption name="authenticate_qualify" default="no">
<synopsis>Authenticates a qualify request if needed</synopsis>
<description><para>
If true and a qualify request receives a challenge or authenticate response
authentication is attempted before declaring the contact available.
</para></description>
</configOption>
<configOption name="outbound_proxy">
<synopsis>Outbound proxy used when sending OPTIONS request</synopsis>
<description><para>

View File

@ -1116,6 +1116,7 @@ int ast_sip_initialize_sorcery_location(void)
ast_sorcery_object_field_register(sorcery, "contact", "qualify_frequency", 0, OPT_UINT_T,
PARSE_IN_RANGE, FLDSET(struct ast_sip_contact, qualify_frequency), 0, 86400);
ast_sorcery_object_field_register(sorcery, "contact", "qualify_timeout", "3.0", OPT_DOUBLE_T, 0, FLDSET(struct ast_sip_contact, qualify_timeout));
ast_sorcery_object_field_register(sorcery, "contact", "authenticate_qualify", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_contact, authenticate_qualify));
ast_sorcery_object_field_register(sorcery, "contact", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, outbound_proxy));
ast_sorcery_object_field_register(sorcery, "contact", "user_agent", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, user_agent));
ast_sorcery_object_field_register(sorcery, "contact", "reg_server", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, reg_server));

View File

@ -1025,17 +1025,11 @@ int ast_sip_initialize_sorcery_qualify(void)
return 0;
}
static int qualify_and_schedule_cb(void *obj, void *arg, int flags)
static void qualify_and_schedule_contact(struct ast_sip_contact *contact)
{
struct ast_sip_contact *contact = obj;
struct ast_sip_aor *aor = arg;
int initial_interval;
int max_time = ast_sip_get_max_initial_qualify_time();
contact->qualify_frequency = aor->qualify_frequency;
contact->qualify_timeout = aor->qualify_timeout;
contact->authenticate_qualify = aor->authenticate_qualify;
/* Delay initial qualification by a random fraction of the specified interval */
if (max_time && max_time < contact->qualify_frequency) {
initial_interval = max_time;
@ -1051,26 +1045,47 @@ static int qualify_and_schedule_cb(void *obj, void *arg, int flags)
} else {
update_contact_status(contact, UNKNOWN);
}
}
static int qualify_and_schedule_cb_with_aor(void *obj, void *arg, int flags)
{
struct ast_sip_contact *contact = obj;
struct ast_sip_aor *aor = arg;
contact->qualify_frequency = aor->qualify_frequency;
contact->qualify_timeout = aor->qualify_timeout;
contact->authenticate_qualify = aor->authenticate_qualify;
qualify_and_schedule_contact(contact);
return 0;
}
static int qualify_and_schedule_cb_without_aor(void *obj, void *arg, int flags)
{
qualify_and_schedule_contact((struct ast_sip_contact *) obj);
return 0;
}
/*!
* \internal
* \brief Qualify and schedule an endpoint's contacts
* \brief Qualify and schedule an aor's contacts
*
* \details For the given endpoint retrieve its list of aors, qualify all
* contacts, and schedule for checks if configured.
* \details For the given aor check if it has permanent contacts,
* qualify all contacts and schedule for checks if configured.
*/
static int qualify_and_schedule_all_cb(void *obj, void *arg, int flags)
{
struct ast_sip_aor *aor = obj;
struct ao2_container *contacts;
contacts = ast_sip_location_retrieve_aor_contacts(aor);
if (contacts) {
ao2_callback(contacts, OBJ_NODATA, qualify_and_schedule_cb, aor);
ao2_ref(contacts, -1);
if (aor->permanent_contacts) {
contacts = ast_sip_location_retrieve_aor_contacts(aor);
if (contacts) {
ao2_callback(contacts, OBJ_NODATA, qualify_and_schedule_cb_with_aor, aor);
ao2_ref(contacts, -1);
}
}
return 0;
@ -1093,6 +1108,7 @@ static void qualify_and_schedule_all(void)
{
struct ast_variable *var = ast_variable_new("qualify_frequency >", "0", "");
struct ao2_container *aors;
struct ao2_container *contacts;
if (!var) {
return;
@ -1100,16 +1116,22 @@ static void qualify_and_schedule_all(void)
aors = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(),
"aor", AST_RETRIEVE_FLAG_MULTIPLE, var);
ast_variables_destroy(var);
ao2_callback(sched_qualifies, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, unschedule_all_cb, NULL);
if (!aors) {
return;
if (aors) {
ao2_callback(aors, OBJ_NODATA, qualify_and_schedule_all_cb, NULL);
ao2_ref(aors, -1);
}
ao2_callback(aors, OBJ_NODATA, qualify_and_schedule_all_cb, NULL);
ao2_ref(aors, -1);
contacts = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(),
"contact", AST_RETRIEVE_FLAG_MULTIPLE, var);
if (contacts) {
ao2_callback(contacts, OBJ_NODATA, qualify_and_schedule_cb_without_aor, NULL);
ao2_ref(contacts, -1);
}
ast_variables_destroy(var);
}
static int format_contact_status(void *obj, void *arg, int flags)
@ -1175,7 +1197,7 @@ static void aor_observer_modified(const void *obj)
contacts = ast_sip_location_retrieve_aor_contacts(aor);
if (contacts) {
ao2_callback(contacts, OBJ_NODATA, qualify_and_schedule_cb, aor);
ao2_callback(contacts, OBJ_NODATA, qualify_and_schedule_cb_with_aor, aor);
ao2_ref(contacts, -1);
}
}

View File

@ -97,7 +97,6 @@ static void *sorcery_astdb_retrieve_fields_common(const struct ast_sorcery *sorc
const char *key = entry->key + strlen(family) + 2;
RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
struct ast_json_error error;
RAII_VAR(struct ast_variable *, objset, NULL, ast_variables_destroy);
RAII_VAR(struct ast_variable *, existing, NULL, ast_variables_destroy);
void *object = NULL;
@ -113,7 +112,7 @@ static void *sorcery_astdb_retrieve_fields_common(const struct ast_sorcery *sorc
}
if (!(object = ast_sorcery_alloc(sorcery, type, key)) ||
ast_sorcery_objectset_apply(sorcery, object, objset)) {
ast_sorcery_objectset_apply(sorcery, object, existing)) {
ao2_cleanup(object);
return NULL;
}