155714Skris/* crypto/threads/mttest.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 8296465Sdelphij * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15296465Sdelphij * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 22296465Sdelphij * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 37296465Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40296465Sdelphij * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 52296465Sdelphij * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 5855714Skris 5955714Skris#include <stdio.h> 6055714Skris#include <stdlib.h> 6155714Skris#include <string.h> 6255714Skris#include <errno.h> 6355714Skris#ifdef LINUX 64296465Sdelphij# include <typedefs.h> 6555714Skris#endif 66109998Smarkm#ifdef OPENSSL_SYS_WIN32 67296465Sdelphij# include <windows.h> 6855714Skris#endif 6955714Skris#ifdef SOLARIS 70296465Sdelphij# include <synch.h> 71296465Sdelphij# include <thread.h> 7255714Skris#endif 7355714Skris#ifdef IRIX 74296465Sdelphij# include <ulocks.h> 75296465Sdelphij# include <sys/prctl.h> 7655714Skris#endif 7759191Skris#ifdef PTHREADS 78296465Sdelphij# include <pthread.h> 7959191Skris#endif 80160814Ssimon#ifdef OPENSSL_SYS_NETWARE 81296465Sdelphij# if !defined __int64 82160814Ssimon# define __int64 long long 83296465Sdelphij# endif 84296465Sdelphij# include <nwmpk.h> 85160814Ssimon#endif 8655714Skris#include <openssl/lhash.h> 8755714Skris#include <openssl/crypto.h> 8855714Skris#include <openssl/buffer.h> 8959191Skris#include "../../e_os.h" 9055714Skris#include <openssl/x509.h> 9155714Skris#include <openssl/ssl.h> 9255714Skris#include <openssl/err.h> 9359191Skris#include <openssl/rand.h> 9455714Skris 95160814Ssimon#ifdef OPENSSL_NO_FP_API 96296465Sdelphij# define APPS_WIN16 97296465Sdelphij# include "../buffer/bss_file.c" 98160814Ssimon#endif 99160814Ssimon 100160814Ssimon#ifdef OPENSSL_SYS_NETWARE 101296465Sdelphij# define TEST_SERVER_CERT "/openssl/apps/server.pem" 102296465Sdelphij# define TEST_CLIENT_CERT "/openssl/apps/client.pem" 103160814Ssimon#else 104296465Sdelphij# define TEST_SERVER_CERT "../../apps/server.pem" 105296465Sdelphij# define TEST_CLIENT_CERT "../../apps/client.pem" 106160814Ssimon#endif 10755714Skris 108296465Sdelphij#define MAX_THREAD_NUMBER 100 10955714Skris 11059191Skrisint MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *xs); 11155714Skrisvoid thread_setup(void); 11255714Skrisvoid thread_cleanup(void); 113296465Sdelphijvoid do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx); 11455714Skris 115296465Sdelphijvoid irix_locking_callback(int mode, int type, char *file, int line); 116296465Sdelphijvoid solaris_locking_callback(int mode, int type, char *file, int line); 117296465Sdelphijvoid win32_locking_callback(int mode, int type, char *file, int line); 118296465Sdelphijvoid pthreads_locking_callback(int mode, int type, char *file, int line); 119296465Sdelphijvoid netware_locking_callback(int mode, int type, char *file, int line); 12055714Skris 121296465Sdelphijunsigned long irix_thread_id(void); 122296465Sdelphijunsigned long solaris_thread_id(void); 123296465Sdelphijunsigned long pthreads_thread_id(void); 124296465Sdelphijunsigned long netware_thread_id(void); 12555714Skris 126160814Ssimon#if defined(OPENSSL_SYS_NETWARE) 127160814Ssimonstatic MPKMutex *lock_cs; 128160814Ssimonstatic MPKSema ThreadSem; 129160814Ssimonstatic long *lock_count; 130160814Ssimon#endif 131160814Ssimon 132296465SdelphijBIO *bio_err = NULL; 133296465SdelphijBIO *bio_stdout = NULL; 13455714Skris 135296465Sdelphijstatic char *cipher = NULL; 136296465Sdelphijint verbose = 0; 13755714Skris#ifdef FIONBIO 138296465Sdelphijstatic int s_nbio = 0; 13955714Skris#endif 14055714Skris 141296465Sdelphijint thread_number = 10; 142296465Sdelphijint number_of_loops = 10; 143296465Sdelphijint reconnect = 0; 144296465Sdelphijint cache_stats = 0; 14555714Skris 146296465Sdelphijstatic const char rnd_seed[] = 147296465Sdelphij "string to make the random number generator think it has entropy"; 14859191Skris 14955714Skrisint doit(char *ctx[4]); 15055714Skrisstatic void print_stats(FILE *fp, SSL_CTX *ctx) 15155714Skris{ 152296465Sdelphij fprintf(fp, "%4ld items in the session cache\n", 153296465Sdelphij SSL_CTX_sess_number(ctx)); 154296465Sdelphij fprintf(fp, "%4d client connects (SSL_connect())\n", 155296465Sdelphij SSL_CTX_sess_connect(ctx)); 156296465Sdelphij fprintf(fp, "%4d client connects that finished\n", 157296465Sdelphij SSL_CTX_sess_connect_good(ctx)); 158296465Sdelphij fprintf(fp, "%4d server connects (SSL_accept())\n", 159296465Sdelphij SSL_CTX_sess_accept(ctx)); 160296465Sdelphij fprintf(fp, "%4d server connects that finished\n", 161296465Sdelphij SSL_CTX_sess_accept_good(ctx)); 162296465Sdelphij fprintf(fp, "%4d session cache hits\n", SSL_CTX_sess_hits(ctx)); 163296465Sdelphij fprintf(fp, "%4d session cache misses\n", SSL_CTX_sess_misses(ctx)); 164296465Sdelphij fprintf(fp, "%4d session cache timeouts\n", SSL_CTX_sess_timeouts(ctx)); 165296465Sdelphij} 16655714Skris 16755714Skrisstatic void sv_usage(void) 168296465Sdelphij{ 169296465Sdelphij fprintf(stderr, "usage: ssltest [args ...]\n"); 170296465Sdelphij fprintf(stderr, "\n"); 171296465Sdelphij fprintf(stderr, " -server_auth - check server certificate\n"); 172296465Sdelphij fprintf(stderr, " -client_auth - do client authentication\n"); 173296465Sdelphij fprintf(stderr, " -v - more output\n"); 174296465Sdelphij fprintf(stderr, " -CApath arg - PEM format directory of CA's\n"); 175296465Sdelphij fprintf(stderr, " -CAfile arg - PEM format file of CA's\n"); 176296465Sdelphij fprintf(stderr, " -threads arg - number of threads\n"); 177296465Sdelphij fprintf(stderr, " -loops arg - number of 'connections', per thread\n"); 178296465Sdelphij fprintf(stderr, " -reconnect - reuse session-id's\n"); 179296465Sdelphij fprintf(stderr, " -stats - server session-id cache stats\n"); 180296465Sdelphij fprintf(stderr, " -cert arg - server certificate/key\n"); 181296465Sdelphij fprintf(stderr, " -ccert arg - client certificate/key\n"); 182296465Sdelphij fprintf(stderr, " -ssl3 - just SSLv3n\n"); 183296465Sdelphij} 18455714Skris 18555714Skrisint main(int argc, char *argv[]) 186296465Sdelphij{ 187296465Sdelphij char *CApath = NULL, *CAfile = NULL; 188296465Sdelphij int badop = 0; 189296465Sdelphij int ret = 1; 190296465Sdelphij int client_auth = 0; 191296465Sdelphij int server_auth = 0; 192296465Sdelphij SSL_CTX *s_ctx = NULL; 193296465Sdelphij SSL_CTX *c_ctx = NULL; 194296465Sdelphij char *scert = TEST_SERVER_CERT; 195296465Sdelphij char *ccert = TEST_CLIENT_CERT; 196296465Sdelphij SSL_METHOD *ssl_method = SSLv23_method(); 19755714Skris 198296465Sdelphij RAND_seed(rnd_seed, sizeof rnd_seed); 19959191Skris 200296465Sdelphij if (bio_err == NULL) 201296465Sdelphij bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 202296465Sdelphij if (bio_stdout == NULL) 203296465Sdelphij bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE); 204296465Sdelphij argc--; 205296465Sdelphij argv++; 20655714Skris 207296465Sdelphij while (argc >= 1) { 208296465Sdelphij if (strcmp(*argv, "-server_auth") == 0) 209296465Sdelphij server_auth = 1; 210296465Sdelphij else if (strcmp(*argv, "-client_auth") == 0) 211296465Sdelphij client_auth = 1; 212296465Sdelphij else if (strcmp(*argv, "-reconnect") == 0) 213296465Sdelphij reconnect = 1; 214296465Sdelphij else if (strcmp(*argv, "-stats") == 0) 215296465Sdelphij cache_stats = 1; 216296465Sdelphij else if (strcmp(*argv, "-ssl3") == 0) 217296465Sdelphij ssl_method = SSLv3_method(); 218296465Sdelphij else if (strcmp(*argv, "-ssl2") == 0) 219296465Sdelphij ssl_method = SSLv2_method(); 220296465Sdelphij else if (strcmp(*argv, "-CApath") == 0) { 221296465Sdelphij if (--argc < 1) 222296465Sdelphij goto bad; 223296465Sdelphij CApath = *(++argv); 224296465Sdelphij } else if (strcmp(*argv, "-CAfile") == 0) { 225296465Sdelphij if (--argc < 1) 226296465Sdelphij goto bad; 227296465Sdelphij CAfile = *(++argv); 228296465Sdelphij } else if (strcmp(*argv, "-cert") == 0) { 229296465Sdelphij if (--argc < 1) 230296465Sdelphij goto bad; 231296465Sdelphij scert = *(++argv); 232296465Sdelphij } else if (strcmp(*argv, "-ccert") == 0) { 233296465Sdelphij if (--argc < 1) 234296465Sdelphij goto bad; 235296465Sdelphij ccert = *(++argv); 236296465Sdelphij } else if (strcmp(*argv, "-threads") == 0) { 237296465Sdelphij if (--argc < 1) 238296465Sdelphij goto bad; 239296465Sdelphij thread_number = atoi(*(++argv)); 240296465Sdelphij if (thread_number == 0) 241296465Sdelphij thread_number = 1; 242296465Sdelphij if (thread_number > MAX_THREAD_NUMBER) 243296465Sdelphij thread_number = MAX_THREAD_NUMBER; 244296465Sdelphij } else if (strcmp(*argv, "-loops") == 0) { 245296465Sdelphij if (--argc < 1) 246296465Sdelphij goto bad; 247296465Sdelphij number_of_loops = atoi(*(++argv)); 248296465Sdelphij if (number_of_loops == 0) 249296465Sdelphij number_of_loops = 1; 250296465Sdelphij } else { 251296465Sdelphij fprintf(stderr, "unknown option %s\n", *argv); 252296465Sdelphij badop = 1; 253296465Sdelphij break; 254296465Sdelphij } 255296465Sdelphij argc--; 256296465Sdelphij argv++; 257296465Sdelphij } 258296465Sdelphij if (badop) { 259296465Sdelphij bad: 260296465Sdelphij sv_usage(); 261296465Sdelphij goto end; 262296465Sdelphij } 26355714Skris 264296465Sdelphij if (cipher == NULL && OPENSSL_issetugid() == 0) 265296465Sdelphij cipher = getenv("SSL_CIPHER"); 26655714Skris 267296465Sdelphij SSL_load_error_strings(); 268296465Sdelphij OpenSSL_add_ssl_algorithms(); 26955714Skris 270296465Sdelphij c_ctx = SSL_CTX_new(ssl_method); 271296465Sdelphij s_ctx = SSL_CTX_new(ssl_method); 272296465Sdelphij if ((c_ctx == NULL) || (s_ctx == NULL)) { 273296465Sdelphij ERR_print_errors(bio_err); 274296465Sdelphij goto end; 275296465Sdelphij } 27655714Skris 277296465Sdelphij SSL_CTX_set_session_cache_mode(s_ctx, 278296465Sdelphij SSL_SESS_CACHE_NO_AUTO_CLEAR | 279296465Sdelphij SSL_SESS_CACHE_SERVER); 280296465Sdelphij SSL_CTX_set_session_cache_mode(c_ctx, 281296465Sdelphij SSL_SESS_CACHE_NO_AUTO_CLEAR | 282296465Sdelphij SSL_SESS_CACHE_SERVER); 28355714Skris 284296465Sdelphij if (!SSL_CTX_use_certificate_file(s_ctx, scert, SSL_FILETYPE_PEM)) { 285296465Sdelphij ERR_print_errors(bio_err); 286296465Sdelphij } else 287296465Sdelphij if (!SSL_CTX_use_RSAPrivateKey_file(s_ctx, scert, SSL_FILETYPE_PEM)) { 288296465Sdelphij ERR_print_errors(bio_err); 289296465Sdelphij goto end; 290296465Sdelphij } 29155714Skris 292296465Sdelphij if (client_auth) { 293296465Sdelphij SSL_CTX_use_certificate_file(c_ctx, ccert, SSL_FILETYPE_PEM); 294296465Sdelphij SSL_CTX_use_RSAPrivateKey_file(c_ctx, ccert, SSL_FILETYPE_PEM); 295296465Sdelphij } 29655714Skris 297296465Sdelphij if ((!SSL_CTX_load_verify_locations(s_ctx, CAfile, CApath)) || 298296465Sdelphij (!SSL_CTX_set_default_verify_paths(s_ctx)) || 299296465Sdelphij (!SSL_CTX_load_verify_locations(c_ctx, CAfile, CApath)) || 300296465Sdelphij (!SSL_CTX_set_default_verify_paths(c_ctx))) { 301296465Sdelphij fprintf(stderr, "SSL_load_verify_locations\n"); 302296465Sdelphij ERR_print_errors(bio_err); 303296465Sdelphij goto end; 304296465Sdelphij } 30555714Skris 306296465Sdelphij if (client_auth) { 307296465Sdelphij fprintf(stderr, "client authentication\n"); 308296465Sdelphij SSL_CTX_set_verify(s_ctx, 309296465Sdelphij SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 310296465Sdelphij verify_callback); 311296465Sdelphij } 312296465Sdelphij if (server_auth) { 313296465Sdelphij fprintf(stderr, "server authentication\n"); 314296465Sdelphij SSL_CTX_set_verify(c_ctx, SSL_VERIFY_PEER, verify_callback); 315296465Sdelphij } 31655714Skris 317296465Sdelphij thread_setup(); 318296465Sdelphij do_threads(s_ctx, c_ctx); 319296465Sdelphij thread_cleanup(); 320296465Sdelphij end: 32155714Skris 322296465Sdelphij if (c_ctx != NULL) { 323296465Sdelphij fprintf(stderr, "Client SSL_CTX stats then free it\n"); 324296465Sdelphij print_stats(stderr, c_ctx); 325296465Sdelphij SSL_CTX_free(c_ctx); 326296465Sdelphij } 327296465Sdelphij if (s_ctx != NULL) { 328296465Sdelphij fprintf(stderr, "Server SSL_CTX stats then free it\n"); 329296465Sdelphij print_stats(stderr, s_ctx); 330296465Sdelphij if (cache_stats) { 331296465Sdelphij fprintf(stderr, "-----\n"); 332296465Sdelphij lh_stats(SSL_CTX_sessions(s_ctx), stderr); 333296465Sdelphij fprintf(stderr, "-----\n"); 334296465Sdelphij /*- lh_node_stats(SSL_CTX_sessions(s_ctx),stderr); 335296465Sdelphij fprintf(stderr,"-----\n"); */ 336296465Sdelphij lh_node_usage_stats(SSL_CTX_sessions(s_ctx), stderr); 337296465Sdelphij fprintf(stderr, "-----\n"); 338296465Sdelphij } 339296465Sdelphij SSL_CTX_free(s_ctx); 340296465Sdelphij fprintf(stderr, "done free\n"); 341296465Sdelphij } 342296465Sdelphij exit(ret); 343296465Sdelphij return (0); 344296465Sdelphij} 34555714Skris 346296465Sdelphij#define W_READ 1 347296465Sdelphij#define W_WRITE 2 348296465Sdelphij#define C_DONE 1 349296465Sdelphij#define S_DONE 2 350296465Sdelphij 35155714Skrisint ndoit(SSL_CTX *ssl_ctx[2]) 352296465Sdelphij{ 353296465Sdelphij int i; 354296465Sdelphij int ret; 355296465Sdelphij char *ctx[4]; 35655714Skris 357296465Sdelphij ctx[0] = (char *)ssl_ctx[0]; 358296465Sdelphij ctx[1] = (char *)ssl_ctx[1]; 35955714Skris 360296465Sdelphij if (reconnect) { 361296465Sdelphij ctx[2] = (char *)SSL_new(ssl_ctx[0]); 362296465Sdelphij ctx[3] = (char *)SSL_new(ssl_ctx[1]); 363296465Sdelphij } else { 364296465Sdelphij ctx[2] = NULL; 365296465Sdelphij ctx[3] = NULL; 366296465Sdelphij } 36755714Skris 368296465Sdelphij fprintf(stdout, "started thread %lu\n", CRYPTO_thread_id()); 369296465Sdelphij for (i = 0; i < number_of_loops; i++) { 370296465Sdelphij/*- fprintf(stderr,"%4d %2d ctx->ref (%3d,%3d)\n", 371296465Sdelphij CRYPTO_thread_id(),i, 372296465Sdelphij ssl_ctx[0]->references, 373296465Sdelphij ssl_ctx[1]->references); */ 374296465Sdelphij/* pthread_delay_np(&tm); */ 37555714Skris 376296465Sdelphij ret = doit(ctx); 377296465Sdelphij if (ret != 0) { 378296465Sdelphij fprintf(stdout, "error[%d] %lu - %d\n", 379296465Sdelphij i, CRYPTO_thread_id(), ret); 380296465Sdelphij return (ret); 381296465Sdelphij } 382296465Sdelphij } 383296465Sdelphij fprintf(stdout, "DONE %lu\n", CRYPTO_thread_id()); 384296465Sdelphij if (reconnect) { 385296465Sdelphij SSL_free((SSL *)ctx[2]); 386296465Sdelphij SSL_free((SSL *)ctx[3]); 387296465Sdelphij } 388296465Sdelphij#ifdef OPENSSL_SYS_NETWARE 389296465Sdelphij MPKSemaphoreSignal(ThreadSem); 390296465Sdelphij#endif 391296465Sdelphij return (0); 392296465Sdelphij} 39355714Skris 39455714Skrisint doit(char *ctx[4]) 395296465Sdelphij{ 396296465Sdelphij SSL_CTX *s_ctx, *c_ctx; 397296465Sdelphij static char cbuf[200], sbuf[200]; 398296465Sdelphij SSL *c_ssl = NULL; 399296465Sdelphij SSL *s_ssl = NULL; 400296465Sdelphij BIO *c_to_s = NULL; 401296465Sdelphij BIO *s_to_c = NULL; 402296465Sdelphij BIO *c_bio = NULL; 403296465Sdelphij BIO *s_bio = NULL; 404296465Sdelphij int c_r, c_w, s_r, s_w; 405296465Sdelphij int c_want, s_want; 406296465Sdelphij int i; 407296465Sdelphij int done = 0; 408296465Sdelphij int c_write, s_write; 409296465Sdelphij int do_server = 0, do_client = 0; 41055714Skris 411296465Sdelphij s_ctx = (SSL_CTX *)ctx[0]; 412296465Sdelphij c_ctx = (SSL_CTX *)ctx[1]; 41355714Skris 414296465Sdelphij if (ctx[2] != NULL) 415296465Sdelphij s_ssl = (SSL *)ctx[2]; 416296465Sdelphij else 417296465Sdelphij s_ssl = SSL_new(s_ctx); 41855714Skris 419296465Sdelphij if (ctx[3] != NULL) 420296465Sdelphij c_ssl = (SSL *)ctx[3]; 421296465Sdelphij else 422296465Sdelphij c_ssl = SSL_new(c_ctx); 42355714Skris 424296465Sdelphij if ((s_ssl == NULL) || (c_ssl == NULL)) 425296465Sdelphij goto err; 42655714Skris 427296465Sdelphij c_to_s = BIO_new(BIO_s_mem()); 428296465Sdelphij s_to_c = BIO_new(BIO_s_mem()); 429296465Sdelphij if ((s_to_c == NULL) || (c_to_s == NULL)) 430296465Sdelphij goto err; 43155714Skris 432296465Sdelphij c_bio = BIO_new(BIO_f_ssl()); 433296465Sdelphij s_bio = BIO_new(BIO_f_ssl()); 434296465Sdelphij if ((c_bio == NULL) || (s_bio == NULL)) 435296465Sdelphij goto err; 43655714Skris 437296465Sdelphij SSL_set_connect_state(c_ssl); 438296465Sdelphij SSL_set_bio(c_ssl, s_to_c, c_to_s); 439296465Sdelphij BIO_set_ssl(c_bio, c_ssl, (ctx[2] == NULL) ? BIO_CLOSE : BIO_NOCLOSE); 44055714Skris 441296465Sdelphij SSL_set_accept_state(s_ssl); 442296465Sdelphij SSL_set_bio(s_ssl, c_to_s, s_to_c); 443296465Sdelphij BIO_set_ssl(s_bio, s_ssl, (ctx[3] == NULL) ? BIO_CLOSE : BIO_NOCLOSE); 44455714Skris 445296465Sdelphij c_r = 0; 446296465Sdelphij s_r = 1; 447296465Sdelphij c_w = 1; 448296465Sdelphij s_w = 0; 449296465Sdelphij c_want = W_WRITE; 450296465Sdelphij s_want = 0; 451296465Sdelphij c_write = 1, s_write = 0; 45255714Skris 453296465Sdelphij /* We can always do writes */ 454296465Sdelphij for (;;) { 455296465Sdelphij do_server = 0; 456296465Sdelphij do_client = 0; 45755714Skris 458296465Sdelphij i = (int)BIO_pending(s_bio); 459296465Sdelphij if ((i && s_r) || s_w) 460296465Sdelphij do_server = 1; 46155714Skris 462296465Sdelphij i = (int)BIO_pending(c_bio); 463296465Sdelphij if ((i && c_r) || c_w) 464296465Sdelphij do_client = 1; 46555714Skris 466296465Sdelphij if (do_server && verbose) { 467296465Sdelphij if (SSL_in_init(s_ssl)) 468296465Sdelphij printf("server waiting in SSL_accept - %s\n", 469296465Sdelphij SSL_state_string_long(s_ssl)); 470296465Sdelphij else if (s_write) 471296465Sdelphij printf("server:SSL_write()\n"); 472296465Sdelphij else 473296465Sdelphij printf("server:SSL_read()\n"); 474296465Sdelphij } 47555714Skris 476296465Sdelphij if (do_client && verbose) { 477296465Sdelphij if (SSL_in_init(c_ssl)) 478296465Sdelphij printf("client waiting in SSL_connect - %s\n", 479296465Sdelphij SSL_state_string_long(c_ssl)); 480296465Sdelphij else if (c_write) 481296465Sdelphij printf("client:SSL_write()\n"); 482296465Sdelphij else 483296465Sdelphij printf("client:SSL_read()\n"); 484296465Sdelphij } 48555714Skris 486296465Sdelphij if (!do_client && !do_server) { 487296465Sdelphij fprintf(stdout, "ERROR IN STARTUP\n"); 488296465Sdelphij break; 489296465Sdelphij } 490296465Sdelphij if (do_client && !(done & C_DONE)) { 491296465Sdelphij if (c_write) { 492296465Sdelphij i = BIO_write(c_bio, "hello from client\n", 18); 493296465Sdelphij if (i < 0) { 494296465Sdelphij c_r = 0; 495296465Sdelphij c_w = 0; 496296465Sdelphij if (BIO_should_retry(c_bio)) { 497296465Sdelphij if (BIO_should_read(c_bio)) 498296465Sdelphij c_r = 1; 499296465Sdelphij if (BIO_should_write(c_bio)) 500296465Sdelphij c_w = 1; 501296465Sdelphij } else { 502296465Sdelphij fprintf(stderr, "ERROR in CLIENT\n"); 503296465Sdelphij ERR_print_errors_fp(stderr); 504296465Sdelphij return (1); 505296465Sdelphij } 506296465Sdelphij } else if (i == 0) { 507296465Sdelphij fprintf(stderr, "SSL CLIENT STARTUP FAILED\n"); 508296465Sdelphij return (1); 509296465Sdelphij } else { 510296465Sdelphij /* ok */ 511296465Sdelphij c_write = 0; 512296465Sdelphij } 513296465Sdelphij } else { 514296465Sdelphij i = BIO_read(c_bio, cbuf, 100); 515296465Sdelphij if (i < 0) { 516296465Sdelphij c_r = 0; 517296465Sdelphij c_w = 0; 518296465Sdelphij if (BIO_should_retry(c_bio)) { 519296465Sdelphij if (BIO_should_read(c_bio)) 520296465Sdelphij c_r = 1; 521296465Sdelphij if (BIO_should_write(c_bio)) 522296465Sdelphij c_w = 1; 523296465Sdelphij } else { 524296465Sdelphij fprintf(stderr, "ERROR in CLIENT\n"); 525296465Sdelphij ERR_print_errors_fp(stderr); 526296465Sdelphij return (1); 527296465Sdelphij } 528296465Sdelphij } else if (i == 0) { 529296465Sdelphij fprintf(stderr, "SSL CLIENT STARTUP FAILED\n"); 530296465Sdelphij return (1); 531296465Sdelphij } else { 532296465Sdelphij done |= C_DONE; 53355714Skris#ifdef undef 534296465Sdelphij fprintf(stdout, "CLIENT:from server:"); 535296465Sdelphij fwrite(cbuf, 1, i, stdout); 536296465Sdelphij fflush(stdout); 53755714Skris#endif 538296465Sdelphij } 539296465Sdelphij } 540296465Sdelphij } 54155714Skris 542296465Sdelphij if (do_server && !(done & S_DONE)) { 543296465Sdelphij if (!s_write) { 544296465Sdelphij i = BIO_read(s_bio, sbuf, 100); 545296465Sdelphij if (i < 0) { 546296465Sdelphij s_r = 0; 547296465Sdelphij s_w = 0; 548296465Sdelphij if (BIO_should_retry(s_bio)) { 549296465Sdelphij if (BIO_should_read(s_bio)) 550296465Sdelphij s_r = 1; 551296465Sdelphij if (BIO_should_write(s_bio)) 552296465Sdelphij s_w = 1; 553296465Sdelphij } else { 554296465Sdelphij fprintf(stderr, "ERROR in SERVER\n"); 555296465Sdelphij ERR_print_errors_fp(stderr); 556296465Sdelphij return (1); 557296465Sdelphij } 558296465Sdelphij } else if (i == 0) { 559296465Sdelphij fprintf(stderr, "SSL SERVER STARTUP FAILED\n"); 560296465Sdelphij return (1); 561296465Sdelphij } else { 562296465Sdelphij s_write = 1; 563296465Sdelphij s_w = 1; 56455714Skris#ifdef undef 565296465Sdelphij fprintf(stdout, "SERVER:from client:"); 566296465Sdelphij fwrite(sbuf, 1, i, stdout); 567296465Sdelphij fflush(stdout); 56855714Skris#endif 569296465Sdelphij } 570296465Sdelphij } else { 571296465Sdelphij i = BIO_write(s_bio, "hello from server\n", 18); 572296465Sdelphij if (i < 0) { 573296465Sdelphij s_r = 0; 574296465Sdelphij s_w = 0; 575296465Sdelphij if (BIO_should_retry(s_bio)) { 576296465Sdelphij if (BIO_should_read(s_bio)) 577296465Sdelphij s_r = 1; 578296465Sdelphij if (BIO_should_write(s_bio)) 579296465Sdelphij s_w = 1; 580296465Sdelphij } else { 581296465Sdelphij fprintf(stderr, "ERROR in SERVER\n"); 582296465Sdelphij ERR_print_errors_fp(stderr); 583296465Sdelphij return (1); 584296465Sdelphij } 585296465Sdelphij } else if (i == 0) { 586296465Sdelphij fprintf(stderr, "SSL SERVER STARTUP FAILED\n"); 587296465Sdelphij return (1); 588296465Sdelphij } else { 589296465Sdelphij s_write = 0; 590296465Sdelphij s_r = 1; 591296465Sdelphij done |= S_DONE; 592296465Sdelphij } 593296465Sdelphij } 594296465Sdelphij } 59555714Skris 596296465Sdelphij if ((done & S_DONE) && (done & C_DONE)) 597296465Sdelphij break; 598296465Sdelphij#if defined(OPENSSL_SYS_NETWARE) 599160814Ssimon ThreadSwitchWithDelay(); 600296465Sdelphij#endif 601296465Sdelphij } 60255714Skris 603296465Sdelphij SSL_set_shutdown(c_ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); 604296465Sdelphij SSL_set_shutdown(s_ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); 60555714Skris 60655714Skris#ifdef undef 607296465Sdelphij fprintf(stdout, "DONE\n"); 60855714Skris#endif 609296465Sdelphij err: 610296465Sdelphij /* 611296465Sdelphij * We have to set the BIO's to NULL otherwise they will be free()ed 612296465Sdelphij * twice. Once when th s_ssl is SSL_free()ed and again when c_ssl is 613296465Sdelphij * SSL_free()ed. This is a hack required because s_ssl and c_ssl are 614296465Sdelphij * sharing the same BIO structure and SSL_set_bio() and SSL_free() 615296465Sdelphij * automatically BIO_free non NULL entries. You should not normally do 616296465Sdelphij * this or be required to do this 617296465Sdelphij */ 61855714Skris 619296465Sdelphij if (s_ssl != NULL) { 620296465Sdelphij s_ssl->rbio = NULL; 621296465Sdelphij s_ssl->wbio = NULL; 622296465Sdelphij } 623296465Sdelphij if (c_ssl != NULL) { 624296465Sdelphij c_ssl->rbio = NULL; 625296465Sdelphij c_ssl->wbio = NULL; 626296465Sdelphij } 62755714Skris 628296465Sdelphij /* The SSL's are optionally freed in the following calls */ 629296465Sdelphij if (c_to_s != NULL) 630296465Sdelphij BIO_free(c_to_s); 631296465Sdelphij if (s_to_c != NULL) 632296465Sdelphij BIO_free(s_to_c); 63355714Skris 634296465Sdelphij if (c_bio != NULL) 635296465Sdelphij BIO_free(c_bio); 636296465Sdelphij if (s_bio != NULL) 637296465Sdelphij BIO_free(s_bio); 638296465Sdelphij return (0); 639296465Sdelphij} 64055714Skris 64159191Skrisint MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) 642296465Sdelphij{ 643296465Sdelphij char *s, buf[256]; 64455714Skris 645296465Sdelphij if (verbose) { 646296465Sdelphij s = X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), 647296465Sdelphij buf, 256); 648296465Sdelphij if (s != NULL) { 649296465Sdelphij if (ok) 650296465Sdelphij fprintf(stderr, "depth=%d %s\n", ctx->error_depth, buf); 651296465Sdelphij else 652296465Sdelphij fprintf(stderr, "depth=%d error=%d %s\n", 653296465Sdelphij ctx->error_depth, ctx->error, buf); 654296465Sdelphij } 655296465Sdelphij } 656296465Sdelphij return (ok); 657296465Sdelphij} 65855714Skris 65955714Skris#define THREAD_STACK_SIZE (16*1024) 66055714Skris 661109998Smarkm#ifdef OPENSSL_SYS_WIN32 66255714Skris 66359191Skrisstatic HANDLE *lock_cs; 66455714Skris 66555714Skrisvoid thread_setup(void) 666296465Sdelphij{ 667296465Sdelphij int i; 66855714Skris 669296465Sdelphij lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE)); 670296465Sdelphij for (i = 0; i < CRYPTO_num_locks(); i++) { 671296465Sdelphij lock_cs[i] = CreateMutex(NULL, FALSE, NULL); 672296465Sdelphij } 67355714Skris 674296465Sdelphij CRYPTO_set_locking_callback((void (*)(int, int, char *, int)) 675296465Sdelphij win32_locking_callback); 676296465Sdelphij /* id callback defined */ 677296465Sdelphij} 67855714Skris 67955714Skrisvoid thread_cleanup(void) 680296465Sdelphij{ 681296465Sdelphij int i; 68255714Skris 683296465Sdelphij CRYPTO_set_locking_callback(NULL); 684296465Sdelphij for (i = 0; i < CRYPTO_num_locks(); i++) 685296465Sdelphij CloseHandle(lock_cs[i]); 686296465Sdelphij OPENSSL_free(lock_cs); 687296465Sdelphij} 68855714Skris 68955714Skrisvoid win32_locking_callback(int mode, int type, char *file, int line) 690296465Sdelphij{ 691296465Sdelphij if (mode & CRYPTO_LOCK) { 692296465Sdelphij WaitForSingleObject(lock_cs[type], INFINITE); 693296465Sdelphij } else { 694296465Sdelphij ReleaseMutex(lock_cs[type]); 695296465Sdelphij } 696296465Sdelphij} 69755714Skris 69855714Skrisvoid do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) 699296465Sdelphij{ 700296465Sdelphij double ret; 701296465Sdelphij SSL_CTX *ssl_ctx[2]; 702296465Sdelphij DWORD thread_id[MAX_THREAD_NUMBER]; 703296465Sdelphij HANDLE thread_handle[MAX_THREAD_NUMBER]; 704296465Sdelphij int i; 705296465Sdelphij SYSTEMTIME start, end; 70655714Skris 707296465Sdelphij ssl_ctx[0] = s_ctx; 708296465Sdelphij ssl_ctx[1] = c_ctx; 70955714Skris 710296465Sdelphij GetSystemTime(&start); 711296465Sdelphij for (i = 0; i < thread_number; i++) { 712296465Sdelphij thread_handle[i] = CreateThread(NULL, 713296465Sdelphij THREAD_STACK_SIZE, 714296465Sdelphij (LPTHREAD_START_ROUTINE) ndoit, 715296465Sdelphij (void *)ssl_ctx, 0L, &(thread_id[i])); 716296465Sdelphij } 71755714Skris 718296465Sdelphij printf("reaping\n"); 719296465Sdelphij for (i = 0; i < thread_number; i += 50) { 720296465Sdelphij int j; 72155714Skris 722296465Sdelphij j = (thread_number < (i + 50)) ? (thread_number - i) : 50; 72355714Skris 724296465Sdelphij if (WaitForMultipleObjects(j, 725296465Sdelphij (CONST HANDLE *) & (thread_handle[i]), 726296465Sdelphij TRUE, INFINITE) 727296465Sdelphij == WAIT_FAILED) { 728296465Sdelphij fprintf(stderr, "WaitForMultipleObjects failed:%d\n", 729296465Sdelphij GetLastError()); 730296465Sdelphij exit(1); 731296465Sdelphij } 732296465Sdelphij } 733296465Sdelphij GetSystemTime(&end); 73455714Skris 735296465Sdelphij if (start.wDayOfWeek > end.wDayOfWeek) 736296465Sdelphij end.wDayOfWeek += 7; 737296465Sdelphij ret = (end.wDayOfWeek - start.wDayOfWeek) * 24; 73855714Skris 739296465Sdelphij ret = (ret + end.wHour - start.wHour) * 60; 740296465Sdelphij ret = (ret + end.wMinute - start.wMinute) * 60; 741296465Sdelphij ret = (ret + end.wSecond - start.wSecond); 742296465Sdelphij ret += (end.wMilliseconds - start.wMilliseconds) / 1000.0; 74355714Skris 744296465Sdelphij printf("win32 threads done - %.3f seconds\n", ret); 745296465Sdelphij} 74655714Skris 747296465Sdelphij#endif /* OPENSSL_SYS_WIN32 */ 74855714Skris 74955714Skris#ifdef SOLARIS 75055714Skris 75159191Skrisstatic mutex_t *lock_cs; 752296465Sdelphij/* 753296465Sdelphij * static rwlock_t *lock_cs; 754296465Sdelphij */ 75559191Skrisstatic long *lock_count; 75655714Skris 75755714Skrisvoid thread_setup(void) 758296465Sdelphij{ 759296465Sdelphij int i; 76055714Skris 761296465Sdelphij lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(mutex_t)); 762296465Sdelphij lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); 763296465Sdelphij for (i = 0; i < CRYPTO_num_locks(); i++) { 764296465Sdelphij lock_count[i] = 0; 765296465Sdelphij /* rwlock_init(&(lock_cs[i]),USYNC_THREAD,NULL); */ 766296465Sdelphij mutex_init(&(lock_cs[i]), USYNC_THREAD, NULL); 767296465Sdelphij } 76855714Skris 769296465Sdelphij CRYPTO_set_id_callback((unsigned long (*)())solaris_thread_id); 770296465Sdelphij CRYPTO_set_locking_callback((void (*)())solaris_locking_callback); 771296465Sdelphij} 77255714Skris 77355714Skrisvoid thread_cleanup(void) 774296465Sdelphij{ 775296465Sdelphij int i; 77655714Skris 777296465Sdelphij CRYPTO_set_locking_callback(NULL); 77859191Skris 779296465Sdelphij fprintf(stderr, "cleanup\n"); 78059191Skris 781296465Sdelphij for (i = 0; i < CRYPTO_num_locks(); i++) { 782296465Sdelphij /* rwlock_destroy(&(lock_cs[i])); */ 783296465Sdelphij mutex_destroy(&(lock_cs[i])); 784296465Sdelphij fprintf(stderr, "%8ld:%s\n", lock_count[i], CRYPTO_get_lock_name(i)); 785296465Sdelphij } 786296465Sdelphij OPENSSL_free(lock_cs); 787296465Sdelphij OPENSSL_free(lock_count); 78859191Skris 789296465Sdelphij fprintf(stderr, "done cleanup\n"); 79059191Skris 791296465Sdelphij} 79255714Skris 79355714Skrisvoid solaris_locking_callback(int mode, int type, char *file, int line) 794296465Sdelphij{ 795296465Sdelphij# ifdef undef 796296465Sdelphij fprintf(stderr, "thread=%4d mode=%s lock=%s %s:%d\n", 797296465Sdelphij CRYPTO_thread_id(), 798296465Sdelphij (mode & CRYPTO_LOCK) ? "l" : "u", 799296465Sdelphij (type & CRYPTO_READ) ? "r" : "w", file, line); 800296465Sdelphij# endif 80155714Skris 802296465Sdelphij /*- 803296465Sdelphij if (CRYPTO_LOCK_SSL_CERT == type) 804296465Sdelphij fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n", 805296465Sdelphij CRYPTO_thread_id(), 806296465Sdelphij mode,file,line); 807296465Sdelphij */ 808296465Sdelphij if (mode & CRYPTO_LOCK) { 809296465Sdelphij /*- 810296465Sdelphij if (mode & CRYPTO_READ) 811296465Sdelphij rw_rdlock(&(lock_cs[type])); 812296465Sdelphij else 813296465Sdelphij rw_wrlock(&(lock_cs[type])); */ 81455714Skris 815296465Sdelphij mutex_lock(&(lock_cs[type])); 816296465Sdelphij lock_count[type]++; 817296465Sdelphij } else { 818296465Sdelphij/* rw_unlock(&(lock_cs[type])); */ 819296465Sdelphij mutex_unlock(&(lock_cs[type])); 820296465Sdelphij } 821296465Sdelphij} 82255714Skris 82355714Skrisvoid do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) 824296465Sdelphij{ 825296465Sdelphij SSL_CTX *ssl_ctx[2]; 826296465Sdelphij thread_t thread_ctx[MAX_THREAD_NUMBER]; 827296465Sdelphij int i; 82855714Skris 829296465Sdelphij ssl_ctx[0] = s_ctx; 830296465Sdelphij ssl_ctx[1] = c_ctx; 83155714Skris 832296465Sdelphij thr_setconcurrency(thread_number); 833296465Sdelphij for (i = 0; i < thread_number; i++) { 834296465Sdelphij thr_create(NULL, THREAD_STACK_SIZE, 835296465Sdelphij (void *(*)())ndoit, (void *)ssl_ctx, 0L, &(thread_ctx[i])); 836296465Sdelphij } 83755714Skris 838296465Sdelphij printf("reaping\n"); 839296465Sdelphij for (i = 0; i < thread_number; i++) { 840296465Sdelphij thr_join(thread_ctx[i], NULL, NULL); 841296465Sdelphij } 84255714Skris 843296465Sdelphij printf("solaris threads done (%d,%d)\n", 844296465Sdelphij s_ctx->references, c_ctx->references); 845296465Sdelphij} 84655714Skris 84755714Skrisunsigned long solaris_thread_id(void) 848296465Sdelphij{ 849296465Sdelphij unsigned long ret; 85055714Skris 851296465Sdelphij ret = (unsigned long)thr_self(); 852296465Sdelphij return (ret); 853296465Sdelphij} 854296465Sdelphij#endif /* SOLARIS */ 85555714Skris 85655714Skris#ifdef IRIX 85755714Skris 85855714Skrisstatic usptr_t *arena; 85959191Skrisstatic usema_t **lock_cs; 86055714Skris 86155714Skrisvoid thread_setup(void) 862296465Sdelphij{ 863296465Sdelphij int i; 864296465Sdelphij char filename[20]; 86555714Skris 866296465Sdelphij strcpy(filename, "/tmp/mttest.XXXXXX"); 867296465Sdelphij mktemp(filename); 86855714Skris 869296465Sdelphij usconfig(CONF_STHREADIOOFF); 870296465Sdelphij usconfig(CONF_STHREADMALLOCOFF); 871296465Sdelphij usconfig(CONF_INITUSERS, 100); 872296465Sdelphij usconfig(CONF_LOCKTYPE, US_DEBUGPLUS); 873296465Sdelphij arena = usinit(filename); 874296465Sdelphij unlink(filename); 87555714Skris 876296465Sdelphij lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(usema_t *)); 877296465Sdelphij for (i = 0; i < CRYPTO_num_locks(); i++) { 878296465Sdelphij lock_cs[i] = usnewsema(arena, 1); 879296465Sdelphij } 88055714Skris 881296465Sdelphij CRYPTO_set_id_callback((unsigned long (*)())irix_thread_id); 882296465Sdelphij CRYPTO_set_locking_callback((void (*)())irix_locking_callback); 883296465Sdelphij} 88455714Skris 88555714Skrisvoid thread_cleanup(void) 886296465Sdelphij{ 887296465Sdelphij int i; 88855714Skris 889296465Sdelphij CRYPTO_set_locking_callback(NULL); 890296465Sdelphij for (i = 0; i < CRYPTO_num_locks(); i++) { 891296465Sdelphij char buf[10]; 89255714Skris 893296465Sdelphij sprintf(buf, "%2d:", i); 894296465Sdelphij usdumpsema(lock_cs[i], stdout, buf); 895296465Sdelphij usfreesema(lock_cs[i], arena); 896296465Sdelphij } 897296465Sdelphij OPENSSL_free(lock_cs); 898296465Sdelphij} 89955714Skris 90055714Skrisvoid irix_locking_callback(int mode, int type, char *file, int line) 901296465Sdelphij{ 902296465Sdelphij if (mode & CRYPTO_LOCK) { 903296465Sdelphij printf("lock %d\n", type); 904296465Sdelphij uspsema(lock_cs[type]); 905296465Sdelphij } else { 906296465Sdelphij printf("unlock %d\n", type); 907296465Sdelphij usvsema(lock_cs[type]); 908296465Sdelphij } 909296465Sdelphij} 91055714Skris 91155714Skrisvoid do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) 912296465Sdelphij{ 913296465Sdelphij SSL_CTX *ssl_ctx[2]; 914296465Sdelphij int thread_ctx[MAX_THREAD_NUMBER]; 915296465Sdelphij int i; 91655714Skris 917296465Sdelphij ssl_ctx[0] = s_ctx; 918296465Sdelphij ssl_ctx[1] = c_ctx; 91955714Skris 920296465Sdelphij for (i = 0; i < thread_number; i++) { 921296465Sdelphij thread_ctx[i] = sproc((void (*)())ndoit, 922296465Sdelphij PR_SADDR | PR_SFDS, (void *)ssl_ctx); 923296465Sdelphij } 92455714Skris 925296465Sdelphij printf("reaping\n"); 926296465Sdelphij for (i = 0; i < thread_number; i++) { 927296465Sdelphij wait(NULL); 928296465Sdelphij } 92955714Skris 930296465Sdelphij printf("irix threads done (%d,%d)\n", 931296465Sdelphij s_ctx->references, c_ctx->references); 932296465Sdelphij} 93355714Skris 93455714Skrisunsigned long irix_thread_id(void) 935296465Sdelphij{ 936296465Sdelphij unsigned long ret; 93755714Skris 938296465Sdelphij ret = (unsigned long)getpid(); 939296465Sdelphij return (ret); 940296465Sdelphij} 941296465Sdelphij#endif /* IRIX */ 94255714Skris 94355714Skris#ifdef PTHREADS 94455714Skris 94559191Skrisstatic pthread_mutex_t *lock_cs; 94659191Skrisstatic long *lock_count; 94755714Skris 94855714Skrisvoid thread_setup(void) 949296465Sdelphij{ 950296465Sdelphij int i; 95155714Skris 952296465Sdelphij lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); 953296465Sdelphij lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); 954296465Sdelphij for (i = 0; i < CRYPTO_num_locks(); i++) { 955296465Sdelphij lock_count[i] = 0; 956296465Sdelphij pthread_mutex_init(&(lock_cs[i]), NULL); 957296465Sdelphij } 95855714Skris 959296465Sdelphij CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id); 960296465Sdelphij CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback); 961296465Sdelphij} 96255714Skris 96355714Skrisvoid thread_cleanup(void) 964296465Sdelphij{ 965296465Sdelphij int i; 96655714Skris 967296465Sdelphij CRYPTO_set_locking_callback(NULL); 968296465Sdelphij fprintf(stderr, "cleanup\n"); 969296465Sdelphij for (i = 0; i < CRYPTO_num_locks(); i++) { 970296465Sdelphij pthread_mutex_destroy(&(lock_cs[i])); 971296465Sdelphij fprintf(stderr, "%8ld:%s\n", lock_count[i], CRYPTO_get_lock_name(i)); 972296465Sdelphij } 973296465Sdelphij OPENSSL_free(lock_cs); 974296465Sdelphij OPENSSL_free(lock_count); 97559191Skris 976296465Sdelphij fprintf(stderr, "done cleanup\n"); 977296465Sdelphij} 97855714Skris 979296465Sdelphijvoid pthreads_locking_callback(int mode, int type, char *file, int line) 980296465Sdelphij{ 981296465Sdelphij# ifdef undef 982296465Sdelphij fprintf(stderr, "thread=%4d mode=%s lock=%s %s:%d\n", 983296465Sdelphij CRYPTO_thread_id(), 984296465Sdelphij (mode & CRYPTO_LOCK) ? "l" : "u", 985296465Sdelphij (type & CRYPTO_READ) ? "r" : "w", file, line); 986296465Sdelphij# endif 987296465Sdelphij/*- 988296465Sdelphij if (CRYPTO_LOCK_SSL_CERT == type) 989296465Sdelphij fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n", 990296465Sdelphij CRYPTO_thread_id(), 991296465Sdelphij mode,file,line); 99255714Skris*/ 993296465Sdelphij if (mode & CRYPTO_LOCK) { 994296465Sdelphij pthread_mutex_lock(&(lock_cs[type])); 995296465Sdelphij lock_count[type]++; 996296465Sdelphij } else { 997296465Sdelphij pthread_mutex_unlock(&(lock_cs[type])); 998296465Sdelphij } 999296465Sdelphij} 100055714Skris 100155714Skrisvoid do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) 1002296465Sdelphij{ 1003296465Sdelphij SSL_CTX *ssl_ctx[2]; 1004296465Sdelphij pthread_t thread_ctx[MAX_THREAD_NUMBER]; 1005296465Sdelphij int i; 100655714Skris 1007296465Sdelphij ssl_ctx[0] = s_ctx; 1008296465Sdelphij ssl_ctx[1] = c_ctx; 100955714Skris 1010296465Sdelphij /* 1011296465Sdelphij * thr_setconcurrency(thread_number); 1012296465Sdelphij */ 1013296465Sdelphij for (i = 0; i < thread_number; i++) { 1014296465Sdelphij pthread_create(&(thread_ctx[i]), NULL, 1015296465Sdelphij (void *(*)())ndoit, (void *)ssl_ctx); 1016296465Sdelphij } 101755714Skris 1018296465Sdelphij printf("reaping\n"); 1019296465Sdelphij for (i = 0; i < thread_number; i++) { 1020296465Sdelphij pthread_join(thread_ctx[i], NULL); 1021296465Sdelphij } 102255714Skris 1023296465Sdelphij printf("pthreads threads done (%d,%d)\n", 1024296465Sdelphij s_ctx->references, c_ctx->references); 1025296465Sdelphij} 102655714Skris 102755714Skrisunsigned long pthreads_thread_id(void) 1028296465Sdelphij{ 1029296465Sdelphij unsigned long ret; 103055714Skris 1031296465Sdelphij ret = (unsigned long)pthread_self(); 1032296465Sdelphij return (ret); 1033296465Sdelphij} 103455714Skris 1035296465Sdelphij#endif /* PTHREADS */ 103655714Skris 1037160814Ssimon#ifdef OPENSSL_SYS_NETWARE 1038160814Ssimon 1039160814Ssimonvoid thread_setup(void) 1040160814Ssimon{ 1041296465Sdelphij int i; 1042160814Ssimon 1043296465Sdelphij lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(MPKMutex)); 1044296465Sdelphij lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); 1045296465Sdelphij for (i = 0; i < CRYPTO_num_locks(); i++) { 1046296465Sdelphij lock_count[i] = 0; 1047296465Sdelphij lock_cs[i] = MPKMutexAlloc("OpenSSL mutex"); 1048296465Sdelphij } 1049160814Ssimon 1050296465Sdelphij ThreadSem = MPKSemaphoreAlloc("OpenSSL mttest semaphore", 0); 1051160814Ssimon 1052296465Sdelphij CRYPTO_set_id_callback((unsigned long (*)())netware_thread_id); 1053296465Sdelphij CRYPTO_set_locking_callback((void (*)())netware_locking_callback); 1054160814Ssimon} 1055160814Ssimon 1056160814Ssimonvoid thread_cleanup(void) 1057160814Ssimon{ 1058296465Sdelphij int i; 1059160814Ssimon 1060296465Sdelphij CRYPTO_set_locking_callback(NULL); 1061160814Ssimon 1062296465Sdelphij fprintf(stdout, "thread_cleanup\n"); 1063160814Ssimon 1064296465Sdelphij for (i = 0; i < CRYPTO_num_locks(); i++) { 1065296465Sdelphij MPKMutexFree(lock_cs[i]); 1066296465Sdelphij fprintf(stdout, "%8ld:%s\n", lock_count[i], CRYPTO_get_lock_name(i)); 1067296465Sdelphij } 1068296465Sdelphij OPENSSL_free(lock_cs); 1069296465Sdelphij OPENSSL_free(lock_count); 1070160814Ssimon 1071296465Sdelphij MPKSemaphoreFree(ThreadSem); 1072160814Ssimon 1073296465Sdelphij fprintf(stdout, "done cleanup\n"); 1074160814Ssimon} 1075160814Ssimon 1076160814Ssimonvoid netware_locking_callback(int mode, int type, char *file, int line) 1077160814Ssimon{ 1078296465Sdelphij if (mode & CRYPTO_LOCK) { 1079296465Sdelphij MPKMutexLock(lock_cs[type]); 1080296465Sdelphij lock_count[type]++; 1081296465Sdelphij } else 1082296465Sdelphij MPKMutexUnlock(lock_cs[type]); 1083160814Ssimon} 1084160814Ssimon 1085160814Ssimonvoid do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) 1086160814Ssimon{ 1087296465Sdelphij SSL_CTX *ssl_ctx[2]; 1088296465Sdelphij int i; 1089296465Sdelphij ssl_ctx[0] = s_ctx; 1090296465Sdelphij ssl_ctx[1] = c_ctx; 1091160814Ssimon 1092296465Sdelphij for (i = 0; i < thread_number; i++) { 1093296465Sdelphij BeginThread((void (*)(void *))ndoit, NULL, THREAD_STACK_SIZE, 1094296465Sdelphij (void *)ssl_ctx); 1095296465Sdelphij ThreadSwitchWithDelay(); 1096296465Sdelphij } 1097160814Ssimon 1098296465Sdelphij printf("reaping\n"); 1099160814Ssimon 1100296465Sdelphij /* loop until all threads have signaled the semaphore */ 1101296465Sdelphij for (i = 0; i < thread_number; i++) { 1102296465Sdelphij MPKSemaphoreWait(ThreadSem); 1103296465Sdelphij } 1104296465Sdelphij printf("netware threads done (%d,%d)\n", 1105296465Sdelphij s_ctx->references, c_ctx->references); 1106160814Ssimon} 1107160814Ssimon 1108160814Ssimonunsigned long netware_thread_id(void) 1109160814Ssimon{ 1110296465Sdelphij unsigned long ret; 1111160814Ssimon 1112296465Sdelphij ret = (unsigned long)GetThreadID(); 1113296465Sdelphij return (ret); 1114160814Ssimon} 1115296465Sdelphij#endif /* NETWARE */ 1116