]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/threads/mttest.c
Import of old SSLeay release: SSLeay 0.9.0b
[thirdparty/openssl.git] / crypto / threads / mttest.c
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 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 #include "lhash.h"
78 #include "crypto.h"
79 #include "buffer.h"
80 #include "../e_os.h"
81 #include "x509.h"
82 #include "ssl.h"
83 #include "err.h"
84
85 #ifdef NO_FP_API
86 #define APPS_WIN16
87 #include "../crypto/buffer/bss_file.c"
88 #endif
89
90 #define TEST_SERVER_CERT "../apps/server.pem"
91 #define TEST_CLIENT_CERT "../apps/client.pem"
92
93 #define MAX_THREAD_NUMBER 100
94
95 #ifndef NOPROTO
96 int MS_CALLBACK verify_callback(int ok, X509 *xs, X509 *xi, int depth,
97 int error,char *arg);
98 void thread_setup(void);
99 void thread_cleanup(void);
100 void do_threads(SSL_CTX *s_ctx,SSL_CTX *c_ctx);
101
102 void irix_locking_callback(int mode,int type,char *file,int line);
103 void solaris_locking_callback(int mode,int type,char *file,int line);
104 void win32_locking_callback(int mode,int type,char *file,int line);
105 void pthreads_locking_callback(int mode,int type,char *file,int line);
106
107 unsigned long irix_thread_id(void );
108 unsigned long solaris_thread_id(void );
109 unsigned long pthreads_thread_id(void );
110
111 #else
112 int MS_CALLBACK verify_callback();
113 void thread_setup();
114 void thread_cleanup();
115 void do_threads();
116
117 void irix_locking_callback();
118 void solaris_locking_callback();
119 void win32_locking_callback();
120 void pthreads_locking_callback();
121
122 unsigned long irix_thread_id();
123 unsigned long solaris_thread_id();
124 unsigned long pthreads_thread_id();
125
126 #endif
127
128 BIO *bio_err=NULL;
129 BIO *bio_stdout=NULL;
130
131 static char *cipher=NULL;
132 int verbose=0;
133 #ifdef FIONBIO
134 static int s_nbio=0;
135 #endif
136
137 int thread_number=10;
138 int number_of_loops=10;
139 int reconnect=0;
140 int cache_stats=0;
141
142 #ifndef NOPROTO
143 int doit(char *ctx[4]);
144 #else
145 int doit();
146 #endif
147
148 static void print_stats(fp,ctx)
149 FILE *fp;
150 SSL_CTX *ctx;
151 {
152 fprintf(fp,"%4ld items in the session cache\n",
153 SSL_CTX_sess_number(ctx));
154 fprintf(fp,"%4d client connects (SSL_connect())\n",
155 SSL_CTX_sess_connect(ctx));
156 fprintf(fp,"%4d client connects that finished\n",
157 SSL_CTX_sess_connect_good(ctx));
158 fprintf(fp,"%4d server connects (SSL_accept())\n",
159 SSL_CTX_sess_accept(ctx));
160 fprintf(fp,"%4d server connects that finished\n",
161 SSL_CTX_sess_accept_good(ctx));
162 fprintf(fp,"%4d session cache hits\n",SSL_CTX_sess_hits(ctx));
163 fprintf(fp,"%4d session cache misses\n",SSL_CTX_sess_misses(ctx));
164 fprintf(fp,"%4d session cache timeouts\n",SSL_CTX_sess_timeouts(ctx));
165 }
166
167 static void sv_usage()
168 {
169 fprintf(stderr,"usage: ssltest [args ...]\n");
170 fprintf(stderr,"\n");
171 fprintf(stderr," -server_auth - check server certificate\n");
172 fprintf(stderr," -client_auth - do client authentication\n");
173 fprintf(stderr," -v - more output\n");
174 fprintf(stderr," -CApath arg - PEM format directory of CA's\n");
175 fprintf(stderr," -CAfile arg - PEM format file of CA's\n");
176 fprintf(stderr," -threads arg - number of threads\n");
177 fprintf(stderr," -loops arg - number of 'connections', per thread\n");
178 fprintf(stderr," -reconnect - reuse session-id's\n");
179 fprintf(stderr," -stats - server session-id cache stats\n");
180 fprintf(stderr," -cert arg - server certificate/key\n");
181 fprintf(stderr," -ccert arg - client certificate/key\n");
182 fprintf(stderr," -ssl3 - just SSLv3n\n");
183 }
184
185 int main(argc, argv)
186 int argc;
187 char *argv[];
188 {
189 char *CApath=NULL,*CAfile=NULL;
190 int badop=0;
191 int ret=1;
192 int client_auth=0;
193 int server_auth=0;
194 SSL_CTX *s_ctx=NULL;
195 SSL_CTX *c_ctx=NULL;
196 char *scert=TEST_SERVER_CERT;
197 char *ccert=TEST_CLIENT_CERT;
198 SSL_METHOD *ssl_method=SSLv23_method();
199
200 if (bio_err == NULL)
201 bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
202 if (bio_stdout == NULL)
203 bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE);
204 argc--;
205 argv++;
206
207 while (argc >= 1)
208 {
209 if (strcmp(*argv,"-server_auth") == 0)
210 server_auth=1;
211 else if (strcmp(*argv,"-client_auth") == 0)
212 client_auth=1;
213 else if (strcmp(*argv,"-reconnect") == 0)
214 reconnect=1;
215 else if (strcmp(*argv,"-stats") == 0)
216 cache_stats=1;
217 else if (strcmp(*argv,"-ssl3") == 0)
218 ssl_method=SSLv3_method();
219 else if (strcmp(*argv,"-ssl2") == 0)
220 ssl_method=SSLv2_method();
221 else if (strcmp(*argv,"-CApath") == 0)
222 {
223 if (--argc < 1) goto bad;
224 CApath= *(++argv);
225 }
226 else if (strcmp(*argv,"-CAfile") == 0)
227 {
228 if (--argc < 1) goto bad;
229 CAfile= *(++argv);
230 }
231 else if (strcmp(*argv,"-cert") == 0)
232 {
233 if (--argc < 1) goto bad;
234 scert= *(++argv);
235 }
236 else if (strcmp(*argv,"-ccert") == 0)
237 {
238 if (--argc < 1) goto bad;
239 ccert= *(++argv);
240 }
241 else if (strcmp(*argv,"-threads") == 0)
242 {
243 if (--argc < 1) goto bad;
244 thread_number= atoi(*(++argv));
245 if (thread_number == 0) thread_number=1;
246 if (thread_number > MAX_THREAD_NUMBER)
247 thread_number=MAX_THREAD_NUMBER;
248 }
249 else if (strcmp(*argv,"-loops") == 0)
250 {
251 if (--argc < 1) goto bad;
252 number_of_loops= atoi(*(++argv));
253 if (number_of_loops == 0) number_of_loops=1;
254 }
255 else
256 {
257 fprintf(stderr,"unknown option %s\n",*argv);
258 badop=1;
259 break;
260 }
261 argc--;
262 argv++;
263 }
264 if (badop)
265 {
266 bad:
267 sv_usage();
268 goto end;
269 }
270
271 if (cipher == NULL) cipher=getenv("SSL_CIPHER");
272
273 SSL_load_error_strings();
274 SSLeay_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 SSL_CTX_use_certificate_file(s_ctx,scert,SSL_FILETYPE_PEM);
290 SSL_CTX_use_RSAPrivateKey_file(s_ctx,scert,SSL_FILETYPE_PEM);
291
292 if (client_auth)
293 {
294 SSL_CTX_use_certificate_file(c_ctx,ccert,
295 SSL_FILETYPE_PEM);
296 SSL_CTX_use_RSAPrivateKey_file(c_ctx,ccert,
297 SSL_FILETYPE_PEM);
298 }
299
300 if ( (!SSL_CTX_load_verify_locations(s_ctx,CAfile,CApath)) ||
301 (!SSL_CTX_set_default_verify_paths(s_ctx)) ||
302 (!SSL_CTX_load_verify_locations(c_ctx,CAfile,CApath)) ||
303 (!SSL_CTX_set_default_verify_paths(c_ctx)))
304 {
305 fprintf(stderr,"SSL_load_verify_locations\n");
306 ERR_print_errors(bio_err);
307 goto end;
308 }
309
310 if (client_auth)
311 {
312 fprintf(stderr,"client authentication\n");
313 SSL_CTX_set_verify(s_ctx,
314 SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
315 verify_callback);
316 }
317 if (server_auth)
318 {
319 fprintf(stderr,"server authentication\n");
320 SSL_CTX_set_verify(c_ctx,SSL_VERIFY_PEER,
321 verify_callback);
322 }
323
324 thread_setup();
325 do_threads(s_ctx,c_ctx);
326 thread_cleanup();
327 end:
328
329 if (c_ctx != NULL)
330 {
331 fprintf(stderr,"Client SSL_CTX stats then free it\n");
332 print_stats(stderr,c_ctx);
333 SSL_CTX_free(c_ctx);
334 }
335 if (s_ctx != NULL)
336 {
337 fprintf(stderr,"Server SSL_CTX stats then free it\n");
338 print_stats(stderr,s_ctx);
339 if (cache_stats)
340 {
341 fprintf(stderr,"-----\n");
342 lh_stats(SSL_CTX_sessions(s_ctx),stderr);
343 fprintf(stderr,"-----\n");
344 /* lh_node_stats(SSL_CTX_sessions(s_ctx),stderr);
345 fprintf(stderr,"-----\n"); */
346 lh_node_usage_stats(SSL_CTX_sessions(s_ctx),stderr);
347 fprintf(stderr,"-----\n");
348 }
349 SSL_CTX_free(s_ctx);
350 fprintf(stderr,"done free\n");
351 }
352 exit(ret);
353 return(0);
354 }
355
356 #define W_READ 1
357 #define W_WRITE 2
358 #define C_DONE 1
359 #define S_DONE 2
360
361 int ndoit(ssl_ctx)
362 SSL_CTX *ssl_ctx[2];
363 {
364 int i;
365 int ret;
366 char *ctx[4];
367
368 ctx[0]=(char *)ssl_ctx[0];
369 ctx[1]=(char *)ssl_ctx[1];
370
371 if (reconnect)
372 {
373 ctx[2]=(char *)SSL_new(ssl_ctx[0]);
374 ctx[3]=(char *)SSL_new(ssl_ctx[1]);
375 }
376 else
377 {
378 ctx[2]=NULL;
379 ctx[3]=NULL;
380 }
381
382 fprintf(stdout,"started thread %lu\n",CRYPTO_thread_id());
383 for (i=0; i<number_of_loops; i++)
384 {
385 /* fprintf(stderr,"%4d %2d ctx->ref (%3d,%3d)\n",
386 CRYPTO_thread_id(),i,
387 ssl_ctx[0]->references,
388 ssl_ctx[1]->references); */
389 /* pthread_delay_np(&tm);*/
390
391 ret=doit(ctx);
392 if (ret != 0)
393 {
394 fprintf(stdout,"error[%d] %lu - %d\n",
395 i,CRYPTO_thread_id(),ret);
396 return(ret);
397 }
398 }
399 fprintf(stdout,"DONE %lu\n",CRYPTO_thread_id());
400 if (reconnect)
401 {
402 SSL_free((SSL *)ctx[2]);
403 SSL_free((SSL *)ctx[3]);
404 }
405 return(0);
406 }
407
408 int doit(ctx)
409 char *ctx[4];
410 {
411 SSL_CTX *s_ctx,*c_ctx;
412 static char cbuf[200],sbuf[200];
413 SSL *c_ssl=NULL;
414 SSL *s_ssl=NULL;
415 BIO *c_to_s=NULL;
416 BIO *s_to_c=NULL;
417 BIO *c_bio=NULL;
418 BIO *s_bio=NULL;
419 int c_r,c_w,s_r,s_w;
420 int c_want,s_want;
421 int i;
422 int done=0;
423 int c_write,s_write;
424 int do_server=0,do_client=0;
425
426 s_ctx=(SSL_CTX *)ctx[0];
427 c_ctx=(SSL_CTX *)ctx[1];
428
429 if (ctx[2] != NULL)
430 s_ssl=(SSL *)ctx[2];
431 else
432 s_ssl=SSL_new(s_ctx);
433
434 if (ctx[3] != NULL)
435 c_ssl=(SSL *)ctx[3];
436 else
437 c_ssl=SSL_new(c_ctx);
438
439 if ((s_ssl == NULL) || (c_ssl == NULL)) goto err;
440
441 c_to_s=BIO_new(BIO_s_mem());
442 s_to_c=BIO_new(BIO_s_mem());
443 if ((s_to_c == NULL) || (c_to_s == NULL)) goto err;
444
445 c_bio=BIO_new(BIO_f_ssl());
446 s_bio=BIO_new(BIO_f_ssl());
447 if ((c_bio == NULL) || (s_bio == NULL)) goto err;
448
449 SSL_set_connect_state(c_ssl);
450 SSL_set_bio(c_ssl,s_to_c,c_to_s);
451 BIO_set_ssl(c_bio,c_ssl,(ctx[2] == NULL)?BIO_CLOSE:BIO_NOCLOSE);
452
453 SSL_set_accept_state(s_ssl);
454 SSL_set_bio(s_ssl,c_to_s,s_to_c);
455 BIO_set_ssl(s_bio,s_ssl,(ctx[3] == NULL)?BIO_CLOSE:BIO_NOCLOSE);
456
457 c_r=0; s_r=1;
458 c_w=1; s_w=0;
459 c_want=W_WRITE;
460 s_want=0;
461 c_write=1,s_write=0;
462
463 /* We can always do writes */
464 for (;;)
465 {
466 do_server=0;
467 do_client=0;
468
469 i=(int)BIO_pending(s_bio);
470 if ((i && s_r) || s_w) do_server=1;
471
472 i=(int)BIO_pending(c_bio);
473 if ((i && c_r) || c_w) do_client=1;
474
475 if (do_server && verbose)
476 {
477 if (SSL_in_init(s_ssl))
478 printf("server waiting in SSL_accept - %s\n",
479 SSL_state_string_long(s_ssl));
480 else if (s_write)
481 printf("server:SSL_write()\n");
482 else
483 printf("server:SSL_read()\n");
484 }
485
486 if (do_client && verbose)
487 {
488 if (SSL_in_init(c_ssl))
489 printf("client waiting in SSL_connect - %s\n",
490 SSL_state_string_long(c_ssl));
491 else if (c_write)
492 printf("client:SSL_write()\n");
493 else
494 printf("client:SSL_read()\n");
495 }
496
497 if (!do_client && !do_server)
498 {
499 fprintf(stdout,"ERROR IN STARTUP\n");
500 break;
501 }
502 if (do_client && !(done & C_DONE))
503 {
504 if (c_write)
505 {
506 i=BIO_write(c_bio,"hello from client\n",18);
507 if (i < 0)
508 {
509 c_r=0;
510 c_w=0;
511 if (BIO_should_retry(c_bio))
512 {
513 if (BIO_should_read(c_bio))
514 c_r=1;
515 if (BIO_should_write(c_bio))
516 c_w=1;
517 }
518 else
519 {
520 fprintf(stderr,"ERROR in CLIENT\n");
521 return(1);
522 }
523 }
524 else if (i == 0)
525 {
526 fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
527 return(1);
528 }
529 else
530 {
531 /* ok */
532 c_write=0;
533 }
534 }
535 else
536 {
537 i=BIO_read(c_bio,cbuf,100);
538 if (i < 0)
539 {
540 c_r=0;
541 c_w=0;
542 if (BIO_should_retry(c_bio))
543 {
544 if (BIO_should_read(c_bio))
545 c_r=1;
546 if (BIO_should_write(c_bio))
547 c_w=1;
548 }
549 else
550 {
551 fprintf(stderr,"ERROR in CLIENT\n");
552 return(1);
553 }
554 }
555 else if (i == 0)
556 {
557 fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
558 return(1);
559 }
560 else
561 {
562 done|=C_DONE;
563 #ifdef undef
564 fprintf(stdout,"CLIENT:from server:");
565 fwrite(cbuf,1,i,stdout);
566 fflush(stdout);
567 #endif
568 }
569 }
570 }
571
572 if (do_server && !(done & S_DONE))
573 {
574 if (!s_write)
575 {
576 i=BIO_read(s_bio,sbuf,100);
577 if (i < 0)
578 {
579 s_r=0;
580 s_w=0;
581 if (BIO_should_retry(s_bio))
582 {
583 if (BIO_should_read(s_bio))
584 s_r=1;
585 if (BIO_should_write(s_bio))
586 s_w=1;
587 }
588 else
589 {
590 fprintf(stderr,"ERROR in SERVER\n");
591 ERR_print_errors_fp(stderr);
592 return(1);
593 }
594 }
595 else if (i == 0)
596 {
597 fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
598 return(1);
599 }
600 else
601 {
602 s_write=1;
603 s_w=1;
604 #ifdef undef
605 fprintf(stdout,"SERVER:from client:");
606 fwrite(sbuf,1,i,stdout);
607 fflush(stdout);
608 #endif
609 }
610 }
611 else
612 {
613 i=BIO_write(s_bio,"hello from server\n",18);
614 if (i < 0)
615 {
616 s_r=0;
617 s_w=0;
618 if (BIO_should_retry(s_bio))
619 {
620 if (BIO_should_read(s_bio))
621 s_r=1;
622 if (BIO_should_write(s_bio))
623 s_w=1;
624 }
625 else
626 {
627 fprintf(stderr,"ERROR in SERVER\n");
628 ERR_print_errors_fp(stderr);
629 return(1);
630 }
631 }
632 else if (i == 0)
633 {
634 fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
635 return(1);
636 }
637 else
638 {
639 s_write=0;
640 s_r=1;
641 done|=S_DONE;
642 }
643 }
644 }
645
646 if ((done & S_DONE) && (done & C_DONE)) break;
647 }
648
649 SSL_set_shutdown(c_ssl,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
650 SSL_set_shutdown(s_ssl,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
651
652 #ifdef undef
653 fprintf(stdout,"DONE\n");
654 #endif
655 err:
656 /* We have to set the BIO's to NULL otherwise they will be
657 * free()ed twice. Once when th s_ssl is SSL_free()ed and
658 * again when c_ssl is SSL_free()ed.
659 * This is a hack required because s_ssl and c_ssl are sharing the same
660 * BIO structure and SSL_set_bio() and SSL_free() automatically
661 * BIO_free non NULL entries.
662 * You should not normally do this or be required to do this */
663
664 if (s_ssl != NULL)
665 {
666 s_ssl->rbio=NULL;
667 s_ssl->wbio=NULL;
668 }
669 if (c_ssl != NULL)
670 {
671 c_ssl->rbio=NULL;
672 c_ssl->wbio=NULL;
673 }
674
675 /* The SSL's are optionally freed in the following calls */
676 if (c_to_s != NULL) BIO_free(c_to_s);
677 if (s_to_c != NULL) BIO_free(s_to_c);
678
679 if (c_bio != NULL) BIO_free(c_bio);
680 if (s_bio != NULL) BIO_free(s_bio);
681 return(0);
682 }
683
684 int MS_CALLBACK verify_callback(ok, xs, xi, depth, error, arg)
685 int ok;
686 X509 *xs;
687 X509 *xi;
688 int depth;
689 int error;
690 char *arg;
691 {
692 char buf[256];
693
694 if (verbose)
695 {
696 X509_NAME_oneline(X509_get_subject_name(xs),buf,256);
697 if (ok)
698 fprintf(stderr,"depth=%d %s\n",depth,buf);
699 else
700 fprintf(stderr,"depth=%d error=%d %s\n",depth,error,buf);
701 }
702 return(ok);
703 }
704
705 #define THREAD_STACK_SIZE (16*1024)
706
707 #ifdef WIN32
708
709 static HANDLE lock_cs[CRYPTO_NUM_LOCKS];
710
711 void thread_setup()
712 {
713 int i;
714
715 for (i=0; i<CRYPTO_NUM_LOCKS; i++)
716 {
717 lock_cs[i]=CreateMutex(NULL,FALSE,NULL);
718 }
719
720 CRYPTO_set_locking_callback((void (*)(int,int,char *,int))win32_locking_callback);
721 /* id callback defined */
722 }
723
724 void thread_cleanup()
725 {
726 int i;
727
728 CRYPTO_set_locking_callback(NULL);
729 for (i=0; i<CRYPTO_NUM_LOCKS; i++)
730 CloseHandle(lock_cs[i]);
731 }
732
733 void win32_locking_callback(mode,type,file,line)
734 int mode;
735 int type;
736 char *file;
737 int line;
738 {
739 if (mode & CRYPTO_LOCK)
740 {
741 WaitForSingleObject(lock_cs[type],INFINITE);
742 }
743 else
744 {
745 ReleaseMutex(lock_cs[type]);
746 }
747 }
748
749 void do_threads(s_ctx,c_ctx)
750 SSL_CTX *s_ctx,*c_ctx;
751 {
752 double ret;
753 SSL_CTX *ssl_ctx[2];
754 DWORD thread_id[MAX_THREAD_NUMBER];
755 HANDLE thread_handle[MAX_THREAD_NUMBER];
756 int i;
757 SYSTEMTIME start,end;
758
759 ssl_ctx[0]=s_ctx;
760 ssl_ctx[1]=c_ctx;
761
762 GetSystemTime(&start);
763 for (i=0; i<thread_number; i++)
764 {
765 thread_handle[i]=CreateThread(NULL,
766 THREAD_STACK_SIZE,
767 (LPTHREAD_START_ROUTINE)ndoit,
768 (void *)ssl_ctx,
769 0L,
770 &(thread_id[i]));
771 }
772
773 printf("reaping\n");
774 for (i=0; i<thread_number; i+=50)
775 {
776 int j;
777
778 j=(thread_number < (i+50))?(thread_number-i):50;
779
780 if (WaitForMultipleObjects(j,
781 (CONST HANDLE *)&(thread_handle[i]),TRUE,INFINITE)
782 == WAIT_FAILED)
783 {
784 fprintf(stderr,"WaitForMultipleObjects failed:%d\n",GetLastError());
785 exit(1);
786 }
787 }
788 GetSystemTime(&end);
789
790 if (start.wDayOfWeek > end.wDayOfWeek) end.wDayOfWeek+=7;
791 ret=(end.wDayOfWeek-start.wDayOfWeek)*24;
792
793 ret=(ret+end.wHour-start.wHour)*60;
794 ret=(ret+end.wMinute-start.wMinute)*60;
795 ret=(ret+end.wSecond-start.wSecond);
796 ret+=(end.wMilliseconds-start.wMilliseconds)/1000.0;
797
798 printf("win32 threads done - %.3f seconds\n",ret);
799 }
800
801 #endif /* WIN32 */
802
803 #ifdef SOLARIS
804
805 static mutex_t lock_cs[CRYPTO_NUM_LOCKS];
806 /*static rwlock_t lock_cs[CRYPTO_NUM_LOCKS]; */
807 static long lock_count[CRYPTO_NUM_LOCKS];
808
809 void thread_setup()
810 {
811 int i;
812
813 for (i=0; i<CRYPTO_NUM_LOCKS; i++)
814 {
815 lock_count[i]=0;
816 /* rwlock_init(&(lock_cs[i]),USYNC_THREAD,NULL); */
817 mutex_init(&(lock_cs[i]),USYNC_THREAD,NULL);
818 }
819
820 CRYPTO_set_id_callback((unsigned long (*)())solaris_thread_id);
821 CRYPTO_set_locking_callback((void (*)())solaris_locking_callback);
822 }
823
824 void thread_cleanup()
825 {
826 int i;
827
828 CRYPTO_set_locking_callback(NULL);
829 fprintf(stderr,"cleanup\n");
830 for (i=0; i<CRYPTO_NUM_LOCKS; i++)
831 {
832 /* rwlock_destroy(&(lock_cs[i])); */
833 mutex_destroy(&(lock_cs[i]));
834 fprintf(stderr,"%8ld:%s\n",lock_count[i],CRYPTO_get_lock_name(i));
835 }
836 fprintf(stderr,"done cleanup\n");
837 }
838
839 void solaris_locking_callback(mode,type,file,line)
840 int mode;
841 int type;
842 char *file;
843 int line;
844 {
845 #ifdef undef
846 fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
847 CRYPTO_thread_id(),
848 (mode&CRYPTO_LOCK)?"l":"u",
849 (type&CRYPTO_READ)?"r":"w",file,line);
850 #endif
851
852 /*
853 if (CRYPTO_LOCK_SSL_CERT == type)
854 fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
855 CRYPTO_thread_id(),
856 mode,file,line);
857 */
858 if (mode & CRYPTO_LOCK)
859 {
860 /* if (mode & CRYPTO_READ)
861 rw_rdlock(&(lock_cs[type]));
862 else
863 rw_wrlock(&(lock_cs[type])); */
864
865 mutex_lock(&(lock_cs[type]));
866 lock_count[type]++;
867 }
868 else
869 {
870 /* rw_unlock(&(lock_cs[type])); */
871 mutex_unlock(&(lock_cs[type]));
872 }
873 }
874
875 void do_threads(s_ctx,c_ctx)
876 SSL_CTX *s_ctx,*c_ctx;
877 {
878 SSL_CTX *ssl_ctx[2];
879 thread_t thread_ctx[MAX_THREAD_NUMBER];
880 int i;
881
882 ssl_ctx[0]=s_ctx;
883 ssl_ctx[1]=c_ctx;
884
885 thr_setconcurrency(thread_number);
886 for (i=0; i<thread_number; i++)
887 {
888 thr_create(NULL, THREAD_STACK_SIZE,
889 (void *(*)())ndoit,
890 (void *)ssl_ctx,
891 0L,
892 &(thread_ctx[i]));
893 }
894
895 printf("reaping\n");
896 for (i=0; i<thread_number; i++)
897 {
898 thr_join(thread_ctx[i],NULL,NULL);
899 }
900
901 printf("solaris threads done (%d,%d)\n",
902 s_ctx->references,c_ctx->references);
903 }
904
905 unsigned long solaris_thread_id()
906 {
907 unsigned long ret;
908
909 ret=(unsigned long)thr_self();
910 return(ret);
911 }
912 #endif /* SOLARIS */
913
914 #ifdef IRIX
915
916
917 static usptr_t *arena;
918 static usema_t *lock_cs[CRYPTO_NUM_LOCKS];
919
920 void thread_setup()
921 {
922 int i;
923 char filename[20];
924
925 strcpy(filename,"/tmp/mttest.XXXXXX");
926 mktemp(filename);
927
928 usconfig(CONF_STHREADIOOFF);
929 usconfig(CONF_STHREADMALLOCOFF);
930 usconfig(CONF_INITUSERS,100);
931 usconfig(CONF_LOCKTYPE,US_DEBUGPLUS);
932 arena=usinit(filename);
933 unlink(filename);
934
935 for (i=0; i<CRYPTO_NUM_LOCKS; i++)
936 {
937 lock_cs[i]=usnewsema(arena,1);
938 }
939
940 CRYPTO_set_id_callback((unsigned long (*)())irix_thread_id);
941 CRYPTO_set_locking_callback((void (*)())irix_locking_callback);
942 }
943
944 void thread_cleanup()
945 {
946 int i;
947
948 CRYPTO_set_locking_callback(NULL);
949 for (i=0; i<CRYPTO_NUM_LOCKS; i++)
950 {
951 char buf[10];
952
953 sprintf(buf,"%2d:",i);
954 usdumpsema(lock_cs[i],stdout,buf);
955 usfreesema(lock_cs[i],arena);
956 }
957 }
958
959 void irix_locking_callback(mode,type,file,line)
960 int mode;
961 int type;
962 char *file;
963 int line;
964 {
965 if (mode & CRYPTO_LOCK)
966 {
967 printf("lock %d\n",type);
968 uspsema(lock_cs[type]);
969 }
970 else
971 {
972 printf("unlock %d\n",type);
973 usvsema(lock_cs[type]);
974 }
975 }
976
977 void do_threads(s_ctx,c_ctx)
978 SSL_CTX *s_ctx,*c_ctx;
979 {
980 SSL_CTX *ssl_ctx[2];
981 int thread_ctx[MAX_THREAD_NUMBER];
982 int i;
983
984 ssl_ctx[0]=s_ctx;
985 ssl_ctx[1]=c_ctx;
986
987 for (i=0; i<thread_number; i++)
988 {
989 thread_ctx[i]=sproc((void (*)())ndoit,
990 PR_SADDR|PR_SFDS,(void *)ssl_ctx);
991 }
992
993 printf("reaping\n");
994 for (i=0; i<thread_number; i++)
995 {
996 wait(NULL);
997 }
998
999 printf("irix threads done (%d,%d)\n",
1000 s_ctx->references,c_ctx->references);
1001 }
1002
1003 unsigned long irix_thread_id()
1004 {
1005 unsigned long ret;
1006
1007 ret=(unsigned long)getpid();
1008 return(ret);
1009 }
1010 #endif /* IRIX */
1011
1012 #ifdef PTHREADS
1013
1014 static pthread_mutex_t lock_cs[CRYPTO_NUM_LOCKS];
1015 static long lock_count[CRYPTO_NUM_LOCKS];
1016
1017 void thread_setup()
1018 {
1019 int i;
1020
1021 for (i=0; i<CRYPTO_NUM_LOCKS; i++)
1022 {
1023 lock_count[i]=0;
1024 pthread_mutex_init(&(lock_cs[i]),NULL);
1025 }
1026
1027 CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
1028 CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
1029 }
1030
1031 void thread_cleanup()
1032 {
1033 int i;
1034
1035 CRYPTO_set_locking_callback(NULL);
1036 fprintf(stderr,"cleanup\n");
1037 for (i=0; i<CRYPTO_NUM_LOCKS; i++)
1038 {
1039 pthread_mutex_destroy(&(lock_cs[i]));
1040 fprintf(stderr,"%8ld:%s\n",lock_count[i],
1041 CRYPTO_get_lock_name(i));
1042 }
1043 fprintf(stderr,"done cleanup\n");
1044 }
1045
1046 void pthreads_locking_callback(mode,type,file,line)
1047 int mode;
1048 int type;
1049 char *file;
1050 int line;
1051 {
1052 #ifdef undef
1053 fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
1054 CRYPTO_thread_id(),
1055 (mode&CRYPTO_LOCK)?"l":"u",
1056 (type&CRYPTO_READ)?"r":"w",file,line);
1057 #endif
1058 /*
1059 if (CRYPTO_LOCK_SSL_CERT == type)
1060 fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
1061 CRYPTO_thread_id(),
1062 mode,file,line);
1063 */
1064 if (mode & CRYPTO_LOCK)
1065 {
1066 pthread_mutex_lock(&(lock_cs[type]));
1067 lock_count[type]++;
1068 }
1069 else
1070 {
1071 pthread_mutex_unlock(&(lock_cs[type]));
1072 }
1073 }
1074
1075 void do_threads(s_ctx,c_ctx)
1076 SSL_CTX *s_ctx,*c_ctx;
1077 {
1078 SSL_CTX *ssl_ctx[2];
1079 pthread_t thread_ctx[MAX_THREAD_NUMBER];
1080 int i;
1081
1082 ssl_ctx[0]=s_ctx;
1083 ssl_ctx[1]=c_ctx;
1084
1085 /*
1086 thr_setconcurrency(thread_number);
1087 */
1088 for (i=0; i<thread_number; i++)
1089 {
1090 pthread_create(&(thread_ctx[i]), NULL,
1091 (void *(*)())ndoit, (void *)ssl_ctx);
1092 }
1093
1094 printf("reaping\n");
1095 for (i=0; i<thread_number; i++)
1096 {
1097 pthread_join(thread_ctx[i],NULL);
1098 }
1099
1100 printf("pthreads threads done (%d,%d)\n",
1101 s_ctx->references,c_ctx->references);
1102 }
1103
1104 unsigned long pthreads_thread_id()
1105 {
1106 unsigned long ret;
1107
1108 ret=(unsigned long)pthread_self();
1109 return(ret);
1110 }
1111
1112 #endif /* PTHREADS */
1113
1114
1115