summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2007-03-17 22:21:58 +0000
committerBenny Prijono <bennylp@teluu.com>2007-03-17 22:21:58 +0000
commit4c8e2d99a37d79df6d1353cec6fac57def32b879 (patch)
treeef7e57deba90abef99729377e82095c9160a258c
parent3f22f72cfe81c4a04de6f45db50ef31951607071 (diff)
Fixed ticket #186: Major bug with destination address calculation for strict route set (thanks Hoi-Ho Chan)
git-svn-id: http://svn.pjsip.org/repos/pjproject/branches/pjproject-0.5-stable@1077 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjsip/include/pjsip/sip_util.h31
-rw-r--r--pjsip/src/pjsip/sip_transaction.c2
-rw-r--r--pjsip/src/pjsip/sip_util.c69
3 files changed, 94 insertions, 8 deletions
diff --git a/pjsip/include/pjsip/sip_util.h b/pjsip/include/pjsip/sip_util.h
index 84affed6..4d19d306 100644
--- a/pjsip/include/pjsip/sip_util.h
+++ b/pjsip/include/pjsip/sip_util.h
@@ -172,6 +172,33 @@ PJ_DECL(pj_status_t) pjsip_endpt_create_cancel( pjsip_endpoint *endpt,
* used here follows the guidelines on sending the request in RFC 3261
* chapter 8.1.2.
*
+ * Note there was a change in the behavior of this function since version
+ * 0.5.10.2. Previously this function may modify the request when strict
+ * route is present (to update request URI and route-set). This is no
+ * longer the case now, and this process is done in separate function
+ * (see #pjsip_process_route_set()).
+ *
+ * @param tdata The transmit data containing the request message.
+ * @param dest_info On return, it contains information about destination
+ * host to contact, along with the preferable transport
+ * type, if any. Caller will then normally proceed with
+ * resolving this host with server resolution procedure
+ * described in RFC 3263.
+ *
+ * @return PJ_SUCCESS, or the appropriate error code.
+ *
+ * @see pjsip_process_route_set
+ */
+PJ_DECL(pj_status_t) pjsip_get_request_dest(const pjsip_tx_data *tdata,
+ pjsip_host_info *dest_info );
+
+
+/**
+ * Process route-set found in the request and calculate destination to be
+ * used to send the request message, based on the request URI and Route
+ * headers in the message. The procedure used here follows the guidelines
+ * on sending the request in RFC 3261 chapter 8.1.2.
+ *
* This function may modify the message (request line and Route headers),
* if the Route information specifies strict routing and the request
* URI in the message is different than the calculated target URI. In that
@@ -186,8 +213,10 @@ PJ_DECL(pj_status_t) pjsip_endpt_create_cancel( pjsip_endpoint *endpt,
* described in RFC 3263.
*
* @return PJ_SUCCESS, or the appropriate error code.
+ *
+ * @see pjsip_get_request_addr
*/
-PJ_DECL(pj_status_t) pjsip_get_request_addr( pjsip_tx_data *tdata,
+PJ_DECL(pj_status_t) pjsip_process_route_set(pjsip_tx_data *tdata,
pjsip_host_info *dest_info );
diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c
index 00893ff5..911cd6c3 100644
--- a/pjsip/src/pjsip/sip_transaction.c
+++ b/pjsip/src/pjsip/sip_transaction.c
@@ -1199,7 +1199,7 @@ PJ_DEF(pj_status_t) pjsip_tsx_create_uac( pjsip_module *tsx_user,
/* Determine whether reliable transport should be used initially.
* This will be updated whenever transport has changed.
*/
- status = pjsip_get_request_addr(tdata, &dst_info);
+ status = pjsip_get_request_dest(tdata, &dst_info);
if (status != PJ_SUCCESS) {
tsx_destroy(tsx);
return status;
diff --git a/pjsip/src/pjsip/sip_util.c b/pjsip/src/pjsip/sip_util.c
index 946bc64d..7fd72119 100644
--- a/pjsip/src/pjsip/sip_util.c
+++ b/pjsip/src/pjsip/sip_util.c
@@ -625,7 +625,67 @@ on_missing_hdr:
* used here follows the guidelines on sending the request in RFC 3261
* chapter 8.1.2.
*/
-PJ_DEF(pj_status_t) pjsip_get_request_addr( pjsip_tx_data *tdata,
+PJ_DEF(pj_status_t) pjsip_get_request_dest(const pjsip_tx_data *tdata,
+ pjsip_host_info *dest_info )
+{
+ const pjsip_uri *target_uri;
+ const pjsip_route_hdr *first_route_hdr;
+
+ PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_REQUEST_MSG,
+ PJSIP_ENOTREQUESTMSG);
+ PJ_ASSERT_RETURN(dest_info != NULL, PJ_EINVAL);
+
+ /* Get the first "Route" header from the message.
+ */
+ first_route_hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL);
+ if (first_route_hdr) {
+ target_uri = (const pjsip_uri*)&first_route_hdr->name_addr;
+ } else {
+ target_uri = tdata->msg->line.req.uri;
+ }
+
+
+ /* The target URI must be a SIP/SIPS URL so we can resolve it's address.
+ * Otherwise we're in trouble (i.e. there's no host part in tel: URL).
+ */
+ pj_bzero(dest_info, sizeof(*dest_info));
+
+ if (PJSIP_URI_SCHEME_IS_SIPS(target_uri)) {
+ pjsip_uri *uri = (pjsip_uri*) target_uri;
+ const pjsip_sip_uri *url=(const pjsip_sip_uri*)pjsip_uri_get_uri(uri);
+ dest_info->flag |= (PJSIP_TRANSPORT_SECURE | PJSIP_TRANSPORT_RELIABLE);
+ pj_strdup(tdata->pool, &dest_info->addr.host, &url->host);
+ dest_info->addr.port = url->port;
+ dest_info->type =
+ pjsip_transport_get_type_from_name(&url->transport_param);
+
+ } else if (PJSIP_URI_SCHEME_IS_SIP(target_uri)) {
+ pjsip_uri *uri = (pjsip_uri*) target_uri;
+ const pjsip_sip_uri *url=(const pjsip_sip_uri*)pjsip_uri_get_uri(uri);
+ pj_strdup(tdata->pool, &dest_info->addr.host, &url->host);
+ dest_info->addr.port = url->port;
+ dest_info->type =
+ pjsip_transport_get_type_from_name(&url->transport_param);
+ dest_info->flag =
+ pjsip_transport_get_flag_from_type(dest_info->type);
+ } else {
+ pj_assert(!"Unsupported URI scheme!");
+ PJ_TODO(SUPPORT_REQUEST_ADDR_RESOLUTION_FOR_TEL_URI);
+ return PJSIP_EINVALIDSCHEME;
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Process route-set found in the request and calculate
+ * the destination to be used to send the request message, based
+ * on the request URI and Route headers in the message. The procedure
+ * used here follows the guidelines on sending the request in RFC 3261
+ * chapter 8.1.2.
+ */
+PJ_DEF(pj_status_t) pjsip_process_route_set(pjsip_tx_data *tdata,
pjsip_host_info *dest_info )
{
const pjsip_uri *new_request_uri, *target_uri;
@@ -636,10 +696,7 @@ PJ_DEF(pj_status_t) pjsip_get_request_addr( pjsip_tx_data *tdata,
PJSIP_ENOTREQUESTMSG);
PJ_ASSERT_RETURN(dest_info != NULL, PJ_EINVAL);
- /* Get the first "Route" header from the message. If the message doesn't
- * have any "Route" headers but the endpoint has, then copy the "Route"
- * headers from the endpoint first.
- */
+ /* Find the first and last "Route" headers from the message. */
last_route_hdr = first_route_hdr =
pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL);
if (first_route_hdr) {
@@ -946,7 +1003,7 @@ pjsip_endpt_send_request_stateless(pjsip_endpoint *endpt,
PJ_ASSERT_RETURN(endpt && tdata, PJ_EINVAL);
/* Get destination name to contact. */
- status = pjsip_get_request_addr(tdata, &dest_info);
+ status = pjsip_process_route_set(tdata, &dest_info);
if (status != PJ_SUCCESS)
return status;