1*23cc9d40Stb /* $OpenBSD: s_time.c,v 1.39 2025/01/02 13:10:03 tb 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 #define SSL_CONNECT_NAME "localhost:4433" 82dab3f910Sjsing 83dab3f910Sjsing #define BUFSIZZ 1024*10 84dab3f910Sjsing 85dab3f910Sjsing #define MYBUFSIZ 1024*8 86dab3f910Sjsing 87dab3f910Sjsing #define SECONDS 30 88abbe1350Sjsing extern int verify_depth; 89dab3f910Sjsing 90dab3f910Sjsing static void s_time_usage(void); 912d831f52Scheloha static int run_test(SSL *); 921ceb7bbbScheloha static int benchmark(int); 9311c2e033Scheloha static void print_tally_mark(SSL *); 94dab3f910Sjsing 95dab3f910Sjsing static SSL_CTX *tm_ctx = NULL; 96dab3f910Sjsing static const SSL_METHOD *s_time_meth = NULL; 97dab3f910Sjsing static long bytes_read = 0; 98dab3f910Sjsing 99efc7e65fStb static struct { 1008c2803e9Sjsing int bugs; 1018c2803e9Sjsing char *CAfile; 1028c2803e9Sjsing char *CApath; 1038c2803e9Sjsing char *certfile; 1048c2803e9Sjsing char *cipher; 1058c2803e9Sjsing char *host; 1068c2803e9Sjsing char *keyfile; 107e7036f67Sderaadt time_t maxtime; 1088c2803e9Sjsing int nbio; 109f33eb045Slteo int no_shutdown; 1108c2803e9Sjsing int perform; 1118c2803e9Sjsing int verify; 1128c2803e9Sjsing int verify_depth; 1138c2803e9Sjsing char *www_path; 114e7718adaStb } cfg; 1158c2803e9Sjsing 116ea149709Sguenther static const struct option s_time_options[] = { 117dab3f910Sjsing { 1188c2803e9Sjsing .name = "bugs", 1198c2803e9Sjsing .desc = "Enable workarounds for known SSL/TLS bugs", 1208c2803e9Sjsing .type = OPTION_FLAG, 121e7718adaStb .opt.flag = &cfg.bugs, 1228c2803e9Sjsing }, 1238c2803e9Sjsing { 1248c2803e9Sjsing .name = "CAfile", 1258c2803e9Sjsing .argname = "file", 1268c2803e9Sjsing .desc = "File containing trusted certificates in PEM format", 1278c2803e9Sjsing .type = OPTION_ARG, 128e7718adaStb .opt.arg = &cfg.CAfile, 1298c2803e9Sjsing }, 1308c2803e9Sjsing { 1318c2803e9Sjsing .name = "CApath", 1328c2803e9Sjsing .argname = "path", 1338c2803e9Sjsing .desc = "Directory containing trusted certificates", 1348c2803e9Sjsing .type = OPTION_ARG, 135e7718adaStb .opt.arg = &cfg.CApath, 1368c2803e9Sjsing }, 1378c2803e9Sjsing { 1388c2803e9Sjsing .name = "cert", 1398c2803e9Sjsing .argname = "file", 1408c2803e9Sjsing .desc = "Client certificate to use, if one is requested", 1418c2803e9Sjsing .type = OPTION_ARG, 142e7718adaStb .opt.arg = &cfg.certfile, 1438c2803e9Sjsing }, 1448c2803e9Sjsing { 1458c2803e9Sjsing .name = "cipher", 1468c2803e9Sjsing .argname = "list", 1478c2803e9Sjsing .desc = "List of cipher suites to send to the server", 1488c2803e9Sjsing .type = OPTION_ARG, 149e7718adaStb .opt.arg = &cfg.cipher, 1508c2803e9Sjsing }, 1518c2803e9Sjsing { 1528c2803e9Sjsing .name = "connect", 1538c2803e9Sjsing .argname = "host:port", 1548c2803e9Sjsing .desc = "Host and port to connect to (default " 1558c2803e9Sjsing SSL_CONNECT_NAME ")", 1568c2803e9Sjsing .type = OPTION_ARG, 157e7718adaStb .opt.arg = &cfg.host, 1588c2803e9Sjsing }, 1598c2803e9Sjsing { 1608c2803e9Sjsing .name = "key", 1618c2803e9Sjsing .argname = "file", 1628c2803e9Sjsing .desc = "Client private key to use, if one is required", 1638c2803e9Sjsing .type = OPTION_ARG, 164e7718adaStb .opt.arg = &cfg.keyfile, 1658c2803e9Sjsing }, 1668c2803e9Sjsing { 1678c2803e9Sjsing .name = "nbio", 1688c2803e9Sjsing .desc = "Use non-blocking I/O", 1698c2803e9Sjsing .type = OPTION_FLAG, 170e7718adaStb .opt.flag = &cfg.nbio, 1718c2803e9Sjsing }, 1728c2803e9Sjsing { 1738c2803e9Sjsing .name = "new", 1748c2803e9Sjsing .desc = "Use a new session ID for each connection", 1758c2803e9Sjsing .type = OPTION_VALUE, 176e7718adaStb .opt.value = &cfg.perform, 1778c2803e9Sjsing .value = 1, 1788c2803e9Sjsing }, 1798c2803e9Sjsing { 180f33eb045Slteo .name = "no_shutdown", 181f33eb045Slteo .desc = "Shut down the connection without notifying the server", 182f33eb045Slteo .type = OPTION_FLAG, 183e7718adaStb .opt.flag = &cfg.no_shutdown, 184f33eb045Slteo }, 185f33eb045Slteo { 1868c2803e9Sjsing .name = "reuse", 1878c2803e9Sjsing .desc = "Reuse the same session ID for each connection", 1888c2803e9Sjsing .type = OPTION_VALUE, 189e7718adaStb .opt.value = &cfg.perform, 1908c2803e9Sjsing .value = 2, 1918c2803e9Sjsing }, 1928c2803e9Sjsing { 1938c2803e9Sjsing .name = "time", 1948c2803e9Sjsing .argname = "seconds", 1958c2803e9Sjsing .desc = "Duration to perform timing tests for (default 30)", 196ea1128d8Sderaadt .type = OPTION_ARG_TIME, 197e7718adaStb .opt.tvalue = &cfg.maxtime, 1988c2803e9Sjsing }, 1998c2803e9Sjsing { 2008c2803e9Sjsing .name = "verify", 2018c2803e9Sjsing .argname = "depth", 2028c2803e9Sjsing .desc = "Enable peer certificate verification with given depth", 2038c2803e9Sjsing .type = OPTION_ARG_INT, 204e7718adaStb .opt.value = &cfg.verify_depth, 2058c2803e9Sjsing }, 2068c2803e9Sjsing { 2078c2803e9Sjsing .name = "www", 2088c2803e9Sjsing .argname = "page", 2098c2803e9Sjsing .desc = "Page to GET from the server (default none)", 2108c2803e9Sjsing .type = OPTION_ARG, 211e7718adaStb .opt.arg = &cfg.www_path, 2128c2803e9Sjsing }, 2138c2803e9Sjsing { NULL }, 2148c2803e9Sjsing }; 215dab3f910Sjsing 216dab3f910Sjsing static void 217dab3f910Sjsing s_time_usage(void) 218dab3f910Sjsing { 2198c2803e9Sjsing fprintf(stderr, 2208c2803e9Sjsing "usage: s_time " 2218c2803e9Sjsing "[-bugs] [-CAfile file] [-CApath directory] [-cert file]\n" 2228c2803e9Sjsing " [-cipher cipherlist] [-connect host:port] [-key keyfile]\n" 223f33eb045Slteo " [-nbio] [-new] [-no_shutdown] [-reuse] [-time seconds]\n" 2248c2803e9Sjsing " [-verify depth] [-www page]\n\n"); 2258c2803e9Sjsing options_usage(s_time_options); 226dab3f910Sjsing } 227dab3f910Sjsing 228dab3f910Sjsing /*********************************************************************** 229dab3f910Sjsing * MAIN - main processing area for client 230dab3f910Sjsing * real name depends on MONOLITH 231dab3f910Sjsing */ 232dab3f910Sjsing int 233dab3f910Sjsing s_time_main(int argc, char **argv) 234dab3f910Sjsing { 235e7036f67Sderaadt int ret = 1; 236dab3f910Sjsing 237ebcad598Smestre if (pledge("stdio rpath inet dns", NULL) == -1) { 2389bc487adSdoug perror("pledge"); 239e370f0eeSdoug exit(1); 240e370f0eeSdoug } 2419bc487adSdoug 2421a76ec68Scheloha s_time_meth = TLS_client_method(); 243dab3f910Sjsing 2448c2803e9Sjsing verify_depth = 0; 2458c2803e9Sjsing 246e7718adaStb memset(&cfg, 0, sizeof(cfg)); 2478c2803e9Sjsing 248e7718adaStb cfg.host = SSL_CONNECT_NAME; 249e7718adaStb cfg.maxtime = SECONDS; 250e7718adaStb cfg.perform = 3; 251e7718adaStb cfg.verify = SSL_VERIFY_NONE; 252e7718adaStb cfg.verify_depth = -1; 2538c2803e9Sjsing 2548c2803e9Sjsing if (options_parse(argc, argv, s_time_options, NULL, NULL) != 0) { 2558c2803e9Sjsing s_time_usage(); 256dab3f910Sjsing goto end; 2578c2803e9Sjsing } 2588c2803e9Sjsing 259e7718adaStb if (cfg.verify_depth >= 0) { 260e7718adaStb cfg.verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; 261e7718adaStb verify_depth = cfg.verify_depth; 2628c2803e9Sjsing BIO_printf(bio_err, "verify depth is %d\n", verify_depth); 2638c2803e9Sjsing } 2648c2803e9Sjsing 265e7718adaStb if (cfg.www_path != NULL && 266e7718adaStb strlen(cfg.www_path) > MYBUFSIZ - 100) { 2678c2803e9Sjsing BIO_printf(bio_err, "-www option too long\n"); 2688c2803e9Sjsing goto end; 2698c2803e9Sjsing } 270dab3f910Sjsing 271dab3f910Sjsing if ((tm_ctx = SSL_CTX_new(s_time_meth)) == NULL) 272dab3f910Sjsing return (1); 273dab3f910Sjsing 274dab3f910Sjsing SSL_CTX_set_quiet_shutdown(tm_ctx, 1); 275dab3f910Sjsing 276e7718adaStb if (cfg.bugs) 277dab3f910Sjsing SSL_CTX_set_options(tm_ctx, SSL_OP_ALL); 278abbe1350Sjsing 279e7718adaStb if (cfg.cipher != NULL) { 280e7718adaStb if (!SSL_CTX_set_cipher_list(tm_ctx, cfg.cipher)) { 281abbe1350Sjsing BIO_printf(bio_err, "error setting cipher list\n"); 282abbe1350Sjsing ERR_print_errors(bio_err); 283abbe1350Sjsing goto end; 284abbe1350Sjsing } 285abbe1350Sjsing } 286abbe1350Sjsing 287e7718adaStb SSL_CTX_set_verify(tm_ctx, cfg.verify, NULL); 2881292f75aSbcook 289e7718adaStb if (!set_cert_stuff(tm_ctx, cfg.certfile, 290e7718adaStb cfg.keyfile)) 291dab3f910Sjsing goto end; 292dab3f910Sjsing 293e7718adaStb if ((!SSL_CTX_load_verify_locations(tm_ctx, cfg.CAfile, 294e7718adaStb cfg.CApath)) || 295dab3f910Sjsing (!SSL_CTX_set_default_verify_paths(tm_ctx))) { 296dab3f910Sjsing /* 297dab3f910Sjsing * BIO_printf(bio_err,"error setting default verify 298dab3f910Sjsing * locations\n"); 299dab3f910Sjsing */ 300dab3f910Sjsing ERR_print_errors(bio_err); 301dab3f910Sjsing /* goto end; */ 302dab3f910Sjsing } 303dab3f910Sjsing 304a81eedd5Scheloha /* Loop and time how long it takes to make connections */ 305e7718adaStb if (cfg.perform & 1) { 306e7036f67Sderaadt printf("Collecting connection statistics for %lld seconds\n", 307e7718adaStb (long long)cfg.maxtime); 3081ceb7bbbScheloha if (benchmark(0)) 309dab3f910Sjsing goto end; 310a81eedd5Scheloha } 311dab3f910Sjsing /* 312dab3f910Sjsing * Now loop and time connections using the same session id over and 313dab3f910Sjsing * over 314dab3f910Sjsing */ 315e7718adaStb if (cfg.perform & 2) { 316dab3f910Sjsing printf("\n\nNow timing with session id reuse.\n"); 3171ceb7bbbScheloha if (benchmark(1)) 318dab3f910Sjsing goto end; 319a81eedd5Scheloha } 320dab3f910Sjsing ret = 0; 321dab3f910Sjsing end: 322dab3f910Sjsing if (tm_ctx != NULL) { 323dab3f910Sjsing SSL_CTX_free(tm_ctx); 324dab3f910Sjsing tm_ctx = NULL; 325dab3f910Sjsing } 326dab3f910Sjsing 327dab3f910Sjsing return (ret); 328dab3f910Sjsing } 329dab3f910Sjsing 330dab3f910Sjsing /*********************************************************************** 3312d831f52Scheloha * run_test - make a connection, get a file, and shut down the connection 3322d831f52Scheloha * 333dab3f910Sjsing * Args: 3345e66bdb3Scheloha * scon = SSL connection 335dab3f910Sjsing * Returns: 3365e66bdb3Scheloha * 1 on success, 0 on error 337dab3f910Sjsing */ 3385e66bdb3Scheloha static int 3392d831f52Scheloha run_test(SSL *scon) 340dab3f910Sjsing { 3412d831f52Scheloha char buf[1024 * 8]; 3427b69b2e4Sderaadt struct pollfd pfd[1]; 3437b69b2e4Sderaadt BIO *conn; 3441292f75aSbcook long verify_error; 3452d831f52Scheloha int i, retval; 346dab3f910Sjsing 347dab3f910Sjsing if ((conn = BIO_new(BIO_s_connect())) == NULL) 3485e66bdb3Scheloha return 0; 349e7718adaStb BIO_set_conn_hostname(conn, cfg.host); 3505e66bdb3Scheloha SSL_set_connect_state(scon); 3515e66bdb3Scheloha SSL_set_bio(scon, conn, conn); 352dab3f910Sjsing for (;;) { 3535e66bdb3Scheloha i = SSL_connect(scon); 354dab3f910Sjsing if (BIO_sock_should_retry(i)) { 355dab3f910Sjsing BIO_printf(bio_err, "DELAY\n"); 3565e66bdb3Scheloha pfd[0].fd = SSL_get_fd(scon); 3577b69b2e4Sderaadt pfd[0].events = POLLIN; 3587b69b2e4Sderaadt poll(pfd, 1, -1); 359dab3f910Sjsing continue; 360dab3f910Sjsing } 361dab3f910Sjsing break; 362dab3f910Sjsing } 363dab3f910Sjsing if (i <= 0) { 364dab3f910Sjsing BIO_printf(bio_err, "ERROR\n"); 3655e66bdb3Scheloha verify_error = SSL_get_verify_result(scon); 366dab3f910Sjsing if (verify_error != X509_V_OK) 367dab3f910Sjsing BIO_printf(bio_err, "verify error:%s\n", 368dab3f910Sjsing X509_verify_cert_error_string(verify_error)); 369dab3f910Sjsing else 370dab3f910Sjsing ERR_print_errors(bio_err); 3715e66bdb3Scheloha return 0; 372dab3f910Sjsing } 373e7718adaStb if (cfg.www_path != NULL) { 3742d831f52Scheloha retval = snprintf(buf, sizeof buf, 375e7718adaStb "GET %s HTTP/1.0\r\n\r\n", cfg.www_path); 376515e489cSderaadt if (retval < 0 || retval >= sizeof buf) { 3772d831f52Scheloha fprintf(stderr, "URL too long\n"); 3782d831f52Scheloha return 0; 3792d831f52Scheloha } 3805f8f2a30Scheloha if (SSL_write(scon, buf, retval) != retval) 3815f8f2a30Scheloha return 0; 3822d831f52Scheloha while ((i = SSL_read(scon, buf, sizeof(buf))) > 0) 3832d831f52Scheloha bytes_read += i; 3842d831f52Scheloha } 385e7718adaStb if (cfg.no_shutdown) 3862d831f52Scheloha SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | 3872d831f52Scheloha SSL_RECEIVED_SHUTDOWN); 3882d831f52Scheloha else 3892d831f52Scheloha SSL_shutdown(scon); 3905e66bdb3Scheloha return 1; 391dab3f910Sjsing } 3921ceb7bbbScheloha 39311c2e033Scheloha static void 39411c2e033Scheloha print_tally_mark(SSL *scon) 39511c2e033Scheloha { 39611c2e033Scheloha int ver; 39711c2e033Scheloha 39811c2e033Scheloha if (SSL_session_reused(scon)) 39911c2e033Scheloha ver = 'r'; 40011c2e033Scheloha else { 40111c2e033Scheloha ver = SSL_version(scon); 40211c2e033Scheloha if (ver == TLS1_VERSION) 40311c2e033Scheloha ver = 't'; 40411c2e033Scheloha else 40511c2e033Scheloha ver = '*'; 40611c2e033Scheloha } 40711c2e033Scheloha fputc(ver, stdout); 40811c2e033Scheloha fflush(stdout); 40911c2e033Scheloha } 41011c2e033Scheloha 4111ceb7bbbScheloha static int 4121ceb7bbbScheloha benchmark(int reuse_session) 4131ceb7bbbScheloha { 414ce92332eScheloha double elapsed, totalTime; 4151ceb7bbbScheloha int nConn = 0; 4161ceb7bbbScheloha SSL *scon = NULL; 4171ceb7bbbScheloha int ret = 1; 4181ceb7bbbScheloha 4191ceb7bbbScheloha if (reuse_session) { 4201ceb7bbbScheloha /* Get an SSL object so we can reuse the session id */ 4215e66bdb3Scheloha if ((scon = SSL_new(tm_ctx)) == NULL) 4225e66bdb3Scheloha goto end; 4232d831f52Scheloha if (!run_test(scon)) { 4241ceb7bbbScheloha fprintf(stderr, "Unable to get connection\n"); 4251ceb7bbbScheloha goto end; 4261ceb7bbbScheloha } 4271ceb7bbbScheloha printf("starting\n"); 4281ceb7bbbScheloha } 4291ceb7bbbScheloha 4301ceb7bbbScheloha nConn = 0; 4311ceb7bbbScheloha bytes_read = 0; 4321ceb7bbbScheloha 433ce92332eScheloha app_timer_real(TM_RESET); 434ce92332eScheloha app_timer_user(TM_RESET); 4351ceb7bbbScheloha for (;;) { 436ce92332eScheloha elapsed = app_timer_real(TM_GET); 437e7718adaStb if (elapsed > cfg.maxtime) 4381ceb7bbbScheloha break; 4395e66bdb3Scheloha if (scon == NULL) { 4405e66bdb3Scheloha if ((scon = SSL_new(tm_ctx)) == NULL) 4415e66bdb3Scheloha goto end; 4425e66bdb3Scheloha } 4432d831f52Scheloha if (!run_test(scon)) 4441ceb7bbbScheloha goto end; 4451ceb7bbbScheloha nConn += 1; 44611c2e033Scheloha print_tally_mark(scon); 4471ceb7bbbScheloha if (!reuse_session) { 4481ceb7bbbScheloha SSL_free(scon); 4491ceb7bbbScheloha scon = NULL; 4501ceb7bbbScheloha } 4511ceb7bbbScheloha } 452ce92332eScheloha totalTime = app_timer_user(TM_GET); 4531ceb7bbbScheloha 4541ceb7bbbScheloha printf("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", 4551ceb7bbbScheloha nConn, totalTime, ((double) nConn / totalTime), bytes_read); 456ce92332eScheloha printf("%d connections in %.0f real seconds, %ld bytes read per connection\n", 4579c9e7ec3Stb nConn, elapsed, nConn > 0 ? bytes_read / nConn : 0); 4581ceb7bbbScheloha 4591ceb7bbbScheloha ret = 0; 4601ceb7bbbScheloha end: 4611ceb7bbbScheloha SSL_free(scon); 4621ceb7bbbScheloha return ret; 4631ceb7bbbScheloha } 464