diff options
author | Benny Prijono <bennylp@teluu.com> | 2008-02-22 08:36:06 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2008-02-22 08:36:06 +0000 |
commit | 604b84d7eac9b00fd43dd52a35a23359f106277c (patch) | |
tree | ef783c2b47e7f22ece491baa31a701e3dbda2c1d /pjsip | |
parent | 2fe9c49e7d023c2efcc69ff835c49a3c3d8662e5 (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
Diffstat (limited to 'pjsip')
-rw-r--r-- | pjsip/include/pjsip/sip_transport.h | 5 | ||||
-rw-r--r-- | pjsip/include/pjsip/sip_util.h | 15 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_auth_client.c | 5 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_util.c | 61 |
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!! |