Index: /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 2314)
+++ /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 2315)
@@ -1231,4 +1231,18 @@
 #endif
 
+    /**
+     * Disconnect other call legs when more than one 2xx responses for 
+     * outgoing INVITE are received due to forking. Currently the library
+     * is not able to handle simultaneous forked media, so disconnecting
+     * the other call legs is necessary. 
+     *
+     * With this setting enabled, the library will handle only one of the
+     * connected call leg, and the other connected call legs will be
+     * disconnected. 
+     *
+     * Default: PJ_TRUE (only disable this setting for testing purposes).
+     */
+    pj_bool_t	     hangup_forked_call;
+
 } pjsua_config;
 
Index: /pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h	(revision 2314)
+++ /pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h	(revision 2315)
@@ -499,5 +499,5 @@
 			   pjsip_tpselector *sel);
 
-
+pjsip_dialog* on_dlg_forked(pjsip_dialog *first_set, pjsip_rx_data *res);
 pj_status_t acquire_call(const char *title,
                          pjsua_call_id call_id,
Index: /pjproject/trunk/pjsip/src/pjsip/sip_dialog.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsip/sip_dialog.c	(revision 2314)
+++ /pjproject/trunk/pjsip/src/pjsip/sip_dialog.c	(revision 2315)
@@ -581,5 +581,7 @@
 {
     pjsip_dialog *dlg;
-    const pjsip_route_hdr *r;
+    const pjsip_msg *msg = rdata->msg_info.msg;
+    const pjsip_hdr *end_hdr, *hdr;
+    const pjsip_contact_hdr *contact;
     pj_status_t status;
 
@@ -588,9 +590,9 @@
     
     /* rdata must be response message. */
-    PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_RESPONSE_MSG,
+    PJ_ASSERT_RETURN(msg->type == PJSIP_RESPONSE_MSG,
 		     PJSIP_ENOTRESPONSEMSG);
 
     /* Status code MUST be 1xx (but not 100), or 2xx */
-    status = rdata->msg_info.msg->line.status.code;
+    status = msg->line.status.code;
     PJ_ASSERT_RETURN( (status/100==1 && status!=100) ||
 		      (status/100==2), PJ_EBUG);
@@ -598,4 +600,10 @@
     /* To tag must present in the response. */
     PJ_ASSERT_RETURN(rdata->msg_info.to->tag.slen != 0, PJSIP_EMISSINGTAG);
+
+    /* Find Contact header in the response */
+    contact = (const pjsip_contact_hdr*)
+	      pjsip_msg_find_hdr(msg, PJSIP_H_CONTACT, NULL);
+    if (contact == NULL)
+	return PJSIP_EMISSINGHDR;
 
     /* Create the dialog. */
@@ -604,6 +612,6 @@
 	return status;
 
-    /* Clone remote target. */
-    dlg->target = (pjsip_uri*) pjsip_uri_clone(dlg->pool, first_dlg->target);
+    /* Set remote target from the response. */
+    dlg->target = (pjsip_uri*) pjsip_uri_clone(dlg->pool, contact->uri);
 
     /* Clone local info. */
@@ -637,5 +645,5 @@
 
     /* Dialog state depends on the response. */
-    status = rdata->msg_info.msg->line.status.code/100;
+    status = msg->line.status.code/100;
     if (status == 1 || status == 2)
 	dlg->state = PJSIP_DIALOG_STATE_ESTABLISHED;
@@ -652,15 +660,16 @@
     		   pjsip_hdr_clone(dlg->pool, first_dlg->call_id);
 
-    /* Duplicate Route-Set. */
+    /* Get route-set from the response. */
     pj_list_init(&dlg->route_set);
-    r = first_dlg->route_set.next;
-    while (r != &first_dlg->route_set) {
-	pjsip_route_hdr *h;
-
-	h = (pjsip_route_hdr*) pjsip_hdr_clone(dlg->pool, r);
-	pj_list_push_back(&dlg->route_set, h);
-
-	r = r->next;
-    }
+    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_route_hdr*) pjsip_hdr_clone(dlg->pool, hdr);
+	    pjsip_routing_hdr_set_route(r);
+	    pj_list_push_back(&dlg->route_set, r);
+	}
+    }
+
     //dlg->route_set_frozen = PJ_TRUE;
 
@@ -1814,4 +1823,39 @@
     }
 
+    /* Handle the case of forked response, when the application creates
+     * the forked dialog but not the invite session. In this case, the
+     * forked 200/OK response will be unhandled, and we must send ACK
+     * here.
+     */
+    if (dlg->usage_cnt==0) {
+	pj_status_t status;
+
+	if (rdata->msg_info.cseq->method.id==PJSIP_INVITE_METHOD && 
+	    rdata->msg_info.msg->line.status.code/100 == 2) 
+	{
+	    pjsip_tx_data *ack;
+
+	    status = pjsip_dlg_create_request(dlg, &pjsip_ack_method,
+					      rdata->msg_info.cseq->cseq,
+					      &ack);
+	    if (status == PJ_SUCCESS)
+		status = pjsip_dlg_send_request(dlg, ack, -1, NULL);
+	} else if (rdata->msg_info.msg->line.status.code==401 ||
+		   rdata->msg_info.msg->line.status.code==407)
+	{
+	    pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
+	    pjsip_tx_data *tdata;
+	    
+	    status = pjsip_auth_clt_reinit_req( &dlg->auth_sess, 
+						rdata, tsx->last_tx,
+						&tdata);
+	    
+	    if (status == PJ_SUCCESS) {
+		/* Re-send request. */
+		status = pjsip_dlg_send_request(dlg, tdata, -1, NULL);
+	    }
+	}
+    }
+
     /* Unhandled response does not necessarily mean error because
        dialog usages may choose to process the transaction state instead.
Index: /pjproject/trunk/pjsip/src/pjsip/sip_ua_layer.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsip/sip_ua_layer.c	(revision 2314)
+++ /pjproject/trunk/pjsip/src/pjsip/sip_ua_layer.c	(revision 2315)
@@ -833,4 +833,8 @@
 		dlg = (*mod_ua.param.on_dlg_forked)(dlg_set->dlg_list.next, 
 						    rdata);
+		if (dlg == NULL) {
+		    pj_mutex_unlock(mod_ua.mutex);
+		    return PJ_TRUE;
+		}
 	    } else {
 		dlg = dlg_set->dlg_list.next;
Index: /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c	(revision 2314)
+++ /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c	(revision 2315)
@@ -2944,4 +2944,45 @@
 
 /*
+ * Callback from UA layer when forked dialog response is received.
+ */
+pjsip_dialog* on_dlg_forked(pjsip_dialog *dlg, pjsip_rx_data *res)
+{
+    if (dlg->uac_has_2xx && 
+	res->msg_info.cseq->method.id == PJSIP_INVITE_METHOD &&
+	pjsip_rdata_get_tsx(res) == NULL &&
+	res->msg_info.msg->line.status.code/100 == 2) 
+    {
+	pjsip_dialog *forked_dlg;
+	pjsip_tx_data *bye;
+	pj_status_t status;
+
+	/* Create forked dialog */
+	status = pjsip_dlg_fork(dlg, res, &forked_dlg);
+	if (status != PJ_SUCCESS)
+	    return NULL;
+
+	pjsip_dlg_inc_lock(forked_dlg);
+
+	/* Disconnect the call */
+	status = pjsip_dlg_create_request(forked_dlg, &pjsip_bye_method,
+					  -1, &bye);
+	if (status == PJ_SUCCESS) {
+	    status = pjsip_dlg_send_request(forked_dlg, bye, -1, NULL);
+	}
+
+	pjsip_dlg_dec_lock(forked_dlg);
+
+	if (status != PJ_SUCCESS) {
+	    return NULL;
+	}
+
+	return forked_dlg;
+
+    } else {
+	return dlg;
+    }
+}
+
+/*
  * Disconnect call upon error.
  */
Index: /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c	(revision 2314)
+++ /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c	(revision 2315)
@@ -97,4 +97,5 @@
     cfg->srtp_secure_signaling = PJSUA_DEFAULT_SRTP_SECURE_SIGNALING;
 #endif
+    cfg->hangup_forked_call = PJ_TRUE;
 }
 
@@ -623,4 +624,5 @@
     pjsua_media_config	 default_media_cfg;
     const pj_str_t	 STR_OPTIONS = { "OPTIONS", 7 };
+    pjsip_ua_init_param  ua_init_param;
     pj_status_t status;
 
@@ -695,5 +697,9 @@
 
     /* Initialize UA layer module: */
-    status = pjsip_ua_init_module( pjsua_var.endpt, NULL );
+    pj_bzero(&ua_init_param, sizeof(ua_init_param));
+    if (ua_cfg->hangup_forked_call) {
+	ua_init_param.on_dlg_forked = &on_dlg_forked;
+    }
+    status = pjsip_ua_init_module( pjsua_var.endpt, &ua_init_param);
     PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
