]> granicus.if.org Git - apache/commitdiff
Merge 1626956 and 1628388 from trunk:
authorRainer Jung <rjung@apache.org>
Thu, 15 Mar 2018 23:02:58 +0000 (23:02 +0000)
committerRainer Jung <rjung@apache.org>
Thu, 15 Mar 2018 23:02:58 +0000 (23:02 +0000)
ab: try all destination socket addresses returned by apr_sockaddr_info_get
instead of failing on first one when not available.
Needed for instance if localhost resolves to both ::1 and 127.0.0.1
e.g. if both are in /etc/hosts.

ab: Use only one connection to determine working destination socket address.

Submitted by: rjung
Reviewed by: rjung, covener, ylavic

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1826891 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
STATUS
support/ab.c

diff --git a/CHANGES b/CHANGES
index 7b5a43b675ea2b3337f4a7b658496f70b1ed782d..8275ca0540a86c61233a70659e5b9e8a5fe75d58 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,14 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.4.33
 
+  *) ab: try all destination socket addresses returned by
+     apr_sockaddr_info_get instead of failing on first one when not available.
+     Needed for instance if localhost resolves to both ::1 and 127.0.0.1
+     e.g. if both are in /etc/hosts.  [Jan Kaluza]
+
+  *) ab: Use only one connection to determine working destination socket
+     address.  [Jan Kaluza]
+
   *) htpasswd/htdbm: report the right limit when get_password() overflows.
      [Yann Ylavic]
 
diff --git a/STATUS b/STATUS
index 74a6c573cdff8429592b84b846ccbf4ab5e9a8fd..badfb746cb01c9c7ebaea875e26f04cd1880b5b0 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -126,17 +126,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
      2.4.x patch: svn merge -c 1826686 ^/httpd/httpd/trunk .
      +1: jailletc36, ylavic, covener
 
-  *) ab: try all destination socket addresses returned by apr_sockaddr_info_get
-     instead of failing on first one when not available.
-     Needed for instance if localhost resolves to both ::1 and 127.0.0.1
-     e.g. if both are in /etc/hosts.
-     ab: Use only one connection to determine working destination socket address.
-     trunk patches: http://svn.apache.org/r1626956
-                    http://svn.apache.org/r1628388
-     2.4.x patch: https://home.apache.org/~rjung/patches/httpd-2.4.x-ab-apr_sockaddr_info_get-all.patch
-                  plus CHANGES
-     +1: rjung, covener, ylavic
-
   *) rotatelogs: Small changes to rotatelogs:
      - add "-n num" to help text
      - clarify in help text, that "program is invoked"
index 9dfd616e89540d5e7ef6b29abec7975514c04df8..8d7bc268bb2cdd746248747d3ff100271aeba8dd 100644 (file)
@@ -366,6 +366,7 @@ apr_time_t start, lasttime, stoptime;
 char _request[8192];
 char *request = _request;
 apr_size_t reqlen;
+int requests_initialized = 0;
 
 /* one global throw-away buffer to read stuff into */
 char buffer[8192];
@@ -1386,12 +1387,18 @@ static void start_connect(struct connection * c)
         else {
             set_conn_state(c, STATE_UNCONNECTED);
             apr_socket_close(c->aprsock);
-            err_conn++;
-            if (bad++ > 10) {
+            if (good == 0 && destsa->next) {
+                destsa = destsa->next;
+                err_conn = 0;
+            }
+            else if (bad++ > 10) {
                 fprintf(stderr,
                    "\nTest aborted after 10 failures\n\n");
                 apr_err("apr_socket_connect()", rv);
             }
+            else {
+                err_conn++;
+            }
 
             start_connect(c);
             return;
@@ -1472,6 +1479,7 @@ static void read_connection(struct connection * c)
     apr_status_t status;
     char *part;
     char respcode[4];       /* 3 digits and null */
+    int i;
 
     r = sizeof(buffer);
 read_more:
@@ -1496,6 +1504,13 @@ read_more:
                 good++;
                 close_connection(c);
             }
+            else if (scode == SSL_ERROR_SYSCALL 
+                     && c->read == 0
+                     && destsa->next
+                     && c->state == STATE_CONNECTING
+                     && good == 0) {
+                return;
+            }
             else if (scode == SSL_ERROR_WANT_READ) {
                 set_polled_events(c, APR_POLLIN);
             }
@@ -1526,8 +1541,8 @@ read_more:
         }
         /* catch legitimate fatal apr_socket_recv errors */
         else if (status != APR_SUCCESS) {
-            err_recv++;
             if (recverrok) {
+                err_recv++;
                 bad++;
                 close_connection(c);
                 if (verbosity >= 1) {
@@ -1535,7 +1550,12 @@ read_more:
                     fprintf(stderr,"%s: %s (%d)\n", "apr_socket_recv", apr_strerror(status, buf, sizeof buf), status);
                 }
                 return;
-            } else {
+            } else if (destsa->next && c->state == STATE_CONNECTING
+                       && c->read == 0 && good == 0) {
+                return;
+            }
+            else {
+                err_recv++;
                 apr_err("apr_socket_recv", status);
             }
         }
@@ -1657,6 +1677,16 @@ read_more:
             }
             c->bread += c->cbx - (s + l - c->cbuff) + r - tocopy;
             totalbread += c->bread;
+
+            /* We have received the header, so we know this destination socket
+             * address is working, so initialize all remaining requests. */
+            if (!requests_initialized) {
+                for (i = 1; i < concurrency; i++) {
+                    con[i].socknum = i;
+                    start_connect(&con[i]);
+                }
+                requests_initialized = 1;
+            }
         }
     }
     else {
@@ -1878,11 +1908,10 @@ static void test(void)
     apr_signal(SIGINT, output_results);
 #endif
 
-    /* initialise lots of requests */
-    for (i = 0; i < concurrency; i++) {
-        con[i].socknum = i;
-        start_connect(&con[i]);
-    }
+    /* initialise first connection to determine destination socket address
+     * which should be used for next connections. */
+    con[0].socknum = 0;
+    start_connect(&con[0]);
 
     do {
         apr_int32_t n;
@@ -1930,14 +1959,20 @@ static void test(void)
             if ((rtnev & APR_POLLIN) || (rtnev & APR_POLLPRI) || (rtnev & APR_POLLHUP))
                 read_connection(c);
             if ((rtnev & APR_POLLERR) || (rtnev & APR_POLLNVAL)) {
-                bad++;
-                err_except++;
-                /* avoid apr_poll/EINPROGRESS loop on HP-UX, let recv discover ECONNREFUSED */
-                if (c->state == STATE_CONNECTING) {
-                    read_connection(c);
+                if (destsa->next && c->state == STATE_CONNECTING && good == 0) {
+                    destsa = destsa->next;
+                    start_connect(c);
                 }
                 else {
-                    start_connect(c);
+                    bad++;
+                    err_except++;
+                    /* avoid apr_poll/EINPROGRESS loop on HP-UX, let recv discover ECONNREFUSED */
+                    if (c->state == STATE_CONNECTING) {
+                        read_connection(c);
+                    }
+                    else {
+                        start_connect(c);
+                    }
                 }
                 continue;
             }