diff options
-rw-r--r-- | CHANGES | 3 | ||||
-rw-r--r-- | docs/manual/programs/ab.xml | 4 | ||||
-rw-r--r-- | support/ab.c | 22 |
3 files changed, 28 insertions, 1 deletions
@@ -2,6 +2,9 @@ Changes with Apache 2.3.13 + *) ab: Support specifying the local address to use. PR 48930. + [Peter Schuller <scode spotify com>] + *) core: Add support to ErrorLogFormat for logging the system unique thread id under Linux. [Stefan Fritsch] diff --git a/docs/manual/programs/ab.xml b/docs/manual/programs/ab.xml index e1f13100b4..11b0f88d13 100644 --- a/docs/manual/programs/ab.xml +++ b/docs/manual/programs/ab.xml @@ -38,6 +38,7 @@ <p><code><strong>ab</strong> [ -<strong>A</strong> <var>auth-username</var>:<var>password</var> ] [ -<strong>b</strong> <var>windowsize</var> ] + [ -<strong>B</strong> <var>local-address</var> ] [ -<strong>c</strong> <var>concurrency</var> ] [ -<strong>C</strong> <var>cookie-name</var>=<var>value</var> ] [ -<strong>d</strong> ] @@ -80,6 +81,9 @@ <dt><code>-b <var>windowsize</var></code></dt> <dd>Size of TCP send/receive buffer, in bytes.</dd> + <dt><code>-B <var>local-address</var></code></dt> + <dd>Address to bind to when making outgoing connections.</dd> + <dt><code>-c <var>concurrency</var></code></dt> <dd>Number of multiple requests to perform at a time. Default is one request at a time.</dd> diff --git a/support/ab.c b/support/ab.c index efe9137645..f1ccd678cf 100644 --- a/support/ab.c +++ b/support/ab.c @@ -306,6 +306,7 @@ apr_port_t port; /* port number */ char proxyhost[1024]; /* proxy host name */ int proxyport = 0; /* proxy port */ const char *connecthost; +const char *myhost; apr_port_t connectport; const char *gnuplot; /* GNUplot file */ const char *csvperc; /* CSV Percentile file */ @@ -370,6 +371,7 @@ apr_pool_t *cntxt; apr_pollset_t *readbits; +apr_sockaddr_t *mysa; apr_sockaddr_t *destsa; #ifdef NOT_ASCII @@ -1201,6 +1203,10 @@ static void start_connect(struct connection * c) apr_err("socket", rv); } + if ((rv = apr_socket_bind(c->aprsock, mysa)) != APR_SUCCESS) { + apr_err("bind", rv); + } + c->pollfd.desc_type = APR_POLL_SOCKET; c->pollfd.desc.s = c->aprsock; c->pollfd.reqevents = 0; @@ -1699,6 +1705,14 @@ static void test(void) #endif /* NOT_ASCII */ /* This only needs to be done once */ + if ((rv = apr_sockaddr_info_get(&mysa, myhost, APR_UNSPEC, 0, 0, cntxt)) != APR_SUCCESS) { + char buf[120]; + apr_snprintf(buf, sizeof(buf), + "apr_sockaddr_info_get() for %s", myhost); + apr_err(buf, rv); + } + + /* This too */ if ((rv = apr_sockaddr_info_get(&destsa, connecthost, APR_UNSPEC, connectport, 0, cntxt)) != APR_SUCCESS) { char buf[120]; @@ -1857,6 +1871,7 @@ static void usage(const char *progname) fprintf(stderr, " -c concurrency Number of multiple requests to make\n"); fprintf(stderr, " -t timelimit Seconds to max. wait for responses\n"); fprintf(stderr, " -b windowsize Size of TCP send/receive buffer, in bytes\n"); + fprintf(stderr, " -B address Address to bind to when making outgoing connections\n"); fprintf(stderr, " -p postfile File containing data to POST. Remember also to set -T\n"); fprintf(stderr, " -u putfile File containing data to PUT. Remember also to set -T\n"); fprintf(stderr, " -T content-type Content-type header for POSTing, eg.\n"); @@ -2051,8 +2066,10 @@ int main(int argc, const char * const argv[]) } #endif + myhost = NULL; /* 0.0.0.0 or :: */ + apr_getopt_init(&opt, cntxt, argc, argv); - while ((status = apr_getopt(opt, "n:c:t:b:T:p:u:v:rkVhwix:y:z:C:H:P:A:g:X:de:Sq" + while ((status = apr_getopt(opt, "n:c:t:b:T:p:u:v:rkVhwix:y:z:C:H:P:A:g:X:de:SqB:" #ifdef USE_SSL "Z:f:" #endif @@ -2212,6 +2229,9 @@ int main(int argc, const char * const argv[]) case 'V': copyright(); return 0; + case 'B': + myhost = apr_pstrdup(cntxt, opt_arg); + break; #ifdef USE_SSL case 'Z': ssl_cipher = strdup(opt_arg); |