Update ticket #408: although route set must not be updated on subsequent requests, dialog MUST recompute the route set upon receiving 2xx response if the route set was previously computed from 1xx response

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@1550 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
Benny Prijono 2007-11-05 23:14:18 +00:00
parent 7129cc7234
commit 42307c7b79
1 changed files with 52 additions and 6 deletions

View File

@ -642,7 +642,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_fork( const pjsip_dialog *first_dlg,
r = r->next;
}
dlg->route_set_frozen = PJ_TRUE;
//dlg->route_set_frozen = PJ_TRUE;
/* Clone client authentication session. */
status = pjsip_auth_clt_clone(dlg->pool, &dlg->auth_sess,
@ -1538,16 +1538,49 @@ on_return:
}
/* Update route-set from incoming message */
static void dlg_update_routeset(pjsip_dialog *dlg, const pjsip_msg *msg)
static void dlg_update_routeset(pjsip_dialog *dlg, const pjsip_rx_data *rdata)
{
const pjsip_hdr *hdr, *end_hdr;
pj_int32_t msg_cseq;
const pjsip_msg *msg;
/* Ignore if route set has been set */
msg = rdata->msg_info.msg;
msg_cseq = rdata->msg_info.cseq->cseq;
/* Ignore if route set has been frozen */
if (dlg->route_set_frozen)
return;
/* Only update route set if this message belongs to the same
* transaction as the initial transaction that establishes dialog.
*/
if (dlg->role == PJSIP_ROLE_UAC) {
/* Ignore subsequent request from remote */
if (msg->type != PJSIP_RESPONSE_MSG)
return;
/* Ignore subsequent responses with higher CSeq than initial CSeq */
if (msg_cseq != dlg->local.first_cseq)
return;
} else {
/* For callee dialog, route set should have been set by initial
* request and it will have been rejected by dlg->route_set_frozen
* check above.
*/
pj_assert(!"Should not happen");
}
/* Based on the checks above, we should only get response message here */
pj_assert(msg->type == PJSIP_RESPONSE_MSG);
/* Reset route set */
pj_list_init(&dlg->route_set);
/* Update route set */
end_hdr = &msg->hdr;
for (hdr=msg->hdr.prev; hdr!=end_hdr; hdr=hdr->prev) {
if (hdr->type == PJSIP_H_RECORD_ROUTE) {
@ -1557,9 +1590,22 @@ static void dlg_update_routeset(pjsip_dialog *dlg, const pjsip_msg *msg)
pj_list_push_back(&dlg->route_set, r);
}
}
dlg->route_set_frozen = PJ_TRUE;
/* Freeze the route set only when the route set comes in 2xx response.
* If it is in 1xx response, prepare to recompute the route set when
* the 2xx response comes in.
*
* There is a debate whether route set should be frozen when the dialog
* is established with reliable provisional response, but I think
* it is safer to not freeze the route set (thus recompute the route set
* upon receiving 2xx response). Also RFC 3261 says so in 13.2.2.4.
*/
if (PJSIP_IS_STATUS_IN_CLASS(msg->line.status.code, 200)) {
dlg->route_set_frozen = PJ_TRUE;
}
}
/* This function is called by user agent upon receiving incoming response
* message.
*/
@ -1618,7 +1664,7 @@ void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata )
* empty set. This route set, even if empty, overrides any pre-existing
* route set for future requests in this dialog.
*/
dlg_update_routeset(dlg, rdata->msg_info.msg);
dlg_update_routeset(dlg, rdata);
/* The remote target MUST be set to the URI from the Contact header
* field of the response.
@ -1678,7 +1724,7 @@ void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata )
dlg->target = dlg->remote.contact->uri;
}
dlg_update_routeset(dlg, rdata->msg_info.msg);
dlg_update_routeset(dlg, rdata);
}