[svn-commits] dvossel: branch dvossel/sip_request_transaction_matching r276598 - /team/dvos...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Jul 14 18:23:10 CDT 2010


Author: dvossel
Date: Wed Jul 14 18:23:06 2010
New Revision: 276598

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=276598
Log:
moved req to dialog matching into a separate function

Modified:
    team/dvossel/sip_request_transaction_matching/channels/chan_sip.c

Modified: team/dvossel/sip_request_transaction_matching/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/sip_request_transaction_matching/channels/chan_sip.c?view=diff&rev=276598&r1=276597&r2=276598
==============================================================================
--- team/dvossel/sip_request_transaction_matching/channels/chan_sip.c (original)
+++ team/dvossel/sip_request_transaction_matching/channels/chan_sip.c Wed Jul 14 18:23:06 2010
@@ -7103,6 +7103,102 @@
 	return p;
 }
 
+enum match_req_to_dialog_res {
+	SIP_REQ_MATCH,
+	SIP_REQ_NOT_MATCH,
+	SIP_REQ_LOOP_DETECTED,
+};
+
+static enum match_req_to_dialog_res match_req_to_dialog(struct sip_request *req, struct sip_pvt *sip_pvt_ptr, const char *totag, const char *fromtag, int seqno)
+{
+	if (req->method == SIP_RESPONSE) {
+		/* MATCH RESPONSE with DIALOG */
+		/* Verify totag if we have one stored for this dialog, but never be strict about this for
+		 * a response until the dialog is established */
+		if (!ast_strlen_zero(sip_pvt_ptr->theirtag) && ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) {
+			if (ast_strlen_zero(totag)) {
+				/* missing totag when they already gave us one earlier */
+				return SIP_REQ_NOT_MATCH;
+			}
+			if (strcmp(totag, sip_pvt_ptr->theirtag)) {
+				/* The totag of the response does not match the one we have stored */
+				return SIP_REQ_NOT_MATCH;
+			}
+		}
+		/* Verify fromtag of response matches the tag we gave them. */
+		if (strcmp(fromtag, sip_pvt_ptr->tag)) {
+			/* fromtag from response does not match our tag */
+			return SIP_REQ_NOT_MATCH;
+		}
+	} else {
+		/* MATCH REQUEST with DIALOG */
+
+		/* Verify the fromtag of Request matches the tag they provided earlier. */
+		if (strcmp(fromtag, sip_pvt_ptr->theirtag)) {
+			/* their tag does not match the one was have stored for them */
+			return SIP_REQ_NOT_MATCH;
+		}
+		/* Verify if totag is present in Request, that it matches what we gave them as our tag earlier */
+		if (!ast_strlen_zero(totag) && (strcmp(totag, sip_pvt_ptr->tag))) {
+			/* totag from Request does not match our tag */
+			return SIP_REQ_NOT_MATCH;
+		}
+
+		/* If the totag is not present in the Request, then we must go forward with
+		 * attempting to match this Request to this dialog's initial transaction. */
+		if (ast_strlen_zero(totag) &&
+			(sip_pvt_ptr->init_icseq == seqno) &&
+			!ast_strlen_zero(sip_pvt_ptr->initviabranch)) {
+			char *sent_by, *branch;
+			const char *initial_rlPart2 = REQ_OFFSET_TO_STR(&sip_pvt_ptr->initreq, rlPart2);
+			const char *this_rlPart2 = REQ_OFFSET_TO_STR(req, rlPart2);
+
+			/* If the Request-URIs are different, then this is neither a match nor a forked request */
+			if (sip_uri_cmp(initial_rlPart2, this_rlPart2)) {
+				/* not a match, request uris are different */
+				return SIP_REQ_NOT_MATCH;
+			}
+
+			/* The requests matched, now compare top VIA headers to see if this is the same transaction */
+			get_viabranch(ast_strdupa(get_header(req, "Via")), &sent_by, &branch);
+			if (ast_strlen_zero(branch) ||
+				strcmp(branch, sip_pvt_ptr->initviabranch) ||
+				ast_strlen_zero(sent_by) ||
+				strcmp(sent_by, sip_pvt_ptr->initviasentby)) {
+
+				/* The TOP VIA's do not match, but the Request-URI is the exact same. Check to
+				 * see if the method's match to determine if this is a forked request or not. */
+				if ((sip_pvt_ptr->method != req->method)) {
+					/* not a match and not a fork. methods are not the same */
+					return SIP_REQ_NOT_MATCH;
+				}
+
+				/* FORK DETECTION CRITERIA
+				 *
+				 * ---Current Matches to Initial Request---
+				 * request uri
+				 * Call-id
+				 * their-tag
+				 * no totag present
+				 * method
+				 * cseq
+				 *
+				 * --- Does not Match Initial Request ---
+				 * Top Via
+				 *
+				 * Without the same Via, this can not match our initial transaction for this dialog,
+				 * but given that this Request matches everything else associated with that initial
+				 * Request this is most certainly a Forked request in which we have already received
+				 * part of the fork.
+				 */
+				return SIP_REQ_LOOP_DETECTED;
+			}
+		} /* end of Request Via check */
+	} /* end of Request/Response matching */
+
+	return SIP_REQ_MATCH;
+}
+
 /*! \brief find or create a dialog structure for an incoming SIP message.
  * Connect incoming SIP message to current dialog or create new dialog structure
  * Returns a reference to the sip_pvt object, remember to give it back once done.
@@ -7174,113 +7270,28 @@
 			.callid = callid,
 		};
 		struct ao2_iterator *iterator = ao2_t_callback(dialogs, OBJ_POINTER | OBJ_MULTIPLE, dialog_find_multiple, &tmp_dialog, "pedantic ao2_find in dialogs");
+		int found;
 		/* Iterate a list of dialogs already matched by Call-id */
 		while (iterator && (sip_pvt_ptr = ao2_iterator_next(iterator))) {
-			if (req->method == SIP_RESPONSE) {
-				/* MATCH RESPONSE with DIALOG */
-				/* Verify totag if we have one stored for this dialog, but never be strict about this for
-				 * a response until the dialog is established */
-				if (!ast_strlen_zero(sip_pvt_ptr->theirtag) && ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) {
-					if (ast_strlen_zero(totag)) {
-						/* missing totag when they already gave us one earlier */
-						goto not_a_match;
-					}
-					if (strcmp(totag, sip_pvt_ptr->theirtag)) {
-						/* The totag of the response does not match the one we have stored */
-						goto not_a_match;
-					}
-				}
-				/* Verify fromtag of response matches the tag we gave them. */
-				if (strcmp(fromtag, sip_pvt_ptr->tag)) {
-					/* fromtag from response does not match our tag */
-					goto not_a_match;
-				}
-			} else {
-				/* MATCH REQUEST with DIALOG */
-
-				/* Verify the fromtag of Request matches the tag they provided earlier. */
-				if (strcmp(fromtag, sip_pvt_ptr->theirtag)) {
-					/* their tag does not match the one was have stored for them */
-					goto not_a_match;
-				}
-
-				/* Verify if totag is present in Request, that it matches what we gave them as our tag earlier */
-				if (!ast_strlen_zero(totag) && (strcmp(totag, sip_pvt_ptr->tag))) {
-					/* totag from Request does not match our tag */
-					goto not_a_match;
-				}
-
-				/* If the totag is not present in the Request, then we must go forward with
-				 * attempting to match this Request to this dialog's initial transaction. */
-				if (ast_strlen_zero(totag) &&
-					(sip_pvt_ptr->init_icseq == seqno) &&
-					!ast_strlen_zero(sip_pvt_ptr->initviabranch)) {
-					char *sent_by, *branch;
-					const char *initial_rlPart2 = REQ_OFFSET_TO_STR(&sip_pvt_ptr->initreq, rlPart2);
-					const char *this_rlPart2 = REQ_OFFSET_TO_STR(req, rlPart2);
-
-					/* If the methods are different, then this does not match this dialog.
-					 * The only time this is not true is when the incoming request is a CANCEL. */
-					if ((sip_pvt_ptr->method != req->method) && (req->method != SIP_CANCEL)) {
-						/* not a match, methods are not the same */
-						goto not_a_match;
-					}
-
-					/* If the Request-uris are different, then this is neither a match nor a forked request */
-					if (sip_uri_cmp(initial_rlPart2, this_rlPart2)) {
-						/* not a match, request uris are different */
-						goto not_a_match;
-					}
-
-					/* At this point check to see if this is a Forked Request by comparing VIA headers.
-					 * If they are the same, this is a retransmit and this dialog matches, otherwise we have
-					 * a forked request. */
-					get_viabranch(ast_strdupa(get_header(req, "Via")), &sent_by, &branch);
-					if (ast_strlen_zero(branch) ||
-						strcmp(branch, sip_pvt_ptr->initviabranch) ||
-						ast_strlen_zero(sent_by) ||
-						strcmp(sent_by, sip_pvt_ptr->initviasentby)) {
-
-						/* If we are here, everything matches the initial Request except for the top Via */
-
-						/* FORK DETECTION CRITERIA
-						 *
-						 * ---Current Matches to Initial Request---
-						 * request uri
-						 * Call-id
-						 * their-tag
-						 * no totag present
-					 	 * method
-					 	 * cseq
-						 *
-					 	 * --- Does not Match Initial Request ---
-					 	 * Top Via
-						 *
-						 * Without the same Via, this can not match our initial transaction for this dialog,
-						 * but given that this Request matches everything else associated with that initial
-						 * Request this is most certainly a Forked request in which we have already received
-						 * part of the fork.
-					 	 */
-						goto loop_detected;
-					}
-				} /* end of Request Via check */
-			} /* end of Request/Response matching */
-
-			/* If we made it here, then this is a match. Leave the reference from the iterator */
-			sip_pvt_lock(sip_pvt_ptr);
-			ao2_iterator_destroy(iterator);
-			return sip_pvt_ptr;
-
-loop_detected:
-			/* This is likely a forked Request that somehow resulted in us receiving multiple parts of the fork.
-			 * RFC 3261 section 8.2.2.2, Indicate that we want to merge requests by sending a 482 response. */
-			transmit_response_using_temp(callid, addr, 1, intended_method, req, "482 (Loop Detected)");
-			dialog_unref(sip_pvt_ptr, "This pvt did not match incoming SIP msg, unref pvt from find_call search.");
-			return NULL;
-not_a_match:
-			dialog_unref(sip_pvt_ptr, "This pvt did not match incoming SIP msg, unref pvt from find_call search.");
-		} /* end of while */
-
+			found = match_req_to_dialog(req, sip_pvt_ptr, totag, fromtag, seqno);
+
+			switch (found) {
+			case SIP_REQ_MATCH:
+				sip_pvt_lock(sip_pvt_ptr);
+				ao2_iterator_destroy(iterator);
+				return sip_pvt_ptr; /* return pvt with ref */
+			case SIP_REQ_LOOP_DETECTED:
+				/* This is likely a forked Request that somehow resulted in us receiving multiple parts of the fork.
+			 	* RFC 3261 section 8.2.2.2, Indicate that we want to merge requests by sending a 482 response. */
+				transmit_response_using_temp(callid, addr, 1, intended_method, req, "482 (Loop Detected)");
+				dialog_unref(sip_pvt_ptr, "This pvt did not match incoming SIP msg, unref pvt from find_call search.");
+				ao2_iterator_destroy(iterator);
+				return NULL;
+			case SIP_REQ_NOT_MATCH:
+			default:
+				dialog_unref(sip_pvt_ptr, "This pvt did not match incoming SIP msg, unref pvt from find_call search.");
+			}
+		}
 		if (iterator) {
 			ao2_iterator_destroy(iterator);
 		}




More information about the svn-commits mailing list