From cc4c5f5693101b3c63ba083044729f24c3924685 Mon Sep 17 00:00:00 2001 From: Alexei Gradinari Date: Fri, 15 Apr 2016 10:32:12 -0400 Subject: res_pjsip: improve realtime performance This patch modified pjsip_options to retrieve only permament contacts for aor if the qualify_frequency is > 0 and persisted contacts if the qualify_frequency is > 0. This patch also fixed a bug in res_sorcery_astdb. res_sorcery_astdb doesn't save object data retrived from astdb. ASTERISK-25826 Change-Id: I1831fa46c4578eae5a3e574ee3362fddf08a1f05 --- res/res_pjsip.c | 7 +++++ res/res_pjsip/location.c | 1 + res/res_pjsip/pjsip_options.c | 64 +++++++++++++++++++++++++++++-------------- res/res_sorcery_astdb.c | 3 +- 4 files changed, 52 insertions(+), 23 deletions(-) (limited to 'res') diff --git a/res/res_pjsip.c b/res/res_pjsip.c index db3395fa7..a3b2d081d 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -1095,6 +1095,13 @@ If 0 no timeout. Time in fractional seconds. + + Authenticates a qualify request if needed + + If true and a qualify request receives a challenge or authenticate response + authentication is attempted before declaring the contact available. + + Outbound proxy used when sending OPTIONS request diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c index 2779fe396..fd6db6edc 100644 --- a/res/res_pjsip/location.c +++ b/res/res_pjsip/location.c @@ -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)); diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c index c0d41c3d1..62640fe4e 100644 --- a/res/res_pjsip/pjsip_options.c +++ b/res/res_pjsip/pjsip_options.c @@ -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); } } diff --git a/res/res_sorcery_astdb.c b/res/res_sorcery_astdb.c index b3642d81e..dcfaba528 100644 --- a/res/res_sorcery_astdb.c +++ b/res/res_sorcery_astdb.c @@ -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; } -- cgit v1.2.3