[asterisk-commits] rmudgett: branch 12 r411141 - in /branches/12: include/asterisk/ res/ res/res...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Mar 25 11:55:23 CDT 2014


Author: rmudgett
Date: Tue Mar 25 11:55:16 2014
New Revision: 411141

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=411141
Log:
res_pjsip: Fix contact authenticate_qualify endpoint lookup when qualifing a contact.

* Fixed bad use of ao2_find() in on_endpoint().

* Replaced use of find_endpoints() with find_an_endpoint() since only the
first found endpoint is ever needed.

* Fixed qualify_contact_cb() to update the contact with the aor
authenticate_qualify setting.  Otherwise, permanent contacts in the aor
type sections would have a config line order dependancy.

* Fixed off nominal path contact ref leak in qualify_contact().  The
comment saying the unref is not needed was wrong.

* Fixed off nominal path use of the endpoint parameter if it is NULL in
send_out_of_dialog_request().

* Added missing off nominal path unref of pjsip tdata in
send_out_of_dialog_request().

* Fixed off nominal path failing to call the callback in send_request_cb()
when the request is challenged for authentication.

* Eliminated silly RAII_VAR() use in qualify_contact_cb().

* Updated ast_sip_send_request() doxygen to better reflect reality.

(closes issue ASTERISK-23254)
Reported by: rmudgett

Review: https://reviewboard.asterisk.org/r/3381/

Modified:
    branches/12/include/asterisk/res_pjsip.h
    branches/12/res/res_pjsip.c
    branches/12/res/res_pjsip/pjsip_options.c

Modified: branches/12/include/asterisk/res_pjsip.h
URL: http://svnview.digium.com/svn/asterisk/branches/12/include/asterisk/res_pjsip.h?view=diff&rev=411141&r1=411140&r2=411141
==============================================================================
--- branches/12/include/asterisk/res_pjsip.h (original)
+++ branches/12/include/asterisk/res_pjsip.h Tue Mar 25 11:55:16 2014
@@ -1265,13 +1265,13 @@
  * they arrive.
  *
  * \param tdata The request to send
- * \param dlg Optional. If specified, the dialog on which the request should be sent
- * \param endpoint Optional. If specified, the request is sent out-of-dialog to the endpoint.
- * \param token Data to be passed to the callback upon receipt of response
- * \param callback Callback to be called upon receipt of response
- *
- * \retval 0 Success
- * \retval -1 Failure
+ * \param dlg Optional. The dialog in which the request is sent.  Otherwise it is out-of-dialog.
+ * \param endpoint Optional. If specified, the out-of-dialog request is sent to the endpoint.
+ * \param token Data to be passed to the callback upon receipt of out-of-dialog response.
+ * \param callback Callback to be called upon receipt of out-of-dialog response.
+ *
+ * \retval 0 Success
+ * \retval -1 Failure (out-of-dialog callback will not be called.)
  */
 int ast_sip_send_request(pjsip_tx_data *tdata, struct pjsip_dialog *dlg,
 	struct ast_sip_endpoint *endpoint, void *token,

Modified: branches/12/res/res_pjsip.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/res_pjsip.c?view=diff&rev=411141&r1=411140&r2=411141
==============================================================================
--- branches/12/res/res_pjsip.c (original)
+++ branches/12/res/res_pjsip.c Tue Mar 25 11:55:16 2014
@@ -1850,10 +1850,11 @@
 	}
 	AST_RWLIST_UNLOCK(&supplements);
 
-	if ((tsx->status_code == 401 || tsx->status_code == 407) && req_data->endpoint) {
-		if (!ast_sip_create_request_with_auth(&req_data->endpoint->outbound_auths, challenge, tsx, &tdata)) {
-			pjsip_endpt_send_request(ast_sip_get_pjsip_endpoint(), tdata, -1, req_data->token, req_data->callback);
-		}
+	if ((tsx->status_code == 401 || tsx->status_code == 407)
+		&& req_data->endpoint
+		&& !ast_sip_create_request_with_auth(&req_data->endpoint->outbound_auths, challenge, tsx, &tdata)
+		&& pjsip_endpt_send_request(ast_sip_get_pjsip_endpoint(), tdata, -1, req_data->token, req_data->callback)
+			== PJ_SUCCESS) {
 		return;
 	}
 
@@ -1870,6 +1871,7 @@
 	struct ast_sip_contact *contact = ast_sip_mod_data_get(tdata->mod_data, supplement_module.id, MOD_DATA_CONTACT);
 
 	if (!req_data) {
+		pjsip_tx_data_dec_ref(tdata);
 		return -1;
 	}
 
@@ -1888,7 +1890,7 @@
 		ast_log(LOG_ERROR, "Error attempting to send outbound %.*s request to endpoint %s\n",
 				(int) pj_strlen(&tdata->msg->line.req.method.name),
 				pj_strbuf(&tdata->msg->line.req.method.name),
-				ast_sorcery_object_get_id(endpoint));
+				endpoint ? ast_sorcery_object_get_id(endpoint) : "<unknown>");
 		ao2_cleanup(req_data);
 		return -1;
 	}

Modified: branches/12/res/res_pjsip/pjsip_options.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/res_pjsip/pjsip_options.c?view=diff&rev=411141&r1=411140&r2=411141
==============================================================================
--- branches/12/res/res_pjsip/pjsip_options.c (original)
+++ branches/12/res/res_pjsip/pjsip_options.c Tue Mar 25 11:55:16 2014
@@ -34,8 +34,6 @@
 #define DEFAULT_ENCODING "text/plain"
 #define QUALIFIED_BUCKETS 211
 
-static int qualify_contact(struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact);
-
 /*!
  * \internal
  * \brief Create a ast_sip_contact_status object.
@@ -152,12 +150,33 @@
 
 /*!
  * \internal
- * \brief For an endpoint try to match on a given contact.
+ * \brief Match a container contact object with the contact sorcery id looking for.
+ *
+ * \param obj pointer to the (user-defined part) of an object.
+ * \param arg callback argument from ao2_callback()
+ * \param flags flags from ao2_callback()
+ *
+ * \return Values are a combination of enum _cb_results.
+ */
+static int match_contact_id(void *obj, void *arg, int flags)
+{
+	struct ast_sip_contact *contact = obj;
+	const char *looking_for = arg;
+
+	return strcmp(ast_sorcery_object_get_id(contact), looking_for) ? 0 : CMP_MATCH;
+}
+
+/*!
+ * \internal
+ * \brief For an endpoint try to match the given contact sorcery id.
  */
 static int on_endpoint(void *obj, void *arg, int flags)
 {
 	struct ast_sip_endpoint *endpoint = obj;
-	char *aor_name, *aors;
+	struct ast_sip_contact *contact;
+	char *looking_for = arg;
+	char *aor_name;
+	char *aors;
 
 	if (!arg || ast_strlen_zero(endpoint->aors)) {
 		return 0;
@@ -174,7 +193,9 @@
 			continue;
 		}
 
-		if (ao2_find(contacts, arg, OBJ_NODATA | OBJ_POINTER)) {
+		contact = ao2_callback(contacts, 0, match_contact_id, looking_for);
+		if (contact) {
+			ao2_ref(contact,  -1);
 			return CMP_MATCH;
 		}
 	}
@@ -184,14 +205,14 @@
 
 /*!
  * \internal
- * \brief Find endpoints associated with the given contact.
- */
-static struct ao2_iterator *find_endpoints(struct ast_sip_contact *contact)
-{
-	RAII_VAR(struct ao2_container *, endpoints,
-		 ast_sip_get_endpoints(), ao2_cleanup);
-
-	return ao2_callback(endpoints, OBJ_MULTIPLE, on_endpoint, contact);
+ * \brief Find an endpoint associated with the given contact.
+ */
+static struct ast_sip_endpoint *find_an_endpoint(struct ast_sip_contact *contact)
+{
+	RAII_VAR(struct ao2_container *, endpoints, ast_sip_get_endpoints(), ao2_cleanup);
+	char *looking_for = (char *) ast_sorcery_object_get_id(contact);
+
+	return ao2_callback(endpoints, 0, on_endpoint, looking_for);
 }
 
 /*!
@@ -200,7 +221,7 @@
  */
 static void qualify_contact_cb(void *token, pjsip_event *e)
 {
-	RAII_VAR(struct ast_sip_contact *, contact, token, ao2_cleanup);
+	struct ast_sip_contact *contact = token;
 
 	switch(e->body.tsx_state.type) {
 	case PJSIP_EVENT_TRANSPORT_ERROR:
@@ -211,30 +232,34 @@
 		update_contact_status(contact, AVAILABLE);
 		break;
 	}
+	ao2_cleanup(contact);
 }
 
 /*!
  * \internal
  * \brief Attempt to qualify the contact
  *
- * \detail Sends a SIP OPTIONS request to the given contact in order to make
+ * \details Sends a SIP OPTIONS request to the given contact in order to make
  *         sure that contact is available.
  */
 static int qualify_contact(struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact)
 {
 	pjsip_tx_data *tdata;
-	RAII_VAR(struct ast_sip_endpoint *, endpoint_local, ao2_bump(endpoint), ao2_cleanup);
-
-
-	if (!endpoint_local && contact->authenticate_qualify) {
-		struct ao2_iterator *endpoint_iterator = find_endpoints(contact);
-
-		/* try to find endpoints that are associated with the contact */
-		if (endpoint_iterator) {
-			/* find "first" endpoint in order to authenticate - actually any
-			   endpoint should do that matched on the contact */
-			endpoint_local = ao2_iterator_next(endpoint_iterator);
-			ao2_iterator_destroy(endpoint_iterator);
+	RAII_VAR(struct ast_sip_endpoint *, endpoint_local, NULL, ao2_cleanup);
+
+	if (contact->authenticate_qualify) {
+		endpoint_local = ao2_bump(endpoint);
+		if (!endpoint_local) {
+			/*
+			 * Find the "first" endpoint to completely qualify the contact - any
+			 * endpoint that is associated with the contact should do.
+			 */
+			endpoint_local = find_an_endpoint(contact);
+			if (!endpoint_local) {
+				ast_log(LOG_ERROR, "Unable to find an endpoint to qualify contact %s\n",
+					contact->uri);
+				return -1;
+			}
 		}
 	}
 
@@ -256,11 +281,11 @@
 	init_start_time(contact);
 
 	ao2_ref(contact, +1);
-	if (ast_sip_send_request(tdata, NULL, contact->authenticate_qualify ? endpoint_local : NULL, contact,
-		qualify_contact_cb) != PJ_SUCCESS) {
-		/* The callback will be called so we don't need to drop the contact ref*/
+	if (ast_sip_send_request(tdata, NULL, endpoint_local, contact, qualify_contact_cb)
+		!= PJ_SUCCESS) {
 		ast_log(LOG_ERROR, "Unable to send request to qualify contact %s\n",
 			contact->uri);
+		ao2_ref(contact, -1);
 		return -1;
 	}
 
@@ -793,6 +818,7 @@
 	struct ast_sip_aor *aor = arg;
 
 	contact->qualify_frequency = aor->qualify_frequency;
+	contact->authenticate_qualify = aor->authenticate_qualify;
 
 	qualify_and_schedule(contact);
 
@@ -803,7 +829,7 @@
  * \internal
  * \brief Qualify and schedule an endpoint's contacts
  *
- * \detail For the given endpoint retrieve its list of aors, qualify all
+ * \details For the given endpoint retrieve its list of aors, qualify all
  *         contacts, and schedule for checks if configured.
  */
 static int qualify_and_schedule_all_cb(void *obj, void *arg, int flags)




More information about the asterisk-commits mailing list