Index: pjproject/trunk/pjsip/include/pjsip/sip_transport.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsip/sip_transport.h	(revision 2931)
+++ pjproject/trunk/pjsip/include/pjsip/sip_transport.h	(revision 2932)
@@ -28,4 +28,5 @@
 #include <pjsip/sip_msg.h>
 #include <pjsip/sip_parser.h>
+#include <pjsip/sip_resolve.h>
 #include <pj/sock.h>
 #include <pj/list.h>
@@ -522,4 +523,24 @@
     /** Callback to be called when this tx_data has been transmitted.	*/
     void	       (*cb)(void*, pjsip_tx_data*, pj_ssize_t);
+
+    /** Destination information, to be used to determine the network address
+     *  of the message. For a request, this information is  initialized when
+     *  the request is sent with #pjsip_endpt_send_request_stateless() and
+     *  network address is resolved. For CANCEL request, this information
+     *  will be copied from the original INVITE to make sure that the CANCEL
+     *  request goes to the same physical network address as the INVITE
+     *  request.
+     */
+    struct
+    {
+	/** Server addresses resolved. 
+	 */
+	pjsip_server_addresses   addr;
+
+	/** Current server address being tried. 
+	 */
+	unsigned cur_addr;
+
+    } dest_info;
 
     /** Transport information, only valid during on_tx_request() and 
Index: pjproject/trunk/pjsip/include/pjsip/sip_util.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsip/sip_util.h	(revision 2931)
+++ pjproject/trunk/pjsip/include/pjsip/sip_util.h	(revision 2932)
@@ -452,12 +452,4 @@
     pjsip_tx_data *tdata;
 
-    /** Server addresses resolved. 
-     */
-    pjsip_server_addresses   addr;
-
-    /** Current server address being tried. 
-     */
-    unsigned cur_addr;
-
     /** Current transport being used. 
      */
Index: pjproject/trunk/pjsip/src/pjsip/sip_transaction.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_transaction.c	(revision 2931)
+++ pjproject/trunk/pjsip/src/pjsip/sip_transaction.c	(revision 2932)
@@ -1627,4 +1627,5 @@
 {
     pjsip_transaction *tsx = (pjsip_transaction*) send_state->token;
+    pjsip_tx_data *tdata = send_state->tdata;
     struct tsx_lock_data lck;
 
@@ -1645,7 +1646,7 @@
 
 	    /* Update remote address. */
-	    tsx->addr_len = send_state->addr.entry[send_state->cur_addr].addr_len;
+	    tsx->addr_len = tdata->dest_info.addr.entry[tdata->dest_info.cur_addr].addr_len;
 	    pj_memcpy(&tsx->addr, 
-		      &send_state->addr.entry[send_state->cur_addr].addr,
+		      &tdata->dest_info.addr.entry[tdata->dest_info.cur_addr].addr,
 		      tsx->addr_len);
 
Index: pjproject/trunk/pjsip/src/pjsip/sip_util.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_util.c	(revision 2931)
+++ pjproject/trunk/pjsip/src/pjsip/sip_util.c	(revision 2932)
@@ -755,4 +755,16 @@
     }
 
+    /* Must also copy the saved strict route header, otherwise CANCEL will be
+     * sent with swapped Route and request URI!
+     */
+    if (req_tdata->saved_strict_route) {
+	cancel_tdata->saved_strict_route = (pjsip_route_hdr*)
+	    pjsip_hdr_clone(cancel_tdata->pool, req_tdata->saved_strict_route);
+    }
+
+    /* Finally copy the destination info from the original request */
+    pj_memcpy(&cancel_tdata->dest_info, &req_tdata->dest_info,
+	      sizeof(req_tdata->dest_info));
+
     /* Done.
      * Return the transmit buffer containing the CANCEL request.
@@ -1058,5 +1070,5 @@
 	     */
 	    cont = (sent > 0) ? PJ_FALSE :
-		   (stateless_data->cur_addr<stateless_data->addr.count-1);
+		   (tdata->dest_info.cur_addr<tdata->dest_info.addr.count-1);
 	    if (stateless_data->app_cb) {
 		(*stateless_data->app_cb)(stateless_data, sent, &cont);
@@ -1085,9 +1097,9 @@
 	 */
 	if (sent != -PJ_EPENDING) {
-	    stateless_data->cur_addr++;
+	    tdata->dest_info.cur_addr++;
 	}
 
 	/* Have next address? */
-	if (stateless_data->cur_addr >= stateless_data->addr.count) {
+	if (tdata->dest_info.cur_addr >= tdata->dest_info.addr.count) {
 	    /* This only happens when a rather buggy application has
 	     * sent 'cont' to PJ_TRUE when the initial value was PJ_FALSE.
@@ -1101,7 +1113,7 @@
 
 	/* Keep current server address information handy. */
-	cur_addr = &stateless_data->addr.entry[stateless_data->cur_addr].addr;
-	cur_addr_type = stateless_data->addr.entry[stateless_data->cur_addr].type;
-	cur_addr_len = stateless_data->addr.entry[stateless_data->cur_addr].addr_len;
+	cur_addr = &tdata->dest_info.addr.entry[tdata->dest_info.cur_addr].addr;
+	cur_addr_type = tdata->dest_info.addr.entry[tdata->dest_info.cur_addr].type;
+	cur_addr_len = tdata->dest_info.addr.entry[tdata->dest_info.cur_addr].addr_len;
 
 	/* Acquire transport. */
@@ -1179,4 +1191,5 @@
 {
     pjsip_send_state *stateless_data = (pjsip_send_state*) token;
+    pjsip_tx_data *tdata = stateless_data->tdata;
 
     /* Fail on server resolution. */
@@ -1186,10 +1199,14 @@
 	    (*stateless_data->app_cb)(stateless_data, -status, &cont);
 	}
-	pjsip_tx_data_dec_ref(stateless_data->tdata);
+	pjsip_tx_data_dec_ref(tdata);
 	return;
     }
 
     /* Copy server addresses */
-    pj_memcpy( &stateless_data->addr, addr, sizeof(pjsip_server_addresses));
+    if (addr && addr != &tdata->dest_info.addr) {
+	pj_memcpy( &tdata->dest_info.addr, addr, 
+	           sizeof(pjsip_server_addresses));
+    }
+    pj_assert(tdata->dest_info.addr.count != 0);
 
 #if !defined(PJSIP_DONT_SWITCH_TO_TCP) || PJSIP_DONT_SWITCH_TO_TCP==0
@@ -1200,12 +1217,12 @@
      * as TCP.
      */
-    if (stateless_data->tdata->msg->type == PJSIP_REQUEST_MSG &&
-	addr->count > 0 && 
-	addr->entry[0].type == PJSIP_TRANSPORT_UDP)
+    if (tdata->msg->type == PJSIP_REQUEST_MSG &&
+	tdata->dest_info.addr.count > 0 && 
+	tdata->dest_info.addr.entry[0].type == PJSIP_TRANSPORT_UDP)
     {
 	int len;
 
 	/* Encode the request */
-	status = pjsip_tx_data_encode(stateless_data->tdata);
+	status = pjsip_tx_data_encode(tdata);
 	if (status != PJ_SUCCESS) {
 	    if (stateless_data->app_cb) {
@@ -1213,14 +1230,18 @@
 		(*stateless_data->app_cb)(stateless_data, -status, &cont);
 	    }
-	    pjsip_tx_data_dec_ref(stateless_data->tdata);
+	    pjsip_tx_data_dec_ref(tdata);
 	    return;
 	}
 
 	/* Check if request message is larger than 1300 bytes. */
-	len = stateless_data->tdata->buf.cur - 
-		stateless_data->tdata->buf.start;
+	len = tdata->buf.cur - tdata->buf.start;
 	if (len >= PJSIP_UDP_SIZE_THRESHOLD) {
 	    int i;
-	    int count = stateless_data->addr.count;
+	    int count = tdata->dest_info.addr.count;
+
+	    PJ_LOG(5,(THIS_FILE, "%s exceeds UDP size threshold (%u), "
+				 "sending with TCP",
+				 pjsip_tx_data_get_info(tdata),
+				 PJSIP_UDP_SIZE_THRESHOLD));
 
 	    /* Insert "TCP version" of resolved UDP addresses at the
@@ -1230,10 +1251,10 @@
 		count = PJSIP_MAX_RESOLVED_ADDRESSES / 2;
 	    for (i = 0; i < count; ++i) {
-		pj_memcpy(&stateless_data->addr.entry[i+count],
-			  &stateless_data->addr.entry[i],
-			  sizeof(stateless_data->addr.entry[0]));
-		stateless_data->addr.entry[i].type = PJSIP_TRANSPORT_TCP;
+		pj_memcpy(&tdata->dest_info.addr.entry[i+count],
+			  &tdata->dest_info.addr.entry[i],
+			  sizeof(tdata->dest_info.addr.entry[0]));
+		tdata->dest_info.addr.entry[i].type = PJSIP_TRANSPORT_TCP;
 	    }
-	    stateless_data->addr.count = count * 2;
+	    tdata->dest_info.addr.count = count * 2;
 	}
     }
@@ -1241,6 +1262,5 @@
 
     /* Process the addresses. */
-    stateless_send_transport_cb( stateless_data, stateless_data->tdata,
-				 -PJ_EPENDING);
+    stateless_send_transport_cb( stateless_data, tdata, -PJ_EPENDING);
 }
 
@@ -1276,9 +1296,20 @@
     stateless_data->app_cb = cb;
 
-    /* Resolve destination host.
-     * The processing then resumed when the resolving callback is called.
-     */
-    pjsip_endpt_resolve( endpt, tdata->pool, &dest_info, stateless_data,
-			 &stateless_send_resolver_callback);
+    /* If destination info has not been initialized (this applies for most
+     * all requests except CANCEL), resolve destination host. The processing
+     * then resumed when the resolving callback is called. For CANCEL, the
+     * destination info must have been copied from the original INVITE so
+     * proceed to sending the request directly.
+     */
+    if (tdata->dest_info.addr.count == 0) {
+	pjsip_endpt_resolve( endpt, tdata->pool, &dest_info, stateless_data,
+			     &stateless_send_resolver_callback);
+    } else {
+	PJ_LOG(5,(THIS_FILE, "%s: skipping target resolution because "
+	                     "address is already set",
+			     pjsip_tx_data_get_info(tdata)));
+	stateless_send_resolver_callback(PJ_SUCCESS, stateless_data,
+					 &tdata->dest_info.addr);
+    }
     return PJ_SUCCESS;
 }
@@ -1591,5 +1622,5 @@
 
     /* Update address in send_state. */
-    send_state->addr = *addr;
+    pj_memcpy(&send_state->tdata->dest_info.addr, addr, sizeof(*addr));
 
     /* Send response using the transoprt. */
