mttest.c 35 KB

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