Index: chan_sip.c
===================================================================
--- chan_sip.c	(revision 41987)
+++ chan_sip.c	(working copy)
@@ -4149,9 +4149,8 @@
 static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *sin, const int intended_method)
 {
 	struct sip_pvt *p;
-	char *tag = "";	/* note, tag is never NULL */
-	char totag[128];
-	char fromtag[128];
+	char req_totag[128];
+	char req_fromtag[128];
 	const char *callid = get_header(req, "Call-ID");
 	const char *from = get_header(req, "From");
 	const char *to = get_header(req, "To");
@@ -4167,44 +4166,76 @@
 		   For Asterisk to behave correctly, you need to turn on pedanticsipchecking
 		   in sip.conf
 		   */
-		if (gettag(req, "To", totag, sizeof(totag)))
+		if (gettag(req, "To", req_totag, sizeof(req_totag)))
 			ast_set_flag(req, SIP_PKT_WITH_TOTAG);	/* Used in handle_request/response */
-		gettag(req, "From", fromtag, sizeof(fromtag));
-
-		tag = (req->method == SIP_RESPONSE) ? totag : fromtag;
+		gettag(req, "From", req_fromtag, sizeof(req_fromtag));
 
 		if (option_debug > 4 )
-			ast_log(LOG_DEBUG, "= Looking for  Call ID: %s (Checking %s) --From tag %s --To-tag %s  \n", callid, req->method==SIP_RESPONSE ? "To" : "From", fromtag, totag);
+			ast_log(LOG_DEBUG, "= Looking for  Call ID: %s --From tag %s --To-tag %s (request) \n", callid, req_fromtag, req_totag);
 	}
 
 	ast_mutex_lock(&iflock);
 	for (p = iflist; p; p = p->next) {
 		/* In pedantic, we do not want packets with bad syntax to be connected to a PVT */
-		int found = FALSE;
-		if (req->method == SIP_REGISTER)
-			found = (!strcmp(p->callid, callid));
-		else 
-			found = (!strcmp(p->callid, callid) && 
-			(!pedanticsipchecking || !tag || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ;
-
-		if (option_debug > 4)
-			ast_log(LOG_DEBUG, "= %s Their Call ID: %s Their Tag %s Our tag: %s\n", found ? "Found" : "No match", p->callid, p->theirtag, p->tag);
-
-		/* If we get a new request within an existing to-tag - check the to tag as well */
-		if (pedanticsipchecking && found  && req->method != SIP_RESPONSE) {	/* SIP Request */
-			if (p->tag[0] == '\0' && totag[0]) {
-				/* We have no to tag, but they have. Wrong dialog */
+		int found = !strcmp(p->callid, callid);
+		if (req->method != SIP_REGISTER && found && pedanticsipchecking)
+	       	{ 
+			const char *chan_fromtag;
+			const char *chan_totag;
+			int chan_is_outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING);
+			/* If channel is outging (UAC) then our tag
+			   is fromtag and theirtag is totag.
+			   */
+			if (chan_is_outgoing) {
+				chan_fromtag = p->tag;
+				chan_totag = p->theirtag;
+			}
+			/* If channel is incoming (UAS) then our tag
+			   is totag and theirtag is fromtag.
+			   */
+			else {
+				chan_fromtag = p->theirtag;
+				chan_totag = p->tag;
+			}
+			/* Check fromtag first as it should be present at all
+			   times in both responses and requests.
+			   */
+			if (req_fromtag[0] == '\0' || chan_fromtag[0] == '\0')
+				/* Either side doesn't have fromtag.
+				   Wrong dialog.
+				   */
 				found = FALSE;
-			} else if (totag[0]) {			/* Both have tags, compare them */
-				if (strcmp(totag, p->tag)) {
-					found = FALSE;		/* This is not our packet */
+			else
+			       	/* Both have tags, compare them */
+				found = !strcmp(req_fromtag, chan_fromtag);
+			/* Checking To tag. It is NOT present in initial request and
+			   MAY be present in 100 trying response.
+			   */
+			if (found) {
+				const char *totag_originator;
+				const char *totag_peer;
+				if (chan_is_outgoing) {
+					totag_originator = req_totag;
+					totag_peer = chan_totag;
+				}
+				else {
+					totag_originator = chan_totag;
+					totag_peer = req_totag;
 				}
+				if (totag_originator[0] == '\0' &&
+				    totag_peer[0] != '\0')
+					/* Originator has no to tag,
+					   but peer has. Wrong dialog.
+					   */
+					found = FALSE;
+				else if (totag_peer[0] != '\0')
+					/* Both have tags, compare them */
+					found = !strcmp(totag_originator, totag_peer);
 			}
-			if (!found && option_debug > 4)
-				ast_log(LOG_DEBUG, "= Being pedantic: This is not our match on request: Call ID: %s Ourtag <null> Totag %s Method %s\n", p->callid, totag, sip_methods[req->method].text);
 		}
 
-
+		if (option_debug > 4)
+			ast_log(LOG_DEBUG, "= %s Their Call ID: %s Their Tag %s Our tag: %s Channel role: %s\n", found ? "Found" : "No match", p->callid, p->theirtag, p->tag, (ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "UAC" : "UAS"));
 		if (found) {
 			/* Found the call */
 			ast_mutex_lock(&p->lock);
