Index: pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c	(revision 575)
+++ pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c	(revision 576)
@@ -233,8 +233,15 @@
     method = &rdata->msg_info.msg->line.req.method;
 
-    if (method->id == PJSIP_INVITE_METHOD ||
-	method->id == PJSIP_CANCEL_METHOD ||
-	method->id == PJSIP_BYE_METHOD)
+    if (method->id == PJSIP_INVITE_METHOD) {
+	return PJ_TRUE;
+    }
+
+    /* BYE and CANCEL must have existing invite session */
+    if (method->id == PJSIP_BYE_METHOD ||
+	method->id == PJSIP_CANCEL_METHOD)
     {
+	if (inv == NULL)
+	    return PJ_FALSE;
+
 	return PJ_TRUE;
     }
@@ -781,4 +788,11 @@
 
 	*p_tdata = tdata;
+
+	/* Can not return PJ_SUCCESS when response message is produced.
+	 * Ref: PROTOS test ~#2490
+	 */
+	if (status == PJ_SUCCESS)
+	    status = PJSIP_ERRNO_FROM_SIP_STATUS(code);
+
     }
 
@@ -2205,5 +2219,24 @@
 
     }
-
+    else if (tsx->method.id == PJSIP_CANCEL_METHOD &&
+	     tsx->role == PJSIP_ROLE_UAS &&
+	     tsx->status_code < 200 &&
+	     e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) 
+    {
+
+	/*
+	 * Handle strandled incoming CANCEL.
+	 */
+	pjsip_rx_data *rdata = e->body.tsx_state.src.rdata;
+	pjsip_tx_data *tdata;
+	pj_status_t status;
+
+	status = pjsip_dlg_create_response(dlg, rdata, 200, NULL, &tdata);
+	if (status != PJ_SUCCESS) return;
+
+	status = pjsip_dlg_send_response(dlg, tsx, tdata);
+	if (status != PJ_SUCCESS) return;
+
+    }
 }
 
@@ -2243,4 +2276,24 @@
 
 	inv_respond_incoming_bye( inv, tsx, e->body.tsx_state.src.rdata, e );
+
+    }
+    else if (tsx->method.id == PJSIP_CANCEL_METHOD &&
+	     tsx->role == PJSIP_ROLE_UAS &&
+	     tsx->status_code < 200 &&
+	     e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) 
+    {
+
+	/*
+	 * Handle strandled incoming CANCEL.
+	 */
+	pjsip_rx_data *rdata = e->body.tsx_state.src.rdata;
+	pjsip_tx_data *tdata;
+	pj_status_t status;
+
+	status = pjsip_dlg_create_response(dlg, rdata, 200, NULL, &tdata);
+	if (status != PJ_SUCCESS) return;
+
+	status = pjsip_dlg_send_response(dlg, tsx, tdata);
+	if (status != PJ_SUCCESS) return;
 
     }
@@ -2378,17 +2431,30 @@
     PJ_ASSERT_ON_FAIL(tsx && dlg, return);
 
-    if (tsx->method.id == PJSIP_BYE_METHOD &&
-	tsx->role == PJSIP_ROLE_UAS &&
+    if (tsx->role == PJSIP_ROLE_UAS &&
 	tsx->status_code < 200 &&
 	e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) 
     {
+	pjsip_rx_data *rdata = e->body.tsx_state.src.rdata;
 
 	/*
-	 * Be nice, handle incoming BYE.
+	 * Respond BYE with 200/OK
 	 */
-
-	inv_respond_incoming_bye( inv, tsx, e->body.tsx_state.src.rdata, e );
-
-    }
-}
-
+	if (tsx->method.id == PJSIP_BYE_METHOD) {
+	    inv_respond_incoming_bye( inv, tsx, rdata, e );
+	} else if (tsx->method.id == PJSIP_CANCEL_METHOD) {
+	    /*
+	     * Respond CANCEL with 200/OK too.
+	     */
+	    pjsip_tx_data *tdata;
+	    pj_status_t status;
+
+	    status = pjsip_dlg_create_response(dlg, rdata, 200, NULL, &tdata);
+	    if (status != PJ_SUCCESS) return;
+
+	    status = pjsip_dlg_send_response(dlg, tsx, tdata);
+	    if (status != PJ_SUCCESS) return;
+
+	}
+    }
+}
+
Index: pjproject/trunk/pjsip/src/pjsip/sip_dialog.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_dialog.c	(revision 575)
+++ pjproject/trunk/pjsip/src/pjsip/sip_dialog.c	(revision 576)
@@ -703,7 +703,9 @@
     --dlg->sess_count;
 
-    if (dlg->sess_count==0 && dlg->tsx_count==0)
+    if (dlg->sess_count==0 && dlg->tsx_count==0) {
+	pj_mutex_unlock(dlg->mutex);
+	pj_mutex_lock(dlg->mutex);
 	unregister_and_destroy_dialog(dlg);
-    else {
+    } else {
 	pj_mutex_unlock(dlg->mutex);
     }
@@ -972,4 +974,6 @@
      */
     if (msg->line.req.method.id != PJSIP_ACK_METHOD) {
+	int tsx_count;
+
 	status = pjsip_tsx_create_uac(dlg->ua, tdata, &tsx);
 	if (status != PJ_SUCCESS)
@@ -986,10 +990,11 @@
 
 	/* Increment transaction counter. */
-	++dlg->tsx_count;
+	tsx_count = ++dlg->tsx_count;
 
 	/* Send the message. */
 	status = pjsip_tsx_send_msg(tsx, tdata);
 	if (status != PJ_SUCCESS) {
-	    pjsip_tsx_terminate(tsx, tsx->status_code);
+	    if (dlg->tsx_count == tsx_count)
+		pjsip_tsx_terminate(tsx, tsx->status_code);
 	    goto on_error;
 	}
@@ -1260,4 +1265,5 @@
     pj_status_t status;
     pjsip_transaction *tsx = NULL;
+    pj_bool_t processed = PJ_FALSE;
     unsigned i;
 
@@ -1317,5 +1323,4 @@
     /* Report the request to dialog usages. */
     for (i=0; i<dlg->usage_cnt; ++i) {
-	pj_bool_t processed;
 
 	if (!dlg->usage[i]->on_rx_request)
@@ -1331,4 +1336,21 @@
     if (tsx)
 	pjsip_tsx_recv_msg(tsx, rdata);
+
+    /* If no dialog usages has claimed the processing of the transaction,
+     * and if transaction has not sent final response, respond with
+     * 500/Internal Server Error.
+     */
+    if (!processed && tsx && tsx->status_code < 200) {
+	pjsip_tx_data *tdata;
+	const pj_str_t reason = { "No session found", 16};
+
+	PJ_LOG(4,(tsx->obj_name, "Incoming request was unhandled by "
+				 "dialog usages, sending 500 response"));
+
+	status = pjsip_dlg_create_response(dlg, rdata, 500, &reason, &tdata);
+	if (status == PJ_SUCCESS) {
+	    status = pjsip_dlg_send_response(dlg, tsx, tdata);
+	}
+    }
 
 on_return:
Index: pjproject/trunk/pjsip/src/pjsip/sip_parser.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_parser.c	(revision 575)
+++ pjproject/trunk/pjsip/src/pjsip/sip_parser.c	(revision 576)
@@ -479,4 +479,5 @@
     rec.hname_len = strlen(name);
     if (rec.hname_len >= sizeof(rec.hname)) {
+	pj_assert(!"Header name is too long!");
 	return PJ_ENAMETOOLONG;
     }
@@ -546,5 +547,5 @@
 
     if (hname->slen >= PJSIP_MAX_HNAME_LEN) {
-        pj_assert(!"Header name is too long!");
+	/* Guaranteed not to be able to find handler. */
         return NULL;
     }
@@ -832,4 +833,9 @@
 	    pjsip_parse_hdr_func * handler;
 	    pjsip_hdr *hdr = NULL;
+
+	    /* Init hname just in case parsing fails.
+	     * Ref: PROTOS #2412
+	     */
+	    hname.slen = 0;
 	    
 	    /* Get hname. */
@@ -914,4 +920,8 @@
 	    if (parsing_headers)
 		err_info->hname = hname;
+	    else if (msg && msg->type == PJSIP_REQUEST_MSG)
+		err_info->hname = pj_str("Request Line");
+	    else if (msg && msg->type == PJSIP_RESPONSE_MSG)
+		err_info->hname = pj_str("Status Line");
 	    else
 		err_info->hname.slen = 0;
@@ -1126,7 +1136,12 @@
 				pj_bool_t parse_params)
 {
+    /* Bug:
+     * This function should not call back int_parse_name_addr() because
+     * it is called by that function. This would cause stack overflow
+     * with PROTOS test #1223.
     if (*scanner->curptr=='"' || *scanner->curptr=='<') {
 	return (pjsip_uri*)int_parse_name_addr( scanner, pool );
     } else {
+    */
 	pj_str_t scheme;
 	int colon;
@@ -1148,5 +1163,8 @@
 	    UNREACHED({ return NULL; /* Not reached. */ })
 	}
-    }
+
+    /*
+    }
+    */
 }
 
Index: pjproject/trunk/pjsip/src/pjsip/sip_transport.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_transport.c	(revision 575)
+++ pjproject/trunk/pjsip/src/pjsip/sip_transport.c	(revision 576)
@@ -984,10 +984,12 @@
 
 	    PJ_LOG(1, (THIS_FILE, 
-		      "Error processing packet from %s:%d %.*s:\n"
-		      "%s\n"
+		      "Error processing %d bytes packet from %s:%d %.*s:\n"
+		      "%.*s\n"
 		      "-- end of packet.",
+		      msg_fragment_size,
 		      rdata->pkt_info.src_name, 
 		      rdata->pkt_info.src_port,
 		      (int)tmp.slen, tmp.ptr,
+		      (int)msg_fragment_size,
 		      rdata->msg_info.msg_buf));
 
