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"
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];
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;
apr_status_t status;
char *part;
char respcode[4]; /* 3 digits and null */
+ int i;
r = sizeof(buffer);
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);
}
}
/* 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) {
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);
}
}
}
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 {
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;
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;
}