mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	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
This commit is contained in:
		
				
					committed by
					
						 Joshua Colp
						Joshua Colp
					
				
			
			
				
	
			
			
			
						parent
						
							5f78801859
						
					
				
				
					commit
					9c2032240e
				
			| @@ -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') | ||||
|  | ||||
| @@ -1075,6 +1075,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> | ||||
|   | ||||
| @@ -1088,6 +1088,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)); | ||||
|  | ||||
|   | ||||
| @@ -1023,17 +1023,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; | ||||
| @@ -1049,26 +1043,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; | ||||
| @@ -1091,6 +1106,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; | ||||
| @@ -1098,16 +1114,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) | ||||
| @@ -1173,7 +1195,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); | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
| 		} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user