Index: lib/hostip.c
===================================================================
RCS file: /repository/curl/lib/hostip.c,v
retrieving revision 1.131
diff -u -r1.131 hostip.c
--- lib/hostip.c	29 Mar 2004 21:29:24 -0000	1.131
+++ lib/hostip.c	30 Mar 2004 08:39:32 -0000
@@ -482,9 +482,20 @@
   int count;
   struct SessionHandle *data = conn->data;
   int nfds;
+  long diff;
+
+  diff = Curl_tvdiff(Curl_tvnow(),
+                     data->progress.t_startsingle)/1000;
+
+  if(diff > 180) {
+    /* Waited >180 seconds, this is a name resolve timeout! */
+    failf(data, "Name resolve timeout after %ld seconds", diff);
+    return CURLE_OPERATION_TIMEDOUT;
+  }
 
   FD_ZERO(&read_fds);
   FD_ZERO(&write_fds);
+
   nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
 
   count = select(nfds, &read_fds, &write_fds, NULL,
Index: lib/http.c
===================================================================
RCS file: /repository/curl/lib/http.c,v
retrieving revision 1.206
diff -u -r1.206 http.c
--- lib/http.c	30 Mar 2004 08:21:09 -0000	1.206
+++ lib/http.c	30 Mar 2004 08:39:32 -0000
@@ -398,17 +398,14 @@
         *availp |= CURLAUTH_DIGEST;
         if(data->state.authwant == CURLAUTH_DIGEST) {
           /* Digest authentication is activated */
-          CURLdigest dig = CURLDIGEST_BAD;
-
-          if(data->state.digest.nonce)
-            infof(data, "Authentication problem. Ignoring this.\n");
-          else
-            dig = Curl_input_digest(conn, start);
+          CURLdigest dig = Curl_input_digest(conn, start);
           
           if(CURLDIGEST_FINE == dig)
             /* We act on it. Store our new url, which happens to be
                the same one we already use! */
             conn->newurl = strdup(data->change.url); /* clone string */
+          else
+            infof(data, "Authentication problem. Ignoring this.\n");
         }
         else
           if(data->state.authwant & CURLAUTH_DIGEST) {
Index: lib/http_digest.c
===================================================================
RCS file: /repository/curl/lib/http_digest.c,v
retrieving revision 1.8
diff -u -r1.8 http_digest.c
--- lib/http_digest.c	8 Mar 2004 12:37:11 -0000	1.8
+++ lib/http_digest.c	30 Mar 2004 08:39:32 -0000
@@ -57,6 +57,7 @@
 {
   bool more = TRUE;
   struct SessionHandle *data=conn->data;
+  bool before = FALSE; /* got a nonce before */
 
   /* skip initial whitespaces */
   while(*header && isspace((int)*header))
@@ -65,6 +66,10 @@
   if(checkprefix("Digest", header)) {
     header += strlen("Digest");
 
+    /* If we already have received a nonce, keep that in mind */
+    if(data->state.digest.nonce)
+      before = TRUE;
+
     /* clear off any former leftovers and init to defaults */
     Curl_digest_cleanup(data);
 
@@ -82,6 +87,10 @@
         if(strequal(value, "nonce")) {
           data->state.digest.nonce = strdup(content);
         }
+        else if(strequal(value, "stale")) {
+          if(strequal(content, "true"))
+            data->state.digest.stale = TRUE;
+        }
         else if(strequal(value, "cnonce")) {
           data->state.digest.cnonce = strdup(content);
         }
@@ -106,7 +115,14 @@
         /* allow the list to be comma-separated */
         header++; 
     }
+    /* We had a nonce since before, and we got another one now without
+    'stale=true'. This means we provided bad credentials in the previous
+    request */
+
+    if(before && !data->state.digest.stale)
+      return CURLDIGEST_BAD;
 
+    /* We got this header without a nonce, that's a bad Digest line! */
     if(!data->state.digest.nonce)
       return CURLDIGEST_BAD;
   }
@@ -213,19 +229,23 @@
 
 void Curl_digest_cleanup(struct SessionHandle *data)
 {
-  if(data->state.digest.nonce)
-    free(data->state.digest.nonce);
-  data->state.digest.nonce = NULL;
-
-  if(data->state.digest.cnonce)
-    free(data->state.digest.cnonce);
-  data->state.digest.cnonce = NULL;
-
-  if(data->state.digest.realm)
-    free(data->state.digest.realm);
-  data->state.digest.realm = NULL;
+  struct digestdata *d = &data->state.digest;
+
+  if(d->nonce)
+    free(d->nonce);
+  d->nonce = NULL;
+
+  if(d->cnonce)
+    free(d->cnonce);
+  d->cnonce = NULL;
+
+  if(d->realm)
+    free(d->realm);
+  d->realm = NULL;
+
+  d->algo = CURLDIGESTALGO_MD5; /* default algorithm */
 
-  data->state.digest.algo = CURLDIGESTALGO_MD5; /* default algorithm */
+  d->stale = FALSE; /* default means normal, not stale */
 }
 
 #endif
Index: lib/urldata.h
===================================================================
RCS file: /repository/curl/lib/urldata.h,v
retrieving revision 1.208
diff -u -r1.208 urldata.h
--- lib/urldata.h	30 Mar 2004 06:38:52 -0000	1.208
+++ lib/urldata.h	30 Mar 2004 08:39:33 -0000
@@ -173,6 +173,7 @@
   char *cnonce;
   char *realm;
   int algo;
+  bool stale; /* set true for re-negotiation */
 };
 
 typedef enum {
