summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2008-02-22 08:36:06 +0000
committerBenny Prijono <bennylp@teluu.com>2008-02-22 08:36:06 +0000
commit604b84d7eac9b00fd43dd52a35a23359f106277c (patch)
treeef783c2b47e7f22ece491baa31a701e3dbda2c1d
parent2fe9c49e7d023c2efcc69ff835c49a3c3d8662e5 (diff)
Ticket #492: Bug in strict route processing when challenged with 401/407 response
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1816 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjsip/include/pjsip/sip_transport.h5
-rw-r--r--pjsip/include/pjsip/sip_util.h15
-rw-r--r--pjsip/src/pjsip/sip_auth_client.c5
-rw-r--r--pjsip/src/pjsip/sip_util.c61
4 files changed, 85 insertions, 1 deletions
diff --git a/pjsip/include/pjsip/sip_transport.h b/pjsip/include/pjsip/sip_transport.h
index 34ea4b21..9f9c028f 100644
--- a/pjsip/include/pjsip/sip_transport.h
+++ b/pjsip/include/pjsip/sip_transport.h
@@ -496,6 +496,11 @@ struct pjsip_tx_data
/** The message in this buffer. */
pjsip_msg *msg;
+ /** Strict route header saved by #pjsip_process_route_set(), to be
+ * restored by #pjsip_restore_strict_route_set().
+ */
+ pjsip_route_hdr *saved_strict_route;
+
/** Buffer to the printed text representation of the message. When the
* content of this buffer is set, then the transport will send the content
* of this buffer instead of re-printing the message structure. If the
diff --git a/pjsip/include/pjsip/sip_util.h b/pjsip/include/pjsip/sip_util.h
index b6b3df8e..92264be6 100644
--- a/pjsip/include/pjsip/sip_util.h
+++ b/pjsip/include/pjsip/sip_util.h
@@ -220,6 +220,21 @@ PJ_DECL(pj_status_t) pjsip_get_request_dest(const pjsip_tx_data *tdata,
PJ_DECL(pj_status_t) pjsip_process_route_set(pjsip_tx_data *tdata,
pjsip_host_info *dest_info );
+
+/**
+ * Swap the request URI and strict route back to the original position
+ * before #pjsip_process_route_set() function is called. If no strict
+ * route URI was found by #pjsip_process_route_set(), this function will
+ * do nothing.
+ *
+ * This function should only used internally by PJSIP client authentication
+ * module.
+ *
+ * @param tdata Transmit data containing request message.
+ */
+PJ_DECL(void) pjsip_restore_strict_route_set(pjsip_tx_data *tdata);
+
+
/**
* This structure holds the state of outgoing stateless request.
*/
diff --git a/pjsip/src/pjsip/sip_auth_client.c b/pjsip/src/pjsip/sip_auth_client.c
index 3994c0b4..bf09bad8 100644
--- a/pjsip/src/pjsip/sip_auth_client.c
+++ b/pjsip/src/pjsip/sip_auth_client.c
@@ -1098,6 +1098,11 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reinit_req( pjsip_auth_clt_sess *sess,
via = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
via->branch_param.slen = 0;
+ /* Restore strict route set.
+ * See http://trac.pjsip.org/repos/ticket/492
+ */
+ pjsip_restore_strict_route_set(tdata);
+
/* Must invalidate the message! */
pjsip_tx_data_invalidate_msg(tdata);
diff --git a/pjsip/src/pjsip/sip_util.c b/pjsip/src/pjsip/sip_util.c
index c48ff865..988547aa 100644
--- a/pjsip/src/pjsip/sip_util.c
+++ b/pjsip/src/pjsip/sip_util.c
@@ -720,6 +720,14 @@ PJ_DEF(pj_status_t) pjsip_process_route_set(pjsip_tx_data *tdata,
PJSIP_ENOTREQUESTMSG);
PJ_ASSERT_RETURN(dest_info != NULL, PJ_EINVAL);
+ /* Assert if the request contains strict route and strict
+ * route processing has been applied before. We need to
+ * restore the strict route with pjsip_restore_strict_route_set()
+ * before we can call this function again, otherwise strict
+ * route will be swapped twice!
+ */
+ PJ_ASSERT_RETURN(tdata->saved_strict_route==NULL, PJ_EBUG);
+
/* Find the first and last "Route" headers from the message. */
last_route_hdr = first_route_hdr = (pjsip_route_hdr*)
pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL);
@@ -775,8 +783,9 @@ PJ_DEF(pj_status_t) pjsip_process_route_set(pjsip_tx_data *tdata,
new_request_uri = (const pjsip_uri*)
pjsip_uri_get_uri((pjsip_uri*)topmost_route_uri);
pj_list_erase(first_route_hdr);
+ tdata->saved_strict_route = first_route_hdr;
if (first_route_hdr == last_route_hdr)
- last_route_hdr = NULL;
+ first_route_hdr = last_route_hdr = NULL;
}
target_uri = (pjsip_uri*)topmost_route_uri;
@@ -809,6 +818,56 @@ PJ_DEF(pj_status_t) pjsip_process_route_set(pjsip_tx_data *tdata,
}
+/*
+ * Swap the request URI and strict route back to the original position
+ * before #pjsip_process_route_set() function is called. This function
+ * should only used internally by PJSIP client authentication module.
+ */
+PJ_DEF(void) pjsip_restore_strict_route_set(pjsip_tx_data *tdata)
+{
+ pjsip_route_hdr *first_route_hdr, *last_route_hdr;
+
+ /* Check if we have found strict route before */
+ if (tdata->saved_strict_route == NULL) {
+ /* This request doesn't contain strict route */
+ return;
+ }
+
+ /* Find the first "Route" headers from the message. */
+ first_route_hdr = (pjsip_route_hdr*)
+ pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL);
+
+ if (first_route_hdr == NULL) {
+ /* User has modified message route? We don't expect this! */
+ pj_assert(!"Message route was modified?");
+ tdata->saved_strict_route = NULL;
+ return;
+ }
+
+ /* Find last Route header */
+ last_route_hdr = first_route_hdr;
+ while (last_route_hdr->next != (void*)&tdata->msg->hdr) {
+ pjsip_route_hdr *hdr;
+ hdr = (pjsip_route_hdr*)
+ pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE,
+ last_route_hdr->next);
+ if (!hdr)
+ break;
+ last_route_hdr = hdr;
+ }
+
+ /* Put the last Route header as request URI, delete last Route
+ * header, and insert the saved strict route as the first Route.
+ */
+ tdata->msg->line.req.uri = last_route_hdr->name_addr.uri;
+ pj_list_insert_before(first_route_hdr, tdata->saved_strict_route);
+ pj_list_erase(last_route_hdr);
+
+ /* Reset */
+ tdata->saved_strict_route = NULL;
+}
+
+
/* Transport callback for sending stateless request.
* This is one of the most bizzare function in pjsip, so
* good luck if you happen to debug this function!!