[asterisk-commits] kmoore: branch kmoore/pjsip_path_support r403081 - in /team/kmoore/pjsip_path...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Nov 22 15:20:55 CST 2013


Author: kmoore
Date: Fri Nov 22 15:20:51 2013
New Revision: 403081

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=403081
Log:
Add supplement hooks for out-of-dialog messages and endpoint path option parsing and handling

Modified:
    team/kmoore/pjsip_path_support/include/asterisk/res_pjsip.h
    team/kmoore/pjsip_path_support/include/asterisk/res_pjsip_session.h
    team/kmoore/pjsip_path_support/res/res_pjsip.c
    team/kmoore/pjsip_path_support/res/res_pjsip.exports.in
    team/kmoore/pjsip_path_support/res/res_pjsip/pjsip_configuration.c
    team/kmoore/pjsip_path_support/res/res_pjsip/pjsip_distributor.c
    team/kmoore/pjsip_path_support/res/res_pjsip/pjsip_options.c
    team/kmoore/pjsip_path_support/res/res_pjsip_messaging.c
    team/kmoore/pjsip_path_support/res/res_pjsip_registrar.c

Modified: team/kmoore/pjsip_path_support/include/asterisk/res_pjsip.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pjsip_path_support/include/asterisk/res_pjsip.h?view=diff&rev=403081&r1=403080&r2=403081
==============================================================================
--- team/kmoore/pjsip_path_support/include/asterisk/res_pjsip.h (original)
+++ team/kmoore/pjsip_path_support/include/asterisk/res_pjsip.h Fri Nov 22 15:20:51 2013
@@ -541,6 +541,8 @@
 		AST_STRING_FIELD(fromuser);
 		/*! Domain to place in From header */
 		AST_STRING_FIELD(fromdomain);
+		/*! Path information to place in the Route header */
+		AST_STRING_FIELD(path);
 	);
 	/*! Configuration for extensions */
 	struct ast_sip_endpoint_extensions extensions;
@@ -574,6 +576,8 @@
 	unsigned int faxdetect;
 	/*! Determines if transfers (using REFER) are allowed by this endpoint */
 	unsigned int allowtransfer;
+	/*! Determines whether SIP Path headers are supported */
+	unsigned int support_path;
 };
 
 /*!
@@ -1255,6 +1259,19 @@
 int ast_sip_send_request(pjsip_tx_data *tdata, struct pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint);
 
 /*!
+ * \brief Send a response to an out of dialog request
+ *
+ * \param endpt The pjsip_endpoint with which this response is associated
+ * \param res_addr The response address for this response
+ * \param tdata The response to send
+ * \param endpoint The ast_sip_endpoint associated with this response
+ *
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_send_response(pjsip_endpoint *endpt, pjsip_response_addr *res_addr, pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint);
+
+/*!
  * \brief Determine if an incoming request requires authentication
  *
  * This calls into the registered authenticator's requires_authentication callback
@@ -1559,5 +1576,97 @@
 #define ast_sip_mod_data_set(pool, mod_data, id, key, val)		\
 	mod_data[id] = ast_sip_dict_set(pool, mod_data[id], key, val)
 
+enum ast_sip_supplement_priority {
+	/*! Top priority. Supplements with this priority are those that need to run before any others */
+	AST_SIP_SESSION_SUPPLEMENT_PRIORITY_FIRST = 0,
+	/*! Channel creation priority.
+	 * chan_pjsip creates a channel at this priority. If your supplement depends on being run before
+	 * or after channel creation, then set your priority to be lower or higher than this value.
+	 */
+	AST_SIP_SESSION_SUPPLEMENT_PRIORITY_CHANNEL = 1000000,
+	/*! Lowest priority. Supplements with this priority should be run after all other supplements */
+	AST_SIP_SESSION_SUPPLEMENT_PRIORITY_LAST = INT_MAX,
+};
+
+/*!
+ * \brief A supplement to SIP message processing
+ *
+ * These can be registered by any module in order to add
+ * processing to incoming and outgoing SIP out of dialog
+ * requests and responses
+ */
+struct ast_sip_supplement {
+	/*! Method on which to call the callbacks. If NULL, call on all methods */
+	const char *method;
+	/*! Priority for this supplement. Lower numbers are visited before higher numbers */
+	enum ast_sip_supplement_priority priority;
+	/*!
+	 * \brief Called on incoming SIP request
+	 * This method can indicate a failure in processing in its return. If there
+	 * is a failure, it is required that this method sends a response to the request.
+	 * This method is always called from a SIP servant thread.
+	 *
+	 * \note
+	 * The following PJSIP methods will not work properly:
+	 * pjsip_rdata_get_dlg()
+	 * pjsip_rdata_get_tsx()
+	 * The reason is that the rdata passed into this function is a cloned rdata structure,
+	 * and its module data is not copied during the cloning operation.
+	 * If you need to get the dialog, you can get it via session->inv_session->dlg.
+	 *
+	 * \note
+	 * There is no guarantee that a channel will be present on the session when this is called.
+	 */
+	int (*incoming_request)(struct ast_sip_endpoint *endpoint, struct pjsip_rx_data *rdata);
+	/*! 
+	 * \brief Called on an incoming SIP response
+	 * This method is always called from a SIP servant thread.
+	 *
+	 * \note
+	 * The following PJSIP methods will not work properly:
+	 * pjsip_rdata_get_dlg()
+	 * pjsip_rdata_get_tsx()
+	 * The reason is that the rdata passed into this function is a cloned rdata structure,
+	 * and its module data is not copied during the cloning operation.
+	 * If you need to get the dialog, you can get it via session->inv_session->dlg.
+	 *
+	 * \note
+	 * There is no guarantee that a channel will be present on the session when this is called.
+	 */
+	void (*incoming_response)(struct ast_sip_endpoint *endpoint, struct pjsip_rx_data *rdata);
+	/*!
+	 * \brief Called on an outgoing SIP request
+	 * This method is always called from a SIP servant thread.
+	 */
+	void (*outgoing_request)(struct ast_sip_endpoint *endpoint, struct pjsip_tx_data *tdata);
+	/*! 
+	 * \brief Called on an outgoing SIP response
+	 * This method is always called from a SIP servant thread.
+	 */
+	void (*outgoing_response)(struct ast_sip_endpoint *endpoint, struct pjsip_tx_data *tdata);
+	/*! Next item in the list */
+	AST_LIST_ENTRY(ast_sip_supplement) next;
+};
+
+/*!
+ * \brief Register a supplement to SIP out of dialog processing
+ *
+ * This allows for someone to insert themselves in the processing of out
+ * of dialog SIP requests and responses. This, for example could allow for
+ * a module to set channel data based on headers in an incoming message.
+ * Similarly, a module could reject an incoming request if desired.
+ *
+ * \param supplement The supplement to register
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_register_supplement(struct ast_sip_supplement *supplement);
+
+/*!
+ * \brief Unregister a an supplement to SIP out of dialog processing
+ *
+ * \param supplement The supplement to unregister
+ */
+void ast_sip_unregister_supplement(struct ast_sip_supplement *supplement);
 
 #endif /* _RES_PJSIP_H */

Modified: team/kmoore/pjsip_path_support/include/asterisk/res_pjsip_session.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pjsip_path_support/include/asterisk/res_pjsip_session.h?view=diff&rev=403081&r1=403080&r2=403081
==============================================================================
--- team/kmoore/pjsip_path_support/include/asterisk/res_pjsip_session.h (original)
+++ team/kmoore/pjsip_path_support/include/asterisk/res_pjsip_session.h Fri Nov 22 15:20:51 2013
@@ -137,18 +137,6 @@
 typedef int (*ast_sip_session_response_cb)(struct ast_sip_session *session, pjsip_rx_data *rdata);
 typedef int (*ast_sip_session_sdp_creation_cb)(struct ast_sip_session *session, pjmedia_sdp_session *sdp);
 
-enum ast_sip_session_supplement_priority {
-	/*! Top priority. Supplements with this priority are those that need to run before any others */
-	AST_SIP_SESSION_SUPPLEMENT_PRIORITY_FIRST = 0,
-	/*! Channel creation priority.
-	 * chan_pjsip creates a channel at this priority. If your supplement depends on being run before
-	 * or after channel creation, then set your priority to be lower or higher than this value.
-	 */
-	AST_SIP_SESSION_SUPPLEMENT_PRIORITY_CHANNEL = 1000000,
-	/*! Lowest priority. Supplements with this priority should be run after all other supplements */
-	AST_SIP_SESSION_SUPPLEMENT_PRIORITY_LAST = INT_MAX,
-};
-
 /*!
  * \brief A supplement to SIP message processing
  *
@@ -159,7 +147,7 @@
     /*! Method on which to call the callbacks. If NULL, call on all methods */
     const char *method;
 	/*! Priority for this supplement. Lower numbers are visited before higher numbers */
-	enum ast_sip_session_supplement_priority priority;
+	enum ast_sip_supplement_priority priority;
     /*!
 	 * \brief Notification that the session has begun
 	 * This method will always be called from a SIP servant thread.

Modified: team/kmoore/pjsip_path_support/res/res_pjsip.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pjsip_path_support/res/res_pjsip.c?view=diff&rev=403081&r1=403080&r2=403081
==============================================================================
--- team/kmoore/pjsip_path_support/res/res_pjsip.c (original)
+++ team/kmoore/pjsip_path_support/res/res_pjsip.c Fri Nov 22 15:20:51 2013
@@ -644,6 +644,15 @@
 						set to <literal>sdes</literal> or <literal>dtls</literal>.
 					</para></description>
 				</configOption>
+				<configOption name="support_path">
+					<synopsis>Enables Path support for REGISTER requests and Route support for other requests.</synopsis>
+					<description><para>
+						When this option is enabled, the Path header in register requests will be saved
+						and its contents will be used in Route headers for outbound out-of-dialog requests
+						and in Path headers for outbound 200 responses. Path support will also be indicated
+						in the Supported header.
+					</para></description>
+				</configOption>
 			</configObject>
 			<configObject name="auth">
 				<synopsis>Authentication type</synopsis>
@@ -1572,6 +1581,44 @@
 	}
 }
 
+AST_RWLIST_HEAD_STATIC(supplements, ast_sip_supplement);
+
+int ast_sip_register_supplement(struct ast_sip_supplement *supplement)
+{
+	struct ast_sip_supplement *iter;
+	int inserted = 0;
+	SCOPED_LOCK(lock, &supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
+
+	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&supplements, iter, next) {
+		if (iter->priority > supplement->priority) {
+			AST_RWLIST_INSERT_BEFORE_CURRENT(supplement, next);
+			inserted = 1;
+			break;
+		}
+	}
+	AST_RWLIST_TRAVERSE_SAFE_END;
+
+	if (!inserted) {
+		AST_RWLIST_INSERT_TAIL(&supplements, supplement, next);
+	}
+	ast_module_ref(ast_module_info->self);
+	return 0;
+}
+
+void ast_sip_unregister_supplement(struct ast_sip_supplement *supplement)
+{
+	struct ast_sip_supplement *iter;
+	SCOPED_LOCK(lock, &supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
+	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&supplements, iter, next) {
+		if (supplement == iter) {
+			AST_RWLIST_REMOVE_CURRENT(next);
+			ast_module_unref(ast_module_info->self);
+			break;
+		}
+	}
+	AST_RWLIST_TRAVERSE_SAFE_END;
+}
+
 static int send_in_dialog_request(pjsip_tx_data *tdata, struct pjsip_dialog *dlg)
 {
 	if (pjsip_dlg_send_request(dlg, tdata, -1, NULL) != PJ_SUCCESS) {
@@ -1579,6 +1626,19 @@
 		return -1;
 	}
 	return 0;
+}
+
+static pj_bool_t does_method_match(const pj_str_t *message_method, const char *supplement_method)
+{
+	pj_str_t method;
+
+	if (ast_strlen_zero(supplement_method)) {
+		return PJ_TRUE;
+	}
+
+	pj_cstr(&method, supplement_method);
+
+	return pj_stristr(&method, message_method) ? PJ_TRUE : PJ_FALSE;
 }
 
 static void send_request_cb(void *token, pjsip_event *e)
@@ -1587,18 +1647,36 @@
 	pjsip_transaction *tsx = e->body.tsx_state.tsx;
 	pjsip_rx_data *challenge = e->body.tsx_state.src.rdata;
 	pjsip_tx_data *tdata;
-
-	if (tsx->status_code != 401 && tsx->status_code != 407) {
+	struct ast_sip_supplement *supplement;
+
+	if (tsx->status_code == 401 || tsx->status_code == 407) {
+		if (!ast_sip_create_request_with_auth(&endpoint->outbound_auths, challenge, tsx, &tdata)) {
+			pjsip_endpt_send_request(ast_sip_get_pjsip_endpoint(), tdata, -1, NULL, NULL);
+		}
 		return;
 	}
 
-	if (!ast_sip_create_request_with_auth(&endpoint->outbound_auths, challenge, tsx, &tdata)) {
-		pjsip_endpt_send_request(ast_sip_get_pjsip_endpoint(), tdata, -1, NULL, NULL);
-	}
+	AST_RWLIST_RDLOCK(&supplements);
+	AST_LIST_TRAVERSE(&supplements, supplement, next) {
+		if (supplement->incoming_response && does_method_match(&challenge->msg_info.cseq->method.name, supplement->method)) {
+			supplement->incoming_response(endpoint, challenge);
+		}
+	}
+	AST_RWLIST_UNLOCK(&supplements);
 }
 
 static int send_out_of_dialog_request(pjsip_tx_data *tdata, struct ast_sip_endpoint *endpoint)
 {
+	struct ast_sip_supplement *supplement;
+
+	AST_RWLIST_RDLOCK(&supplements);
+	AST_LIST_TRAVERSE(&supplements, supplement, next) {
+		if (supplement->outgoing_request && does_method_match(&tdata->msg->line.req.method.name, supplement->method)) {
+			supplement->outgoing_request(endpoint, tdata);
+		}
+	}
+	AST_RWLIST_UNLOCK(&supplements);
+
 	ao2_ref(endpoint, +1);
 	if (pjsip_endpt_send_request(ast_sip_get_pjsip_endpoint(), tdata, -1, endpoint, send_request_cb) != PJ_SUCCESS) {
 		ast_log(LOG_ERROR, "Error attempting to send outbound %.*s request to endpoint %s\n",
@@ -1870,6 +1948,47 @@
 	pj_hash_set(pool, ht, key, PJ_HASH_KEY_STRING, 0, val);
 
 	return ht;
+}
+
+static pj_bool_t supplement_on_rx_request(pjsip_rx_data *rdata)
+{
+	struct ast_sip_supplement *supplement;
+
+	if (pjsip_rdata_get_dlg(rdata)) {
+		return PJ_FALSE;
+	}
+
+	AST_RWLIST_RDLOCK(&supplements);
+	AST_LIST_TRAVERSE(&supplements, supplement, next) {
+		if (supplement->incoming_request && does_method_match(&rdata->msg_info.cseq->method.name, supplement->method)) {
+			supplement->incoming_request(ast_pjsip_rdata_get_endpoint(rdata), rdata);
+		}
+	}
+	AST_RWLIST_UNLOCK(&supplements);
+
+	return PJ_FALSE;
+}
+
+static pjsip_module supplement_module = {
+	.name = { "Out of dialog supplement hook", 29 },
+	.id = -1,
+	.priority = PJSIP_MOD_PRIORITY_APPLICATION - 1,
+	.on_rx_request = supplement_on_rx_request,
+};
+
+int ast_sip_send_response(pjsip_endpoint *endpt, pjsip_response_addr *res_addr, pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint)
+{
+	struct ast_sip_supplement *supplement;
+
+	AST_RWLIST_RDLOCK(&supplements);
+	AST_LIST_TRAVERSE(&supplements, supplement, next) {
+		if (supplement->outgoing_response && does_method_match(&tdata->msg->line.req.method.name, supplement->method)) {
+			supplement->outgoing_response(sip_endpoint, tdata);
+		}
+	}
+	AST_RWLIST_UNLOCK(&supplements);
+
+	return pjsip_endpt_send_response(endpt, res_addr, tdata, NULL, NULL);
 }
 
 static void remove_request_headers(pjsip_endpoint *endpt)
@@ -1989,8 +2108,8 @@
 		return AST_MODULE_LOAD_DECLINE;
 	}
 
-	if (ast_sip_initialize_outbound_authentication()) {
-		ast_log(LOG_ERROR, "Failed to initialize outbound authentication. Aborting load\n");
+	if (ast_sip_register_service(&supplement_module)) {
+		ast_log(LOG_ERROR, "Failed to initialize supplement hooks. Aborting load\n");
 		ast_sip_destroy_distributor();
 		ast_res_pjsip_destroy_configuration();
 		ast_sip_destroy_global_headers();
@@ -2003,6 +2122,21 @@
 		return AST_MODULE_LOAD_DECLINE;
 	}
 
+	if (ast_sip_initialize_outbound_authentication()) {
+		ast_log(LOG_ERROR, "Failed to initialize outbound authentication. Aborting load\n");
+		ast_sip_unregister_service(&supplement_module);
+		ast_sip_destroy_distributor();
+		ast_res_pjsip_destroy_configuration();
+		ast_sip_destroy_global_headers();
+		stop_monitor_thread();
+		pj_pool_release(memory_pool);
+		memory_pool = NULL;
+		pjsip_endpt_destroy(ast_pjsip_endpoint);
+		ast_pjsip_endpoint = NULL;
+		pj_caching_pool_destroy(&caching_pool);
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
 	ast_res_pjsip_init_options_handling(0);
 
 	ast_res_pjsip_init_contact_transports();

Modified: team/kmoore/pjsip_path_support/res/res_pjsip.exports.in
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pjsip_path_support/res/res_pjsip.exports.in?view=diff&rev=403081&r1=403080&r2=403081
==============================================================================
--- team/kmoore/pjsip_path_support/res/res_pjsip.exports.in (original)
+++ team/kmoore/pjsip_path_support/res/res_pjsip.exports.in Fri Nov 22 15:20:51 2013
@@ -14,6 +14,9 @@
 		LINKER_SYMBOL_PREFIXast_sip_create_request;
 		LINKER_SYMBOL_PREFIXast_sip_create_request_with_auth;
 		LINKER_SYMBOL_PREFIXast_sip_send_request;
+		LINKER_SYMBOL_PREFIXast_sip_send_response;
+		LINKER_SYMBOL_PREFIXast_sip_register_supplement;
+		LINKER_SYMBOL_PREFIXast_sip_unregister_supplement;
 		LINKER_SYMBOL_PREFIXast_sip_requires_authentication;
 		LINKER_SYMBOL_PREFIXast_sip_authenticate_request;
 		LINKER_SYMBOL_PREFIXast_sip_get_authentication_credentials;

Modified: team/kmoore/pjsip_path_support/res/res_pjsip/pjsip_configuration.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pjsip_path_support/res/res_pjsip/pjsip_configuration.c?view=diff&rev=403081&r1=403080&r2=403081
==============================================================================
--- team/kmoore/pjsip_path_support/res/res_pjsip/pjsip_configuration.c (original)
+++ team/kmoore/pjsip_path_support/res/res_pjsip/pjsip_configuration.c Fri Nov 22 15:20:51 2013
@@ -736,6 +736,7 @@
 	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "dtls_ca_path", "", dtls_handler, NULL, 0, 0);
 	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "dtls_setup", "", dtls_handler, NULL, 0, 0);
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "srtp_tag_32", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.rtp.srtp_tag_32));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "support_path", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, support_path));
 
 	if (ast_sip_initialize_sorcery_transport(sip_sorcery)) {
 		ast_log(LOG_ERROR, "Failed to register SIP transport support with sorcery\n");

Modified: team/kmoore/pjsip_path_support/res/res_pjsip/pjsip_distributor.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pjsip_path_support/res/res_pjsip/pjsip_distributor.c?view=diff&rev=403081&r1=403080&r2=403081
==============================================================================
--- team/kmoore/pjsip_path_support/res/res_pjsip/pjsip_distributor.c (original)
+++ team/kmoore/pjsip_path_support/res/res_pjsip/pjsip_distributor.c Fri Nov 22 15:20:51 2013
@@ -321,7 +321,7 @@
 
 static pjsip_module auth_mod = {
 	.name = {"Request Authenticator", 21},
-	.priority = PJSIP_MOD_PRIORITY_APPLICATION - 1,
+	.priority = PJSIP_MOD_PRIORITY_APPLICATION - 2,
 	.on_rx_request = authenticate,
 };
 

Modified: team/kmoore/pjsip_path_support/res/res_pjsip/pjsip_options.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pjsip_path_support/res/res_pjsip/pjsip_options.c?view=diff&rev=403081&r1=403080&r2=403081
==============================================================================
--- team/kmoore/pjsip_path_support/res/res_pjsip/pjsip_options.c (original)
+++ team/kmoore/pjsip_path_support/res/res_pjsip/pjsip_options.c Fri Nov 22 15:20:51 2013
@@ -519,8 +519,8 @@
 			pjsip_tx_data_dec_ref(tdata);
 			return status;
 		}
-		status = pjsip_endpt_send_response(endpt, &res_addr, tdata,
-						   NULL, NULL);
+		status = ast_sip_send_response(endpt, &res_addr, tdata,
+						   ast_pjsip_rdata_get_endpoint(rdata));
 	}
 
 	if (status != PJ_SUCCESS) {

Modified: team/kmoore/pjsip_path_support/res/res_pjsip_messaging.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pjsip_path_support/res/res_pjsip_messaging.c?view=diff&rev=403081&r1=403080&r2=403081
==============================================================================
--- team/kmoore/pjsip_path_support/res/res_pjsip_messaging.c (original)
+++ team/kmoore/pjsip_path_support/res/res_pjsip_messaging.c Fri Nov 22 15:20:51 2013
@@ -576,7 +576,7 @@
 			ast_log(LOG_ERROR, "Unable to get response address (%d)\n", status);
 			return status;
 		}
-		status = pjsip_endpt_send_response(endpt, &res_addr, tdata, NULL, NULL);
+		status = ast_sip_send_response(endpt, &res_addr, tdata, ast_pjsip_rdata_get_endpoint(rdata));
 	}
 
 	if (status != PJ_SUCCESS) {

Modified: team/kmoore/pjsip_path_support/res/res_pjsip_registrar.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pjsip_path_support/res/res_pjsip_registrar.c?view=diff&rev=403081&r1=403080&r2=403081
==============================================================================
--- team/kmoore/pjsip_path_support/res/res_pjsip_registrar.c (original)
+++ team/kmoore/pjsip_path_support/res/res_pjsip_registrar.c Fri Nov 22 15:20:51 2013
@@ -326,6 +326,22 @@
 	ao2_ref(task_data->aor, +1);
 
 	return task_data;
+}
+
+static void update_path_data(struct rx_task_data *task_data)
+{
+	const pj_str_t path_name = { "Path", 4 };
+	pjsip_generic_string_hdr *hdr;
+
+	if (!task_data->endpoint->support_path) {
+		return;
+	}
+
+	if (!(hdr = pjsip_msg_find_hdr_by_name(task_data->rdata->msg_info.msg, &path_name, NULL))) {
+		return;
+	}
+
+	ast_string_field_build(task_data->endpoint, path, "%.*s", (int)hdr->hvalue.slen, hdr->hvalue.ptr);
 }
 
 static int rx_task(void *data)
@@ -444,6 +460,9 @@
 		ao2_callback(contacts, OBJ_NODATA | OBJ_MULTIPLE, registrar_delete_contact, NULL);
 	}
 
+	/* Process Path information */
+	update_path_data(task_data);
+
 	/* Update the contacts as things will probably have changed */
 	ao2_cleanup(contacts);
 	contacts = ast_sip_location_retrieve_aor_contacts(task_data->aor);
@@ -459,7 +478,7 @@
 	ao2_callback(contacts, 0, registrar_add_contact, tdata);
 
 	if (pjsip_get_response_addr(tdata->pool, task_data->rdata, &addr) == PJ_SUCCESS) {
-		pjsip_endpt_send_response(ast_sip_get_pjsip_endpoint(), &addr, tdata, NULL, NULL);
+		ast_sip_send_response(ast_sip_get_pjsip_endpoint(), &addr, tdata, task_data->endpoint);
 	} else {
 		pjsip_tx_data_dec_ref(tdata);
 	}




More information about the asterisk-commits mailing list