1e71b7053SJung-uk Kim /* 2b6c1fdcdSJung-uk Kim * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. 374664626SKris Kennaway * 4e71b7053SJung-uk Kim * Licensed under the OpenSSL license (the "License"). You may not use 5e71b7053SJung-uk Kim * this file except in compliance with the License. You can obtain a copy 6e71b7053SJung-uk Kim * in the file LICENSE in the source distribution or at 7e71b7053SJung-uk Kim * https://www.openssl.org/source/license.html 874664626SKris Kennaway */ 974664626SKris Kennaway 1074664626SKris Kennaway #include <stdio.h> 1174664626SKris Kennaway #include <stdlib.h> 1274664626SKris Kennaway #include <string.h> 1374664626SKris Kennaway 14e71b7053SJung-uk Kim #include <openssl/opensslconf.h> 15e71b7053SJung-uk Kim 16e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SOCK 17e71b7053SJung-uk Kim 185c87c606SMark Murray #include "apps.h" 19e71b7053SJung-uk Kim #include "progs.h" 2074664626SKris Kennaway #include <openssl/x509.h> 2174664626SKris Kennaway #include <openssl/ssl.h> 2274664626SKris Kennaway #include <openssl/pem.h> 2374664626SKris Kennaway #include "s_apps.h" 2474664626SKris Kennaway #include <openssl/err.h> 25e71b7053SJung-uk Kim #include <internal/sockets.h> 265c87c606SMark Murray #if !defined(OPENSSL_SYS_MSDOS) 275c87c606SMark Murray # include OPENSSL_UNISTD 285c87c606SMark Murray #endif 2974664626SKris Kennaway 3074664626SKris Kennaway #define SSL_CONNECT_NAME "localhost:4433" 3174664626SKris Kennaway 3274664626SKris Kennaway #define SECONDS 30 33e71b7053SJung-uk Kim #define SECONDSSTR "30" 3474664626SKris Kennaway 35e71b7053SJung-uk Kim static SSL *doConnection(SSL *scon, const char *host, SSL_CTX *ctx); 3674664626SKris Kennaway 37e71b7053SJung-uk Kim /* 38e71b7053SJung-uk Kim * Define a HTTP get command globally. 39e71b7053SJung-uk Kim * Also define the size of the command, this is two bytes less than 40e71b7053SJung-uk Kim * the size of the string because the %s is replaced by the URL. 4174664626SKris Kennaway */ 42e71b7053SJung-uk Kim static const char fmt_http_get_cmd[] = "GET %s HTTP/1.0\r\n\r\n"; 43e71b7053SJung-uk Kim static const size_t fmt_http_get_cmd_size = sizeof(fmt_http_get_cmd) - 2; 4474664626SKris Kennaway 45e71b7053SJung-uk Kim typedef enum OPTION_choice { 46e71b7053SJung-uk Kim OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, 47e71b7053SJung-uk Kim OPT_CONNECT, OPT_CIPHER, OPT_CIPHERSUITES, OPT_CERT, OPT_NAMEOPT, OPT_KEY, 48e71b7053SJung-uk Kim OPT_CAPATH, OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NEW, OPT_REUSE, 49e71b7053SJung-uk Kim OPT_BUGS, OPT_VERIFY, OPT_TIME, OPT_SSL3, 50e71b7053SJung-uk Kim OPT_WWW 51e71b7053SJung-uk Kim } OPTION_CHOICE; 5274664626SKris Kennaway 53e71b7053SJung-uk Kim const OPTIONS s_time_options[] = { 54e71b7053SJung-uk Kim {"help", OPT_HELP, '-', "Display this summary"}, 55e71b7053SJung-uk Kim {"connect", OPT_CONNECT, 's', 56e71b7053SJung-uk Kim "Where to connect as post:port (default is " SSL_CONNECT_NAME ")"}, 57e71b7053SJung-uk Kim {"cipher", OPT_CIPHER, 's', "TLSv1.2 and below cipher list to be used"}, 58e71b7053SJung-uk Kim {"ciphersuites", OPT_CIPHERSUITES, 's', 59e71b7053SJung-uk Kim "Specify TLSv1.3 ciphersuites to be used"}, 60e71b7053SJung-uk Kim {"cert", OPT_CERT, '<', "Cert file to use, PEM format assumed"}, 61e71b7053SJung-uk Kim {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, 62e71b7053SJung-uk Kim {"key", OPT_KEY, '<', "File with key, PEM; default is -cert file"}, 63e71b7053SJung-uk Kim {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, 64e71b7053SJung-uk Kim {"cafile", OPT_CAFILE, '<', "PEM format file of CA's"}, 65cfac584bSJung-uk Kim {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"}, 66e71b7053SJung-uk Kim {"no-CAfile", OPT_NOCAFILE, '-', 67e71b7053SJung-uk Kim "Do not load the default certificates file"}, 68e71b7053SJung-uk Kim {"no-CApath", OPT_NOCAPATH, '-', 69e71b7053SJung-uk Kim "Do not load certificates from the default certificates directory"}, 70e71b7053SJung-uk Kim {"new", OPT_NEW, '-', "Just time new connections"}, 71e71b7053SJung-uk Kim {"reuse", OPT_REUSE, '-', "Just time connection reuse"}, 72e71b7053SJung-uk Kim {"bugs", OPT_BUGS, '-', "Turn on SSL bug compatibility"}, 73e71b7053SJung-uk Kim {"verify", OPT_VERIFY, 'p', 74e71b7053SJung-uk Kim "Turn on peer certificate verification, set depth"}, 75e71b7053SJung-uk Kim {"time", OPT_TIME, 'p', "Seconds to collect data, default " SECONDSSTR}, 76e71b7053SJung-uk Kim {"www", OPT_WWW, 's', "Fetch specified page from the site"}, 775c87c606SMark Murray #ifndef OPENSSL_NO_SSL3 78e71b7053SJung-uk Kim {"ssl3", OPT_SSL3, '-', "Just use SSLv3"}, 7974664626SKris Kennaway #endif 80e71b7053SJung-uk Kim {NULL} 81e71b7053SJung-uk Kim }; 8274664626SKris Kennaway 8374664626SKris Kennaway #define START 0 8474664626SKris Kennaway #define STOP 1 8574664626SKris Kennaway 8674664626SKris Kennaway static double tm_Time_F(int s) 8774664626SKris Kennaway { 881f13597dSJung-uk Kim return app_tminterval(s, 1); 8974664626SKris Kennaway } 9074664626SKris Kennaway 91e71b7053SJung-uk Kim int s_time_main(int argc, char **argv) 9274664626SKris Kennaway { 93e71b7053SJung-uk Kim char buf[1024 * 8]; 9474664626SKris Kennaway SSL *scon = NULL; 95e71b7053SJung-uk Kim SSL_CTX *ctx = NULL; 96e71b7053SJung-uk Kim const SSL_METHOD *meth = NULL; 97e71b7053SJung-uk Kim char *CApath = NULL, *CAfile = NULL, *cipher = NULL, *ciphersuites = NULL; 98e71b7053SJung-uk Kim char *www_path = NULL; 99e71b7053SJung-uk Kim char *host = SSL_CONNECT_NAME, *certfile = NULL, *keyfile = NULL, *prog; 100e71b7053SJung-uk Kim double totalTime = 0.0; 101e71b7053SJung-uk Kim int noCApath = 0, noCAfile = 0; 102e71b7053SJung-uk Kim int maxtime = SECONDS, nConn = 0, perform = 3, ret = 1, i, st_bugs = 0; 103e71b7053SJung-uk Kim long bytes_read = 0, finishtime = 0; 104e71b7053SJung-uk Kim OPTION_CHOICE o; 105e71b7053SJung-uk Kim int max_version = 0, ver, buf_len; 106e71b7053SJung-uk Kim size_t buf_size; 10774664626SKris Kennaway 108e71b7053SJung-uk Kim meth = TLS_client_method(); 109f579bf8eSKris Kennaway 110e71b7053SJung-uk Kim prog = opt_init(argc, argv, s_time_options); 111e71b7053SJung-uk Kim while ((o = opt_next()) != OPT_EOF) { 112e71b7053SJung-uk Kim switch (o) { 113e71b7053SJung-uk Kim case OPT_EOF: 114e71b7053SJung-uk Kim case OPT_ERR: 115e71b7053SJung-uk Kim opthelp: 116e71b7053SJung-uk Kim BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 117e71b7053SJung-uk Kim goto end; 118e71b7053SJung-uk Kim case OPT_HELP: 119e71b7053SJung-uk Kim opt_help(s_time_options); 120e71b7053SJung-uk Kim ret = 0; 121e71b7053SJung-uk Kim goto end; 122e71b7053SJung-uk Kim case OPT_CONNECT: 123e71b7053SJung-uk Kim host = opt_arg(); 124e71b7053SJung-uk Kim break; 125e71b7053SJung-uk Kim case OPT_REUSE: 126e71b7053SJung-uk Kim perform = 2; 127e71b7053SJung-uk Kim break; 128e71b7053SJung-uk Kim case OPT_NEW: 129e71b7053SJung-uk Kim perform = 1; 130e71b7053SJung-uk Kim break; 131e71b7053SJung-uk Kim case OPT_VERIFY: 132e71b7053SJung-uk Kim if (!opt_int(opt_arg(), &verify_args.depth)) 133e71b7053SJung-uk Kim goto opthelp; 134e71b7053SJung-uk Kim BIO_printf(bio_err, "%s: verify depth is %d\n", 135e71b7053SJung-uk Kim prog, verify_args.depth); 136e71b7053SJung-uk Kim break; 137e71b7053SJung-uk Kim case OPT_CERT: 138e71b7053SJung-uk Kim certfile = opt_arg(); 139e71b7053SJung-uk Kim break; 140e71b7053SJung-uk Kim case OPT_NAMEOPT: 141e71b7053SJung-uk Kim if (!set_nameopt(opt_arg())) 142e71b7053SJung-uk Kim goto end; 143e71b7053SJung-uk Kim break; 144e71b7053SJung-uk Kim case OPT_KEY: 145e71b7053SJung-uk Kim keyfile = opt_arg(); 146e71b7053SJung-uk Kim break; 147e71b7053SJung-uk Kim case OPT_CAPATH: 148e71b7053SJung-uk Kim CApath = opt_arg(); 149e71b7053SJung-uk Kim break; 150e71b7053SJung-uk Kim case OPT_CAFILE: 151e71b7053SJung-uk Kim CAfile = opt_arg(); 152e71b7053SJung-uk Kim break; 153e71b7053SJung-uk Kim case OPT_NOCAPATH: 154e71b7053SJung-uk Kim noCApath = 1; 155e71b7053SJung-uk Kim break; 156e71b7053SJung-uk Kim case OPT_NOCAFILE: 157e71b7053SJung-uk Kim noCAfile = 1; 158e71b7053SJung-uk Kim break; 159e71b7053SJung-uk Kim case OPT_CIPHER: 160e71b7053SJung-uk Kim cipher = opt_arg(); 161e71b7053SJung-uk Kim break; 162e71b7053SJung-uk Kim case OPT_CIPHERSUITES: 163e71b7053SJung-uk Kim ciphersuites = opt_arg(); 164e71b7053SJung-uk Kim break; 165e71b7053SJung-uk Kim case OPT_BUGS: 166e71b7053SJung-uk Kim st_bugs = 1; 167e71b7053SJung-uk Kim break; 168e71b7053SJung-uk Kim case OPT_TIME: 169e71b7053SJung-uk Kim if (!opt_int(opt_arg(), &maxtime)) 170e71b7053SJung-uk Kim goto opthelp; 171e71b7053SJung-uk Kim break; 172e71b7053SJung-uk Kim case OPT_WWW: 173e71b7053SJung-uk Kim www_path = opt_arg(); 174e71b7053SJung-uk Kim buf_size = strlen(www_path) + fmt_http_get_cmd_size; 175e71b7053SJung-uk Kim if (buf_size > sizeof(buf)) { 176e71b7053SJung-uk Kim BIO_printf(bio_err, "%s: -www option is too long\n", prog); 177e71b7053SJung-uk Kim goto end; 178e71b7053SJung-uk Kim } 179e71b7053SJung-uk Kim break; 180e71b7053SJung-uk Kim case OPT_SSL3: 181e71b7053SJung-uk Kim max_version = SSL3_VERSION; 182e71b7053SJung-uk Kim break; 183e71b7053SJung-uk Kim } 184e71b7053SJung-uk Kim } 185e71b7053SJung-uk Kim argc = opt_num_rest(); 186e71b7053SJung-uk Kim if (argc != 0) 187e71b7053SJung-uk Kim goto opthelp; 188f579bf8eSKris Kennaway 189e71b7053SJung-uk Kim if (cipher == NULL) 190e71b7053SJung-uk Kim cipher = getenv("SSL_CIPHER"); 19174664626SKris Kennaway 192e71b7053SJung-uk Kim if ((ctx = SSL_CTX_new(meth)) == NULL) 19374664626SKris Kennaway goto end; 19474664626SKris Kennaway 195e71b7053SJung-uk Kim SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); 196e71b7053SJung-uk Kim SSL_CTX_set_quiet_shutdown(ctx, 1); 197e71b7053SJung-uk Kim if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0) 198e71b7053SJung-uk Kim goto end; 19974664626SKris Kennaway 2006f9291ceSJung-uk Kim if (st_bugs) 201e71b7053SJung-uk Kim SSL_CTX_set_options(ctx, SSL_OP_ALL); 202e71b7053SJung-uk Kim if (cipher != NULL && !SSL_CTX_set_cipher_list(ctx, cipher)) 203e71b7053SJung-uk Kim goto end; 204e71b7053SJung-uk Kim if (ciphersuites != NULL && !SSL_CTX_set_ciphersuites(ctx, ciphersuites)) 205e71b7053SJung-uk Kim goto end; 206e71b7053SJung-uk Kim if (!set_cert_stuff(ctx, certfile, keyfile)) 20774664626SKris Kennaway goto end; 20874664626SKris Kennaway 209e71b7053SJung-uk Kim if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) { 21074664626SKris Kennaway ERR_print_errors(bio_err); 211e71b7053SJung-uk Kim goto end; 21274664626SKris Kennaway } 2136f9291ceSJung-uk Kim if (!(perform & 1)) 2146f9291ceSJung-uk Kim goto next; 215e71b7053SJung-uk Kim printf("Collecting connection statistics for %d seconds\n", maxtime); 21674664626SKris Kennaway 21774664626SKris Kennaway /* Loop and time how long it takes to make connections */ 21874664626SKris Kennaway 21974664626SKris Kennaway bytes_read = 0; 220e71b7053SJung-uk Kim finishtime = (long)time(NULL) + maxtime; 22174664626SKris Kennaway tm_Time_F(START); 2226f9291ceSJung-uk Kim for (;;) { 2236f9291ceSJung-uk Kim if (finishtime < (long)time(NULL)) 2246f9291ceSJung-uk Kim break; 22574664626SKris Kennaway 226e71b7053SJung-uk Kim if ((scon = doConnection(NULL, host, ctx)) == NULL) 22774664626SKris Kennaway goto end; 22874664626SKris Kennaway 229e71b7053SJung-uk Kim if (www_path != NULL) { 230e71b7053SJung-uk Kim buf_len = BIO_snprintf(buf, sizeof(buf), fmt_http_get_cmd, 231e71b7053SJung-uk Kim www_path); 232e71b7053SJung-uk Kim if (buf_len <= 0 || SSL_write(scon, buf, buf_len) <= 0) 23374664626SKris Kennaway goto end; 23474664626SKris Kennaway while ((i = SSL_read(scon, buf, sizeof(buf))) > 0) 23574664626SKris Kennaway bytes_read += i; 23674664626SKris Kennaway } 23774664626SKris Kennaway SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); 238e71b7053SJung-uk Kim BIO_closesocket(SSL_get_fd(scon)); 23974664626SKris Kennaway 24074664626SKris Kennaway nConn += 1; 241e71b7053SJung-uk Kim if (SSL_session_reused(scon)) { 24274664626SKris Kennaway ver = 'r'; 243e71b7053SJung-uk Kim } else { 24474664626SKris Kennaway ver = SSL_version(scon); 24574664626SKris Kennaway if (ver == TLS1_VERSION) 24674664626SKris Kennaway ver = 't'; 24774664626SKris Kennaway else if (ver == SSL3_VERSION) 24874664626SKris Kennaway ver = '3'; 24974664626SKris Kennaway else 25074664626SKris Kennaway ver = '*'; 25174664626SKris Kennaway } 25274664626SKris Kennaway fputc(ver, stdout); 25374664626SKris Kennaway fflush(stdout); 25474664626SKris Kennaway 25574664626SKris Kennaway SSL_free(scon); 25674664626SKris Kennaway scon = NULL; 25774664626SKris Kennaway } 25874664626SKris Kennaway totalTime += tm_Time_F(STOP); /* Add the time for this iteration */ 25974664626SKris Kennaway 260e71b7053SJung-uk Kim i = (int)((long)time(NULL) - finishtime + maxtime); 2616f9291ceSJung-uk Kim printf 2626f9291ceSJung-uk Kim ("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", 2636f9291ceSJung-uk Kim nConn, totalTime, ((double)nConn / totalTime), bytes_read); 2646f9291ceSJung-uk Kim printf 2656f9291ceSJung-uk Kim ("%d connections in %ld real seconds, %ld bytes read per connection\n", 266b6c1fdcdSJung-uk Kim nConn, (long)time(NULL) - finishtime + maxtime, 267b6c1fdcdSJung-uk Kim nConn > 0 ? bytes_read / nConn : 0l); 26874664626SKris Kennaway 2696f9291ceSJung-uk Kim /* 2706f9291ceSJung-uk Kim * Now loop and time connections using the same session id over and over 2716f9291ceSJung-uk Kim */ 27274664626SKris Kennaway 27374664626SKris Kennaway next: 2746f9291ceSJung-uk Kim if (!(perform & 2)) 2756f9291ceSJung-uk Kim goto end; 27674664626SKris Kennaway printf("\n\nNow timing with session id reuse.\n"); 27774664626SKris Kennaway 27874664626SKris Kennaway /* Get an SSL object so we can reuse the session id */ 279e71b7053SJung-uk Kim if ((scon = doConnection(NULL, host, ctx)) == NULL) { 280e71b7053SJung-uk Kim BIO_printf(bio_err, "Unable to get connection\n"); 28174664626SKris Kennaway goto end; 28274664626SKris Kennaway } 28374664626SKris Kennaway 284e71b7053SJung-uk Kim if (www_path != NULL) { 285e71b7053SJung-uk Kim buf_len = BIO_snprintf(buf, sizeof(buf), fmt_http_get_cmd, www_path); 286e71b7053SJung-uk Kim if (buf_len <= 0 || SSL_write(scon, buf, buf_len) <= 0) 287e71b7053SJung-uk Kim goto end; 288e71b7053SJung-uk Kim while ((i = SSL_read(scon, buf, sizeof(buf))) > 0) 289e71b7053SJung-uk Kim continue; 29074664626SKris Kennaway } 29174664626SKris Kennaway SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); 292e71b7053SJung-uk Kim BIO_closesocket(SSL_get_fd(scon)); 29374664626SKris Kennaway 29474664626SKris Kennaway nConn = 0; 29574664626SKris Kennaway totalTime = 0.0; 29674664626SKris Kennaway 297e71b7053SJung-uk Kim finishtime = (long)time(NULL) + maxtime; 29874664626SKris Kennaway 29974664626SKris Kennaway printf("starting\n"); 30074664626SKris Kennaway bytes_read = 0; 30174664626SKris Kennaway tm_Time_F(START); 30274664626SKris Kennaway 3036f9291ceSJung-uk Kim for (;;) { 3046f9291ceSJung-uk Kim if (finishtime < (long)time(NULL)) 3056f9291ceSJung-uk Kim break; 30674664626SKris Kennaway 307e71b7053SJung-uk Kim if ((doConnection(scon, host, ctx)) == NULL) 30874664626SKris Kennaway goto end; 30974664626SKris Kennaway 310e71b7053SJung-uk Kim if (www_path != NULL) { 311e71b7053SJung-uk Kim buf_len = BIO_snprintf(buf, sizeof(buf), fmt_http_get_cmd, 312e71b7053SJung-uk Kim www_path); 313e71b7053SJung-uk Kim if (buf_len <= 0 || SSL_write(scon, buf, buf_len) <= 0) 31474664626SKris Kennaway goto end; 31574664626SKris Kennaway while ((i = SSL_read(scon, buf, sizeof(buf))) > 0) 31674664626SKris Kennaway bytes_read += i; 31774664626SKris Kennaway } 31874664626SKris Kennaway SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); 319e71b7053SJung-uk Kim BIO_closesocket(SSL_get_fd(scon)); 32074664626SKris Kennaway 32174664626SKris Kennaway nConn += 1; 322e71b7053SJung-uk Kim if (SSL_session_reused(scon)) { 32374664626SKris Kennaway ver = 'r'; 324e71b7053SJung-uk Kim } else { 32574664626SKris Kennaway ver = SSL_version(scon); 32674664626SKris Kennaway if (ver == TLS1_VERSION) 32774664626SKris Kennaway ver = 't'; 32874664626SKris Kennaway else if (ver == SSL3_VERSION) 32974664626SKris Kennaway ver = '3'; 33074664626SKris Kennaway else 33174664626SKris Kennaway ver = '*'; 33274664626SKris Kennaway } 33374664626SKris Kennaway fputc(ver, stdout); 33474664626SKris Kennaway fflush(stdout); 33574664626SKris Kennaway } 33674664626SKris Kennaway totalTime += tm_Time_F(STOP); /* Add the time for this iteration */ 33774664626SKris Kennaway 3386f9291ceSJung-uk Kim printf 3396f9291ceSJung-uk Kim ("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", 3406f9291ceSJung-uk Kim nConn, totalTime, ((double)nConn / totalTime), bytes_read); 3416f9291ceSJung-uk Kim printf 3426f9291ceSJung-uk Kim ("%d connections in %ld real seconds, %ld bytes read per connection\n", 343e71b7053SJung-uk Kim nConn, (long)time(NULL) - finishtime + maxtime, bytes_read / nConn); 34474664626SKris Kennaway 34574664626SKris Kennaway ret = 0; 34674664626SKris Kennaway 347e71b7053SJung-uk Kim end: 348e71b7053SJung-uk Kim SSL_free(scon); 349e71b7053SJung-uk Kim SSL_CTX_free(ctx); 350e71b7053SJung-uk Kim return ret; 35174664626SKris Kennaway } 35274664626SKris Kennaway 3536f9291ceSJung-uk Kim /*- 35474664626SKris Kennaway * doConnection - make a connection 35574664626SKris Kennaway */ 356e71b7053SJung-uk Kim static SSL *doConnection(SSL *scon, const char *host, SSL_CTX *ctx) 35774664626SKris Kennaway { 35874664626SKris Kennaway BIO *conn; 35974664626SKris Kennaway SSL *serverCon; 360e71b7053SJung-uk Kim int i; 36174664626SKris Kennaway 36274664626SKris Kennaway if ((conn = BIO_new(BIO_s_connect())) == NULL) 363e71b7053SJung-uk Kim return NULL; 36474664626SKris Kennaway 36574664626SKris Kennaway BIO_set_conn_hostname(conn, host); 366e71b7053SJung-uk Kim BIO_set_conn_mode(conn, BIO_SOCK_NODELAY); 36774664626SKris Kennaway 36874664626SKris Kennaway if (scon == NULL) 369e71b7053SJung-uk Kim serverCon = SSL_new(ctx); 3706f9291ceSJung-uk Kim else { 37174664626SKris Kennaway serverCon = scon; 37274664626SKris Kennaway SSL_set_connect_state(serverCon); 37374664626SKris Kennaway } 37474664626SKris Kennaway 37574664626SKris Kennaway SSL_set_bio(serverCon, conn, conn); 37674664626SKris Kennaway 37774664626SKris Kennaway /* ok, lets connect */ 37874664626SKris Kennaway i = SSL_connect(serverCon); 3796f9291ceSJung-uk Kim if (i <= 0) { 38074664626SKris Kennaway BIO_printf(bio_err, "ERROR\n"); 381e71b7053SJung-uk Kim if (verify_args.error != X509_V_OK) 38274664626SKris Kennaway BIO_printf(bio_err, "verify error:%s\n", 383e71b7053SJung-uk Kim X509_verify_cert_error_string(verify_args.error)); 38474664626SKris Kennaway else 38574664626SKris Kennaway ERR_print_errors(bio_err); 38674664626SKris Kennaway if (scon == NULL) 38774664626SKris Kennaway SSL_free(serverCon); 38874664626SKris Kennaway return NULL; 38974664626SKris Kennaway } 39074664626SKris Kennaway 391e71b7053SJung-uk Kim #if defined(SOL_SOCKET) && defined(SO_LINGER) 392e71b7053SJung-uk Kim { 393e71b7053SJung-uk Kim struct linger no_linger; 394e71b7053SJung-uk Kim int fd; 395e71b7053SJung-uk Kim 396e71b7053SJung-uk Kim no_linger.l_onoff = 1; 397e71b7053SJung-uk Kim no_linger.l_linger = 0; 398e71b7053SJung-uk Kim fd = SSL_get_fd(serverCon); 399e71b7053SJung-uk Kim if (fd >= 0) 400e71b7053SJung-uk Kim (void)setsockopt(fd, SOL_SOCKET, SO_LINGER, (char*)&no_linger, 401e71b7053SJung-uk Kim sizeof(no_linger)); 402e71b7053SJung-uk Kim } 403e71b7053SJung-uk Kim #endif 404e71b7053SJung-uk Kim 40574664626SKris Kennaway return serverCon; 40674664626SKris Kennaway } 407e71b7053SJung-uk Kim #endif /* OPENSSL_NO_SOCK */ 408