I'm having a bit of an issue with something I encountered while unit
testing my socket classes - each test basically creates a thread on
which a server socket listens. From the main thread I connect a client
to the server socket. I've found that after about 10-15 such tests I
cannot create new threads - so I was wondering if I might have missed
something clearing up resources (the pthread_create method returns with
EAGAIN, which means insufficient resources). This only happens with ssl
sockets when I connect a client, if I use normal sockets everything
works well.
I have the following code, stripped of error handling for clarity (I've
marked with * lines which are missing/different in the normal socket
implementation versus the ssl socket one):
ClientSocket:
connect():
this->socket = BIO_new_ssl_connect(ssl_context); *
BIO_get_ssl(this->socket, &this->ssl); *
BIO_set_nbio(this->socket, NON_BLOCKING);
BIO_set_conn_hostname(this->socket, this->host);
BIO_set_conn_port(this->socket, port_str);
bool keep_connecting = true;
while (keep_connecting)
{
if (BIO_do_connect(this->socket) > 0)
{
if (this->do_verify_handshake_result()) this->connected = true;
keep_connecting = false;
}
else if (!BIO_should_retry(this->socket)) keep_connecting = false;
}
--
do_verify_handshake_result(): * (just returns true for normal sockets)
bool keep_trying = true;
while (keep_trying)
{
if (BIO_do_handshake(this->socket) > 0)
{
if (SSL_get_verify_result(this->ssl) == X509_V_OK) result = true;
keep_trying = false;
}
else if (!BIO_should_retry(this->socket)) keep_trying = false;
}
--
ServerSocket:
listen():
this->ssl_socket = BIO_new_ssl(ssl_context, SERVER_CONNECTION); *
BIO_get_ssl(this->ssl_socket, &this->ssl); *
this->accept_socket = BIO_new_accept(port_str);
BIO_set_accept_bios(this->accept_socket, this->ssl_socket); *
BIO_set_nbio(this->accept_socket, NON_BLOCKING);
BIO_do_accept(this->accept_socket);
while (!this->shutdown_requested)
{
if (BIO_do_accept(this->accept_socket) > 0)
{
ClientSocket *incoming_client=
new_client_socket(BIO_pop(this->accept_socket));
incoming_client->do_verify_handshake_result();
connection_complete(incoming_client)
}
}
--
connection_complete(): (this is just a test method)
delete incoming_client;
--
Test code:
typedef struct str_thdata
{
int thread_no;
ServerSocket *socket;
} thdata;
void *print_message_function ( void *ptr )
{
thdata *data = (thdata *) ptr;
printf("Thread %d s\n", data->thread_no);fflush(stdout);
data->socket->listen();
return NULL;
}
int test()
{
for (int i = 0; i < 200; i++)
{
pthread_t thr;
thdata data;
data.thread_no = i;
ServerSocket *socket = SocketFactory::new_server_socket(SSL,
TEST_PORT);
data.socket = socket;
if (pthread_create (&thr, NULL, print_message_function, (void *)
&data) != 0)
printf("Warning, create did not work for thread #%d\n",
i);fflush(stdout);
else
{
Sleep(1000);
ClientSocket *client = SocketFactory::new_client_socket(SSL,
(char *) "127.0.0.1", TEST_PORT);
if (client->connect())
client->disconnect();
delete client;
socket->shutdown();
pthread_join(thr, NULL);
}
delete socket;
}
}
If I use normal server&client sockets, all threads work as expected (can
create 200). Also, if I use an SSL server, but with no client connecting
to it (creating a server socket & thread and then closing them 200
times) - everything works as expected.
If I connect an SSL client socket, no resources after 10-15 threads - I
can get this to happen reliably. Sometimes I get a few error messages
and then I can create threads again for a while.
Initially, I had SSL_MODE_AUTO_RETRY set on the server socket (left
over from when the two classes were using blocking sockets) - removing
it improved the situation a bit, but not by much (ie before I got thread
creation errors on each run, now I get them about once for every two runs).
The disconnect/shutdown methods both for client and server just do
"BIO_free_all(this->socket);", besides setting some bool variables such
as connected/shutdown_requested. The destructors call
disconnect/shutdown if sockets are not already closed.
Any ideas on what I'm doing wrong with this? I think I'm neglecting to
release some resources, but I don't see what could those be - everything
is closed before each new loop iteration. Setting a "Sleep()" right
before the loop restarts did not help either.
Thanks in advance,
--
Laura
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users@openssl.org
Automated List Manager majord...@openssl.org