summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/threads
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/threads')
-rw-r--r--src/lib/libcrypto/threads/README14
-rw-r--r--src/lib/libcrypto/threads/mttest.c1211
-rw-r--r--src/lib/libcrypto/threads/netware.bat79
-rw-r--r--src/lib/libcrypto/threads/profile.sh4
-rw-r--r--src/lib/libcrypto/threads/ptest.bat4
-rw-r--r--src/lib/libcrypto/threads/pthread.sh9
-rw-r--r--src/lib/libcrypto/threads/pthread2.sh7
-rw-r--r--src/lib/libcrypto/threads/pthreads-vms.com9
-rw-r--r--src/lib/libcrypto/threads/purify.sh4
-rw-r--r--src/lib/libcrypto/threads/solaris.sh4
-rw-r--r--src/lib/libcrypto/threads/th-lock.c387
-rw-r--r--src/lib/libcrypto/threads/win32.bat4
12 files changed, 1736 insertions, 0 deletions
diff --git a/src/lib/libcrypto/threads/README b/src/lib/libcrypto/threads/README
new file mode 100644
index 0000000000..df6b26e146
--- /dev/null
+++ b/src/lib/libcrypto/threads/README
@@ -0,0 +1,14 @@
1Mutithreading testing area.
2
3Since this stuff is very very platorm specific, this is not part of the
4normal build. Have a read of doc/threads.doc.
5
6mttest will do some testing and will currently build under Windows NT/95,
7Solaris and Linux. The IRIX stuff is not finished.
8
9I have tested this program on a 12 CPU ultra sparc box (solaris 2.5.1)
10and things seem to work ok.
11
12The Linux pthreads package can be retrieved from
13http://www.mit.edu:8001/people/proven/pthreads.html
14
diff --git a/src/lib/libcrypto/threads/mttest.c b/src/lib/libcrypto/threads/mttest.c
new file mode 100644
index 0000000000..f6f3df4b6a
--- /dev/null
+++ b/src/lib/libcrypto/threads/mttest.c
@@ -0,0 +1,1211 @@
1/* crypto/threads/mttest.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include <stdlib.h>
61#include <string.h>
62#include <errno.h>
63#ifdef LINUX
64#include <typedefs.h>
65#endif
66#ifdef OPENSSL_SYS_WIN32
67#include <windows.h>
68#endif
69#ifdef SOLARIS
70#include <synch.h>
71#include <thread.h>
72#endif
73#ifdef IRIX
74#include <ulocks.h>
75#include <sys/prctl.h>
76#endif
77#ifdef PTHREADS
78#include <pthread.h>
79#endif
80#ifdef OPENSSL_SYS_NETWARE
81#if !defined __int64
82# define __int64 long long
83#endif
84#include <nwmpk.h>
85#endif
86#include <openssl/lhash.h>
87#include <openssl/crypto.h>
88#include <openssl/buffer.h>
89#include "../../e_os.h"
90#include <openssl/x509.h>
91#include <openssl/ssl.h>
92#include <openssl/err.h>
93#include <openssl/rand.h>
94
95#ifdef OPENSSL_NO_FP_API
96#define APPS_WIN16
97#include "../buffer/bss_file.c"
98#endif
99
100#ifdef OPENSSL_SYS_NETWARE
101#define TEST_SERVER_CERT "/openssl/apps/server.pem"
102#define TEST_CLIENT_CERT "/openssl/apps/client.pem"
103#else
104#define TEST_SERVER_CERT "../../apps/server.pem"
105#define TEST_CLIENT_CERT "../../apps/client.pem"
106#endif
107
108#define MAX_THREAD_NUMBER 100
109
110int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *xs);
111void thread_setup(void);
112void thread_cleanup(void);
113void do_threads(SSL_CTX *s_ctx,SSL_CTX *c_ctx);
114
115void irix_locking_callback(int mode,int type,char *file,int line);
116void solaris_locking_callback(int mode,int type,char *file,int line);
117void win32_locking_callback(int mode,int type,char *file,int line);
118void pthreads_locking_callback(int mode,int type,char *file,int line);
119void netware_locking_callback(int mode,int type,char *file,int line);
120
121unsigned long irix_thread_id(void );
122unsigned long solaris_thread_id(void );
123unsigned long pthreads_thread_id(void );
124unsigned long netware_thread_id(void );
125
126#if defined(OPENSSL_SYS_NETWARE)
127static MPKMutex *lock_cs;
128static MPKSema ThreadSem;
129static long *lock_count;
130#endif
131
132BIO *bio_err=NULL;
133BIO *bio_stdout=NULL;
134
135static char *cipher=NULL;
136int verbose=0;
137#ifdef FIONBIO
138static int s_nbio=0;
139#endif
140
141int thread_number=10;
142int number_of_loops=10;
143int reconnect=0;
144int cache_stats=0;
145
146static const char rnd_seed[] = "string to make the random number generator think it has entropy";
147
148int doit(char *ctx[4]);
149static void print_stats(FILE *fp, SSL_CTX *ctx)
150{
151 fprintf(fp,"%4ld items in the session cache\n",
152 SSL_CTX_sess_number(ctx));
153 fprintf(fp,"%4d client connects (SSL_connect())\n",
154 SSL_CTX_sess_connect(ctx));
155 fprintf(fp,"%4d client connects that finished\n",
156 SSL_CTX_sess_connect_good(ctx));
157 fprintf(fp,"%4d server connects (SSL_accept())\n",
158 SSL_CTX_sess_accept(ctx));
159 fprintf(fp,"%4d server connects that finished\n",
160 SSL_CTX_sess_accept_good(ctx));
161 fprintf(fp,"%4d session cache hits\n",SSL_CTX_sess_hits(ctx));
162 fprintf(fp,"%4d session cache misses\n",SSL_CTX_sess_misses(ctx));
163 fprintf(fp,"%4d session cache timeouts\n",SSL_CTX_sess_timeouts(ctx));
164 }
165
166static void sv_usage(void)
167 {
168 fprintf(stderr,"usage: ssltest [args ...]\n");
169 fprintf(stderr,"\n");
170 fprintf(stderr," -server_auth - check server certificate\n");
171 fprintf(stderr," -client_auth - do client authentication\n");
172 fprintf(stderr," -v - more output\n");
173 fprintf(stderr," -CApath arg - PEM format directory of CA's\n");
174 fprintf(stderr," -CAfile arg - PEM format file of CA's\n");
175 fprintf(stderr," -threads arg - number of threads\n");
176 fprintf(stderr," -loops arg - number of 'connections', per thread\n");
177 fprintf(stderr," -reconnect - reuse session-id's\n");
178 fprintf(stderr," -stats - server session-id cache stats\n");
179 fprintf(stderr," -cert arg - server certificate/key\n");
180 fprintf(stderr," -ccert arg - client certificate/key\n");
181 fprintf(stderr," -ssl3 - just SSLv3n\n");
182 }
183
184int main(int argc, char *argv[])
185 {
186 char *CApath=NULL,*CAfile=NULL;
187 int badop=0;
188 int ret=1;
189 int client_auth=0;
190 int server_auth=0;
191 SSL_CTX *s_ctx=NULL;
192 SSL_CTX *c_ctx=NULL;
193 char *scert=TEST_SERVER_CERT;
194 char *ccert=TEST_CLIENT_CERT;
195 SSL_METHOD *ssl_method=SSLv23_method();
196
197 RAND_seed(rnd_seed, sizeof rnd_seed);
198
199 if (bio_err == NULL)
200 bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
201 if (bio_stdout == NULL)
202 bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE);
203 argc--;
204 argv++;
205
206 while (argc >= 1)
207 {
208 if (strcmp(*argv,"-server_auth") == 0)
209 server_auth=1;
210 else if (strcmp(*argv,"-client_auth") == 0)
211 client_auth=1;
212 else if (strcmp(*argv,"-reconnect") == 0)
213 reconnect=1;
214 else if (strcmp(*argv,"-stats") == 0)
215 cache_stats=1;
216 else if (strcmp(*argv,"-ssl3") == 0)
217 ssl_method=SSLv3_method();
218 else if (strcmp(*argv,"-ssl2") == 0)
219 ssl_method=SSLv2_method();
220 else if (strcmp(*argv,"-CApath") == 0)
221 {
222 if (--argc < 1) goto bad;
223 CApath= *(++argv);
224 }
225 else if (strcmp(*argv,"-CAfile") == 0)
226 {
227 if (--argc < 1) goto bad;
228 CAfile= *(++argv);
229 }
230 else if (strcmp(*argv,"-cert") == 0)
231 {
232 if (--argc < 1) goto bad;
233 scert= *(++argv);
234 }
235 else if (strcmp(*argv,"-ccert") == 0)
236 {
237 if (--argc < 1) goto bad;
238 ccert= *(++argv);
239 }
240 else if (strcmp(*argv,"-threads") == 0)
241 {
242 if (--argc < 1) goto bad;
243 thread_number= atoi(*(++argv));
244 if (thread_number == 0) thread_number=1;
245 if (thread_number > MAX_THREAD_NUMBER)
246 thread_number=MAX_THREAD_NUMBER;
247 }
248 else if (strcmp(*argv,"-loops") == 0)
249 {
250 if (--argc < 1) goto bad;
251 number_of_loops= atoi(*(++argv));
252 if (number_of_loops == 0) number_of_loops=1;
253 }
254 else
255 {
256 fprintf(stderr,"unknown option %s\n",*argv);
257 badop=1;
258 break;
259 }
260 argc--;
261 argv++;
262 }
263 if (badop)
264 {
265bad:
266 sv_usage();
267 goto end;
268 }
269
270 if (cipher == NULL && OPENSSL_issetugid() == 0)
271 cipher=getenv("SSL_CIPHER");
272
273 SSL_load_error_strings();
274 OpenSSL_add_ssl_algorithms();
275
276 c_ctx=SSL_CTX_new(ssl_method);
277 s_ctx=SSL_CTX_new(ssl_method);
278 if ((c_ctx == NULL) || (s_ctx == NULL))
279 {
280 ERR_print_errors(bio_err);
281 goto end;
282 }
283
284 SSL_CTX_set_session_cache_mode(s_ctx,
285 SSL_SESS_CACHE_NO_AUTO_CLEAR|SSL_SESS_CACHE_SERVER);
286 SSL_CTX_set_session_cache_mode(c_ctx,
287 SSL_SESS_CACHE_NO_AUTO_CLEAR|SSL_SESS_CACHE_SERVER);
288
289 if (!SSL_CTX_use_certificate_file(s_ctx,scert,SSL_FILETYPE_PEM))
290 {
291 ERR_print_errors(bio_err);
292 }
293 else if (!SSL_CTX_use_RSAPrivateKey_file(s_ctx,scert,SSL_FILETYPE_PEM))
294 {
295 ERR_print_errors(bio_err);
296 goto end;
297 }
298
299 if (client_auth)
300 {
301 SSL_CTX_use_certificate_file(c_ctx,ccert,
302 SSL_FILETYPE_PEM);
303 SSL_CTX_use_RSAPrivateKey_file(c_ctx,ccert,
304 SSL_FILETYPE_PEM);
305 }
306
307 if ( (!SSL_CTX_load_verify_locations(s_ctx,CAfile,CApath)) ||
308 (!SSL_CTX_set_default_verify_paths(s_ctx)) ||
309 (!SSL_CTX_load_verify_locations(c_ctx,CAfile,CApath)) ||
310 (!SSL_CTX_set_default_verify_paths(c_ctx)))
311 {
312 fprintf(stderr,"SSL_load_verify_locations\n");
313 ERR_print_errors(bio_err);
314 goto end;
315 }
316
317 if (client_auth)
318 {
319 fprintf(stderr,"client authentication\n");
320 SSL_CTX_set_verify(s_ctx,
321 SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
322 verify_callback);
323 }
324 if (server_auth)
325 {
326 fprintf(stderr,"server authentication\n");
327 SSL_CTX_set_verify(c_ctx,SSL_VERIFY_PEER,
328 verify_callback);
329 }
330
331 thread_setup();
332 do_threads(s_ctx,c_ctx);
333 thread_cleanup();
334end:
335
336 if (c_ctx != NULL)
337 {
338 fprintf(stderr,"Client SSL_CTX stats then free it\n");
339 print_stats(stderr,c_ctx);
340 SSL_CTX_free(c_ctx);
341 }
342 if (s_ctx != NULL)
343 {
344 fprintf(stderr,"Server SSL_CTX stats then free it\n");
345 print_stats(stderr,s_ctx);
346 if (cache_stats)
347 {
348 fprintf(stderr,"-----\n");
349 lh_stats(SSL_CTX_sessions(s_ctx),stderr);
350 fprintf(stderr,"-----\n");
351 /* lh_node_stats(SSL_CTX_sessions(s_ctx),stderr);
352 fprintf(stderr,"-----\n"); */
353 lh_node_usage_stats(SSL_CTX_sessions(s_ctx),stderr);
354 fprintf(stderr,"-----\n");
355 }
356 SSL_CTX_free(s_ctx);
357 fprintf(stderr,"done free\n");
358 }
359 exit(ret);
360 return(0);
361 }
362
363#define W_READ 1
364#define W_WRITE 2
365#define C_DONE 1
366#define S_DONE 2
367
368int ndoit(SSL_CTX *ssl_ctx[2])
369 {
370 int i;
371 int ret;
372 char *ctx[4];
373
374 ctx[0]=(char *)ssl_ctx[0];
375 ctx[1]=(char *)ssl_ctx[1];
376
377 if (reconnect)
378 {
379 ctx[2]=(char *)SSL_new(ssl_ctx[0]);
380 ctx[3]=(char *)SSL_new(ssl_ctx[1]);
381 }
382 else
383 {
384 ctx[2]=NULL;
385 ctx[3]=NULL;
386 }
387
388 fprintf(stdout,"started thread %lu\n",CRYPTO_thread_id());
389 for (i=0; i<number_of_loops; i++)
390 {
391/* fprintf(stderr,"%4d %2d ctx->ref (%3d,%3d)\n",
392 CRYPTO_thread_id(),i,
393 ssl_ctx[0]->references,
394 ssl_ctx[1]->references); */
395 /* pthread_delay_np(&tm);*/
396
397 ret=doit(ctx);
398 if (ret != 0)
399 {
400 fprintf(stdout,"error[%d] %lu - %d\n",
401 i,CRYPTO_thread_id(),ret);
402 return(ret);
403 }
404 }
405 fprintf(stdout,"DONE %lu\n",CRYPTO_thread_id());
406 if (reconnect)
407 {
408 SSL_free((SSL *)ctx[2]);
409 SSL_free((SSL *)ctx[3]);
410 }
411# ifdef OPENSSL_SYS_NETWARE
412 MPKSemaphoreSignal(ThreadSem);
413# endif
414 return(0);
415 }
416
417int doit(char *ctx[4])
418 {
419 SSL_CTX *s_ctx,*c_ctx;
420 static char cbuf[200],sbuf[200];
421 SSL *c_ssl=NULL;
422 SSL *s_ssl=NULL;
423 BIO *c_to_s=NULL;
424 BIO *s_to_c=NULL;
425 BIO *c_bio=NULL;
426 BIO *s_bio=NULL;
427 int c_r,c_w,s_r,s_w;
428 int c_want,s_want;
429 int i;
430 int done=0;
431 int c_write,s_write;
432 int do_server=0,do_client=0;
433
434 s_ctx=(SSL_CTX *)ctx[0];
435 c_ctx=(SSL_CTX *)ctx[1];
436
437 if (ctx[2] != NULL)
438 s_ssl=(SSL *)ctx[2];
439 else
440 s_ssl=SSL_new(s_ctx);
441
442 if (ctx[3] != NULL)
443 c_ssl=(SSL *)ctx[3];
444 else
445 c_ssl=SSL_new(c_ctx);
446
447 if ((s_ssl == NULL) || (c_ssl == NULL)) goto err;
448
449 c_to_s=BIO_new(BIO_s_mem());
450 s_to_c=BIO_new(BIO_s_mem());
451 if ((s_to_c == NULL) || (c_to_s == NULL)) goto err;
452
453 c_bio=BIO_new(BIO_f_ssl());
454 s_bio=BIO_new(BIO_f_ssl());
455 if ((c_bio == NULL) || (s_bio == NULL)) goto err;
456
457 SSL_set_connect_state(c_ssl);
458 SSL_set_bio(c_ssl,s_to_c,c_to_s);
459 BIO_set_ssl(c_bio,c_ssl,(ctx[2] == NULL)?BIO_CLOSE:BIO_NOCLOSE);
460
461 SSL_set_accept_state(s_ssl);
462 SSL_set_bio(s_ssl,c_to_s,s_to_c);
463 BIO_set_ssl(s_bio,s_ssl,(ctx[3] == NULL)?BIO_CLOSE:BIO_NOCLOSE);
464
465 c_r=0; s_r=1;
466 c_w=1; s_w=0;
467 c_want=W_WRITE;
468 s_want=0;
469 c_write=1,s_write=0;
470
471 /* We can always do writes */
472 for (;;)
473 {
474 do_server=0;
475 do_client=0;
476
477 i=(int)BIO_pending(s_bio);
478 if ((i && s_r) || s_w) do_server=1;
479
480 i=(int)BIO_pending(c_bio);
481 if ((i && c_r) || c_w) do_client=1;
482
483 if (do_server && verbose)
484 {
485 if (SSL_in_init(s_ssl))
486 printf("server waiting in SSL_accept - %s\n",
487 SSL_state_string_long(s_ssl));
488 else if (s_write)
489 printf("server:SSL_write()\n");
490 else
491 printf("server:SSL_read()\n");
492 }
493
494 if (do_client && verbose)
495 {
496 if (SSL_in_init(c_ssl))
497 printf("client waiting in SSL_connect - %s\n",
498 SSL_state_string_long(c_ssl));
499 else if (c_write)
500 printf("client:SSL_write()\n");
501 else
502 printf("client:SSL_read()\n");
503 }
504
505 if (!do_client && !do_server)
506 {
507 fprintf(stdout,"ERROR IN STARTUP\n");
508 break;
509 }
510 if (do_client && !(done & C_DONE))
511 {
512 if (c_write)
513 {
514 i=BIO_write(c_bio,"hello from client\n",18);
515 if (i < 0)
516 {
517 c_r=0;
518 c_w=0;
519 if (BIO_should_retry(c_bio))
520 {
521 if (BIO_should_read(c_bio))
522 c_r=1;
523 if (BIO_should_write(c_bio))
524 c_w=1;
525 }
526 else
527 {
528 fprintf(stderr,"ERROR in CLIENT\n");
529 ERR_print_errors_fp(stderr);
530 return(1);
531 }
532 }
533 else if (i == 0)
534 {
535 fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
536 return(1);
537 }
538 else
539 {
540 /* ok */
541 c_write=0;
542 }
543 }
544 else
545 {
546 i=BIO_read(c_bio,cbuf,100);
547 if (i < 0)
548 {
549 c_r=0;
550 c_w=0;
551 if (BIO_should_retry(c_bio))
552 {
553 if (BIO_should_read(c_bio))
554 c_r=1;
555 if (BIO_should_write(c_bio))
556 c_w=1;
557 }
558 else
559 {
560 fprintf(stderr,"ERROR in CLIENT\n");
561 ERR_print_errors_fp(stderr);
562 return(1);
563 }
564 }
565 else if (i == 0)
566 {
567 fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
568 return(1);
569 }
570 else
571 {
572 done|=C_DONE;
573#ifdef undef
574 fprintf(stdout,"CLIENT:from server:");
575 fwrite(cbuf,1,i,stdout);
576 fflush(stdout);
577#endif
578 }
579 }
580 }
581
582 if (do_server && !(done & S_DONE))
583 {
584 if (!s_write)
585 {
586 i=BIO_read(s_bio,sbuf,100);
587 if (i < 0)
588 {
589 s_r=0;
590 s_w=0;
591 if (BIO_should_retry(s_bio))
592 {
593 if (BIO_should_read(s_bio))
594 s_r=1;
595 if (BIO_should_write(s_bio))
596 s_w=1;
597 }
598 else
599 {
600 fprintf(stderr,"ERROR in SERVER\n");
601 ERR_print_errors_fp(stderr);
602 return(1);
603 }
604 }
605 else if (i == 0)
606 {
607 fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
608 return(1);
609 }
610 else
611 {
612 s_write=1;
613 s_w=1;
614#ifdef undef
615 fprintf(stdout,"SERVER:from client:");
616 fwrite(sbuf,1,i,stdout);
617 fflush(stdout);
618#endif
619 }
620 }
621 else
622 {
623 i=BIO_write(s_bio,"hello from server\n",18);
624 if (i < 0)
625 {
626 s_r=0;
627 s_w=0;
628 if (BIO_should_retry(s_bio))
629 {
630 if (BIO_should_read(s_bio))
631 s_r=1;
632 if (BIO_should_write(s_bio))
633 s_w=1;
634 }
635 else
636 {
637 fprintf(stderr,"ERROR in SERVER\n");
638 ERR_print_errors_fp(stderr);
639 return(1);
640 }
641 }
642 else if (i == 0)
643 {
644 fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
645 return(1);
646 }
647 else
648 {
649 s_write=0;
650 s_r=1;
651 done|=S_DONE;
652 }
653 }
654 }
655
656 if ((done & S_DONE) && (done & C_DONE)) break;
657# if defined(OPENSSL_SYS_NETWARE)
658 ThreadSwitchWithDelay();
659# endif
660 }
661
662 SSL_set_shutdown(c_ssl,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
663 SSL_set_shutdown(s_ssl,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
664
665#ifdef undef
666 fprintf(stdout,"DONE\n");
667#endif
668err:
669 /* We have to set the BIO's to NULL otherwise they will be
670 * free()ed twice. Once when th s_ssl is SSL_free()ed and
671 * again when c_ssl is SSL_free()ed.
672 * This is a hack required because s_ssl and c_ssl are sharing the same
673 * BIO structure and SSL_set_bio() and SSL_free() automatically
674 * BIO_free non NULL entries.
675 * You should not normally do this or be required to do this */
676
677 if (s_ssl != NULL)
678 {
679 s_ssl->rbio=NULL;
680 s_ssl->wbio=NULL;
681 }
682 if (c_ssl != NULL)
683 {
684 c_ssl->rbio=NULL;
685 c_ssl->wbio=NULL;
686 }
687
688 /* The SSL's are optionally freed in the following calls */
689 if (c_to_s != NULL) BIO_free(c_to_s);
690 if (s_to_c != NULL) BIO_free(s_to_c);
691
692 if (c_bio != NULL) BIO_free(c_bio);
693 if (s_bio != NULL) BIO_free(s_bio);
694 return(0);
695 }
696
697int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
698 {
699 char *s, buf[256];
700
701 if (verbose)
702 {
703 s=X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),
704 buf,256);
705 if (s != NULL)
706 {
707 if (ok)
708 fprintf(stderr,"depth=%d %s\n",
709 ctx->error_depth,buf);
710 else
711 fprintf(stderr,"depth=%d error=%d %s\n",
712 ctx->error_depth,ctx->error,buf);
713 }
714 }
715 return(ok);
716 }
717
718#define THREAD_STACK_SIZE (16*1024)
719
720#ifdef OPENSSL_SYS_WIN32
721
722static HANDLE *lock_cs;
723
724void thread_setup(void)
725 {
726 int i;
727
728 lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE));
729 for (i=0; i<CRYPTO_num_locks(); i++)
730 {
731 lock_cs[i]=CreateMutex(NULL,FALSE,NULL);
732 }
733
734 CRYPTO_set_locking_callback((void (*)(int,int,char *,int))win32_locking_callback);
735 /* id callback defined */
736 }
737
738void thread_cleanup(void)
739 {
740 int i;
741
742 CRYPTO_set_locking_callback(NULL);
743 for (i=0; i<CRYPTO_num_locks(); i++)
744 CloseHandle(lock_cs[i]);
745 OPENSSL_free(lock_cs);
746 }
747
748void win32_locking_callback(int mode, int type, char *file, int line)
749 {
750 if (mode & CRYPTO_LOCK)
751 {
752 WaitForSingleObject(lock_cs[type],INFINITE);
753 }
754 else
755 {
756 ReleaseMutex(lock_cs[type]);
757 }
758 }
759
760void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
761 {
762 double ret;
763 SSL_CTX *ssl_ctx[2];
764 DWORD thread_id[MAX_THREAD_NUMBER];
765 HANDLE thread_handle[MAX_THREAD_NUMBER];
766 int i;
767 SYSTEMTIME start,end;
768
769 ssl_ctx[0]=s_ctx;
770 ssl_ctx[1]=c_ctx;
771
772 GetSystemTime(&start);
773 for (i=0; i<thread_number; i++)
774 {
775 thread_handle[i]=CreateThread(NULL,
776 THREAD_STACK_SIZE,
777 (LPTHREAD_START_ROUTINE)ndoit,
778 (void *)ssl_ctx,
779 0L,
780 &(thread_id[i]));
781 }
782
783 printf("reaping\n");
784 for (i=0; i<thread_number; i+=50)
785 {
786 int j;
787
788 j=(thread_number < (i+50))?(thread_number-i):50;
789
790 if (WaitForMultipleObjects(j,
791 (CONST HANDLE *)&(thread_handle[i]),TRUE,INFINITE)
792 == WAIT_FAILED)
793 {
794 fprintf(stderr,"WaitForMultipleObjects failed:%d\n",GetLastError());
795 exit(1);
796 }
797 }
798 GetSystemTime(&end);
799
800 if (start.wDayOfWeek > end.wDayOfWeek) end.wDayOfWeek+=7;
801 ret=(end.wDayOfWeek-start.wDayOfWeek)*24;
802
803 ret=(ret+end.wHour-start.wHour)*60;
804 ret=(ret+end.wMinute-start.wMinute)*60;
805 ret=(ret+end.wSecond-start.wSecond);
806 ret+=(end.wMilliseconds-start.wMilliseconds)/1000.0;
807
808 printf("win32 threads done - %.3f seconds\n",ret);
809 }
810
811#endif /* OPENSSL_SYS_WIN32 */
812
813#ifdef SOLARIS
814
815static mutex_t *lock_cs;
816/*static rwlock_t *lock_cs; */
817static long *lock_count;
818
819void thread_setup(void)
820 {
821 int i;
822
823 lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(mutex_t));
824 lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
825 for (i=0; i<CRYPTO_num_locks(); i++)
826 {
827 lock_count[i]=0;
828 /* rwlock_init(&(lock_cs[i]),USYNC_THREAD,NULL); */
829 mutex_init(&(lock_cs[i]),USYNC_THREAD,NULL);
830 }
831
832 CRYPTO_set_id_callback((unsigned long (*)())solaris_thread_id);
833 CRYPTO_set_locking_callback((void (*)())solaris_locking_callback);
834 }
835
836void thread_cleanup(void)
837 {
838 int i;
839
840 CRYPTO_set_locking_callback(NULL);
841
842 fprintf(stderr,"cleanup\n");
843
844 for (i=0; i<CRYPTO_num_locks(); i++)
845 {
846 /* rwlock_destroy(&(lock_cs[i])); */
847 mutex_destroy(&(lock_cs[i]));
848 fprintf(stderr,"%8ld:%s\n",lock_count[i],CRYPTO_get_lock_name(i));
849 }
850 OPENSSL_free(lock_cs);
851 OPENSSL_free(lock_count);
852
853 fprintf(stderr,"done cleanup\n");
854
855 }
856
857void solaris_locking_callback(int mode, int type, char *file, int line)
858 {
859#ifdef undef
860 fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
861 CRYPTO_thread_id(),
862 (mode&CRYPTO_LOCK)?"l":"u",
863 (type&CRYPTO_READ)?"r":"w",file,line);
864#endif
865
866 /*
867 if (CRYPTO_LOCK_SSL_CERT == type)
868 fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
869 CRYPTO_thread_id(),
870 mode,file,line);
871 */
872 if (mode & CRYPTO_LOCK)
873 {
874 /* if (mode & CRYPTO_READ)
875 rw_rdlock(&(lock_cs[type]));
876 else
877 rw_wrlock(&(lock_cs[type])); */
878
879 mutex_lock(&(lock_cs[type]));
880 lock_count[type]++;
881 }
882 else
883 {
884/* rw_unlock(&(lock_cs[type])); */
885 mutex_unlock(&(lock_cs[type]));
886 }
887 }
888
889void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
890 {
891 SSL_CTX *ssl_ctx[2];
892 thread_t thread_ctx[MAX_THREAD_NUMBER];
893 int i;
894
895 ssl_ctx[0]=s_ctx;
896 ssl_ctx[1]=c_ctx;
897
898 thr_setconcurrency(thread_number);
899 for (i=0; i<thread_number; i++)
900 {
901 thr_create(NULL, THREAD_STACK_SIZE,
902 (void *(*)())ndoit,
903 (void *)ssl_ctx,
904 0L,
905 &(thread_ctx[i]));
906 }
907
908 printf("reaping\n");
909 for (i=0; i<thread_number; i++)
910 {
911 thr_join(thread_ctx[i],NULL,NULL);
912 }
913
914 printf("solaris threads done (%d,%d)\n",
915 s_ctx->references,c_ctx->references);
916 }
917
918unsigned long solaris_thread_id(void)
919 {
920 unsigned long ret;
921
922 ret=(unsigned long)thr_self();
923 return(ret);
924 }
925#endif /* SOLARIS */
926
927#ifdef IRIX
928
929
930static usptr_t *arena;
931static usema_t **lock_cs;
932
933void thread_setup(void)
934 {
935 int i;
936 char filename[20];
937
938 strcpy(filename,"/tmp/mttest.XXXXXX");
939 mktemp(filename);
940
941 usconfig(CONF_STHREADIOOFF);
942 usconfig(CONF_STHREADMALLOCOFF);
943 usconfig(CONF_INITUSERS,100);
944 usconfig(CONF_LOCKTYPE,US_DEBUGPLUS);
945 arena=usinit(filename);
946 unlink(filename);
947
948 lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(usema_t *));
949 for (i=0; i<CRYPTO_num_locks(); i++)
950 {
951 lock_cs[i]=usnewsema(arena,1);
952 }
953
954 CRYPTO_set_id_callback((unsigned long (*)())irix_thread_id);
955 CRYPTO_set_locking_callback((void (*)())irix_locking_callback);
956 }
957
958void thread_cleanup(void)
959 {
960 int i;
961
962 CRYPTO_set_locking_callback(NULL);
963 for (i=0; i<CRYPTO_num_locks(); i++)
964 {
965 char buf[10];
966
967 sprintf(buf,"%2d:",i);
968 usdumpsema(lock_cs[i],stdout,buf);
969 usfreesema(lock_cs[i],arena);
970 }
971 OPENSSL_free(lock_cs);
972 }
973
974void irix_locking_callback(int mode, int type, char *file, int line)
975 {
976 if (mode & CRYPTO_LOCK)
977 {
978 printf("lock %d\n",type);
979 uspsema(lock_cs[type]);
980 }
981 else
982 {
983 printf("unlock %d\n",type);
984 usvsema(lock_cs[type]);
985 }
986 }
987
988void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
989 {
990 SSL_CTX *ssl_ctx[2];
991 int thread_ctx[MAX_THREAD_NUMBER];
992 int i;
993
994 ssl_ctx[0]=s_ctx;
995 ssl_ctx[1]=c_ctx;
996
997 for (i=0; i<thread_number; i++)
998 {
999 thread_ctx[i]=sproc((void (*)())ndoit,
1000 PR_SADDR|PR_SFDS,(void *)ssl_ctx);
1001 }
1002
1003 printf("reaping\n");
1004 for (i=0; i<thread_number; i++)
1005 {
1006 wait(NULL);
1007 }
1008
1009 printf("irix threads done (%d,%d)\n",
1010 s_ctx->references,c_ctx->references);
1011 }
1012
1013unsigned long irix_thread_id(void)
1014 {
1015 unsigned long ret;
1016
1017 ret=(unsigned long)getpid();
1018 return(ret);
1019 }
1020#endif /* IRIX */
1021
1022#ifdef PTHREADS
1023
1024static pthread_mutex_t *lock_cs;
1025static long *lock_count;
1026
1027void thread_setup(void)
1028 {
1029 int i;
1030
1031 lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
1032 lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
1033 for (i=0; i<CRYPTO_num_locks(); i++)
1034 {
1035 lock_count[i]=0;
1036 pthread_mutex_init(&(lock_cs[i]),NULL);
1037 }
1038
1039 CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
1040 CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
1041 }
1042
1043void thread_cleanup(void)
1044 {
1045 int i;
1046
1047 CRYPTO_set_locking_callback(NULL);
1048 fprintf(stderr,"cleanup\n");
1049 for (i=0; i<CRYPTO_num_locks(); i++)
1050 {
1051 pthread_mutex_destroy(&(lock_cs[i]));
1052 fprintf(stderr,"%8ld:%s\n",lock_count[i],
1053 CRYPTO_get_lock_name(i));
1054 }
1055 OPENSSL_free(lock_cs);
1056 OPENSSL_free(lock_count);
1057
1058 fprintf(stderr,"done cleanup\n");
1059 }
1060
1061void pthreads_locking_callback(int mode, int type, char *file,
1062 int line)
1063 {
1064#ifdef undef
1065 fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
1066 CRYPTO_thread_id(),
1067 (mode&CRYPTO_LOCK)?"l":"u",
1068 (type&CRYPTO_READ)?"r":"w",file,line);
1069#endif
1070/*
1071 if (CRYPTO_LOCK_SSL_CERT == type)
1072 fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
1073 CRYPTO_thread_id(),
1074 mode,file,line);
1075*/
1076 if (mode & CRYPTO_LOCK)
1077 {
1078 pthread_mutex_lock(&(lock_cs[type]));
1079 lock_count[type]++;
1080 }
1081 else
1082 {
1083 pthread_mutex_unlock(&(lock_cs[type]));
1084 }
1085 }
1086
1087void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
1088 {
1089 SSL_CTX *ssl_ctx[2];
1090 pthread_t thread_ctx[MAX_THREAD_NUMBER];
1091 int i;
1092
1093 ssl_ctx[0]=s_ctx;
1094 ssl_ctx[1]=c_ctx;
1095
1096 /*
1097 thr_setconcurrency(thread_number);
1098 */
1099 for (i=0; i<thread_number; i++)
1100 {
1101 pthread_create(&(thread_ctx[i]), NULL,
1102 (void *(*)())ndoit, (void *)ssl_ctx);
1103 }
1104
1105 printf("reaping\n");
1106 for (i=0; i<thread_number; i++)
1107 {
1108 pthread_join(thread_ctx[i],NULL);
1109 }
1110
1111 printf("pthreads threads done (%d,%d)\n",
1112 s_ctx->references,c_ctx->references);
1113 }
1114
1115unsigned long pthreads_thread_id(void)
1116 {
1117 unsigned long ret;
1118
1119 ret=(unsigned long)pthread_self();
1120 return(ret);
1121 }
1122
1123#endif /* PTHREADS */
1124
1125
1126
1127#ifdef OPENSSL_SYS_NETWARE
1128
1129void thread_setup(void)
1130{
1131 int i;
1132
1133 lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(MPKMutex));
1134 lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
1135 for (i=0; i<CRYPTO_num_locks(); i++)
1136 {
1137 lock_count[i]=0;
1138 lock_cs[i]=MPKMutexAlloc("OpenSSL mutex");
1139 }
1140
1141 ThreadSem = MPKSemaphoreAlloc("OpenSSL mttest semaphore", 0 );
1142
1143 CRYPTO_set_id_callback((unsigned long (*)())netware_thread_id);
1144 CRYPTO_set_locking_callback((void (*)())netware_locking_callback);
1145}
1146
1147void thread_cleanup(void)
1148{
1149 int i;
1150
1151 CRYPTO_set_locking_callback(NULL);
1152
1153 fprintf(stdout,"thread_cleanup\n");
1154
1155 for (i=0; i<CRYPTO_num_locks(); i++)
1156 {
1157 MPKMutexFree(lock_cs[i]);
1158 fprintf(stdout,"%8ld:%s\n",lock_count[i],CRYPTO_get_lock_name(i));
1159 }
1160 OPENSSL_free(lock_cs);
1161 OPENSSL_free(lock_count);
1162
1163 MPKSemaphoreFree(ThreadSem);
1164
1165 fprintf(stdout,"done cleanup\n");
1166}
1167
1168void netware_locking_callback(int mode, int type, char *file, int line)
1169{
1170 if (mode & CRYPTO_LOCK)
1171 {
1172 MPKMutexLock(lock_cs[type]);
1173 lock_count[type]++;
1174 }
1175 else
1176 MPKMutexUnlock(lock_cs[type]);
1177}
1178
1179void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
1180{
1181 SSL_CTX *ssl_ctx[2];
1182 int i;
1183 ssl_ctx[0]=s_ctx;
1184 ssl_ctx[1]=c_ctx;
1185
1186 for (i=0; i<thread_number; i++)
1187 {
1188 BeginThread( (void(*)(void*))ndoit, NULL, THREAD_STACK_SIZE,
1189 (void*)ssl_ctx);
1190 ThreadSwitchWithDelay();
1191 }
1192
1193 printf("reaping\n");
1194
1195 /* loop until all threads have signaled the semaphore */
1196 for (i=0; i<thread_number; i++)
1197 {
1198 MPKSemaphoreWait(ThreadSem);
1199 }
1200 printf("netware threads done (%d,%d)\n",
1201 s_ctx->references,c_ctx->references);
1202}
1203
1204unsigned long netware_thread_id(void)
1205{
1206 unsigned long ret;
1207
1208 ret=(unsigned long)GetThreadID();
1209 return(ret);
1210}
1211#endif /* NETWARE */
diff --git a/src/lib/libcrypto/threads/netware.bat b/src/lib/libcrypto/threads/netware.bat
new file mode 100644
index 0000000000..0b3eca3caf
--- /dev/null
+++ b/src/lib/libcrypto/threads/netware.bat
@@ -0,0 +1,79 @@
1@echo off
2rem batch file to build multi-thread test ( mttest.nlm )
3
4rem command line arguments:
5rem debug => build using debug settings
6
7rem
8rem After building, copy mttest.nlm to the server and run it, you'll probably
9rem want to redirect stdout and stderr. An example command line would be
10rem "mttest.nlm -thread 20 -loops 10 -CAfile \openssl\apps\server.pem >mttest.out 2>mttest.err"
11rem
12
13del mttest.nlm
14
15set BLD_DEBUG=
16set CFLAGS=
17set LFLAGS=
18set LIBS=
19
20if "%1" == "DEBUG" set BLD_DEBUG=YES
21if "%1" == "debug" set BLD_DEBUG=YES
22
23if "%MWCIncludes%" == "" goto inc_error
24if "%PRELUDE%" == "" goto prelude_error
25if "%IMPORTS%" == "" goto imports_error
26
27set CFLAGS=-c -I..\..\outinc_nw -nosyspath -DOPENSSL_SYS_NETWARE -opt off -g -sym internal -maxerrors 20
28
29if "%BLD_DEBUG%" == "YES" set LIBS=..\..\out_nw.dbg\ssl.lib ..\..\out_nw.dbg\crypto.lib
30if "%BLD_DEBUG%" == "" set LIBS=..\..\out_nw\ssl.lib ..\..\out_nw\crypto.lib
31
32set LFLAGS=-msgstyle gcc -zerobss -stacksize 32768 -nostdlib -sym internal
33
34rem generate command file for metrowerks
35echo.
36echo Generating Metrowerks command file: mttest.def
37echo # dynamically generated command file for metrowerks build > mttest.def
38echo IMPORT @%IMPORTS%\clib.imp >> mttest.def
39echo IMPORT @%IMPORTS%\threads.imp >> mttest.def
40echo IMPORT @%IMPORTS%\ws2nlm.imp >> mttest.def
41echo IMPORT GetProcessSwitchCount >> mttest.def
42echo MODULE clib >> mttest.def
43
44rem compile
45echo.
46echo Compiling mttest.c
47mwccnlm.exe mttest.c %CFLAGS%
48if errorlevel 1 goto end
49
50rem link
51echo.
52echo Linking mttest.nlm
53mwldnlm.exe %LFLAGS% -screenname mttest -commandfile mttest.def mttest.o "%PRELUDE%" %LIBS% -o mttest.nlm
54if errorlevel 1 goto end
55
56goto end
57
58:inc_error
59echo.
60echo Environment variable MWCIncludes is not set - see install.nw
61goto end
62
63:prelude_error
64echo.
65echo Environment variable PRELUDE is not set - see install.nw
66goto end
67
68:imports_error
69echo.
70echo Environment variable IMPORTS is not set - see install.nw
71goto end
72
73
74:end
75set BLD_DEBUG=
76set CFLAGS=
77set LFLAGS=
78set LIBS=
79
diff --git a/src/lib/libcrypto/threads/profile.sh b/src/lib/libcrypto/threads/profile.sh
new file mode 100644
index 0000000000..6e3e342fc0
--- /dev/null
+++ b/src/lib/libcrypto/threads/profile.sh
@@ -0,0 +1,4 @@
1#!/bin/sh
2/bin/rm -f mttest
3cc -p -DSOLARIS -I../../include -g mttest.c -o mttest -L/usr/lib/libc -ldl -L../.. -lthread -lssl -lcrypto -lnsl -lsocket
4
diff --git a/src/lib/libcrypto/threads/ptest.bat b/src/lib/libcrypto/threads/ptest.bat
new file mode 100644
index 0000000000..4071b5ffea
--- /dev/null
+++ b/src/lib/libcrypto/threads/ptest.bat
@@ -0,0 +1,4 @@
1del mttest.exe
2
3purify cl /O2 -DWIN32 /MD -I..\..\out mttest.c /Femttest ..\..\out\ssl32.lib ..\..\out\crypt32.lib
4
diff --git a/src/lib/libcrypto/threads/pthread.sh b/src/lib/libcrypto/threads/pthread.sh
new file mode 100644
index 0000000000..f1c49821d2
--- /dev/null
+++ b/src/lib/libcrypto/threads/pthread.sh
@@ -0,0 +1,9 @@
1#!/bin/sh
2#
3# build using pthreads
4#
5# http://www.mit.edu:8001/people/proven/pthreads.html
6#
7/bin/rm -f mttest
8pgcc -DPTHREADS -I../../include -g mttest.c -o mttest -L../.. -lssl -lcrypto
9
diff --git a/src/lib/libcrypto/threads/pthread2.sh b/src/lib/libcrypto/threads/pthread2.sh
new file mode 100644
index 0000000000..41264c6a50
--- /dev/null
+++ b/src/lib/libcrypto/threads/pthread2.sh
@@ -0,0 +1,7 @@
1#!/bin/sh
2#
3# build using pthreads where it's already built into the system
4#
5/bin/rm -f mttest
6gcc -DPTHREADS -I../../include -g mttest.c -o mttest -L../.. -lssl -lcrypto -lpthread
7
diff --git a/src/lib/libcrypto/threads/pthreads-vms.com b/src/lib/libcrypto/threads/pthreads-vms.com
new file mode 100644
index 0000000000..63f5b8cc2e
--- /dev/null
+++ b/src/lib/libcrypto/threads/pthreads-vms.com
@@ -0,0 +1,9 @@
1$! To compile mttest on VMS.
2$!
3$! WARNING: only tested with DEC C so far.
4$
5$ arch := vax
6$ if f$getsyi("CPU") .ge. 128 then arch := axp
7$ define/user openssl [--.include.openssl]
8$ cc/def=PTHREADS mttest.c
9$ link mttest,[--.'arch'.exe.ssl]libssl/lib,[--.'arch'.exe.crypto]libcrypto/lib
diff --git a/src/lib/libcrypto/threads/purify.sh b/src/lib/libcrypto/threads/purify.sh
new file mode 100644
index 0000000000..6d44fe26b7
--- /dev/null
+++ b/src/lib/libcrypto/threads/purify.sh
@@ -0,0 +1,4 @@
1#!/bin/sh
2/bin/rm -f mttest
3purify cc -DSOLARIS -I../../include -g mttest.c -o mttest -L../.. -lthread -lssl -lcrypto -lnsl -lsocket
4
diff --git a/src/lib/libcrypto/threads/solaris.sh b/src/lib/libcrypto/threads/solaris.sh
new file mode 100644
index 0000000000..bc93094a27
--- /dev/null
+++ b/src/lib/libcrypto/threads/solaris.sh
@@ -0,0 +1,4 @@
1#!/bin/sh
2/bin/rm -f mttest
3cc -DSOLARIS -I../../include -g mttest.c -o mttest -L../.. -lthread -lssl -lcrypto -lnsl -lsocket
4
diff --git a/src/lib/libcrypto/threads/th-lock.c b/src/lib/libcrypto/threads/th-lock.c
new file mode 100644
index 0000000000..14aae5f912
--- /dev/null
+++ b/src/lib/libcrypto/threads/th-lock.c
@@ -0,0 +1,387 @@
1/* crypto/threads/th-lock.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include <stdlib.h>
61#include <string.h>
62#include <errno.h>
63#ifdef LINUX
64#include <typedefs.h>
65#endif
66#ifdef OPENSSL_SYS_WIN32
67#include <windows.h>
68#endif
69#ifdef SOLARIS
70#include <synch.h>
71#include <thread.h>
72#endif
73#ifdef IRIX
74#include <ulocks.h>
75#include <sys/prctl.h>
76#endif
77#ifdef PTHREADS
78#include <pthread.h>
79#endif
80#include <openssl/lhash.h>
81#include <openssl/crypto.h>
82#include <openssl/buffer.h>
83#include "../../e_os.h"
84#include <openssl/x509.h>
85#include <openssl/ssl.h>
86#include <openssl/err.h>
87
88void CRYPTO_thread_setup(void);
89void CRYPTO_thread_cleanup(void);
90
91static void irix_locking_callback(int mode,int type,char *file,int line);
92static void solaris_locking_callback(int mode,int type,char *file,int line);
93static void win32_locking_callback(int mode,int type,char *file,int line);
94static void pthreads_locking_callback(int mode,int type,char *file,int line);
95
96static unsigned long irix_thread_id(void );
97static unsigned long solaris_thread_id(void );
98static unsigned long pthreads_thread_id(void );
99
100/* usage:
101 * CRYPTO_thread_setup();
102 * application code
103 * CRYPTO_thread_cleanup();
104 */
105
106#define THREAD_STACK_SIZE (16*1024)
107
108#ifdef OPENSSL_SYS_WIN32
109
110static HANDLE *lock_cs;
111
112void CRYPTO_thread_setup(void)
113 {
114 int i;
115
116 lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE));
117 for (i=0; i<CRYPTO_num_locks(); i++)
118 {
119 lock_cs[i]=CreateMutex(NULL,FALSE,NULL);
120 }
121
122 CRYPTO_set_locking_callback((void (*)(int,int,char *,int))win32_locking_callback);
123 /* id callback defined */
124 return(1);
125 }
126
127static void CRYPTO_thread_cleanup(void)
128 {
129 int i;
130
131 CRYPTO_set_locking_callback(NULL);
132 for (i=0; i<CRYPTO_num_locks(); i++)
133 CloseHandle(lock_cs[i]);
134 OPENSSL_free(lock_cs);
135 }
136
137void win32_locking_callback(int mode, int type, char *file, int line)
138 {
139 if (mode & CRYPTO_LOCK)
140 {
141 WaitForSingleObject(lock_cs[type],INFINITE);
142 }
143 else
144 {
145 ReleaseMutex(lock_cs[type]);
146 }
147 }
148
149#endif /* OPENSSL_SYS_WIN32 */
150
151#ifdef SOLARIS
152
153#define USE_MUTEX
154
155#ifdef USE_MUTEX
156static mutex_t *lock_cs;
157#else
158static rwlock_t *lock_cs;
159#endif
160static long *lock_count;
161
162void CRYPTO_thread_setup(void)
163 {
164 int i;
165
166#ifdef USE_MUTEX
167 lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(mutex_t));
168#else
169 lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(rwlock_t));
170#endif
171 lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
172 for (i=0; i<CRYPTO_num_locks(); i++)
173 {
174 lock_count[i]=0;
175#ifdef USE_MUTEX
176 mutex_init(&(lock_cs[i]),USYNC_THREAD,NULL);
177#else
178 rwlock_init(&(lock_cs[i]),USYNC_THREAD,NULL);
179#endif
180 }
181
182 CRYPTO_set_id_callback((unsigned long (*)())solaris_thread_id);
183 CRYPTO_set_locking_callback((void (*)())solaris_locking_callback);
184 }
185
186void CRYPTO_thread_cleanup(void)
187 {
188 int i;
189
190 CRYPTO_set_locking_callback(NULL);
191 for (i=0; i<CRYPTO_num_locks(); i++)
192 {
193#ifdef USE_MUTEX
194 mutex_destroy(&(lock_cs[i]));
195#else
196 rwlock_destroy(&(lock_cs[i]));
197#endif
198 }
199 OPENSSL_free(lock_cs);
200 OPENSSL_free(lock_count);
201 }
202
203void solaris_locking_callback(int mode, int type, char *file, int line)
204 {
205#if 0
206 fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
207 CRYPTO_thread_id(),
208 (mode&CRYPTO_LOCK)?"l":"u",
209 (type&CRYPTO_READ)?"r":"w",file,line);
210#endif
211
212#if 0
213 if (CRYPTO_LOCK_SSL_CERT == type)
214 fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
215 CRYPTO_thread_id(),
216 mode,file,line);
217#endif
218 if (mode & CRYPTO_LOCK)
219 {
220#ifdef USE_MUTEX
221 mutex_lock(&(lock_cs[type]));
222#else
223 if (mode & CRYPTO_READ)
224 rw_rdlock(&(lock_cs[type]));
225 else
226 rw_wrlock(&(lock_cs[type]));
227#endif
228 lock_count[type]++;
229 }
230 else
231 {
232#ifdef USE_MUTEX
233 mutex_unlock(&(lock_cs[type]));
234#else
235 rw_unlock(&(lock_cs[type]));
236#endif
237 }
238 }
239
240unsigned long solaris_thread_id(void)
241 {
242 unsigned long ret;
243
244 ret=(unsigned long)thr_self();
245 return(ret);
246 }
247#endif /* SOLARIS */
248
249#ifdef IRIX
250/* I don't think this works..... */
251
252static usptr_t *arena;
253static usema_t **lock_cs;
254
255void CRYPTO_thread_setup(void)
256 {
257 int i;
258 char filename[20];
259
260 strcpy(filename,"/tmp/mttest.XXXXXX");
261 mktemp(filename);
262
263 usconfig(CONF_STHREADIOOFF);
264 usconfig(CONF_STHREADMALLOCOFF);
265 usconfig(CONF_INITUSERS,100);
266 usconfig(CONF_LOCKTYPE,US_DEBUGPLUS);
267 arena=usinit(filename);
268 unlink(filename);
269
270 lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(usema_t *));
271 for (i=0; i<CRYPTO_num_locks(); i++)
272 {
273 lock_cs[i]=usnewsema(arena,1);
274 }
275
276 CRYPTO_set_id_callback((unsigned long (*)())irix_thread_id);
277 CRYPTO_set_locking_callback((void (*)())irix_locking_callback);
278 }
279
280void CRYPTO_thread_cleanup(void)
281 {
282 int i;
283
284 CRYPTO_set_locking_callback(NULL);
285 for (i=0; i<CRYPTO_num_locks(); i++)
286 {
287 char buf[10];
288
289 sprintf(buf,"%2d:",i);
290 usdumpsema(lock_cs[i],stdout,buf);
291 usfreesema(lock_cs[i],arena);
292 }
293 OPENSSL_free(lock_cs);
294 }
295
296void irix_locking_callback(int mode, int type, char *file, int line)
297 {
298 if (mode & CRYPTO_LOCK)
299 {
300 uspsema(lock_cs[type]);
301 }
302 else
303 {
304 usvsema(lock_cs[type]);
305 }
306 }
307
308unsigned long irix_thread_id(void)
309 {
310 unsigned long ret;
311
312 ret=(unsigned long)getpid();
313 return(ret);
314 }
315#endif /* IRIX */
316
317/* Linux and a few others */
318#ifdef PTHREADS
319
320static pthread_mutex_t *lock_cs;
321static long *lock_count;
322
323void CRYPTO_thread_setup(void)
324 {
325 int i;
326
327 lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
328 lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
329 for (i=0; i<CRYPTO_num_locks(); i++)
330 {
331 lock_count[i]=0;
332 pthread_mutex_init(&(lock_cs[i]),NULL);
333 }
334
335 CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
336 CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
337 }
338
339void thread_cleanup(void)
340 {
341 int i;
342
343 CRYPTO_set_locking_callback(NULL);
344 for (i=0; i<CRYPTO_num_locks(); i++)
345 {
346 pthread_mutex_destroy(&(lock_cs[i]));
347 }
348 OPENSSL_free(lock_cs);
349 OPENSSL_free(lock_count);
350 }
351
352void pthreads_locking_callback(int mode, int type, char *file,
353 int line)
354 {
355#if 0
356 fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
357 CRYPTO_thread_id(),
358 (mode&CRYPTO_LOCK)?"l":"u",
359 (type&CRYPTO_READ)?"r":"w",file,line);
360#endif
361#if 0
362 if (CRYPTO_LOCK_SSL_CERT == type)
363 fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
364 CRYPTO_thread_id(),
365 mode,file,line);
366#endif
367 if (mode & CRYPTO_LOCK)
368 {
369 pthread_mutex_lock(&(lock_cs[type]));
370 lock_count[type]++;
371 }
372 else
373 {
374 pthread_mutex_unlock(&(lock_cs[type]));
375 }
376 }
377
378unsigned long pthreads_thread_id(void)
379 {
380 unsigned long ret;
381
382 ret=(unsigned long)pthread_self();
383 return(ret);
384 }
385
386#endif /* PTHREADS */
387
diff --git a/src/lib/libcrypto/threads/win32.bat b/src/lib/libcrypto/threads/win32.bat
new file mode 100644
index 0000000000..ee6da80a07
--- /dev/null
+++ b/src/lib/libcrypto/threads/win32.bat
@@ -0,0 +1,4 @@
1del mttest.exe
2
3cl /O2 -DWIN32 /MD -I..\..\out mttest.c /Femttest ..\..\out\ssleay32.lib ..\..\out\libeay32.lib
4