[svn-commits] mmichelson: branch mmichelson/pool_shark2 r381592 - /team/mmichelson/pool_sha...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Feb 15 16:38:45 CST 2013


Author: mmichelson
Date: Fri Feb 15 16:38:41 2013
New Revision: 381592

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=381592
Log:
Ease the out-of-dialog vs. in-dialog nature of endpoint lookup and authentication.

Endpoint lookup and authentication now are their own pjsip modules. This way, they
can live above the dialog layer so that they only will get called into on out-of-dialog
requests. In-dialog requests will get stopped at the dialog layer if no dialog users
handle the request.

Responses don't undergo endpoint lookup or authentication because authentication can't
be done on responses and endpoints should be stored by the requester.


Modified:
    team/mmichelson/pool_shark2/res/res_sip/sip_distributor.c

Modified: team/mmichelson/pool_shark2/res/res_sip/sip_distributor.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pool_shark2/res/res_sip/sip_distributor.c?view=diff&rev=381592&r1=381591&r2=381592
==============================================================================
--- team/mmichelson/pool_shark2/res/res_sip/sip_distributor.c (original)
+++ team/mmichelson/pool_shark2/res/res_sip/sip_distributor.c Fri Feb 15 16:38:41 2013
@@ -40,6 +40,63 @@
 	.on_rx_response = distributor,
 };
 
+static pj_bool_t endpoint_lookup(pjsip_rx_data *rdata);
+
+pjsip_module endpoint_mod = {
+	.name = {"Endpoint Identifier", 19},
+	.priority = PJSIP_MOD_PRIORITY_APPLICATION - 2,
+	.on_rx_request = endpoint_lookup,
+};
+
+static pj_bool_t endpoint_lookup(pjsip_rx_data *rdata)
+{
+	struct ast_sip_endpoint *endpoint = ast_sip_identify_endpoint(rdata);
+	int is_ack = rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD;
+
+	if (!endpoint && !is_ack) {
+		/* XXX When we do an alwaysauthreject-like option, we'll need to take that into account
+		 * for this option. Either that, or have a pseudo-endpoint to pass along so that authentication
+		 * will fail
+		 */
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
+		return PJ_TRUE;
+	}
+	rdata->endpt_info.mod_data[endpoint_mod.id] = endpoint;
+	return PJ_FALSE;
+}
+
+static pj_bool_t authenticate(pjsip_rx_data *rdata)
+{
+	struct ast_sip_endpoint *endpoint = ast_pjsip_rdata_get_endpoint(rdata);
+	ast_assert(endpoint != NULL);
+
+	if (ast_sip_requires_authentication(endpoint, rdata)) {
+		pjsip_tx_data *tdata;
+		pjsip_endpt_create_response(ast_sip_get_pjsip_endpoint(), rdata, 401, NULL, &tdata);
+		switch (ast_sip_check_authentication(endpoint, rdata, tdata)) {
+		case AST_SIP_AUTHENTICATION_CHALLENGE:
+			/* Send the 401 we created for them */
+			pjsip_endpt_send_response2(ast_sip_get_pjsip_endpoint(), rdata, tdata, NULL, NULL);
+			return PJ_TRUE;
+		case AST_SIP_AUTHENTICATION_SUCCESS:
+			return PJ_FALSE;
+		case AST_SIP_AUTHENTICATION_FAILED:
+			pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
+			return PJ_TRUE;
+		case AST_SIP_AUTHENTICATION_ERROR:
+			pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
+			return PJ_TRUE;
+		}
+	}
+	return PJ_FALSE;
+}
+
+pjsip_module auth_mod = {
+	.name = {"Request Authenticator", 21},
+	.priority = PJSIP_MOD_PRIORITY_APPLICATION - 1,
+	.on_rx_request = authenticate,
+};
+
 static int distribute(void *data)
 {
 	static pjsip_process_rdata_param param = {
@@ -49,54 +106,15 @@
 	pj_bool_t handled;
 	pjsip_rx_data *rdata = data;
 	int is_request = rdata->msg_info.msg->type == PJSIP_REQUEST_MSG;
-	pjsip_method *req_method = is_request ? &rdata->msg_info.msg->line.req.method : NULL;
-	int is_ack = req_method ? req_method->id == PJSIP_ACK_METHOD : 0;
-	struct ast_sip_endpoint *endpoint = NULL;
-	pjsip_to_hdr *to_header = PJSIP_MSG_TO_HDR(rdata->msg_info.msg);
-	int in_dialog = pj_strlen(&to_header->tag) > 0;
-
-	if (!in_dialog) {
-		endpoint = ast_sip_identify_endpoint(rdata);
-		if (!endpoint) {
-			if (is_request && !is_ack) {
-				/* XXX When we do an alwaysauthreject-like option, we'll need to take that into account
-				 * for this option. Either that, or have a pseudo-endpoint to pass along so that authentication
-				 * will fail
-				 */
-				pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
-			}
-			goto end;
-		}
-		rdata->endpt_info.mod_data[distributor_mod.id] = endpoint;
-
-		if (is_request) {
-			if (ast_sip_requires_authentication(endpoint, rdata)) {
-				pjsip_tx_data *tdata;
-				pjsip_endpt_create_response(ast_sip_get_pjsip_endpoint(), rdata, 401, NULL, &tdata);
-				switch (ast_sip_check_authentication(endpoint, rdata, tdata)) {
-				case AST_SIP_AUTHENTICATION_CHALLENGE:
-					/* Send the 401 we created for them */
-					pjsip_endpt_send_response2(ast_sip_get_pjsip_endpoint(), rdata, tdata, NULL, NULL);
-					goto end;
-				case AST_SIP_AUTHENTICATION_SUCCESS:
-					break;
-				case AST_SIP_AUTHENTICATION_FAILED:
-					pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
-					goto end;
-				case AST_SIP_AUTHENTICATION_ERROR:
-					pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
-					goto end;
-				}
-			}
-		}
-	}
+	int is_ack = is_request ? rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD : 0;
+	struct ast_sip_endpoint *endpoint;
 
 	pjsip_endpt_process_rx_data(ast_sip_get_pjsip_endpoint(), rdata, &param, &handled);
 	if (!handled && is_request && !is_ack) {
 		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 501, NULL, NULL, NULL);
 	}
 
-end:
+	endpoint = rdata->endpt_info.mod_data[endpoint_mod.id];
 	ao2_cleanup(endpoint);
 	pjsip_rx_data_free_cloned(rdata);
 	return 0;
@@ -104,7 +122,7 @@
 
 struct ast_sip_endpoint *ast_pjsip_rdata_get_endpoint(pjsip_rx_data *rdata)
 {
-	struct ast_sip_endpoint *endpoint = rdata->endpt_info.mod_data[distributor_mod.id];
+	struct ast_sip_endpoint *endpoint = rdata->endpt_info.mod_data[endpoint_mod.id];
 	if (endpoint) {
 		ao2_ref(endpoint, +1);
 	}
@@ -121,7 +139,7 @@
 		return NULL;
 	}
 	memcpy(clone->endpt_info.mod_data, rdata->endpt_info.mod_data, sizeof(clone->endpt_info.mod_data));
-	endpoint = clone->endpt_info.mod_data[distributor_mod.id];
+	endpoint = clone->endpt_info.mod_data[endpoint_mod.id];
 	if (endpoint) {
 		ao2_ref(endpoint, +1);
 	}
@@ -131,12 +149,21 @@
 void ast_pjsip_rx_data_free_cloned(pjsip_rx_data *rdata)
 {
 	struct ast_sip_endpoint *endpoint;
-	endpoint = rdata->endpt_info.mod_data[distributor_mod.id];
+	endpoint = rdata->endpt_info.mod_data[endpoint_mod.id];
 	pjsip_rx_data_free_cloned(rdata);
 	ao2_cleanup(endpoint);
 }
 
 int ast_sip_initialize_distributor(void)
 {
-	return ast_sip_register_service(&distributor_mod);
+	if (ast_sip_register_service(&distributor_mod)) {
+		return -1;
+	}
+	if (ast_sip_register_service(&endpoint_mod)) {
+		return -1;
+	}
+	if (ast_sip_register_service(&auth_mod)) {
+		return -1;
+	}
+	return 0;
 }




More information about the svn-commits mailing list