summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2007-02-19 18:37:42 +0000
committerBenny Prijono <bennylp@teluu.com>2007-02-19 18:37:42 +0000
commitb4363468b7fed4b36a45b5893ed475b1128fb4de (patch)
tree5db95e495f44ed1bbda044351a68634fff41cb9d
parent1c001439c1bbe352f5b6a972ac601a786a00ff14 (diff)
Fixed ticket #111 on stable branch: workaround for forked dialog
git-svn-id: http://svn.pjsip.org/repos/pjproject/branches/pjproject-0.5-stable@980 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjsip/include/pjsip/sip_dialog.h1
-rw-r--r--pjsip/src/pjsip/sip_dialog.c35
2 files changed, 31 insertions, 5 deletions
diff --git a/pjsip/include/pjsip/sip_dialog.h b/pjsip/include/pjsip/sip_dialog.h
index cb2e90fa..deaa80ac 100644
--- a/pjsip/include/pjsip/sip_dialog.h
+++ b/pjsip/include/pjsip/sip_dialog.h
@@ -124,6 +124,7 @@ struct pjsip_dialog
pjsip_dlg_party local; /**< Local party info. */
pjsip_dlg_party remote; /**< Remote party info. */
pjsip_role_e role; /**< Initial role. */
+ pj_bool_t uac_has_2xx;/**< UAC has received 2xx response? */
pj_bool_t secure; /**< Use secure transport? */
pjsip_cid_hdr *call_id; /**< Call-ID header. */
pjsip_route_hdr route_set; /**< Route set. */
diff --git a/pjsip/src/pjsip/sip_dialog.c b/pjsip/src/pjsip/sip_dialog.c
index e22091d9..dc9d8ffa 100644
--- a/pjsip/src/pjsip/sip_dialog.c
+++ b/pjsip/src/pjsip/sip_dialog.c
@@ -1518,11 +1518,26 @@ void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata )
/* When we receive response that establishes dialog, update To tag,
* route set and dialog target.
- */
- if (dlg->state == PJSIP_DIALOG_STATE_NULL &&
- pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) &&
- (res_code > 100 && res_code < 300) &&
- rdata->msg_info.to->tag.slen)
+ *
+ * The second condition of the "if" is a workaround for forking.
+ * Originally, the dialog takes the first To tag seen and set it as
+ * the remote tag. If the tag in 2xx response is different than this
+ * tag, ACK will be sent with wrong To tag and incoming request with
+ * this tag will be rejected with 481.
+ *
+ * The workaround for this is to take the To tag received in the
+ * 2xx response and set it as remote tag.
+ */
+ if ((dlg->state == PJSIP_DIALOG_STATE_NULL &&
+ pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) &&
+ (res_code > 100 && res_code < 300) &&
+ rdata->msg_info.to->tag.slen)
+ ||
+ (dlg->role==PJSIP_ROLE_UAC &&
+ !dlg->uac_has_2xx &&
+ res_code/100 == 2 &&
+ 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;
@@ -1563,6 +1578,16 @@ void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata )
}
dlg->state = PJSIP_DIALOG_STATE_ESTABLISHED;
+
+
+ /* Prevent dialog from being updated just in case more 2xx
+ * gets through this dialog (it shouldn't happen).
+ */
+ if (dlg->role==PJSIP_ROLE_UAC && !dlg->uac_has_2xx &&
+ res_code/100==2)
+ {
+ dlg->uac_has_2xx = PJ_TRUE;
+ }
}
/* Update remote target (again) when receiving 2xx response messages