[asterisk-commits] mmichelson: branch mmichelson/pool_shark r380646 - /team/mmichelson/pool_shar...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Jan 31 09:56:01 CST 2013


Author: mmichelson
Date: Thu Jan 31 09:55:56 2013
New Revision: 380646

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=380646
Log:
Make OPTIONS handling use the threadpool.

For those wondering about the changes with regards to dialogs in this commit,
pjsip_rx_data_clone() does not copy the mod_data of the rdata. This means that
function calls like pjsip_rdata_get_dlg() and pjsip_rdata_get_tsx() will not
work on a cloned rdata structure. The solution here is to save the information
along with the rdata when we pass the data to the threadpool.


Modified:
    team/mmichelson/pool_shark/res/res_sip/sip_options.c

Modified: team/mmichelson/pool_shark/res/res_sip/sip_options.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pool_shark/res/res_sip/sip_options.c?view=diff&rev=380646&r1=380645&r2=380646
==============================================================================
--- team/mmichelson/pool_shark/res/res_sip/sip_options.c (original)
+++ team/mmichelson/pool_shark/res/res_sip/sip_options.c Thu Jan 31 09:55:56 2013
@@ -47,11 +47,10 @@
 	.on_rx_response = options_module_on_rx_response,
 };
 
-static pj_status_t send_options_response(pjsip_rx_data *rdata, int code)
+static pj_status_t send_options_response(pjsip_rx_data *rdata, pjsip_dialog *pj_dlg, int code)
 {
 	pjsip_endpoint *endpt = ast_sip_get_pjsip_endpoint();
 	pjsip_transaction *pj_trans = pjsip_rdata_get_tsx(rdata);
-	pjsip_dialog *pj_dlg = pjsip_rdata_get_dlg(rdata);
 	pjsip_tx_data *tdata;
 	const pjsip_hdr *hdr;
 	pjsip_response_addr res_addr;
@@ -98,27 +97,59 @@
 	return status;
 }
 
-static pj_bool_t options_module_on_rx_request(pjsip_rx_data *rdata)
-{
+struct incoming_options_data {
+	pjsip_rx_data *rdata;
+	pjsip_dialog *dialog;
+};
+
+static void incoming_options_data_destroy(void *obj)
+{
+	struct incoming_options_data *iod = obj;
+	if (iod->rdata) {
+		pjsip_rx_data_free_cloned(iod->rdata);
+	}
+	if (iod->dialog) {
+		pjsip_dlg_dec_session(iod->dialog, &options_module);
+	}
+}
+
+static struct incoming_options_data *incoming_options_data_alloc(pjsip_rx_data *rdata, pjsip_dialog *dialog)
+{
+	struct incoming_options_data *iod = ao2_alloc(sizeof(*iod), incoming_options_data_destroy);
+	if (!iod) {
+		return NULL;
+	}
+	if (pjsip_rx_data_clone(rdata, 0, &iod->rdata) != PJ_SUCCESS) {
+		ao2_cleanup(iod);
+		return NULL;
+	}
+	if (dialog) {
+		iod->dialog = dialog;
+		pjsip_dlg_inc_session(iod->dialog, &options_module);
+	}
+	return iod;
+}
+
+static int incoming_options(void *data)
+{
+	RAII_VAR(struct incoming_options_data *, iod, data, ao2_cleanup);
 	RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
 	pjsip_uri *ruri;
 	pjsip_sip_uri *sip_ruri;
+	pjsip_rx_data *rdata = iod->rdata;
+	pjsip_dialog *dlg = iod->dialog;
 	char exten[AST_MAX_EXTENSION];
-
-	if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_options_method)) {
-		return PJ_FALSE;
-	}
 
 	/* If no endpoint is available for the request treat them as completely untrusted */
 	if (!(endpoint = ast_sip_identify_endpoint(rdata))) {
-		send_options_response(rdata, 404);
-		return PJ_TRUE;
+		send_options_response(rdata, dlg, 404);
+		return -1;
 	}
 
 	ruri = rdata->msg_info.msg->line.req.uri;
 	if (!PJSIP_URI_SCHEME_IS_SIP(ruri) && !PJSIP_URI_SCHEME_IS_SIPS(ruri)) {
-		send_options_response(rdata, 416);
-		return PJ_TRUE;
+		send_options_response(rdata, dlg, 416);
+		return -1;
 	}
 	
 	sip_ruri = pjsip_uri_get_uri(ruri);
@@ -127,11 +158,31 @@
 	/* XXX TODO: authenticate the user */
 
 	if (ast_shutting_down()) {
-		send_options_response(rdata, 503);
+		send_options_response(rdata, dlg, 503);
 	} else if (!ast_exists_extension(NULL, endpoint->context, exten, 1, NULL)) {
-		send_options_response(rdata, 404);
+		send_options_response(rdata, dlg, 404);
 	} else {
-		send_options_response(rdata, 200);
+		send_options_response(rdata, dlg, 200);
+	}
+	return 0;
+}
+
+static pj_bool_t options_module_on_rx_request(pjsip_rx_data *rdata)
+{
+	struct incoming_options_data *iod;
+	pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
+	if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_options_method)) {
+		return PJ_FALSE;
+	}
+
+	iod = incoming_options_data_alloc(rdata, dlg);
+	if (!iod) {
+		send_options_response(rdata, dlg, 500);
+		return PJ_TRUE;
+	}
+
+	if (ast_sip_push_task(NULL, incoming_options, iod)) {
+		send_options_response(rdata, dlg, 500);
 	}
 
 	return PJ_TRUE;
@@ -197,13 +248,15 @@
 	return info;
 }
 
-static void send_qualify_request(struct ast_sip_endpoint *endpoint)
-{
+static int send_qualify_request(void *data)
+{
+	struct ast_sip_endpoint *endpoint = data;
 	/* YAY! Send an OPTIONS request. */
 
 	ast_sip_send_request("OPTIONS", NULL, NULL, endpoint);
 
-	return;
+	ao2_cleanup(endpoint);
+	return 0;
 }
 
 static int qualify_endpoint_scheduler_cb(const void *data)
@@ -225,8 +278,7 @@
 		return 0;
 	}
 
-	/* Actually do the qualify */
-	send_qualify_request(endpoint);
+	ast_sip_push_task(NULL, send_qualify_request, endpoint);
 
 	return 1;
 }




More information about the asterisk-commits mailing list