]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
* If we fail to connect to all looked up IP's from the worker lookup cache it
authorRuediger Pluem <rpluem@apache.org>
Thu, 27 Apr 2023 08:15:20 +0000 (08:15 +0000)
committerRuediger Pluem <rpluem@apache.org>
Thu, 27 Apr 2023 08:15:20 +0000 (08:15 +0000)
  might be caused by a change on DNS side. Try another DNS lookup in this case
  and in case this causes a successful connection trigger a refresh of the
  worker lookup cache.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1909451 13f79535-47bb-0310-9956-ffa450edef68

modules/proxy/proxy_util.c

index bb678c8a80f7af53d9695ba5c7637603646fcb12..439e4193708d89b949927c5751b3f5e7cfb745fd 100644 (file)
@@ -3206,6 +3206,7 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
     apr_sockaddr_t *local_addr;
     apr_socket_t *newsock;
     void *sconf = s->module_config;
+    int did_dns_lookup = 0;
     proxy_server_conf *conf =
         (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
 
@@ -3345,6 +3346,23 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
                              worker->s->hostname_ex,
                              (int)worker->s->port);
                 backend_addr = backend_addr->next;
+                /*
+                 * If we run out of resolved IP's when connecting and if
+                 * we cache the resolution in the worker the resolution
+                 * might have changed. Hence try a DNS lookup to see if this
+                 * helps.
+                 */
+                if (!backend_addr && !did_dns_lookup && worker->cp->addr) {
+                    /*
+                     * In case of an error backend_addr will be NULL which
+                     * is enough to leave the loop.
+                     */
+                    apr_sockaddr_info_get(&backend_addr,
+                                          conn->hostname, APR_UNSPEC,
+                                          conn->port, 0,
+                                          conn->pool);
+                    did_dns_lookup = 1;
+                }
                 continue;
             }
 
@@ -3438,6 +3456,19 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
         rv = APR_EINVAL;
     }
 
+    if ((rv == APR_SUCCESS) && did_dns_lookup) {
+        /*
+         * A local DNS lookup caused a successful connect. Trigger to update
+         * the worker cache next time.
+         * We don't care handling any locking errors. If something fails we
+         * just continue with the existing cache value.
+         */
+        if (PROXY_THREAD_LOCK(worker) == APR_SUCCESS) {
+            worker->cp->addr = NULL;
+            PROXY_THREAD_UNLOCK(worker);
+        }
+    }
+
     return rv == APR_SUCCESS ? OK : DECLINED;
 }