1*ea149709Sguenther /* $OpenBSD: s_time.c,v 1.34 2019/07/14 03:30:46 guenther Exp $ */ 2dab3f910Sjsing /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3dab3f910Sjsing * All rights reserved. 4dab3f910Sjsing * 5dab3f910Sjsing * This package is an SSL implementation written 6dab3f910Sjsing * by Eric Young (eay@cryptsoft.com). 7dab3f910Sjsing * The implementation was written so as to conform with Netscapes SSL. 8dab3f910Sjsing * 9dab3f910Sjsing * This library is free for commercial and non-commercial use as long as 10dab3f910Sjsing * the following conditions are aheared to. The following conditions 11dab3f910Sjsing * apply to all code found in this distribution, be it the RC4, RSA, 12dab3f910Sjsing * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13dab3f910Sjsing * included with this distribution is covered by the same copyright terms 14dab3f910Sjsing * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15dab3f910Sjsing * 16dab3f910Sjsing * Copyright remains Eric Young's, and as such any Copyright notices in 17dab3f910Sjsing * the code are not to be removed. 18dab3f910Sjsing * If this package is used in a product, Eric Young should be given attribution 19dab3f910Sjsing * as the author of the parts of the library used. 20dab3f910Sjsing * This can be in the form of a textual message at program startup or 21dab3f910Sjsing * in documentation (online or textual) provided with the package. 22dab3f910Sjsing * 23dab3f910Sjsing * Redistribution and use in source and binary forms, with or without 24dab3f910Sjsing * modification, are permitted provided that the following conditions 25dab3f910Sjsing * are met: 26dab3f910Sjsing * 1. Redistributions of source code must retain the copyright 27dab3f910Sjsing * notice, this list of conditions and the following disclaimer. 28dab3f910Sjsing * 2. Redistributions in binary form must reproduce the above copyright 29dab3f910Sjsing * notice, this list of conditions and the following disclaimer in the 30dab3f910Sjsing * documentation and/or other materials provided with the distribution. 31dab3f910Sjsing * 3. All advertising materials mentioning features or use of this software 32dab3f910Sjsing * must display the following acknowledgement: 33dab3f910Sjsing * "This product includes cryptographic software written by 34dab3f910Sjsing * Eric Young (eay@cryptsoft.com)" 35dab3f910Sjsing * The word 'cryptographic' can be left out if the rouines from the library 36dab3f910Sjsing * being used are not cryptographic related :-). 37dab3f910Sjsing * 4. If you include any Windows specific code (or a derivative thereof) from 38dab3f910Sjsing * the apps directory (application code) you must include an acknowledgement: 39dab3f910Sjsing * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40dab3f910Sjsing * 41dab3f910Sjsing * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42dab3f910Sjsing * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43dab3f910Sjsing * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44dab3f910Sjsing * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45dab3f910Sjsing * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46dab3f910Sjsing * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47dab3f910Sjsing * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48dab3f910Sjsing * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49dab3f910Sjsing * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50dab3f910Sjsing * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51dab3f910Sjsing * SUCH DAMAGE. 52dab3f910Sjsing * 53dab3f910Sjsing * The licence and distribution terms for any publically available version or 54dab3f910Sjsing * derivative of this code cannot be changed. i.e. this code cannot simply be 55dab3f910Sjsing * copied and put under another distribution licence 56dab3f910Sjsing * [including the GNU Public Licence.] 57dab3f910Sjsing */ 58dab3f910Sjsing 59dab3f910Sjsing /*----------------------------------------- 60dab3f910Sjsing s_time - SSL client connection timer program 61dab3f910Sjsing Written and donated by Larry Streepy <streepy@healthcare.com> 62dab3f910Sjsing -----------------------------------------*/ 63dab3f910Sjsing 647b69b2e4Sderaadt #include <sys/types.h> 65dab3f910Sjsing #include <sys/socket.h> 66dab3f910Sjsing 67dab3f910Sjsing #include <stdio.h> 68dab3f910Sjsing #include <stdlib.h> 69dab3f910Sjsing #include <limits.h> 70dab3f910Sjsing #include <string.h> 71dab3f910Sjsing #include <unistd.h> 727b69b2e4Sderaadt #include <poll.h> 73dab3f910Sjsing 74dab3f910Sjsing #include "apps.h" 75dab3f910Sjsing 76dab3f910Sjsing #include <openssl/err.h> 77dab3f910Sjsing #include <openssl/pem.h> 78dab3f910Sjsing #include <openssl/ssl.h> 79dab3f910Sjsing #include <openssl/x509.h> 80dab3f910Sjsing 81dab3f910Sjsing #include "s_apps.h" 82dab3f910Sjsing 83dab3f910Sjsing #define SSL_CONNECT_NAME "localhost:4433" 84dab3f910Sjsing 85dab3f910Sjsing #define BUFSIZZ 1024*10 86dab3f910Sjsing 87dab3f910Sjsing #define MYBUFSIZ 1024*8 88dab3f910Sjsing 89dab3f910Sjsing #define SECONDS 30 90abbe1350Sjsing extern int verify_depth; 91dab3f910Sjsing 92dab3f910Sjsing static void s_time_usage(void); 932d831f52Scheloha static int run_test(SSL *); 941ceb7bbbScheloha static int benchmark(int); 9511c2e033Scheloha static void print_tally_mark(SSL *); 96dab3f910Sjsing 97dab3f910Sjsing static SSL_CTX *tm_ctx = NULL; 98dab3f910Sjsing static const SSL_METHOD *s_time_meth = NULL; 99dab3f910Sjsing static long bytes_read = 0; 100dab3f910Sjsing 1018c2803e9Sjsing struct { 1028c2803e9Sjsing int bugs; 1038c2803e9Sjsing char *CAfile; 1048c2803e9Sjsing char *CApath; 1058c2803e9Sjsing char *certfile; 1068c2803e9Sjsing char *cipher; 1078c2803e9Sjsing char *host; 1088c2803e9Sjsing char *keyfile; 109e7036f67Sderaadt time_t maxtime; 1108c2803e9Sjsing int nbio; 111f33eb045Slteo int no_shutdown; 1128c2803e9Sjsing int perform; 1138c2803e9Sjsing int verify; 1148c2803e9Sjsing int verify_depth; 1158c2803e9Sjsing char *www_path; 1168c2803e9Sjsing } s_time_config; 1178c2803e9Sjsing 118*ea149709Sguenther static const struct option s_time_options[] = { 119dab3f910Sjsing { 1208c2803e9Sjsing .name = "bugs", 1218c2803e9Sjsing .desc = "Enable workarounds for known SSL/TLS bugs", 1228c2803e9Sjsing .type = OPTION_FLAG, 1238c2803e9Sjsing .opt.flag = &s_time_config.bugs, 1248c2803e9Sjsing }, 1258c2803e9Sjsing { 1268c2803e9Sjsing .name = "CAfile", 1278c2803e9Sjsing .argname = "file", 1288c2803e9Sjsing .desc = "File containing trusted certificates in PEM format", 1298c2803e9Sjsing .type = OPTION_ARG, 1308c2803e9Sjsing .opt.arg = &s_time_config.CAfile, 1318c2803e9Sjsing }, 1328c2803e9Sjsing { 1338c2803e9Sjsing .name = "CApath", 1348c2803e9Sjsing .argname = "path", 1358c2803e9Sjsing .desc = "Directory containing trusted certificates", 1368c2803e9Sjsing .type = OPTION_ARG, 1378c2803e9Sjsing .opt.arg = &s_time_config.CApath, 1388c2803e9Sjsing }, 1398c2803e9Sjsing { 1408c2803e9Sjsing .name = "cert", 1418c2803e9Sjsing .argname = "file", 1428c2803e9Sjsing .desc = "Client certificate to use, if one is requested", 1438c2803e9Sjsing .type = OPTION_ARG, 1448c2803e9Sjsing .opt.arg = &s_time_config.certfile, 1458c2803e9Sjsing }, 1468c2803e9Sjsing { 1478c2803e9Sjsing .name = "cipher", 1488c2803e9Sjsing .argname = "list", 1498c2803e9Sjsing .desc = "List of cipher suites to send to the server", 1508c2803e9Sjsing .type = OPTION_ARG, 1518c2803e9Sjsing .opt.arg = &s_time_config.cipher, 1528c2803e9Sjsing }, 1538c2803e9Sjsing { 1548c2803e9Sjsing .name = "connect", 1558c2803e9Sjsing .argname = "host:port", 1568c2803e9Sjsing .desc = "Host and port to connect to (default " 1578c2803e9Sjsing SSL_CONNECT_NAME ")", 1588c2803e9Sjsing .type = OPTION_ARG, 1598c2803e9Sjsing .opt.arg = &s_time_config.host, 1608c2803e9Sjsing }, 1618c2803e9Sjsing { 1628c2803e9Sjsing .name = "key", 1638c2803e9Sjsing .argname = "file", 1648c2803e9Sjsing .desc = "Client private key to use, if one is required", 1658c2803e9Sjsing .type = OPTION_ARG, 1668c2803e9Sjsing .opt.arg = &s_time_config.keyfile, 1678c2803e9Sjsing }, 1688c2803e9Sjsing { 1698c2803e9Sjsing .name = "nbio", 1708c2803e9Sjsing .desc = "Use non-blocking I/O", 1718c2803e9Sjsing .type = OPTION_FLAG, 1728c2803e9Sjsing .opt.flag = &s_time_config.nbio, 1738c2803e9Sjsing }, 1748c2803e9Sjsing { 1758c2803e9Sjsing .name = "new", 1768c2803e9Sjsing .desc = "Use a new session ID for each connection", 1778c2803e9Sjsing .type = OPTION_VALUE, 1788c2803e9Sjsing .opt.value = &s_time_config.perform, 1798c2803e9Sjsing .value = 1, 1808c2803e9Sjsing }, 1818c2803e9Sjsing { 182f33eb045Slteo .name = "no_shutdown", 183f33eb045Slteo .desc = "Shut down the connection without notifying the server", 184f33eb045Slteo .type = OPTION_FLAG, 185f33eb045Slteo .opt.flag = &s_time_config.no_shutdown, 186f33eb045Slteo }, 187f33eb045Slteo { 1888c2803e9Sjsing .name = "reuse", 1898c2803e9Sjsing .desc = "Reuse the same session ID for each connection", 1908c2803e9Sjsing .type = OPTION_VALUE, 1918c2803e9Sjsing .opt.value = &s_time_config.perform, 1928c2803e9Sjsing .value = 2, 1938c2803e9Sjsing }, 1948c2803e9Sjsing { 1958c2803e9Sjsing .name = "time", 1968c2803e9Sjsing .argname = "seconds", 1978c2803e9Sjsing .desc = "Duration to perform timing tests for (default 30)", 198ea1128d8Sderaadt .type = OPTION_ARG_TIME, 199e7036f67Sderaadt .opt.tvalue = &s_time_config.maxtime, 2008c2803e9Sjsing }, 2018c2803e9Sjsing { 2028c2803e9Sjsing .name = "verify", 2038c2803e9Sjsing .argname = "depth", 2048c2803e9Sjsing .desc = "Enable peer certificate verification with given depth", 2058c2803e9Sjsing .type = OPTION_ARG_INT, 2068c2803e9Sjsing .opt.value = &s_time_config.verify_depth, 2078c2803e9Sjsing }, 2088c2803e9Sjsing { 2098c2803e9Sjsing .name = "www", 2108c2803e9Sjsing .argname = "page", 2118c2803e9Sjsing .desc = "Page to GET from the server (default none)", 2128c2803e9Sjsing .type = OPTION_ARG, 2138c2803e9Sjsing .opt.arg = &s_time_config.www_path, 2148c2803e9Sjsing }, 2158c2803e9Sjsing { NULL }, 2168c2803e9Sjsing }; 217dab3f910Sjsing 218dab3f910Sjsing static void 219dab3f910Sjsing s_time_usage(void) 220dab3f910Sjsing { 2218c2803e9Sjsing fprintf(stderr, 2228c2803e9Sjsing "usage: s_time " 2238c2803e9Sjsing "[-bugs] [-CAfile file] [-CApath directory] [-cert file]\n" 2248c2803e9Sjsing " [-cipher cipherlist] [-connect host:port] [-key keyfile]\n" 225f33eb045Slteo " [-nbio] [-new] [-no_shutdown] [-reuse] [-time seconds]\n" 2268c2803e9Sjsing " [-verify depth] [-www page]\n\n"); 2278c2803e9Sjsing options_usage(s_time_options); 228dab3f910Sjsing } 229dab3f910Sjsing 230dab3f910Sjsing /*********************************************************************** 231dab3f910Sjsing * MAIN - main processing area for client 232dab3f910Sjsing * real name depends on MONOLITH 233dab3f910Sjsing */ 234dab3f910Sjsing int 235dab3f910Sjsing s_time_main(int argc, char **argv) 236dab3f910Sjsing { 237e7036f67Sderaadt int ret = 1; 238dab3f910Sjsing 2399bc487adSdoug if (single_execution) { 240ebcad598Smestre if (pledge("stdio rpath inet dns", NULL) == -1) { 2419bc487adSdoug perror("pledge"); 242e370f0eeSdoug exit(1); 243e370f0eeSdoug } 2449bc487adSdoug } 2459bc487adSdoug 2461a76ec68Scheloha s_time_meth = TLS_client_method(); 247dab3f910Sjsing 2488c2803e9Sjsing verify_depth = 0; 2498c2803e9Sjsing 2508c2803e9Sjsing memset(&s_time_config, 0, sizeof(s_time_config)); 2518c2803e9Sjsing 2528c2803e9Sjsing s_time_config.host = SSL_CONNECT_NAME; 2538c2803e9Sjsing s_time_config.maxtime = SECONDS; 2548c2803e9Sjsing s_time_config.perform = 3; 2558c2803e9Sjsing s_time_config.verify = SSL_VERIFY_NONE; 2568c2803e9Sjsing s_time_config.verify_depth = -1; 2578c2803e9Sjsing 2588c2803e9Sjsing if (options_parse(argc, argv, s_time_options, NULL, NULL) != 0) { 2598c2803e9Sjsing s_time_usage(); 260dab3f910Sjsing goto end; 2618c2803e9Sjsing } 2628c2803e9Sjsing 2638c2803e9Sjsing if (s_time_config.verify_depth >= 0) { 2648c2803e9Sjsing s_time_config.verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; 2658c2803e9Sjsing verify_depth = s_time_config.verify_depth; 2668c2803e9Sjsing BIO_printf(bio_err, "verify depth is %d\n", verify_depth); 2678c2803e9Sjsing } 2688c2803e9Sjsing 2698c2803e9Sjsing if (s_time_config.www_path != NULL && 2708c2803e9Sjsing strlen(s_time_config.www_path) > MYBUFSIZ - 100) { 2718c2803e9Sjsing BIO_printf(bio_err, "-www option too long\n"); 2728c2803e9Sjsing goto end; 2738c2803e9Sjsing } 274dab3f910Sjsing 275dab3f910Sjsing if ((tm_ctx = SSL_CTX_new(s_time_meth)) == NULL) 276dab3f910Sjsing return (1); 277dab3f910Sjsing 278dab3f910Sjsing SSL_CTX_set_quiet_shutdown(tm_ctx, 1); 279dab3f910Sjsing 2808c2803e9Sjsing if (s_time_config.bugs) 281dab3f910Sjsing SSL_CTX_set_options(tm_ctx, SSL_OP_ALL); 282abbe1350Sjsing 283abbe1350Sjsing if (s_time_config.cipher != NULL) { 284abbe1350Sjsing if (!SSL_CTX_set_cipher_list(tm_ctx, s_time_config.cipher)) { 285abbe1350Sjsing BIO_printf(bio_err, "error setting cipher list\n"); 286abbe1350Sjsing ERR_print_errors(bio_err); 287abbe1350Sjsing goto end; 288abbe1350Sjsing } 289abbe1350Sjsing } 290abbe1350Sjsing 2911292f75aSbcook SSL_CTX_set_verify(tm_ctx, s_time_config.verify, NULL); 2921292f75aSbcook 2938c2803e9Sjsing if (!set_cert_stuff(tm_ctx, s_time_config.certfile, 2948c2803e9Sjsing s_time_config.keyfile)) 295dab3f910Sjsing goto end; 296dab3f910Sjsing 2978c2803e9Sjsing if ((!SSL_CTX_load_verify_locations(tm_ctx, s_time_config.CAfile, 2988c2803e9Sjsing s_time_config.CApath)) || 299dab3f910Sjsing (!SSL_CTX_set_default_verify_paths(tm_ctx))) { 300dab3f910Sjsing /* 301dab3f910Sjsing * BIO_printf(bio_err,"error setting default verify 302dab3f910Sjsing * locations\n"); 303dab3f910Sjsing */ 304dab3f910Sjsing ERR_print_errors(bio_err); 305dab3f910Sjsing /* goto end; */ 306dab3f910Sjsing } 307dab3f910Sjsing 308a81eedd5Scheloha /* Loop and time how long it takes to make connections */ 309a81eedd5Scheloha if (s_time_config.perform & 1) { 310e7036f67Sderaadt printf("Collecting connection statistics for %lld seconds\n", 311e7036f67Sderaadt (long long)s_time_config.maxtime); 3121ceb7bbbScheloha if (benchmark(0)) 313dab3f910Sjsing goto end; 314a81eedd5Scheloha } 315dab3f910Sjsing /* 316dab3f910Sjsing * Now loop and time connections using the same session id over and 317dab3f910Sjsing * over 318dab3f910Sjsing */ 319a81eedd5Scheloha if (s_time_config.perform & 2) { 320dab3f910Sjsing printf("\n\nNow timing with session id reuse.\n"); 3211ceb7bbbScheloha if (benchmark(1)) 322dab3f910Sjsing goto end; 323a81eedd5Scheloha } 324dab3f910Sjsing ret = 0; 325dab3f910Sjsing end: 326dab3f910Sjsing if (tm_ctx != NULL) { 327dab3f910Sjsing SSL_CTX_free(tm_ctx); 328dab3f910Sjsing tm_ctx = NULL; 329dab3f910Sjsing } 330dab3f910Sjsing 331dab3f910Sjsing return (ret); 332dab3f910Sjsing } 333dab3f910Sjsing 334dab3f910Sjsing /*********************************************************************** 3352d831f52Scheloha * run_test - make a connection, get a file, and shut down the connection 3362d831f52Scheloha * 337dab3f910Sjsing * Args: 3385e66bdb3Scheloha * scon = SSL connection 339dab3f910Sjsing * Returns: 3405e66bdb3Scheloha * 1 on success, 0 on error 341dab3f910Sjsing */ 3425e66bdb3Scheloha static int 3432d831f52Scheloha run_test(SSL *scon) 344dab3f910Sjsing { 3452d831f52Scheloha char buf[1024 * 8]; 3467b69b2e4Sderaadt struct pollfd pfd[1]; 3477b69b2e4Sderaadt BIO *conn; 3481292f75aSbcook long verify_error; 3492d831f52Scheloha int i, retval; 350dab3f910Sjsing 351dab3f910Sjsing if ((conn = BIO_new(BIO_s_connect())) == NULL) 3525e66bdb3Scheloha return 0; 3538c2803e9Sjsing BIO_set_conn_hostname(conn, s_time_config.host); 3545e66bdb3Scheloha SSL_set_connect_state(scon); 3555e66bdb3Scheloha SSL_set_bio(scon, conn, conn); 356dab3f910Sjsing for (;;) { 3575e66bdb3Scheloha i = SSL_connect(scon); 358dab3f910Sjsing if (BIO_sock_should_retry(i)) { 359dab3f910Sjsing BIO_printf(bio_err, "DELAY\n"); 3605e66bdb3Scheloha pfd[0].fd = SSL_get_fd(scon); 3617b69b2e4Sderaadt pfd[0].events = POLLIN; 3627b69b2e4Sderaadt poll(pfd, 1, -1); 363dab3f910Sjsing continue; 364dab3f910Sjsing } 365dab3f910Sjsing break; 366dab3f910Sjsing } 367dab3f910Sjsing if (i <= 0) { 368dab3f910Sjsing BIO_printf(bio_err, "ERROR\n"); 3695e66bdb3Scheloha verify_error = SSL_get_verify_result(scon); 370dab3f910Sjsing if (verify_error != X509_V_OK) 371dab3f910Sjsing BIO_printf(bio_err, "verify error:%s\n", 372dab3f910Sjsing X509_verify_cert_error_string(verify_error)); 373dab3f910Sjsing else 374dab3f910Sjsing ERR_print_errors(bio_err); 3755e66bdb3Scheloha return 0; 376dab3f910Sjsing } 3772d831f52Scheloha if (s_time_config.www_path != NULL) { 3782d831f52Scheloha retval = snprintf(buf, sizeof buf, 3792d831f52Scheloha "GET %s HTTP/1.0\r\n\r\n", s_time_config.www_path); 380515e489cSderaadt if (retval < 0 || retval >= sizeof buf) { 3812d831f52Scheloha fprintf(stderr, "URL too long\n"); 3822d831f52Scheloha return 0; 3832d831f52Scheloha } 3845f8f2a30Scheloha if (SSL_write(scon, buf, retval) != retval) 3855f8f2a30Scheloha return 0; 3862d831f52Scheloha while ((i = SSL_read(scon, buf, sizeof(buf))) > 0) 3872d831f52Scheloha bytes_read += i; 3882d831f52Scheloha } 3892d831f52Scheloha if (s_time_config.no_shutdown) 3902d831f52Scheloha SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | 3912d831f52Scheloha SSL_RECEIVED_SHUTDOWN); 3922d831f52Scheloha else 3932d831f52Scheloha SSL_shutdown(scon); 3945e66bdb3Scheloha return 1; 395dab3f910Sjsing } 3961ceb7bbbScheloha 39711c2e033Scheloha static void 39811c2e033Scheloha print_tally_mark(SSL *scon) 39911c2e033Scheloha { 40011c2e033Scheloha int ver; 40111c2e033Scheloha 40211c2e033Scheloha if (SSL_session_reused(scon)) 40311c2e033Scheloha ver = 'r'; 40411c2e033Scheloha else { 40511c2e033Scheloha ver = SSL_version(scon); 40611c2e033Scheloha if (ver == TLS1_VERSION) 40711c2e033Scheloha ver = 't'; 40811c2e033Scheloha else 40911c2e033Scheloha ver = '*'; 41011c2e033Scheloha } 41111c2e033Scheloha fputc(ver, stdout); 41211c2e033Scheloha fflush(stdout); 41311c2e033Scheloha } 41411c2e033Scheloha 4151ceb7bbbScheloha static int 4161ceb7bbbScheloha benchmark(int reuse_session) 4171ceb7bbbScheloha { 418ce92332eScheloha double elapsed, totalTime; 4191ceb7bbbScheloha int nConn = 0; 4201ceb7bbbScheloha SSL *scon = NULL; 4211ceb7bbbScheloha int ret = 1; 4221ceb7bbbScheloha 4231ceb7bbbScheloha if (reuse_session) { 4241ceb7bbbScheloha /* Get an SSL object so we can reuse the session id */ 4255e66bdb3Scheloha if ((scon = SSL_new(tm_ctx)) == NULL) 4265e66bdb3Scheloha goto end; 4272d831f52Scheloha if (!run_test(scon)) { 4281ceb7bbbScheloha fprintf(stderr, "Unable to get connection\n"); 4291ceb7bbbScheloha goto end; 4301ceb7bbbScheloha } 4311ceb7bbbScheloha printf("starting\n"); 4321ceb7bbbScheloha } 4331ceb7bbbScheloha 4341ceb7bbbScheloha nConn = 0; 4351ceb7bbbScheloha bytes_read = 0; 4361ceb7bbbScheloha 437ce92332eScheloha app_timer_real(TM_RESET); 438ce92332eScheloha app_timer_user(TM_RESET); 4391ceb7bbbScheloha for (;;) { 440ce92332eScheloha elapsed = app_timer_real(TM_GET); 441ce92332eScheloha if (elapsed > s_time_config.maxtime) 4421ceb7bbbScheloha break; 4435e66bdb3Scheloha if (scon == NULL) { 4445e66bdb3Scheloha if ((scon = SSL_new(tm_ctx)) == NULL) 4455e66bdb3Scheloha goto end; 4465e66bdb3Scheloha } 4472d831f52Scheloha if (!run_test(scon)) 4481ceb7bbbScheloha goto end; 4491ceb7bbbScheloha nConn += 1; 45011c2e033Scheloha print_tally_mark(scon); 4511ceb7bbbScheloha if (!reuse_session) { 4521ceb7bbbScheloha SSL_free(scon); 4531ceb7bbbScheloha scon = NULL; 4541ceb7bbbScheloha } 4551ceb7bbbScheloha } 456ce92332eScheloha totalTime = app_timer_user(TM_GET); 4571ceb7bbbScheloha 4581ceb7bbbScheloha printf("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", 4591ceb7bbbScheloha nConn, totalTime, ((double) nConn / totalTime), bytes_read); 460ce92332eScheloha printf("%d connections in %.0f real seconds, %ld bytes read per connection\n", 4611ceb7bbbScheloha nConn, 462ce92332eScheloha elapsed, 4631ceb7bbbScheloha bytes_read / nConn); 4641ceb7bbbScheloha 4651ceb7bbbScheloha ret = 0; 4661ceb7bbbScheloha end: 4671ceb7bbbScheloha SSL_free(scon); 4681ceb7bbbScheloha return ret; 4691ceb7bbbScheloha } 470