diff options
author | ryker <> | 1998-10-05 20:13:15 +0000 |
---|---|---|
committer | ryker <> | 1998-10-05 20:13:15 +0000 |
commit | 536c76cbb863bab152f19842ab88772c01e922c7 (patch) | |
tree | dfecec371a097b73d605aae665887946d9982219 /src/lib/libcrypto/threads/mttest.c | |
download | openbsd-536c76cbb863bab152f19842ab88772c01e922c7.tar.gz openbsd-536c76cbb863bab152f19842ab88772c01e922c7.tar.bz2 openbsd-536c76cbb863bab152f19842ab88772c01e922c7.zip |
Import of SSLeay-0.9.0b with RSA and IDEA stubbed + OpenBSD build
functionality for shared libs.
Note that routines such as sslv2_init and friends that use RSA will
not work due to lack of RSA in this library.
Needs documentation and help from ports for easy upgrade to full
functionality where legally possible.
Diffstat (limited to 'src/lib/libcrypto/threads/mttest.c')
-rw-r--r-- | src/lib/libcrypto/threads/mttest.c | 1115 |
1 files changed, 1115 insertions, 0 deletions
diff --git a/src/lib/libcrypto/threads/mttest.c b/src/lib/libcrypto/threads/mttest.c new file mode 100644 index 0000000000..be395f2bc4 --- /dev/null +++ b/src/lib/libcrypto/threads/mttest.c | |||
@@ -0,0 +1,1115 @@ | |||
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 | |||