diff options
author | Benny Prijono <bennylp@teluu.com> | 2007-03-01 18:39:37 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2007-03-01 18:39:37 +0000 |
commit | 341422c2ad4f7b1d9a784bf473485043b9674753 (patch) | |
tree | e402cc5f639b6657036da8e9741b309887097223 /pjsip | |
parent | b4e052ff22291a55e9791baa1c8a73f278550215 (diff) |
Fixed ticket #153: UAC dialog doesn't update route_set when calling RFC 2543 UAS (thanks Binu K S)
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1026 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r-- | pjsip/src/pjsip/sip_dialog.c | 55 |
1 files changed, 43 insertions, 12 deletions
diff --git a/pjsip/src/pjsip/sip_dialog.c b/pjsip/src/pjsip/sip_dialog.c index 97bee7fa..bd6e99f1 100644 --- a/pjsip/src/pjsip/sip_dialog.c +++ b/pjsip/src/pjsip/sip_dialog.c @@ -1515,12 +1515,31 @@ on_return: pjsip_dlg_dec_lock(dlg); } +/* Update route-set from incoming message */ +static void dlg_update_routeset(pjsip_dialog *dlg, const pjsip_msg *msg) +{ + const pjsip_hdr *hdr, *end_hdr; + + pj_list_init(&dlg->route_set); + + end_hdr = &msg->hdr; + for (hdr=msg->hdr.prev; hdr!=end_hdr; hdr=hdr->prev) { + if (hdr->type == PJSIP_H_RECORD_ROUTE) { + pjsip_route_hdr *r; + r = pjsip_hdr_clone(dlg->pool, hdr); + pjsip_routing_hdr_set_route(r); + pj_list_push_back(&dlg->route_set, r); + } + } +} + /* This function is called by user agent upon receiving incoming response * message. */ void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata ) { unsigned i; + pj_bool_t routeset_updated = PJ_FALSE; int res_code; PJ_LOG(5,(dlg->obj_name, "Received %s", @@ -1558,7 +1577,6 @@ void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata ) pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) && pj_strcmp(&dlg->remote.info->tag, &rdata->msg_info.to->tag))) { - pjsip_hdr *hdr, *end_hdr; pjsip_contact_hdr *contact; /* Update To tag. */ @@ -1574,17 +1592,8 @@ 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. */ - pj_list_init(&dlg->route_set); - - end_hdr = &rdata->msg_info.msg->hdr; - for (hdr=rdata->msg_info.msg->hdr.prev; hdr!=end_hdr; hdr=hdr->prev) { - if (hdr->type == PJSIP_H_RECORD_ROUTE) { - pjsip_route_hdr *r; - r = pjsip_hdr_clone(dlg->pool, hdr); - pjsip_routing_hdr_set_route(r); - pj_list_push_back(&dlg->route_set, r); - } - } + dlg_update_routeset(dlg, rdata->msg_info.msg); + routeset_updated = PJ_TRUE; /* The remote target MUST be set to the URI from the Contact header * field of the response. @@ -1610,6 +1619,23 @@ void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata ) /* Update remote target (again) when receiving 2xx response messages * that's defined as target refresh. + * + * Also upon receiving 2xx response, recheck again the route set. + * This is for compatibility with RFC 2543, as described in Section + * 13.2.2.4 of RFC 3261: + + If the dialog identifier in the 2xx response matches the dialog + identifier of an existing dialog, the dialog MUST be transitioned to + the "confirmed" state, and the route set for the dialog MUST be + recomputed based on the 2xx response using the procedures of Section + 12.2.1.2. + + Note that the only piece of state that is recomputed is the route + set. Other pieces of state such as the highest sequence numbers + (remote and local) sent within the dialog are not recomputed. The + route set only is recomputed for backwards compatibility. RFC + 2543 did not mandate mirroring of the Record-Route header field in + a 1xx, only 2xx. */ if (pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) && res_code/100 == 2) @@ -1622,6 +1648,11 @@ void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata ) dlg->remote.contact = pjsip_hdr_clone(dlg->pool, contact); dlg->target = dlg->remote.contact->uri; } + + if (!routeset_updated) { + dlg_update_routeset(dlg, rdata->msg_info.msg); + routeset_updated = PJ_TRUE; + } } |