]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Bug 3301: ERR_DNS_FAIL never shown
authorAmos Jeffries <squid3@treenet.co.nz>
Tue, 29 Nov 2011 06:48:59 +0000 (23:48 -0700)
committerAmos Jeffries <squid3@treenet.co.nz>
Tue, 29 Nov 2011 06:48:59 +0000 (23:48 -0700)
errors/templates/ERR_CANNOT_FORWARD
src/PeerSelectState.h
src/forward.cc
src/peer_select.cc
src/tunnel.cc

index 7e7a7a45185747a395ccd5739ed9738eeca90363..63fc1fc2efbaaf74fc4e6fde4bbbf57afce02bf8 100644 (file)
@@ -23,7 +23,14 @@ body
 <p><b>Unable to forward this request at this time.</b></p>
 </blockquote>
 
-<p>This request could not be forwarded to the origin server or to any parent caches. The most likely cause for this error is that the cache administrator does not allow this cache to make direct connections to origin servers, and all configured parent caches are currently unreachable.</p>
+<p>This request could not be forwarded to the origin server or to any parent caches.</p>
+
+<p>Some possible problems are:</p>
+<ul>
+<li id="network-down">An Internet connection needed to access this domains origin servers may be down.</li>
+<li id="no-peer">All configured parent caches may be currently unreachable.</li>
+<li id="permission-denied">The administrator may not allow this cache to make direct connections to origin servers.</li>
+</ul>
 
 <p>Your cache administrator is <a href="mailto:%w%W">%w</a>.</p>
 
index 7a323ac9c0083794cad8d60f0b9d7297281a29fd..639f041a4f2435873f12c65f1483cc15336be308 100644 (file)
@@ -43,8 +43,9 @@
 
 class HttpRequest;
 class StoreEntry;
+class ErrorState;
 
-typedef void PSC(Comm::ConnectionList *, void *);
+typedef void PSC(Comm::ConnectionList *, ErrorState *, void *);
 
 SQUIDCEXTERN void peerSelect(Comm::ConnectionList *, HttpRequest *, StoreEntry *, PSC *, void *data);
 SQUIDCEXTERN void peerSelectInit(void);
@@ -79,6 +80,7 @@ public:
     int direct;   // TODO: fold always_direct/never_direct/prefer_direct into this now that ACL can do a multi-state result.
     PSC *callback;
     void *callback_data;
+    ErrorState *lastError;
 
     Comm::ConnectionList *paths;    ///< the callers paths array. to be filled with our final results.
     FwdServer *servers;    ///< temporary linked list of peers we will pass back.
index 56f3c65471cdf70e7533e00e588469d9566cfb63..c72101379072bc8d650d8da21dc7aedcd2570348 100644 (file)
@@ -410,9 +410,11 @@ FwdState::complete()
 /**** CALLBACK WRAPPERS ************************************************************/
 
 static void
-fwdPeerSelectionCompleteWrapper(Comm::ConnectionList * unused, void *data)
+fwdPeerSelectionCompleteWrapper(Comm::ConnectionList * unused, ErrorState *err, void *data)
 {
     FwdState *fwd = (FwdState *) data;
+    if (err)
+        fwd->fail(err);
     fwd->startConnectionOrFail();
 }
 
index dc1a0ea57cce9faef640ed0ba1c30a6ccf2ae2fe..13f31d4b2c6b2afd201d80ae7d6be97b39195711 100644 (file)
@@ -34,6 +34,7 @@
 
 #include "squid.h"
 #include "DnsLookupDetails.h"
+#include "errorpage.h"
 #include "event.h"
 #include "PeerSelectState.h"
 #include "Store.h"
@@ -104,6 +105,8 @@ peerSelectStateFree(ps_state * psstate)
         psstate->entry = NULL;
     }
 
+    delete psstate->lastError;
+
     cbdataFree(psstate);
 }
 
@@ -265,7 +268,8 @@ peerSelectDnsPaths(ps_state *psstate)
 
     void *cbdata;
     if (cbdataReferenceValidDone(psstate->callback_data, &cbdata)) {
-        callback(psstate->paths, cbdata);
+        callback(psstate->paths, psstate->lastError, cbdata);
+        psstate->lastError = NULL; // FwdState has taken control over the ErrorState object.
     }
 
     peerSelectStateFree(psstate);
@@ -317,6 +321,13 @@ peerSelectDnsResults(const ipcache_addrs *ia, const DnsLookupDetails &details, v
         }
     } else {
         debugs(44, 3, HERE << "Unknown host: " << fs->_peer ? fs->_peer->host : psstate->request->GetHost());
+        // discard any previous error.
+        delete psstate->lastError;
+        psstate->lastError = NULL;
+        if (fs->code == HIER_DIRECT) {
+            psstate->lastError = new ErrorState(ERR_DNS_FAIL, HTTP_SERVICE_UNAVAILABLE, psstate->request);
+            psstate->lastError->dnsError = details.error;
+        }
     }
 
     psstate->servers = fs->next;
@@ -899,6 +910,7 @@ ps_state::ps_state() : request (NULL),
         direct(DIRECT_UNKNOWN),
         callback (NULL),
         callback_data (NULL),
+        lastError(NULL),
         servers (NULL),
         first_parent_miss(),
         closest_parent_miss(),
index 3344f799260ffa1df4f9f742df1dc87c7440483d..8c3cc4b05c94770626cbf2fa2dc32b5a9849ebd8 100644 (file)
@@ -697,20 +697,23 @@ tunnelRelayConnectRequest(const Comm::ConnectionPointer &srv, void *data)
 }
 
 static void
-tunnelPeerSelectComplete(Comm::ConnectionList *peer_paths, void *data)
+tunnelPeerSelectComplete(Comm::ConnectionList *peer_paths, ErrorState *err, void *data)
 {
     TunnelStateData *tunnelState = (TunnelStateData *)data;
 
     if (peer_paths == NULL || peer_paths->size() < 1) {
         debugs(26, 3, HERE << "No paths found. Aborting CONNECT");
-        ErrorState *err;
-        err = errorCon(ERR_CANNOT_FORWARD, HTTP_SERVICE_UNAVAILABLE, tunnelState->request);
-        *tunnelState->status_ptr = HTTP_SERVICE_UNAVAILABLE;
+        if (!err) {
+            err = errorCon(ERR_CANNOT_FORWARD, HTTP_SERVICE_UNAVAILABLE, tunnelState->request);
+        }
+        *tunnelState->status_ptr = err->httpStatus;
         err->callback = tunnelErrorComplete;
         err->callback_data = tunnelState;
         errorSend(tunnelState->client.conn, err);
         return;
     }
+    delete err;
+
     debugs(26, 3, HERE << "paths=" << peer_paths->size() << ", p[0]={" << (*peer_paths)[0] << "}, serverDest[0]={" <<
            tunnelState->serverDestinations[0] << "}");