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