ab.c revision 873c287c391b0bbc4719b68bb84946515811e1ba
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce/* Licensed to the Apache Software Foundation (ASF) under one or more
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce * contributor license agreements. See the NOTICE file distributed with
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce * this work for additional information regarding copyright ownership.
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce * The ASF licenses this file to You under the Apache License, Version 2.0
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce * (the "License"); you may not use this file except in compliance with
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce * the License. You may obtain a copy of the License at
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce * Unless required by applicable law or agreed to in writing, software
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce * distributed under the License is distributed on an "AS IS" BASIS,
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce * See the License for the specific language governing permissions and
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce * limitations under the License.
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** This program is based on ZeusBench V1.0 written by Adam Twiss
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** which is Copyright (c) 1996 by Zeus Technology Ltd. http://www.zeustech.net/
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** This software is provided "as is" and any express or implied waranties,
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek ** including but not limited to, the implied warranties of merchantability and
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** fitness for a particular purpose are disclaimed. In no event shall
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** Zeus Technology Ltd. be liable for any direct, indirect, incidental, special,
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** exemplary, or consequential damaged (including, but not limited to,
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** procurement of substitute good or services; loss of use, data, or profits;
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek ** or business interruption) however caused and on theory of liability. Whether
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek ** in contract, strict liability or tort (including negligence or otherwise)
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** arising in any way out of the use of this software, even if advised of the
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek ** possibility of such damage.
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek ** - Originally written by Adam Twiss <adam@zeus.co.uk>, March 1996
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek ** with input from Mike Belshe <mbelshe@netscape.com> and
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek ** Michael Campanella <campanella@stevms.enet.dec.com>
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek ** - Enhanced by Dean Gaudet <dgaudet@apache.org>, November 1997
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** - Cleaned up by Ralf S. Engelschall <rse@apache.org>, March 1998
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek ** - POST and verbosity by Kurt Sussman <kls@merlot.com>, August 1998
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek ** - HTML table output added by David N. Welton <davidw@prosa.it>, January 1999
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek ** - Added Cookie, Arbitrary header and auth support. <dirkx@webweaving.org>, April 1999
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek ** Version 1.3d
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek ** - Increased version number - as some of the socket/error handling has
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek ** fundamentally changed - and will give fundamentally different results
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek ** in situations where a server is dropping requests. Therefore you can
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek ** no longer compare results of AB as easily. Hence the inc of the version.
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** They should be closer to the truth though. Sander & <dirkx@covalent.net>, End 2000.
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** - Fixed proxy functionality, added median/mean statistics, added gnuplot
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** output option, added _experimental/rudimentary_ SSL support. Added
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** confidence guestimators and warnings. Sander & <dirkx@covalent.net>, End 2000
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** - Fixed serious int overflow issues which would cause realistic (longer
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek ** than a few minutes) run's to have wrong (but believable) results. Added
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek ** trapping of connection errors which influenced measurements.
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** Contributed by Sander Temme, Early 2001
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** Version 1.3e
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** - Changed timeout behavour during write to work whilst the sockets
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** are filling up and apr_write() does writes a few - but not all.
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** This will potentially change results. <dirkx@webweaving.org>, April 2001
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** Version 2.0.36-dev
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** Improvements to concurrent processing:
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** - Enabled non-blocking connect()s.
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** - Prevent blocking calls to apr_socket_recv() (thereby allowing AB to
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** manage its entire set of socket descriptors).
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** - Any error returned from apr_socket_recv() that is not EAGAIN or EOF
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** is now treated as fatal.
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** Contributed by Aaron Bannert, April 24, 2002
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek ** Version 2.0.36-2
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** Internalized the version string - this string is part
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** of the Agent: header and the result output.
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** Version 2.0.37-dev
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** Adopted SSL code by Madhu Mathihalli <madhusudan_mathihalli@hp.com>
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** [PATCH] ab with SSL support Posted Wed, 15 Aug 2001 20:55:06 GMT
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** Introduces four 'if (int == value)' tests per non-ssl request.
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek ** Version 2.0.40-dev
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** Switched to the new abstract pollset API, allowing ab to
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** take advantage of future apr_pollset_t scalability improvements.
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** Contributed by Brian Pane, August 31, 2002
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** Version 2.3
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** SIGINT now triggers output_results().
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce ** Contributed by colm, March 30, 2006
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek/* Note: this version string should start with \d+[\d\.]* and be a valid
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek * string for an HTTP Agent: header when prefixed with 'ApacheBench/'.
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce * It should reflect the version of AB - and not that of the apache server
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek * it happens to accompany. And it should be updated or changed whenever
8e195a545d41647e591c1d06082133cbd25dc0a4Jakub Hrozek * the results are no longer fundamentally comparable to the results of
8e195a545d41647e591c1d06082133cbd25dc0a4Jakub Hrozek * a previous version of ab. Either due to a change in the logic of
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek * ab - or to due to a change in the distribution it is compiled with
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek * (such as an APR change in for example blocking).
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce * - has various other poor buffer attacks related to the lazy parsing of
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce * response headers from the server
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce * - doesn't implement much of HTTP/1.x, only accepts certain forms of
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek * - (performance problem) heavy use of strstr shows up top in profile
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce * only an issue for loopback usage
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce/* -------------------------------------------------------------------- */
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce/* Hmmm... This source code isn't being compiled in ASCII.
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce * In order for data that flows over the network to make
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce * sense, we need to translate to/from ASCII.
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorce/* affects include files on Solaris */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek/* Libraries for RSA SSL-C */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek/* Libraries on most systems.. */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek/* ------------------- DEFINITIONS -------------------------- */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek/* maximum number of requests on a time limited test */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek#define MAX_REQUESTS (INT_MAX > 50000 ? 50000 : INT_MAX)
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek/* connection state
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek * don't add enums or rearrange or otherwise change values without
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek * visiting set_conn_state()
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozektypedef enum {
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek STATE_CONNECTING, /* TCP connect initiated, but we don't
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek * know if it worked yet
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek STATE_CONNECTED, /* we know TCP connect completed */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek apr_size_t rwrite, rwrote; /* keep pointers in what we write - across
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek * EAGAINs */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek apr_size_t length; /* Content-Length value used for keep-alive */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek char cbuff[CBUFFSIZE]; /* a buffer to store server response header */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek int keepalive; /* non-zero if a keep-alive request */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek int gotheader; /* non-zero if we have the entire header in
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek apr_int16_t reqevents; /* current poll events for this socket */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek apr_time_t starttime; /* start time of connection */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek apr_interval_time_t waittime; /* between request and reading response */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek apr_interval_time_t ctime; /* time to connect */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek apr_interval_time_t time; /* time for connection */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek#define ap_min(a,b) ((a)<(b))?(a):(b)
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek#define ap_max(a,b) ((a)>(b))?(a):(b)
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek#define ap_round_ms(a) ((apr_time_t)((a) + 500)/1000)
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek/* --------------------- GLOBALS ---------------------------- */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint verbosity = 0; /* no verbosity by default */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint recverrok = 0; /* ok to proceed after socket receive errors */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint requests = 1; /* Number of requests to make */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint heartbeatres = 100; /* How often do we say we're alive */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint concurrency = 1; /* Number of multiple requests to make */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint percentile = 1; /* Show percentile served */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint confidence = 1; /* Show confidence estimator and warnings */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint keepalive = 0; /* try and do keepalive connections */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint windowsize = 0; /* we use the OS default window size */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekchar servername[1024]; /* name that server reports */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekchar *host_field; /* value of "Host:" header field */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekchar postfile[1024]; /* name of file containing post data */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekchar *postdata; /* *buffer containing data from postfile */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekapr_size_t postlen = 0; /* length of data to be POSTed */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekchar content_type[1024];/* content type to put in POST header */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek *auth, /* optional (basic/uuencoded) auhentication */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekapr_interval_time_t aprtimeout = apr_time_from_sec(30); /* timeout value */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek/* overrides for ab-generated common headers */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint opt_host = 0; /* was an optional "Host:" header specified? */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint opt_useragent = 0; /* was an optional "User-Agent:" header specified? */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint opt_accept = 0; /* was an optional "Accept:" header specified? */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek * XXX - this is now a per read/write transact type of value
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekapr_size_t doclen = 0; /* the length the document should be */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekapr_int64_t totalread = 0; /* total number of bytes read */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekapr_int64_t totalbread = 0; /* totoal amount of entity body read */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekapr_int64_t totalposted = 0; /* total number of bytes posted, inc. headers */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint started = 0; /* number of requests started, so no excess */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint done = 0; /* number of requests we have done */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint doneka = 0; /* number of keep alive connections done */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint good = 0, bad = 0; /* number of good and bad requests */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint epipe = 0; /* number of broken pipe writes */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint err_length = 0; /* requests failed due to response length */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint err_conn = 0; /* requests failed due to connection drop */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint err_recv = 0; /* requests failed due to broken read */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint err_except = 0; /* requests failed due to exception */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint err_response = 0; /* requests with invalid or non-200 response */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek/* global request (and its length) */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek/* one global throw-away buffer to read stuff into */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek/* interesting percentiles */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekint percs[] = {50, 66, 75, 80, 90, 95, 98, 99, 100};
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekstatic void write_request(struct connection * c);
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekstatic void close_connection(struct connection * c);
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek/* --------------------------------------------------------- */
8e195a545d41647e591c1d06082133cbd25dc0a4Jakub Hrozek/* simple little function to write an error string and exit */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekstatic void err(char *s)
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek printf("Total of %d requests completed\n" , done);
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek/* simple little function to write an APR error string and exit */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek "%s: %s (%d)\n",
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek printf("Total of %d requests completed\n" , done);
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekstatic void set_polled_events(struct connection *c, apr_int16_t new_reqevents)
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekstatic void set_conn_state(struct connection *c, connect_state_e new_state)
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek 0, /* for STATE_UNCONNECTED */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek APR_POLLIN, /* for STATE_CONNECTED; we don't poll in this state,
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek * so prepare for polling in the following state --
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek * STATE_READ
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek set_polled_events(c, events_by_state[new_state]);
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek/* --------------------------------------------------------- */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek/* write out request to a connection - assumes we can write
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek * (small) request out in one go into our new socket buffer
225d845476b6136be9b77f528ed986bba7a7f732Simo Sorcestatic long ssl_print_cb(BIO *bio,int cmd,const char *argp,int argi,long argl,long ret)
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek BIO_printf(out,"read from %p [%p] (%d bytes => %ld (0x%lX))\n",
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN)) {
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek BIO_printf(out,"write to %p [%p] (%d bytes => %ld (0x%lX))\n",
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekstatic void ssl_state_cb(const SSL *s, int w, int r)
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek BIO_printf(bio_err, "SSL/TLS Alert [%s] %s:%s\n",
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek } else if (w & SSL_CB_LOOP) {
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek (SSL_in_connect_init((SSL*)s) ? "connect" : "-"),
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek } else if (w & (SSL_CB_HANDSHAKE_START|SSL_CB_HANDSHAKE_DONE)) {
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek BIO_printf(bio_err, "SSL/TLS Handshake [%s] %s\n",
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek (w & SSL_CB_HANDSHAKE_START ? "Start" : "Done"),
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekstatic int ssl_rand_choosenum(int l, int h)
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek if (i < l) i = l;
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek if (i > h) i = h;
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekstatic void ssl_rand_seed(void)
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek * seed in the current time (usually just 4 bytes)
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek RAND_seed((unsigned char *)&t, l);
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek * seed in the current process id (usually just 4 bytes)
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek * seed in some current state of the run-time stack (128 bytes)
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek n = ssl_rand_choosenum(0, sizeof(stackdata)-128-1);
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekstatic int ssl_print_connection_info(BIO *bio, SSL *ssl)
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek BIO_printf(bio,"Cipher Suite Protocol :%s\n", SSL_CIPHER_get_version(c));
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek BIO_printf(bio,"Cipher Suite Name :%s\n",SSL_CIPHER_get_name(c));
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek BIO_printf(bio,"Cipher Suite Cipher Bits:%d (%d)\n",bits,alg_bits);
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekstatic void ssl_print_cert_info(BIO *bio, X509 *cert)
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek BIO_printf(bio, "Certificate version: %ld\n", X509_get_version(cert)+1);
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek ASN1_UTCTIME_print(bio, X509_get_notBefore(cert));
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek ASN1_UTCTIME_print(bio, X509_get_notAfter(cert));
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek BIO_printf(bio,"The issuer name is %s\n", buf);
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek BIO_printf(bio,"The subject name is %s\n", buf);
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek /* dump the extension list too */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek BIO_printf(bio, "Extension Count: %d\n", X509_get_ext_count(cert));
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekstatic void ssl_print_info(struct connection *c)
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek SSL_SESSION_print(bio_err, SSL_get_session(c->ssl));
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekstatic void ssl_proceed_handshake(struct connection *c)
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek pk_bits = EVP_PKEY_bits(X509_get_pubkey(cert));
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek /* Try again */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek /* Unexpected result */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek BIO_printf(bio_err, "SSL handshake failed (%d).\n", ecode);
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek#endif /* USE_SSL */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozekstatic void write_request(struct connection * c)
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek apr_status_t e = APR_SUCCESS; /* prevent gcc warning */
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek * First time round ?
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek if (c->rwrite == 0) {
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek e_ssl = SSL_write(c->ssl,request + c->rwrote, l);
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek BIO_printf(bio_err, "SSL write failed - closing connection\n");
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek e = apr_socket_send(c->aprsock, request + c->rwrote, &l);
c0bca1722d6f9dfb654ad78397be70f79ff39af1Jakub Hrozek if (e != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(e)) {
c->rwrite -= l;
} while (c->rwrite);
double timetaken;
if (sig) {
#ifdef USE_SSL
if (bad)
if (err_response)
if (keepalive)
if (posting > 0)
if (posting > 0) {
if (done > 0) {
for (i = 0; i < done; i++) {
for (i = 0; i < done; i++) {
sdtot += a * a;
sdcon += a * a;
sdd += a * a;
sdwait += a * a;
(int (*) (const void *, const void *)) compradre);
(int (*) (const void *, const void *)) compri);
(int (*) (const void *, const void *)) compwait);
(int (*) (const void *, const void *)) comprando);
if (confidence) {
#define CONF_FMT_STRING "%5" APR_TIME_T_FMT " %4" APR_TIME_T_FMT " %5.1f %6" APR_TIME_T_FMT " %7" APR_TIME_T_FMT "\n"
else if (d > sd ) \
for (i = 0; i < sizeof(percs) / sizeof(int); i++) {
if (percs[i] <= 0)
if (csvperc) {
if (!out) {
if (gnuplot) {
if (!out) {
for (i = 0; i < done; i++) {
if (sig) {
static void output_html_results(void)
if (bad)
if (err_response)
if (keepalive)
if (posting > 0)
if (timetaken) {
if (posting > 0) {
for (i = 0; i < done; i++) {
c->read = 0;
c->bread = 0;
c->keepalive = 0;
c->cbx = 0;
c->gotheader = 0;
c->rwrite = 0;
if (c->ctx)
!= APR_SUCCESS) {
if (windowsize != 0) {
#ifdef USE_SSL
if (is_ssl) {
c->rwrite = 0;
err_conn++;
start_connect(c);
started++;
#ifdef USE_SSL
if (c->ssl) {
write_request(c);
if (good)
bad++;
err_length++;
#ifdef USE_SSL
if (c->ssl) {
start_connect(c);
apr_size_t r;
char *part;
r = sizeof(buffer);
#ifdef USE_SSL
if (c->ssl) {
if (status <= 0) {
good++;
close_connection(c);
c->read = 0;
close_connection(c);
r = status;
good++;
close_connection(c);
err_recv++;
if (recverrok) {
bad++;
close_connection(c);
totalread += r;
if (c->read == 0) {
c->read += r;
if (!c->gotheader) {
#ifdef NOT_ASCII
if (space) {
err_response++;
start_connect(c);
if (!good) {
q = servername;
err_response++;
if (keepalive &&
char *cl;
if (!cl)
if (cl) {
if (!cl) {
c->length = 0;
c->bread += r;
totalbread += r;
good++;
bad++;
err_length++;
doneka++;
c->keepalive = 0;
c->length = 0;
c->gotheader = 0;
c->cbx = 0;
write_request(c);
static void test(void)
int snprintf_res = 0;
#ifdef NOT_ASCII
if (isproxy) {
if (!use_html) {
if (isproxy)
if (!opt_host) {
if (!opt_useragent) {
if (!opt_accept) {
if (posting <= 0) {
if (!buff) {
#ifdef NOT_ASCII
!= APR_SUCCESS) {
#ifdef SIGINT
for (i = 0; i < concurrency; i++) {
apr_int32_t n;
n = concurrency;
struct connection *c;
#ifdef USE_SSL
read_connection(c);
bad++;
err_except++;
start_connect(c);
err_conn++;
start_connect(c);
started++;
#ifdef USE_SSL
if (c->ssl)
write_request(c);
write_request(c);
if (heartbeatres)
if (use_html)
output_results(0);
static void copyright(void)
if (!use_html) {
printf(" This is ApacheBench, Version %s <i><%s></i><br>\n", AP_AB_BASEREVISION, "$Revision$");
#ifdef USE_SSL
/* 80 column ruler: ********************************************************************************
#ifdef USE_SSL
char *cp;
char *scope_id;
#ifdef USE_SSL
is_ssl = 0;
#ifdef USE_SSL
#ifdef USE_SSL
if (is_ssl)
#ifdef USE_SSL
return rv;
return rv;
if (!postdata) {
return APR_ENOMEM;
return rv;
const char *optarg;
#ifdef USE_SSL
#ifdef NOT_ASCII
if (status) {
if (status) {
if (status) {
#ifdef USE_SSL
if (requests <= 0) {
heartbeatres = 0;
percentile = 0;
confidence = 0;
if (posting != 0)
else if (postdata) {
exit(r);
optarg++;
optarg++;
copyright();
#ifdef USE_SSL
heartbeatres = 0;
#ifdef USE_SSL
#ifdef RSAREF
#ifdef SIGPIPE
copyright();
test();