|
|
41a6c3 |
diff --git a/support/ab.c b/support/ab.c
|
|
|
41a6c3 |
index f54c402..93c9066 100644
|
|
|
41a6c3 |
--- a/support/ab.c
|
|
|
41a6c3 |
+++ b/support/ab.c
|
|
|
41a6c3 |
@@ -344,6 +344,7 @@ apr_time_t start, lasttime, stoptime;
|
|
|
41a6c3 |
char _request[2048];
|
|
|
41a6c3 |
char *request = _request;
|
|
|
41a6c3 |
apr_size_t reqlen;
|
|
|
41a6c3 |
+int requests_initialized = 0;
|
|
|
41a6c3 |
|
|
|
41a6c3 |
/* one global throw-away buffer to read stuff into */
|
|
|
41a6c3 |
char buffer[8192];
|
|
|
41a6c3 |
@@ -1253,12 +1254,18 @@ static void start_connect(struct connection * c)
|
|
|
41a6c3 |
else {
|
|
|
41a6c3 |
set_conn_state(c, STATE_UNCONNECTED);
|
|
|
41a6c3 |
apr_socket_close(c->aprsock);
|
|
|
41a6c3 |
- err_conn++;
|
|
|
41a6c3 |
- if (bad++ > 10) {
|
|
|
41a6c3 |
+ if (good == 0 && destsa->next) {
|
|
|
41a6c3 |
+ destsa = destsa->next;
|
|
|
41a6c3 |
+ err_conn = 0;
|
|
|
41a6c3 |
+ }
|
|
|
41a6c3 |
+ else if (bad++ > 10) {
|
|
|
41a6c3 |
fprintf(stderr,
|
|
|
41a6c3 |
"\nTest aborted after 10 failures\n\n");
|
|
|
41a6c3 |
apr_err("apr_socket_connect()", rv);
|
|
|
41a6c3 |
}
|
|
|
41a6c3 |
+ else {
|
|
|
41a6c3 |
+ err_conn++;
|
|
|
41a6c3 |
+ }
|
|
|
41a6c3 |
|
|
|
41a6c3 |
start_connect(c);
|
|
|
41a6c3 |
return;
|
|
|
41a6c3 |
@@ -1339,6 +1346,7 @@ static void read_connection(struct connection * c)
|
|
|
41a6c3 |
apr_status_t status;
|
|
|
41a6c3 |
char *part;
|
|
|
41a6c3 |
char respcode[4]; /* 3 digits and null */
|
|
|
41a6c3 |
+ int i;
|
|
|
41a6c3 |
|
|
|
41a6c3 |
r = sizeof(buffer);
|
|
|
41a6c3 |
#ifdef USE_SSL
|
|
|
41a6c3 |
@@ -1362,6 +1370,13 @@ static void read_connection(struct connection * c)
|
|
|
41a6c3 |
good++;
|
|
|
41a6c3 |
close_connection(c);
|
|
|
41a6c3 |
}
|
|
|
41a6c3 |
+ else if (scode == SSL_ERROR_SYSCALL
|
|
|
41a6c3 |
+ && c->read == 0
|
|
|
41a6c3 |
+ && destsa->next
|
|
|
41a6c3 |
+ && c->state == STATE_CONNECTING
|
|
|
41a6c3 |
+ && good == 0) {
|
|
|
41a6c3 |
+ return;
|
|
|
41a6c3 |
+ }
|
|
|
41a6c3 |
else if (scode != SSL_ERROR_WANT_WRITE
|
|
|
41a6c3 |
&& scode != SSL_ERROR_WANT_READ) {
|
|
|
41a6c3 |
/* some fatal error: */
|
|
|
41a6c3 |
@@ -1387,8 +1402,8 @@ static void read_connection(struct connection * c)
|
|
|
41a6c3 |
}
|
|
|
41a6c3 |
/* catch legitimate fatal apr_socket_recv errors */
|
|
|
41a6c3 |
else if (status != APR_SUCCESS) {
|
|
|
41a6c3 |
- err_recv++;
|
|
|
41a6c3 |
if (recverrok) {
|
|
|
41a6c3 |
+ err_recv++;
|
|
|
41a6c3 |
bad++;
|
|
|
41a6c3 |
close_connection(c);
|
|
|
41a6c3 |
if (verbosity >= 1) {
|
|
|
41a6c3 |
@@ -1396,7 +1411,12 @@ static void read_connection(struct connection * c)
|
|
|
41a6c3 |
fprintf(stderr,"%s: %s (%d)\n", "apr_socket_recv", apr_strerror(status, buf, sizeof buf), status);
|
|
|
41a6c3 |
}
|
|
|
41a6c3 |
return;
|
|
|
41a6c3 |
- } else {
|
|
|
41a6c3 |
+ } else if (destsa->next && c->state == STATE_CONNECTING
|
|
|
41a6c3 |
+ && c->read == 0 && good == 0) {
|
|
|
41a6c3 |
+ return;
|
|
|
41a6c3 |
+ }
|
|
|
41a6c3 |
+ else {
|
|
|
41a6c3 |
+ err_recv++;
|
|
|
41a6c3 |
apr_err("apr_socket_recv", status);
|
|
|
41a6c3 |
}
|
|
|
41a6c3 |
}
|
|
|
41a6c3 |
@@ -1523,6 +1543,16 @@ static void read_connection(struct connection * c)
|
|
|
41a6c3 |
}
|
|
|
41a6c3 |
c->bread += c->cbx - (s + l - c->cbuff) + r - tocopy;
|
|
|
41a6c3 |
totalbread += c->bread;
|
|
|
41a6c3 |
+
|
|
|
41a6c3 |
+ /* We have received the header, so we know this destination socket
|
|
|
41a6c3 |
+ * address is working, so initialize all remaining requests. */
|
|
|
41a6c3 |
+ if (!requests_initialized) {
|
|
|
41a6c3 |
+ for (i = 1; i < concurrency; i++) {
|
|
|
41a6c3 |
+ con[i].socknum = i;
|
|
|
41a6c3 |
+ start_connect(&con[i]);
|
|
|
41a6c3 |
+ }
|
|
|
41a6c3 |
+ requests_initialized = 1;
|
|
|
41a6c3 |
+ }
|
|
|
41a6c3 |
}
|
|
|
41a6c3 |
}
|
|
|
41a6c3 |
else {
|
|
|
41a6c3 |
@@ -1734,11 +1764,10 @@ static void test(void)
|
|
|
41a6c3 |
apr_signal(SIGINT, output_results);
|
|
|
41a6c3 |
#endif
|
|
|
41a6c3 |
|
|
|
41a6c3 |
- /* initialise lots of requests */
|
|
|
41a6c3 |
- for (i = 0; i < concurrency; i++) {
|
|
|
41a6c3 |
- con[i].socknum = i;
|
|
|
41a6c3 |
- start_connect(&con[i]);
|
|
|
41a6c3 |
- }
|
|
|
41a6c3 |
+ /* initialise first connection to determine destination socket address
|
|
|
41a6c3 |
+ * which should be used for next connections. */
|
|
|
41a6c3 |
+ con[0].socknum = 0;
|
|
|
41a6c3 |
+ start_connect(&con[0]);
|
|
|
41a6c3 |
|
|
|
41a6c3 |
do {
|
|
|
41a6c3 |
apr_int32_t n;
|
|
|
41a6c3 |
@@ -1786,14 +1815,20 @@ static void test(void)
|
|
|
41a6c3 |
if ((rtnev & APR_POLLIN) || (rtnev & APR_POLLPRI) || (rtnev & APR_POLLHUP))
|
|
|
41a6c3 |
read_connection(c);
|
|
|
41a6c3 |
if ((rtnev & APR_POLLERR) || (rtnev & APR_POLLNVAL)) {
|
|
|
41a6c3 |
- bad++;
|
|
|
41a6c3 |
- err_except++;
|
|
|
41a6c3 |
- /* avoid apr_poll/EINPROGRESS loop on HP-UX, let recv discover ECONNREFUSED */
|
|
|
41a6c3 |
- if (c->state == STATE_CONNECTING) {
|
|
|
41a6c3 |
- read_connection(c);
|
|
|
41a6c3 |
+ if (destsa->next && c->state == STATE_CONNECTING && good == 0) {
|
|
|
41a6c3 |
+ destsa = destsa->next;
|
|
|
41a6c3 |
+ start_connect(c);
|
|
|
41a6c3 |
}
|
|
|
41a6c3 |
else {
|
|
|
41a6c3 |
- start_connect(c);
|
|
|
41a6c3 |
+ bad++;
|
|
|
41a6c3 |
+ err_except++;
|
|
|
41a6c3 |
+ /* avoid apr_poll/EINPROGRESS loop on HP-UX, let recv discover ECONNREFUSED */
|
|
|
41a6c3 |
+ if (c->state == STATE_CONNECTING) {
|
|
|
41a6c3 |
+ read_connection(c);
|
|
|
41a6c3 |
+ }
|
|
|
41a6c3 |
+ else {
|
|
|
41a6c3 |
+ start_connect(c);
|
|
|
41a6c3 |
+ }
|
|
|
41a6c3 |
}
|
|
|
41a6c3 |
continue;
|
|
|
41a6c3 |
}
|