[asterisk-commits] dvossel: branch dvossel/sip_forked_responses r289093 - /team/dvossel/sip_fork...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Sep 28 12:19:48 CDT 2010
Author: dvossel
Date: Tue Sep 28 12:19:45 2010
New Revision: 289093
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=289093
Log:
detect a forked 200ok response
Modified:
team/dvossel/sip_forked_responses/channels/chan_sip.c
Modified: team/dvossel/sip_forked_responses/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/sip_forked_responses/channels/chan_sip.c?view=diff&rev=289093&r1=289092&r2=289093
==============================================================================
--- team/dvossel/sip_forked_responses/channels/chan_sip.c (original)
+++ team/dvossel/sip_forked_responses/channels/chan_sip.c Tue Sep 28 12:19:45 2010
@@ -7241,6 +7241,9 @@
const char *fromtag;
unsigned int seqno;
+ /* Set if this method is a Response */
+ int respid;
+
/* Set if the method is a Request */
const char *ruri;
const char *viabranch;
@@ -7254,6 +7257,7 @@
SIP_REQ_MATCH,
SIP_REQ_NOT_MATCH,
SIP_REQ_LOOP_DETECTED,
+ SIP_REQ_FORKED_RESPONSE,
};
/*
@@ -7276,6 +7280,12 @@
return SIP_REQ_NOT_MATCH;
}
if (arg->method == SIP_RESPONSE) {
+ /* Verify fromtag of response matches the tag we gave them. */
+ if (strcmp(arg->fromtag, sip_pvt_ptr->tag)) {
+ /* fromtag from response does not match our tag */
+ return SIP_REQ_NOT_MATCH;
+ }
+
/* 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)) {
@@ -7283,15 +7293,35 @@
/* missing totag when they already gave us one earlier */
return SIP_REQ_NOT_MATCH;
}
+ /* compare the totag of response with the tag we have stored for them */
if (strcmp(arg->totag, sip_pvt_ptr->theirtag)) {
- /* The totag of the response does not match the one we have stored */
+ /* totag did not match what we had stored for them. */
+ char invite_branch[32] = { 0, };
+ if (sip_pvt_ptr->invite_branch) {
+ snprintf(invite_branch, sizeof(invite_branch), "z9hG4bK%08x", (int) sip_pvt_ptr->invite_branch);
+ }
+ /* Forked Request Detection
+ *
+ * If this is a 200ok response and the totags do not match, this
+ * might be a forked response to an outgoing Request. Detection of
+ * a forked response must meet the criteria below.
+ *
+ * 1. must be a 2xx Response
+ * 2. call-d equal to call-id of Request. this is done earlier
+ * 3. from-tag equal to from-tag of Request. this is done earlier
+ * 4. branch parameter equal to branch of inital Request
+ * 5. to-tag _NOT_ equal to previous 2xx response that already established the dialog.
+ */
+ if ((arg->respid == 200) &&
+ !ast_strlen_zero(invite_branch) &&
+ !ast_strlen_zero(arg->viabranch) &&
+ !strcmp(invite_branch, arg->viabranch)) {
+ return SIP_REQ_FORKED_RESPONSE;
+ }
+
+ /* The totag did not match the one we had stored, and this is not a Forked Request. */
return SIP_REQ_NOT_MATCH;
}
- }
- /* Verify fromtag of response matches the tag we gave them. */
- if (strcmp(arg->fromtag, sip_pvt_ptr->tag)) {
- /* fromtag from response does not match our tag */
- return SIP_REQ_NOT_MATCH;
}
} else {
/* Verify the fromtag of Request matches the tag they provided earlier.
@@ -7473,14 +7503,20 @@
args.totag = totag;
args.fromtag = fromtag;
args.seqno = seqno;
-
- /* If this is a Request, set the Via and Authorization header arguments */
- if (req->method != SIP_RESPONSE) {
- args.ruri = REQ_OFFSET_TO_STR(req, rlPart2);
- get_viabranch(ast_strdupa(get_header(req, "Via")), (char **) &args.viasentby, (char **) &args.viabranch);
- if (!ast_strlen_zero(get_header(req, "Authorization")) ||
- !ast_strlen_zero(get_header(req, "Proxy-Authorization"))) {
- args.authentication_present = 1;
+ /* get via header information. */
+ args.ruri = REQ_OFFSET_TO_STR(req, rlPart2);
+ get_viabranch(ast_strdupa(get_header(req, "Via")), (char **) &args.viasentby, (char **) &args.viabranch);
+ /* determine if this is a Request with authentication credentials. */
+ if (!ast_strlen_zero(get_header(req, "Authorization")) ||
+ !ast_strlen_zero(get_header(req, "Proxy-Authorization"))) {
+ args.authentication_present = 1;
+ }
+ /* if it is a response, get the response code */
+ if (req->method == SIP_RESPONSE) {
+ const char* e = ast_skip_blanks(REQ_OFFSET_TO_STR(req, rlPart2));
+ int respid;
+ if (!ast_strlen_zero(e) && (sscanf(e, "%30d", &respid) == 1)) {
+ args.respid = respid;
}
}
@@ -7500,6 +7536,8 @@
dialog_unref(sip_pvt_ptr, "pvt did not match incoming SIP msg, unref from search.");
ao2_iterator_destroy(iterator);
return NULL;
+ case SIP_REQ_FORKED_REQUEST:
+ //todohere handle forked request
case SIP_REQ_NOT_MATCH:
default:
dialog_unref(sip_pvt_ptr, "pvt did not match incoming SIP msg, unref from search");
More information about the asterisk-commits
mailing list