1e71b7053SJung-uk Kim /* 2e71b7053SJung-uk Kim * Copyright 1995-2018 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"}, 65e71b7053SJung-uk Kim {"no-CAfile", OPT_NOCAFILE, '-', 66e71b7053SJung-uk Kim "Do not load the default certificates file"}, 67e71b7053SJung-uk Kim {"no-CApath", OPT_NOCAPATH, '-', 68e71b7053SJung-uk Kim "Do not load certificates from the default certificates directory"}, 69e71b7053SJung-uk Kim {"new", OPT_NEW, '-', "Just time new connections"}, 70e71b7053SJung-uk Kim {"reuse", OPT_REUSE, '-', "Just time connection reuse"}, 71e71b7053SJung-uk Kim {"bugs", OPT_BUGS, '-', "Turn on SSL bug compatibility"}, 72e71b7053SJung-uk Kim {"verify", OPT_VERIFY, 'p', 73e71b7053SJung-uk Kim "Turn on peer certificate verification, set depth"}, 74e71b7053SJung-uk Kim {"time", OPT_TIME, 'p', "Seconds to collect data, default " SECONDSSTR}, 75e71b7053SJung-uk Kim {"www", OPT_WWW, 's', "Fetch specified page from the site"}, 765c87c606SMark Murray #ifndef OPENSSL_NO_SSL3 77e71b7053SJung-uk Kim {"ssl3", OPT_SSL3, '-', "Just use SSLv3"}, 7874664626SKris Kennaway #endif 79e71b7053SJung-uk Kim {NULL} 80e71b7053SJung-uk Kim }; 8174664626SKris Kennaway 8274664626SKris Kennaway #define START 0 8374664626SKris Kennaway #define STOP 1 8474664626SKris Kennaway 8574664626SKris Kennaway static double tm_Time_F(int s) 8674664626SKris Kennaway { 871f13597dSJung-uk Kim return app_tminterval(s, 1); 8874664626SKris Kennaway } 8974664626SKris Kennaway 90e71b7053SJung-uk Kim int s_time_main(int argc, char **argv) 9174664626SKris Kennaway { 92e71b7053SJung-uk Kim char buf[1024 * 8]; 9374664626SKris Kennaway SSL *scon = NULL; 94e71b7053SJung-uk Kim SSL_CTX *ctx = NULL; 95e71b7053SJung-uk Kim const SSL_METHOD *meth = NULL; 96e71b7053SJung-uk Kim char *CApath = NULL, *CAfile = NULL, *cipher = NULL, *ciphersuites = NULL; 97e71b7053SJung-uk Kim char *www_path = NULL; 98e71b7053SJung-uk Kim char *host = SSL_CONNECT_NAME, *certfile = NULL, *keyfile = NULL, *prog; 99e71b7053SJung-uk Kim double totalTime = 0.0; 100e71b7053SJung-uk Kim int noCApath = 0, noCAfile = 0; 101e71b7053SJung-uk Kim int maxtime = SECONDS, nConn = 0, perform = 3, ret = 1, i, st_bugs = 0; 102e71b7053SJung-uk Kim long bytes_read = 0, finishtime = 0; 103e71b7053SJung-uk Kim OPTION_CHOICE o; 104e71b7053SJung-uk Kim int max_version = 0, ver, buf_len; 105e71b7053SJung-uk Kim size_t buf_size; 10674664626SKris Kennaway 107e71b7053SJung-uk Kim meth = TLS_client_method(); 108f579bf8eSKris Kennaway 109e71b7053SJung-uk Kim prog = opt_init(argc, argv, s_time_options); 110e71b7053SJung-uk Kim while ((o = opt_next()) != OPT_EOF) { 111e71b7053SJung-uk Kim switch (o) { 112e71b7053SJung-uk Kim case OPT_EOF: 113e71b7053SJung-uk Kim case OPT_ERR: 114e71b7053SJung-uk Kim opthelp: 115e71b7053SJung-uk Kim BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 116e71b7053SJung-uk Kim goto end; 117e71b7053SJung-uk Kim case OPT_HELP: 118e71b7053SJung-uk Kim opt_help(s_time_options); 119e71b7053SJung-uk Kim ret = 0; 120e71b7053SJung-uk Kim goto end; 121e71b7053SJung-uk Kim case OPT_CONNECT: 122e71b7053SJung-uk Kim host = opt_arg(); 123e71b7053SJung-uk Kim break; 124e71b7053SJung-uk Kim case OPT_REUSE: 125e71b7053SJung-uk Kim perform = 2; 126e71b7053SJung-uk Kim break; 127e71b7053SJung-uk Kim case OPT_NEW: 128e71b7053SJung-uk Kim perform = 1; 129e71b7053SJung-uk Kim break; 130e71b7053SJung-uk Kim case OPT_VERIFY: 131e71b7053SJung-uk Kim if (!opt_int(opt_arg(), &verify_args.depth)) 132e71b7053SJung-uk Kim goto opthelp; 133e71b7053SJung-uk Kim BIO_printf(bio_err, "%s: verify depth is %d\n", 134e71b7053SJung-uk Kim prog, verify_args.depth); 135e71b7053SJung-uk Kim break; 136e71b7053SJung-uk Kim case OPT_CERT: 137e71b7053SJung-uk Kim certfile = opt_arg(); 138e71b7053SJung-uk Kim break; 139e71b7053SJung-uk Kim case OPT_NAMEOPT: 140e71b7053SJung-uk Kim if (!set_nameopt(opt_arg())) 141e71b7053SJung-uk Kim goto end; 142e71b7053SJung-uk Kim break; 143e71b7053SJung-uk Kim case OPT_KEY: 144e71b7053SJung-uk Kim keyfile = opt_arg(); 145e71b7053SJung-uk Kim break; 146e71b7053SJung-uk Kim case OPT_CAPATH: 147e71b7053SJung-uk Kim CApath = opt_arg(); 148e71b7053SJung-uk Kim break; 149e71b7053SJung-uk Kim case OPT_CAFILE: 150e71b7053SJung-uk Kim CAfile = opt_arg(); 151e71b7053SJung-uk Kim break; 152e71b7053SJung-uk Kim case OPT_NOCAPATH: 153e71b7053SJung-uk Kim noCApath = 1; 154e71b7053SJung-uk Kim break; 155e71b7053SJung-uk Kim case OPT_NOCAFILE: 156e71b7053SJung-uk Kim noCAfile = 1; 157e71b7053SJung-uk Kim break; 158e71b7053SJung-uk Kim case OPT_CIPHER: 159e71b7053SJung-uk Kim cipher = opt_arg(); 160e71b7053SJung-uk Kim break; 161e71b7053SJung-uk Kim case OPT_CIPHERSUITES: 162e71b7053SJung-uk Kim ciphersuites = opt_arg(); 163e71b7053SJung-uk Kim break; 164e71b7053SJung-uk Kim case OPT_BUGS: 165e71b7053SJung-uk Kim st_bugs = 1; 166e71b7053SJung-uk Kim break; 167e71b7053SJung-uk Kim case OPT_TIME: 168e71b7053SJung-uk Kim if (!opt_int(opt_arg(), &maxtime)) 169e71b7053SJung-uk Kim goto opthelp; 170e71b7053SJung-uk Kim break; 171e71b7053SJung-uk Kim case OPT_WWW: 172e71b7053SJung-uk Kim www_path = opt_arg(); 173e71b7053SJung-uk Kim buf_size = strlen(www_path) + fmt_http_get_cmd_size; 174e71b7053SJung-uk Kim if (buf_size > sizeof(buf)) { 175e71b7053SJung-uk Kim BIO_printf(bio_err, "%s: -www option is too long\n", prog); 176e71b7053SJung-uk Kim goto end; 177e71b7053SJung-uk Kim } 178e71b7053SJung-uk Kim break; 179e71b7053SJung-uk Kim case OPT_SSL3: 180e71b7053SJung-uk Kim max_version = SSL3_VERSION; 181e71b7053SJung-uk Kim break; 182e71b7053SJung-uk Kim } 183e71b7053SJung-uk Kim } 184e71b7053SJung-uk Kim argc = opt_num_rest(); 185e71b7053SJung-uk Kim if (argc != 0) 186e71b7053SJung-uk Kim goto opthelp; 187f579bf8eSKris Kennaway 188e71b7053SJung-uk Kim if (cipher == NULL) 189e71b7053SJung-uk Kim cipher = getenv("SSL_CIPHER"); 19074664626SKris Kennaway 191e71b7053SJung-uk Kim if ((ctx = SSL_CTX_new(meth)) == NULL) 19274664626SKris Kennaway goto end; 19374664626SKris Kennaway 194e71b7053SJung-uk Kim SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); 195e71b7053SJung-uk Kim SSL_CTX_set_quiet_shutdown(ctx, 1); 196e71b7053SJung-uk Kim if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0) 197e71b7053SJung-uk Kim goto end; 19874664626SKris Kennaway 1996f9291ceSJung-uk Kim if (st_bugs) 200e71b7053SJung-uk Kim SSL_CTX_set_options(ctx, SSL_OP_ALL); 201e71b7053SJung-uk Kim if (cipher != NULL && !SSL_CTX_set_cipher_list(ctx, cipher)) 202e71b7053SJung-uk Kim goto end; 203e71b7053SJung-uk Kim if (ciphersuites != NULL && !SSL_CTX_set_ciphersuites(ctx, ciphersuites)) 204e71b7053SJung-uk Kim goto end; 205e71b7053SJung-uk Kim if (!set_cert_stuff(ctx, certfile, keyfile)) 20674664626SKris Kennaway goto end; 20774664626SKris Kennaway 208e71b7053SJung-uk Kim if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) { 20974664626SKris Kennaway ERR_print_errors(bio_err); 210e71b7053SJung-uk Kim goto end; 21174664626SKris Kennaway } 2126f9291ceSJung-uk Kim if (!(perform & 1)) 2136f9291ceSJung-uk Kim goto next; 214e71b7053SJung-uk Kim printf("Collecting connection statistics for %d seconds\n", maxtime); 21574664626SKris Kennaway 21674664626SKris Kennaway /* Loop and time how long it takes to make connections */ 21774664626SKris Kennaway 21874664626SKris Kennaway bytes_read = 0; 219e71b7053SJung-uk Kim finishtime = (long)time(NULL) + maxtime; 22074664626SKris Kennaway tm_Time_F(START); 2216f9291ceSJung-uk Kim for (;;) { 2226f9291ceSJung-uk Kim if (finishtime < (long)time(NULL)) 2236f9291ceSJung-uk Kim break; 22474664626SKris Kennaway 225e71b7053SJung-uk Kim if ((scon = doConnection(NULL, host, ctx)) == NULL) 22674664626SKris Kennaway goto end; 22774664626SKris Kennaway 228e71b7053SJung-uk Kim if (www_path != NULL) { 229e71b7053SJung-uk Kim buf_len = BIO_snprintf(buf, sizeof(buf), fmt_http_get_cmd, 230e71b7053SJung-uk Kim www_path); 231e71b7053SJung-uk Kim if (buf_len <= 0 || SSL_write(scon, buf, buf_len) <= 0) 23274664626SKris Kennaway goto end; 23374664626SKris Kennaway while ((i = SSL_read(scon, buf, sizeof(buf))) > 0) 23474664626SKris Kennaway bytes_read += i; 23574664626SKris Kennaway } 23674664626SKris Kennaway SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); 237e71b7053SJung-uk Kim BIO_closesocket(SSL_get_fd(scon)); 23874664626SKris Kennaway 23974664626SKris Kennaway nConn += 1; 240e71b7053SJung-uk Kim if (SSL_session_reused(scon)) { 24174664626SKris Kennaway ver = 'r'; 242e71b7053SJung-uk Kim } else { 24374664626SKris Kennaway ver = SSL_version(scon); 24474664626SKris Kennaway if (ver == TLS1_VERSION) 24574664626SKris Kennaway ver = 't'; 24674664626SKris Kennaway else if (ver == SSL3_VERSION) 24774664626SKris Kennaway ver = '3'; 24874664626SKris Kennaway else 24974664626SKris Kennaway ver = '*'; 25074664626SKris Kennaway } 25174664626SKris Kennaway fputc(ver, stdout); 25274664626SKris Kennaway fflush(stdout); 25374664626SKris Kennaway 25474664626SKris Kennaway SSL_free(scon); 25574664626SKris Kennaway scon = NULL; 25674664626SKris Kennaway } 25774664626SKris Kennaway totalTime += tm_Time_F(STOP); /* Add the time for this iteration */ 25874664626SKris Kennaway 259e71b7053SJung-uk Kim i = (int)((long)time(NULL) - finishtime + maxtime); 2606f9291ceSJung-uk Kim printf 2616f9291ceSJung-uk Kim ("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", 2626f9291ceSJung-uk Kim nConn, totalTime, ((double)nConn / totalTime), bytes_read); 2636f9291ceSJung-uk Kim printf 2646f9291ceSJung-uk Kim ("%d connections in %ld real seconds, %ld bytes read per connection\n", 265e71b7053SJung-uk Kim nConn, (long)time(NULL) - finishtime + maxtime, bytes_read / nConn); 26674664626SKris Kennaway 2676f9291ceSJung-uk Kim /* 2686f9291ceSJung-uk Kim * Now loop and time connections using the same session id over and over 2696f9291ceSJung-uk Kim */ 27074664626SKris Kennaway 27174664626SKris Kennaway next: 2726f9291ceSJung-uk Kim if (!(perform & 2)) 2736f9291ceSJung-uk Kim goto end; 27474664626SKris Kennaway printf("\n\nNow timing with session id reuse.\n"); 27574664626SKris Kennaway 27674664626SKris Kennaway /* Get an SSL object so we can reuse the session id */ 277e71b7053SJung-uk Kim if ((scon = doConnection(NULL, host, ctx)) == NULL) { 278e71b7053SJung-uk Kim BIO_printf(bio_err, "Unable to get connection\n"); 27974664626SKris Kennaway goto end; 28074664626SKris Kennaway } 28174664626SKris Kennaway 282e71b7053SJung-uk Kim if (www_path != NULL) { 283e71b7053SJung-uk Kim buf_len = BIO_snprintf(buf, sizeof(buf), fmt_http_get_cmd, www_path); 284e71b7053SJung-uk Kim if (buf_len <= 0 || SSL_write(scon, buf, buf_len) <= 0) 285e71b7053SJung-uk Kim goto end; 286e71b7053SJung-uk Kim while ((i = SSL_read(scon, buf, sizeof(buf))) > 0) 287e71b7053SJung-uk Kim continue; 28874664626SKris Kennaway } 28974664626SKris Kennaway SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); 290e71b7053SJung-uk Kim BIO_closesocket(SSL_get_fd(scon)); 29174664626SKris Kennaway 29274664626SKris Kennaway nConn = 0; 29374664626SKris Kennaway totalTime = 0.0; 29474664626SKris Kennaway 295e71b7053SJung-uk Kim finishtime = (long)time(NULL) + maxtime; 29674664626SKris Kennaway 29774664626SKris Kennaway printf("starting\n"); 29874664626SKris Kennaway bytes_read = 0; 29974664626SKris Kennaway tm_Time_F(START); 30074664626SKris Kennaway 3016f9291ceSJung-uk Kim for (;;) { 3026f9291ceSJung-uk Kim if (finishtime < (long)time(NULL)) 3036f9291ceSJung-uk Kim break; 30474664626SKris Kennaway 305e71b7053SJung-uk Kim if ((doConnection(scon, host, ctx)) == NULL) 30674664626SKris Kennaway goto end; 30774664626SKris Kennaway 308e71b7053SJung-uk Kim if (www_path != NULL) { 309e71b7053SJung-uk Kim buf_len = BIO_snprintf(buf, sizeof(buf), fmt_http_get_cmd, 310e71b7053SJung-uk Kim www_path); 311e71b7053SJung-uk Kim if (buf_len <= 0 || SSL_write(scon, buf, buf_len) <= 0) 31274664626SKris Kennaway goto end; 31374664626SKris Kennaway while ((i = SSL_read(scon, buf, sizeof(buf))) > 0) 31474664626SKris Kennaway bytes_read += i; 31574664626SKris Kennaway } 31674664626SKris Kennaway SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); 317e71b7053SJung-uk Kim BIO_closesocket(SSL_get_fd(scon)); 31874664626SKris Kennaway 31974664626SKris Kennaway nConn += 1; 320e71b7053SJung-uk Kim if (SSL_session_reused(scon)) { 32174664626SKris Kennaway ver = 'r'; 322e71b7053SJung-uk Kim } else { 32374664626SKris Kennaway ver = SSL_version(scon); 32474664626SKris Kennaway if (ver == TLS1_VERSION) 32574664626SKris Kennaway ver = 't'; 32674664626SKris Kennaway else if (ver == SSL3_VERSION) 32774664626SKris Kennaway ver = '3'; 32874664626SKris Kennaway else 32974664626SKris Kennaway ver = '*'; 33074664626SKris Kennaway } 33174664626SKris Kennaway fputc(ver, stdout); 33274664626SKris Kennaway fflush(stdout); 33374664626SKris Kennaway } 33474664626SKris Kennaway totalTime += tm_Time_F(STOP); /* Add the time for this iteration */ 33574664626SKris Kennaway 3366f9291ceSJung-uk Kim printf 3376f9291ceSJung-uk Kim ("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", 3386f9291ceSJung-uk Kim nConn, totalTime, ((double)nConn / totalTime), bytes_read); 3396f9291ceSJung-uk Kim printf 3406f9291ceSJung-uk Kim ("%d connections in %ld real seconds, %ld bytes read per connection\n", 341e71b7053SJung-uk Kim nConn, (long)time(NULL) - finishtime + maxtime, bytes_read / nConn); 34274664626SKris Kennaway 34374664626SKris Kennaway ret = 0; 34474664626SKris Kennaway 345e71b7053SJung-uk Kim end: 346e71b7053SJung-uk Kim SSL_free(scon); 347e71b7053SJung-uk Kim SSL_CTX_free(ctx); 348e71b7053SJung-uk Kim return ret; 34974664626SKris Kennaway } 35074664626SKris Kennaway 3516f9291ceSJung-uk Kim /*- 35274664626SKris Kennaway * doConnection - make a connection 35374664626SKris Kennaway */ 354e71b7053SJung-uk Kim static SSL *doConnection(SSL *scon, const char *host, SSL_CTX *ctx) 35574664626SKris Kennaway { 35674664626SKris Kennaway BIO *conn; 35774664626SKris Kennaway SSL *serverCon; 358e71b7053SJung-uk Kim int i; 35974664626SKris Kennaway 36074664626SKris Kennaway if ((conn = BIO_new(BIO_s_connect())) == NULL) 361e71b7053SJung-uk Kim return NULL; 36274664626SKris Kennaway 36374664626SKris Kennaway BIO_set_conn_hostname(conn, host); 364e71b7053SJung-uk Kim BIO_set_conn_mode(conn, BIO_SOCK_NODELAY); 36574664626SKris Kennaway 36674664626SKris Kennaway if (scon == NULL) 367e71b7053SJung-uk Kim serverCon = SSL_new(ctx); 3686f9291ceSJung-uk Kim else { 36974664626SKris Kennaway serverCon = scon; 37074664626SKris Kennaway SSL_set_connect_state(serverCon); 37174664626SKris Kennaway } 37274664626SKris Kennaway 37374664626SKris Kennaway SSL_set_bio(serverCon, conn, conn); 37474664626SKris Kennaway 37574664626SKris Kennaway /* ok, lets connect */ 37674664626SKris Kennaway i = SSL_connect(serverCon); 3776f9291ceSJung-uk Kim if (i <= 0) { 37874664626SKris Kennaway BIO_printf(bio_err, "ERROR\n"); 379e71b7053SJung-uk Kim if (verify_args.error != X509_V_OK) 38074664626SKris Kennaway BIO_printf(bio_err, "verify error:%s\n", 381e71b7053SJung-uk Kim X509_verify_cert_error_string(verify_args.error)); 38274664626SKris Kennaway else 38374664626SKris Kennaway ERR_print_errors(bio_err); 38474664626SKris Kennaway if (scon == NULL) 38574664626SKris Kennaway SSL_free(serverCon); 38674664626SKris Kennaway return NULL; 38774664626SKris Kennaway } 38874664626SKris Kennaway 389e71b7053SJung-uk Kim #if defined(SOL_SOCKET) && defined(SO_LINGER) 390e71b7053SJung-uk Kim { 391e71b7053SJung-uk Kim struct linger no_linger; 392e71b7053SJung-uk Kim int fd; 393e71b7053SJung-uk Kim 394e71b7053SJung-uk Kim no_linger.l_onoff = 1; 395e71b7053SJung-uk Kim no_linger.l_linger = 0; 396e71b7053SJung-uk Kim fd = SSL_get_fd(serverCon); 397e71b7053SJung-uk Kim if (fd >= 0) 398e71b7053SJung-uk Kim (void)setsockopt(fd, SOL_SOCKET, SO_LINGER, (char*)&no_linger, 399e71b7053SJung-uk Kim sizeof(no_linger)); 400e71b7053SJung-uk Kim } 401e71b7053SJung-uk Kim #endif 402e71b7053SJung-uk Kim 40374664626SKris Kennaway return serverCon; 40474664626SKris Kennaway } 405e71b7053SJung-uk Kim #endif /* OPENSSL_NO_SOCK */ 406