Greetings, I have a multi-threaded openssl server-based daemon whose function is to service requests from any number of clients. The application follows the conventions for threaded openssl programming, such as registering the two required callbacks. The openssl version being used is 0.9.7a on both the Linux server and Win32 client.
Unfortunately, the following sequence of events is giving me difficulties: - Connect from client A - Connect from client B - Disconnect from client B - Connect from client B - Disconnect from client A -> this results in an SSL_ERROR_SYSCALL error in client B's thread upon its next SSL_read() call, with a non-zero return value from SSL_read(). The client application, not knowing that its connection was terminated, must be restarted to sync up using a new thread of the daemon. The following, hopefully relevant, code snippets form the basis of the daemon's SSL usage. For brevity, both the thread id and locking callbacks follow the format in openssl/crypto/threads/mttest.c. I've tried several variations on both threading and openssl, with the same or worse results. Accept thread: tci = malloc(sizeof(comm_info)); memset(tci, 0, sizeof(comm_info)); lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); for (i=0; i<CRYPTO_num_locks(); i++) pthread_mutex_init(&(lock_cs[i]),NULL); CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id); CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback); while(1) { ... tci->sd = accept(sd, (struct sockaddr *)(&(tci->si)), &address_len); ... pthread_create(&th, &thread_attr, comm_main, (void *) tci); ... tci = malloc(sizeof(comm_info)); // set up for next accept... memset(tci, 0, sizeof(comm_info)); } CRYPTO_set_locking_callback(NULL); for (i=0; i<CRYPTO_num_locks(); i++) pthread_mutex_destroy(&(lock_cs[i])); OPENSSL_free(lock_cs); Client communications thread (spawned by pthread_create() above): comm_main (void *argv) { comm_info *tci = (comm_info *)argv; // negotiate TLS, authenticate, etc... for (;;) { retval = my_read(tci, buf, count); if (retval > 0) { // ...process request in buf, then respond to client my_write(tci, outbuf, count); } else if (retval == 0) my_shutdown(tci); else my_error(tci); } } int my_read (comm_info *tci, char *buf, int *count) { while (1) { retval = SSL_read(tci->ssl, buf, count); switch (SSL_get_error(tci->ssl, retval)) { case SSL_ERROR_NONE: return retval; case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_X509_LOOKUP: continue; case SSL_ERROR_SYSCALL: if (retval == 0) return 0; // EOF without close_notify return -1; case SSL_ERROR_ZERO_RETURN: return 0; // SSL connection has been closed case SSL_ERROR_SSL: return -1; default: return -1; // Unknown SSL error } } } void my_shutdown(comm_info *tci) { if (tci->ssl) { ret = SSL_shutdown(tci->ssl); if (ret == 0) // send TCP FIN to trigger close_notify ret = SSL_shutdown(tci->ssl); if (ret == 1) SSL_free(tci->ssl); } if (tci) free((void *) tci); pthread_exit((void *)0); } If anyone has had experience in this area and has suggestions, please respond. Thanks in advance, Stan ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]