Fixed ticket #986: Assertion when authorization PJSIP_AUTH_AUTO_SEND_NEXT is enabled (thanks Zhefeng Du for the report)
 - also added SIPp scenario for testing


git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@2988 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjsip/src/pjsip/sip_auth_client.c b/pjsip/src/pjsip/sip_auth_client.c
index d232229..66c8c65 100644
--- a/pjsip/src/pjsip/sip_auth_client.c
+++ b/pjsip/src/pjsip/sip_auth_client.c
@@ -322,8 +322,33 @@
 				   pjsip_cached_auth *cached_auth,
 				   const pjsip_www_authenticate_hdr *hdr )
 {
-    if (hdr->challenge.digest.qop.slen == 0)
+    if (hdr->challenge.digest.qop.slen == 0) {
+#if PJSIP_AUTH_AUTO_SEND_NEXT!=0
+	if (!cached_auth->last_chal || pj_stricmp2(&hdr->scheme, "digest")) {
+	    cached_auth->last_chal = (pjsip_www_authenticate_hdr*)
+				     pjsip_hdr_clone(ses_pool, hdr);
+	} else {
+	    /* Only update if the new challenge is "significantly different"
+	     * than the one in the cache, to reduce memory usage.
+	     */
+	    const pjsip_digest_challenge *d1 = 
+			&cached_auth->last_chal->challenge.digest;
+	    const pjsip_digest_challenge *d2 = &hdr->challenge.digest;
+
+	    if (pj_strcmp(&d1->domain, &d2->domain) ||
+		pj_strcmp(&d1->realm, &d2->realm) ||
+		pj_strcmp(&d1->nonce, &d2->nonce) ||
+		pj_strcmp(&d1->opaque, &d2->opaque) ||
+		pj_strcmp(&d1->algorithm, &d2->algorithm) ||
+		pj_strcmp(&d1->qop, &d2->qop))
+	    {
+		cached_auth->last_chal = (pjsip_www_authenticate_hdr*)
+				         pjsip_hdr_clone(ses_pool, hdr);
+	    }
+	}
+#endif
 	return;
+    }
 
     /* Initialize cnonce and qop if not present. */
     if (cached_auth->cnonce.slen == 0) {
diff --git a/tests/pjsua/scripts-sipp/uas-auth.xml b/tests/pjsua/scripts-sipp/uas-auth.xml
new file mode 100644
index 0000000..71da30f
--- /dev/null
+++ b/tests/pjsua/scripts-sipp/uas-auth.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>

+<!DOCTYPE scenario SYSTEM "sipp.dtd">

+

+<!-- This program is free software; you can redistribute it and/or      -->

+<!-- modify it under the terms of the GNU General Public License as     -->

+<!-- published by the Free Software Foundation; either version 2 of the -->

+<!-- License, or (at your option) any later version.                    -->

+<!--                                                                    -->

+<!-- This program is distributed in the hope that it will be useful,    -->

+<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->

+<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->

+<!-- GNU General Public License for more details.                       -->

+<!--                                                                    -->

+<!-- You should have received a copy of the GNU General Public License  -->

+<!-- along with this program; if not, write to the                      -->

+<!-- Free Software Foundation, Inc.,                                    -->

+<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->

+<!--                                                                    -->

+<!--                 Sipp default 'uas' scenario.                       -->

+<!--                                                                    -->

+

+<scenario name="UAS authorization server">

+  <recv request="REGISTER" crlf="true">

+  </recv>

+

+  <send>

+    <![CDATA[

+

+      SIP/2.0 401 Unauthorized

+      [last_Via:]

+      [last_From:]

+      [last_To:];tag=[call_number]

+      [last_Call-ID:]

+      [last_CSeq:]

+      WWW-Authenticate: digest realm="test",stale=true

+    ]]>

+  </send>

+

+

+  <recv request="REGISTER" crlf="true">

+  </recv>

+

+  <send>

+    <![CDATA[

+

+      SIP/2.0 200 OK

+      [last_Via:]

+      [last_From:]

+      [last_To:];tag=[call_number]

+      [last_Call-ID:]

+      [last_CSeq:]

+      Expires: 30

+    ]]>

+  </send>

+

+

+  <pause milliseconds="1000"/>

+

+

+  <!-- definition of the response time repartition table (unit is ms)   -->

+  <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>

+

+  <!-- definition of the call length repartition table (unit is ms)     -->

+  <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>

+

+</scenario>

+