/* mt/mttest.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 * 
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 * 
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 * 
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#ifdef LINUX
#include <typedefs.h>
#endif
#ifdef WIN32
#include <windows.h>
#endif
#ifdef SOLARIS
#include <synch.h>
#include <thread.h>
#endif
#ifdef IRIX
#include <ulocks.h>
#include <sys/prctl.h>
#endif
#include "lhash.h"
#include "crypto.h"
#include "buffer.h"
#include "../e_os.h"
#include "x509.h"
#include "ssl.h"
#include "err.h"

#ifdef NO_FP_API
#define APPS_WIN16
#include "../crypto/buffer/bss_file.c"
#endif

#define TEST_SERVER_CERT "../apps/server.pem"
#define TEST_CLIENT_CERT "../apps/client.pem"

#define MAX_THREAD_NUMBER	100

#ifndef NOPROTO
int MS_CALLBACK verify_callback(int ok, X509 *xs, X509 *xi, int depth,
	int error,char *arg);
void thread_setup(void);
void thread_cleanup(void);
void do_threads(SSL_CTX *s_ctx,SSL_CTX *c_ctx);

void irix_locking_callback(int mode,int type,char *file,int line);
void solaris_locking_callback(int mode,int type,char *file,int line);
void win32_locking_callback(int mode,int type,char *file,int line);
void pthreads_locking_callback(int mode,int type,char *file,int line);

unsigned long irix_thread_id(void );
unsigned long solaris_thread_id(void );
unsigned long pthreads_thread_id(void );

#else
int MS_CALLBACK verify_callback();
void thread_setup();
void thread_cleanup();
void do_threads();

void irix_locking_callback();
void solaris_locking_callback();
void win32_locking_callback();
void pthreads_locking_callback();

unsigned long irix_thread_id();
unsigned long solaris_thread_id();
unsigned long pthreads_thread_id();

#endif

BIO *bio_err=NULL;
BIO *bio_stdout=NULL;

static char *cipher=NULL;
int verbose=0;
#ifdef FIONBIO
static int s_nbio=0;
#endif

int thread_number=10;
int number_of_loops=10;
int reconnect=0;
int cache_stats=0;

#ifndef  NOPROTO
int doit(char *ctx[4]);
#else
int doit();
#endif

static void print_stats(fp,ctx)
FILE *fp;
SSL_CTX *ctx;
{
	fprintf(fp,"%4ld items in the session cache\n",
		SSL_CTX_sess_number(ctx));
	fprintf(fp,"%4d client connects (SSL_connect())\n",
		SSL_CTX_sess_connect(ctx));
	fprintf(fp,"%4d client connects that finished\n",
		SSL_CTX_sess_connect_good(ctx));
	fprintf(fp,"%4d server connects (SSL_accept())\n",
		SSL_CTX_sess_accept(ctx));
	fprintf(fp,"%4d server connects that finished\n",
		SSL_CTX_sess_accept_good(ctx));
	fprintf(fp,"%4d session cache hits\n",SSL_CTX_sess_hits(ctx));
	fprintf(fp,"%4d session cache misses\n",SSL_CTX_sess_misses(ctx));
	fprintf(fp,"%4d session cache timeouts\n",SSL_CTX_sess_timeouts(ctx));
	}

static void sv_usage()
	{
	fprintf(stderr,"usage: ssltest [args ...]\n");
	fprintf(stderr,"\n");
	fprintf(stderr," -server_auth  - check server certificate\n");
	fprintf(stderr," -client_auth  - do client authentication\n");
	fprintf(stderr," -v            - more output\n");
	fprintf(stderr," -CApath arg   - PEM format directory of CA's\n");
	fprintf(stderr," -CAfile arg   - PEM format file of CA's\n");
	fprintf(stderr," -threads arg  - number of threads\n");
	fprintf(stderr," -loops arg    - number of 'connections', per thread\n");
	fprintf(stderr," -reconnect    - reuse session-id's\n");
	fprintf(stderr," -stats        - server session-id cache stats\n");
	fprintf(stderr," -cert arg     - server certificate/key\n");
	fprintf(stderr," -ccert arg    - client certificate/key\n");
	fprintf(stderr," -ssl3         - just SSLv3n\n");
	}

int main(argc, argv)
int argc;
char *argv[];
	{
	char *CApath=NULL,*CAfile=NULL;
	int badop=0;
	int ret=1;
	int client_auth=0;
	int server_auth=0;
	SSL_CTX *s_ctx=NULL;
	SSL_CTX *c_ctx=NULL;
	char *scert=TEST_SERVER_CERT;
	char *ccert=TEST_CLIENT_CERT;
	SSL_METHOD *ssl_method=SSLv23_method();

	if (bio_err == NULL)
		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
	if (bio_stdout == NULL)
		bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE);
	argc--;
	argv++;

	while (argc >= 1)
		{
		if	(strcmp(*argv,"-server_auth") == 0)
			server_auth=1;
		else if	(strcmp(*argv,"-client_auth") == 0)
			client_auth=1;
		else if	(strcmp(*argv,"-reconnect") == 0)
			reconnect=1;
		else if	(strcmp(*argv,"-stats") == 0)
			cache_stats=1;
		else if	(strcmp(*argv,"-ssl3") == 0)
			ssl_method=SSLv3_method();
		else if	(strcmp(*argv,"-ssl2") == 0)
			ssl_method=SSLv2_method();
		else if	(strcmp(*argv,"-CApath") == 0)
			{
			if (--argc < 1) goto bad;
			CApath= *(++argv);
			}
		else if	(strcmp(*argv,"-CAfile") == 0)
			{
			if (--argc < 1) goto bad;
			CAfile= *(++argv);
			}
		else if	(strcmp(*argv,"-cert") == 0)
			{
			if (--argc < 1) goto bad;
			scert= *(++argv);
			}
		else if	(strcmp(*argv,"-ccert") == 0)
			{
			if (--argc < 1) goto bad;
			ccert= *(++argv);
			}
		else if	(strcmp(*argv,"-threads") == 0)
			{
			if (--argc < 1) goto bad;
			thread_number= atoi(*(++argv));
			if (thread_number == 0) thread_number=1;
			if (thread_number > MAX_THREAD_NUMBER)
				thread_number=MAX_THREAD_NUMBER;
			}
		else if	(strcmp(*argv,"-loops") == 0)
			{
			if (--argc < 1) goto bad;
			number_of_loops= atoi(*(++argv));
			if (number_of_loops == 0) number_of_loops=1;
			}
		else
			{
			fprintf(stderr,"unknown option %s\n",*argv);
			badop=1;
			break;
			}
		argc--;
		argv++;
		}
	if (badop)
		{
bad:
		sv_usage();
		goto end;
		}

	if (cipher == NULL) cipher=getenv("SSL_CIPHER");

	SSL_load_error_strings();
	SSLeay_add_ssl_algorithms();

	c_ctx=SSL_CTX_new(ssl_method);
	s_ctx=SSL_CTX_new(ssl_method);
	if ((c_ctx == NULL) || (s_ctx == NULL))
		{
		ERR_print_errors(bio_err);
		goto end;
		}

	SSL_CTX_set_session_cache_mode(s_ctx,
		SSL_SESS_CACHE_NO_AUTO_CLEAR|SSL_SESS_CACHE_SERVER);
	SSL_CTX_set_session_cache_mode(c_ctx,
		SSL_SESS_CACHE_NO_AUTO_CLEAR|SSL_SESS_CACHE_SERVER);

	SSL_CTX_use_certificate_file(s_ctx,scert,SSL_FILETYPE_PEM);
	SSL_CTX_use_RSAPrivateKey_file(s_ctx,scert,SSL_FILETYPE_PEM);

	if (client_auth)
		{
		SSL_CTX_use_certificate_file(c_ctx,ccert,
			SSL_FILETYPE_PEM);
		SSL_CTX_use_RSAPrivateKey_file(c_ctx,ccert,
			SSL_FILETYPE_PEM);
		}

	if (	(!SSL_CTX_load_verify_locations(s_ctx,CAfile,CApath)) ||
		(!SSL_CTX_set_default_verify_paths(s_ctx)) ||
		(!SSL_CTX_load_verify_locations(c_ctx,CAfile,CApath)) ||
		(!SSL_CTX_set_default_verify_paths(c_ctx)))
		{
		fprintf(stderr,"SSL_load_verify_locations\n");
		ERR_print_errors(bio_err);
		goto end;
		}

	if (client_auth)
		{
		fprintf(stderr,"client authentication\n");
		SSL_CTX_set_verify(s_ctx,
			SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
			verify_callback);
		}
	if (server_auth)
		{
		fprintf(stderr,"server authentication\n");
		SSL_CTX_set_verify(c_ctx,SSL_VERIFY_PEER,
			verify_callback);
		}

	thread_setup();
	do_threads(s_ctx,c_ctx);
	thread_cleanup();
end:
	
	if (c_ctx != NULL) 
		{
		fprintf(stderr,"Client SSL_CTX stats then free it\n");
		print_stats(stderr,c_ctx);
		SSL_CTX_free(c_ctx);
		}
	if (s_ctx != NULL)
		{
		fprintf(stderr,"Server SSL_CTX stats then free it\n");
		print_stats(stderr,s_ctx);
		if (cache_stats)
			{
			fprintf(stderr,"-----\n");
			lh_stats(SSL_CTX_sessions(s_ctx),stderr);
			fprintf(stderr,"-----\n");
		/*	lh_node_stats(SSL_CTX_sessions(s_ctx),stderr);
			fprintf(stderr,"-----\n"); */
			lh_node_usage_stats(SSL_CTX_sessions(s_ctx),stderr);
			fprintf(stderr,"-----\n");
			}
		SSL_CTX_free(s_ctx);
		fprintf(stderr,"done free\n");
		}
	exit(ret);
	return(0);
	}

#define W_READ	1
#define W_WRITE	2
#define C_DONE	1
#define S_DONE	2

int ndoit(ssl_ctx)
SSL_CTX *ssl_ctx[2];
	{
	int i;
	int ret;
	char *ctx[4];

	ctx[0]=(char *)ssl_ctx[0];
	ctx[1]=(char *)ssl_ctx[1];

	if (reconnect)
		{
		ctx[2]=(char *)SSL_new(ssl_ctx[0]);
		ctx[3]=(char *)SSL_new(ssl_ctx[1]);
		}
	else
		{
		ctx[2]=NULL;
		ctx[3]=NULL;
		}

	fprintf(stdout,"started thread %lu\n",CRYPTO_thread_id());
	for (i=0; i<number_of_loops; i++)
		{
/*		fprintf(stderr,"%4d %2d ctx->ref (%3d,%3d)\n",
			CRYPTO_thread_id(),i,
			ssl_ctx[0]->references,
			ssl_ctx[1]->references); */
	/*	pthread_delay_np(&tm);*/

		ret=doit(ctx);
		if (ret != 0)
			{
			fprintf(stdout,"error[%d] %lu - %d\n",
				i,CRYPTO_thread_id(),ret);
			return(ret);
			}
		}
	fprintf(stdout,"DONE %lu\n",CRYPTO_thread_id());
	if (reconnect)
		{
		SSL_free((SSL *)ctx[2]);
		SSL_free((SSL *)ctx[3]);
		}
	return(0);
	}

int doit(ctx)
char *ctx[4];
	{
	SSL_CTX *s_ctx,*c_ctx;
	static char cbuf[200],sbuf[200];
	SSL *c_ssl=NULL;
	SSL *s_ssl=NULL;
	BIO *c_to_s=NULL;
	BIO *s_to_c=NULL;
	BIO *c_bio=NULL;
	BIO *s_bio=NULL;
	int c_r,c_w,s_r,s_w;
	int c_want,s_want;
	int i;
	int done=0;
	int c_write,s_write;
	int do_server=0,do_client=0;

	s_ctx=(SSL_CTX *)ctx[0];
	c_ctx=(SSL_CTX *)ctx[1];

	if (ctx[2] != NULL)
		s_ssl=(SSL *)ctx[2];
	else
		s_ssl=SSL_new(s_ctx);

	if (ctx[3] != NULL)
		c_ssl=(SSL *)ctx[3];
	else
		c_ssl=SSL_new(c_ctx);

	if ((s_ssl == NULL) || (c_ssl == NULL)) goto err;

	c_to_s=BIO_new(BIO_s_mem());
	s_to_c=BIO_new(BIO_s_mem());
	if ((s_to_c == NULL) || (c_to_s == NULL)) goto err;

	c_bio=BIO_new(BIO_f_ssl());
	s_bio=BIO_new(BIO_f_ssl());
	if ((c_bio == NULL) || (s_bio == NULL)) goto err;

	SSL_set_connect_state(c_ssl);
	SSL_set_bio(c_ssl,s_to_c,c_to_s);
	BIO_set_ssl(c_bio,c_ssl,(ctx[2] == NULL)?BIO_CLOSE:BIO_NOCLOSE);

	SSL_set_accept_state(s_ssl);
	SSL_set_bio(s_ssl,c_to_s,s_to_c);
	BIO_set_ssl(s_bio,s_ssl,(ctx[3] == NULL)?BIO_CLOSE:BIO_NOCLOSE);

	c_r=0; s_r=1;
	c_w=1; s_w=0;
	c_want=W_WRITE;
	s_want=0;
	c_write=1,s_write=0;

	/* We can always do writes */
	for (;;)
		{
		do_server=0;
		do_client=0;

		i=(int)BIO_pending(s_bio);
		if ((i && s_r) || s_w) do_server=1;

		i=(int)BIO_pending(c_bio);
		if ((i && c_r) || c_w) do_client=1;

		if (do_server && verbose)
			{
			if (SSL_in_init(s_ssl))
				printf("server waiting in SSL_accept - %s\n",
					SSL_state_string_long(s_ssl));
			else if (s_write)
				printf("server:SSL_write()\n");
			else 
				printf("server:SSL_read()\n");
			}

		if (do_client && verbose)
			{
			if (SSL_in_init(c_ssl))
				printf("client waiting in SSL_connect - %s\n",
					SSL_state_string_long(c_ssl));
			else if (c_write)
				printf("client:SSL_write()\n");
			else
				printf("client:SSL_read()\n");
			}

		if (!do_client && !do_server)
			{
			fprintf(stdout,"ERROR IN STARTUP\n");
			break;
			}
		if (do_client && !(done & C_DONE))
			{
			if (c_write)
				{
				i=BIO_write(c_bio,"hello from client\n",18);
				if (i < 0)
					{
					c_r=0;
					c_w=0;
					if (BIO_should_retry(c_bio))
						{
						if (BIO_should_read(c_bio))
							c_r=1;
						if (BIO_should_write(c_bio))
							c_w=1;
						}
					else
						{
						fprintf(stderr,"ERROR in CLIENT\n");
						return(1);
						}
					}
				else if (i == 0)
					{
					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
					return(1);
					}
				else
					{
					/* ok */
					c_write=0;
					}
				}
			else
				{
				i=BIO_read(c_bio,cbuf,100);
				if (i < 0)
					{
					c_r=0;
					c_w=0;
					if (BIO_should_retry(c_bio))
						{
						if (BIO_should_read(c_bio))
							c_r=1;
						if (BIO_should_write(c_bio))
							c_w=1;
						}
					else
						{
						fprintf(stderr,"ERROR in CLIENT\n");
						return(1);
						}
					}
				else if (i == 0)
					{
					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
					return(1);
					}
				else
					{
					done|=C_DONE;
#ifdef undef
					fprintf(stdout,"CLIENT:from server:");
					fwrite(cbuf,1,i,stdout);
					fflush(stdout);
#endif
					}
				}
			}

		if (do_server && !(done & S_DONE))
			{
			if (!s_write)
				{
				i=BIO_read(s_bio,sbuf,100);
				if (i < 0)
					{
					s_r=0;
					s_w=0;
					if (BIO_should_retry(s_bio))
						{
						if (BIO_should_read(s_bio))
							s_r=1;
						if (BIO_should_write(s_bio))
							s_w=1;
						}
					else
						{
						fprintf(stderr,"ERROR in SERVER\n");
						ERR_print_errors_fp(stderr);
						return(1);
						}
					}
				else if (i == 0)
					{
					fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
					return(1);
					}
				else
					{
					s_write=1;
					s_w=1;
#ifdef undef
					fprintf(stdout,"SERVER:from client:");
					fwrite(sbuf,1,i,stdout);
					fflush(stdout);
#endif
					}
				}
			else
				{
				i=BIO_write(s_bio,"hello from server\n",18);
				if (i < 0)
					{
					s_r=0;
					s_w=0;
					if (BIO_should_retry(s_bio))
						{
						if (BIO_should_read(s_bio))
							s_r=1;
						if (BIO_should_write(s_bio))
							s_w=1;
						}
					else
						{
						fprintf(stderr,"ERROR in SERVER\n");
						ERR_print_errors_fp(stderr);
						return(1);
						}
					}
				else if (i == 0)
					{
					fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
					return(1);
					}
				else
					{
					s_write=0;
					s_r=1;
					done|=S_DONE;
					}
				}
			}

		if ((done & S_DONE) && (done & C_DONE)) break;
		}

	SSL_set_shutdown(c_ssl,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
	SSL_set_shutdown(s_ssl,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);

#ifdef undef
	fprintf(stdout,"DONE\n");
#endif
err:
	/* We have to set the BIO's to NULL otherwise they will be
	 * free()ed twice.  Once when th s_ssl is SSL_free()ed and
	 * again when c_ssl is SSL_free()ed.
	 * This is a hack required because s_ssl and c_ssl are sharing the same
	 * BIO structure and SSL_set_bio() and SSL_free() automatically
	 * BIO_free non NULL entries.
	 * You should not normally do this or be required to do this */

	if (s_ssl != NULL)
		{
		s_ssl->rbio=NULL;
		s_ssl->wbio=NULL;
		}
	if (c_ssl != NULL)
		{
		c_ssl->rbio=NULL;
		c_ssl->wbio=NULL;
		}

	/* The SSL's are optionally freed in the following calls */
	if (c_to_s != NULL) BIO_free(c_to_s);
	if (s_to_c != NULL) BIO_free(s_to_c);

	if (c_bio != NULL) BIO_free(c_bio);
	if (s_bio != NULL) BIO_free(s_bio);
	return(0);
	}

int MS_CALLBACK verify_callback(ok, xs, xi, depth, error, arg)
int ok;
X509 *xs;
X509 *xi;
int depth;
int error;
char *arg;
	{
	char buf[256];

	if (verbose)
		{
		X509_NAME_oneline(X509_get_subject_name(xs),buf,256);
		if (ok)
			fprintf(stderr,"depth=%d %s\n",depth,buf);
		else
			fprintf(stderr,"depth=%d error=%d %s\n",depth,error,buf);
		}
	return(ok);
	}

#define THREAD_STACK_SIZE (16*1024)

#ifdef WIN32

static PRLOCK lock_cs[CRYPTO_NUM_LOCKS];

void thread_setup()
	{
	int i;

	for (i=0; i<CRYPTO_NUM_LOCKS; i++)
		{
		lock_cs[i]=CreateMutex(NULL,FALSE,NULL);
		}

	CRYPTO_set_locking_callback((void (*)(int,int,char *,int))win32_locking_callback);
	/* id callback defined */
	}

void thread_cleanup()
	{
	int i;

	CRYPTO_set_locking_callback(NULL);
	for (i=0; i<CRYPTO_NUM_LOCKS; i++)
		CloseHandle(lock_cs[i]);
	}

void win32_locking_callback(mode,type,file,line)
int mode;
int type;
char *file;
int line;
	{
	if (mode & CRYPTO_LOCK)
		{
		WaitForSingleObject(lock_cs[type],INFINITE);
		}
	else
		{
		ReleaseMutex(lock_cs[type]);
		}
	}

void do_threads(s_ctx,c_ctx)
SSL_CTX *s_ctx,*c_ctx;
	{
	double ret;
	SSL_CTX *ssl_ctx[2];
	DWORD thread_id[MAX_THREAD_NUMBER];
	HANDLE thread_handle[MAX_THREAD_NUMBER];
	int i;
	SYSTEMTIME start,end;

	ssl_ctx[0]=s_ctx;
	ssl_ctx[1]=c_ctx;

	GetSystemTime(&start);
	for (i=0; i<thread_number; i++)
		{
		thread_handle[i]=CreateThread(NULL,
			THREAD_STACK_SIZE,
			(LPTHREAD_START_ROUTINE)ndoit,
			(void *)ssl_ctx,
			0L,
			&(thread_id[i]));
		}

	printf("reaping\n");
	for (i=0; i<thread_number; i+=50)
		{
		int j;

		j=(thread_number < (i+50))?(thread_number-i):50;

		if (WaitForMultipleObjects(j,
			(CONST HANDLE *)&(thread_handle[i]),TRUE,INFINITE)
			== WAIT_FAILED)
			{
			fprintf(stderr,"WaitForMultipleObjects failed:%d\n",GetLastError());
			exit(1);
			}
		}
	GetSystemTime(&end);

	if (start.wDayOfWeek > end.wDayOfWeek) end.wDayOfWeek+=7;
	ret=(end.wDayOfWeek-start.wDayOfWeek)*24;

	ret=(ret+end.wHour-start.wHour)*60;
	ret=(ret+end.wMinute-start.wMinute)*60;
	ret=(ret+end.wSecond-start.wSecond);
	ret+=(end.wMilliseconds-start.wMilliseconds)/1000.0;

	printf("win32 threads done - %.3f seconds\n",ret);
	}

#endif /* WIN32 */

#ifdef SOLARIS

static mutex_t lock_cs[CRYPTO_NUM_LOCKS];
/*static rwlock_t lock_cs[CRYPTO_NUM_LOCKS]; */
static long lock_count[CRYPTO_NUM_LOCKS];

void thread_setup()
	{
	int i;

	for (i=0; i<CRYPTO_NUM_LOCKS; i++)
		{
		lock_count[i]=0;
		/* rwlock_init(&(lock_cs[i]),USYNC_THREAD,NULL); */
		mutex_init(&(lock_cs[i]),USYNC_THREAD,NULL);
		}

	CRYPTO_set_id_callback((unsigned long (*)())solaris_thread_id);
	CRYPTO_set_locking_callback((void (*)())solaris_locking_callback);
	}

void thread_cleanup()
	{
	int i;

	CRYPTO_set_locking_callback(NULL);
fprintf(stderr,"cleanup\n");
	for (i=0; i<CRYPTO_NUM_LOCKS; i++)
		{
		/* rwlock_destroy(&(lock_cs[i])); */
		mutex_destroy(&(lock_cs[i]));
		fprintf(stderr,"%8ld:%s\n",lock_count[i],CRYPTO_get_lock_name(i));
		}
fprintf(stderr,"done cleanup\n");
	}

void solaris_locking_callback(mode,type,file,line)
int mode;
int type;
char *file;
int line;
	{
#ifdef undef
fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
	CRYPTO_thread_id(),
	(mode&CRYPTO_LOCK)?"l":"u",
	(type&CRYPTO_READ)?"r":"w",file,line);
#endif

/*
if (CRYPTO_LOCK_SSL_CERT == type)
	fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
		CRYPTO_thread_id(),
		mode,file,line);
*/
	if (mode & CRYPTO_LOCK)
		{
	/*	if (mode & CRYPTO_READ)
			rw_rdlock(&(lock_cs[type]));
		else
			rw_wrlock(&(lock_cs[type])); */

		mutex_lock(&(lock_cs[type]));
		lock_count[type]++;
		}
	else
		{
/*		rw_unlock(&(lock_cs[type]));  */
		mutex_unlock(&(lock_cs[type]));
		}
	}

void do_threads(s_ctx,c_ctx)
SSL_CTX *s_ctx,*c_ctx;
	{
	SSL_CTX *ssl_ctx[2];
	thread_t thread_ctx[MAX_THREAD_NUMBER];
	int i;

	ssl_ctx[0]=s_ctx;
	ssl_ctx[1]=c_ctx;

	thr_setconcurrency(thread_number);
	for (i=0; i<thread_number; i++)
		{
		thr_create(NULL, THREAD_STACK_SIZE,
			(void *(*)())ndoit,
			(void *)ssl_ctx,
			0L,
			&(thread_ctx[i]));
		}

	printf("reaping\n");
	for (i=0; i<thread_number; i++)
		{
		thr_join(thread_ctx[i],NULL,NULL);
		}

	printf("solaris threads done (%d,%d)\n",
		s_ctx->references,c_ctx->references);
	}

unsigned long solaris_thread_id()
	{
	unsigned long ret;

	ret=(unsigned long)thr_self();
	return(ret);
	}
#endif /* SOLARIS */

#ifdef IRIX


static usptr_t *arena;
static usema_t *lock_cs[CRYPTO_NUM_LOCKS];

void thread_setup()
	{
	int i;
	char filename[20];

	strcpy(filename,"/tmp/mttest.XXXXXX");
	mktemp(filename);

	usconfig(CONF_STHREADIOOFF);
	usconfig(CONF_STHREADMALLOCOFF);
	usconfig(CONF_INITUSERS,100);
	usconfig(CONF_LOCKTYPE,US_DEBUGPLUS);
	arena=usinit(filename);
	unlink(filename);

	for (i=0; i<CRYPTO_NUM_LOCKS; i++)
		{
		lock_cs[i]=usnewsema(arena,1);
		}

	CRYPTO_set_id_callback((unsigned long (*)())irix_thread_id);
	CRYPTO_set_locking_callback((void (*)())irix_locking_callback);
	}

void thread_cleanup()
	{
	int i;

	CRYPTO_set_locking_callback(NULL);
	for (i=0; i<CRYPTO_NUM_LOCKS; i++)
		{
		char buf[10];

		sprintf(buf,"%2d:",i);
		usdumpsema(lock_cs[i],stdout,buf);
		usfreesema(lock_cs[i],arena);
		}
	}

void irix_locking_callback(mode,type,file,line)
int mode;
int type;
char *file;
int line;
	{
	if (mode & CRYPTO_LOCK)
		{
		printf("lock %d\n",type);
		uspsema(lock_cs[type]);
		}
	else
		{
		printf("unlock %d\n",type);
		usvsema(lock_cs[type]);
		}
	}

void do_threads(s_ctx,c_ctx)
SSL_CTX *s_ctx,*c_ctx;
	{
	SSL_CTX *ssl_ctx[2];
	int thread_ctx[MAX_THREAD_NUMBER];
	int i;

	ssl_ctx[0]=s_ctx;
	ssl_ctx[1]=c_ctx;

	for (i=0; i<thread_number; i++)
		{
		thread_ctx[i]=sproc((void (*)())ndoit,
			PR_SADDR|PR_SFDS,(void *)ssl_ctx);
		}

	printf("reaping\n");
	for (i=0; i<thread_number; i++)
		{
		wait(NULL);
		}

	printf("irix threads done (%d,%d)\n",
		s_ctx->references,c_ctx->references);
	}

unsigned long irix_thread_id()
	{
	unsigned long ret;

	ret=(unsigned long)getpid();
	return(ret);
	}
#endif /* IRIX */

#ifdef PTHREADS

static pthread_mutex_t lock_cs[CRYPTO_NUM_LOCKS];
static long lock_count[CRYPTO_NUM_LOCKS];

void thread_setup()
	{
	int i;

	for (i=0; i<CRYPTO_NUM_LOCKS; i++)
		{
		lock_count[i]=0;
		pthread_mutex_init(&(lock_cs[i]),NULL);
		}

	CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
	CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
	}

void thread_cleanup()
	{
	int i;

	CRYPTO_set_locking_callback(NULL);
	fprintf(stderr,"cleanup\n");
	for (i=0; i<CRYPTO_NUM_LOCKS; i++)
		{
		pthread_mutex_destroy(&(lock_cs[i]));
		fprintf(stderr,"%8ld:%s\n",lock_count[i],
			CRYPTO_get_lock_name(i));
		}
	fprintf(stderr,"done cleanup\n");
	}

void pthreads_locking_callback(mode,type,file,line)
int mode;
int type;
char *file;
int line;
      {
#ifdef undef
	fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
		CRYPTO_thread_id(),
		(mode&CRYPTO_LOCK)?"l":"u",
		(type&CRYPTO_READ)?"r":"w",file,line);
#endif
/*
	if (CRYPTO_LOCK_SSL_CERT == type)
		fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
		CRYPTO_thread_id(),
		mode,file,line);
*/
	if (mode & CRYPTO_LOCK)
		{
		pthread_mutex_lock(&(lock_cs[type]));
		lock_count[type]++;
		}
	else
		{
		pthread_mutex_unlock(&(lock_cs[type]));
		}
	}

void do_threads(s_ctx,c_ctx)
SSL_CTX *s_ctx,*c_ctx;
	{
	SSL_CTX *ssl_ctx[2];
	pthread_t thread_ctx[MAX_THREAD_NUMBER];
	int i;

	ssl_ctx[0]=s_ctx;
	ssl_ctx[1]=c_ctx;

	/*
	thr_setconcurrency(thread_number);
	*/
	for (i=0; i<thread_number; i++)
		{
		pthread_create(&(thread_ctx[i]), NULL,
			(void *(*)())ndoit, (void *)ssl_ctx);
		}

	printf("reaping\n");
	for (i=0; i<thread_number; i++)
		{
		pthread_join(thread_ctx[i],NULL);
		}

	printf("pthreads threads done (%d,%d)\n",
	s_ctx->references,c_ctx->references);
	}

unsigned long pthreads_thread_id()
	{
	unsigned long ret;

	ret=(unsigned long)pthread_self();
	return(ret);
	}

#endif /* PTHREADS */



