The OpenSSL FAQ states that it can be used in threaded applications:
1. Is OpenSSL thread-safe?
Provided an application sets up the thread callback functions, the answer is yes.
This callback functions refers to a global SSL-lock, thus if you have 2 ssl connections running these will both use this global lock.
However the FAQ continues:
There are limitations; for example, an SSL connection cannot be used concurrently by multiple threads. This is true for most OpenSSL objects.
This indicates that an additional mutex is needed for every SSL-connection. Is this correct? Or do I not need the additional mutex for every SSL-connection?
It means that if your connection is shared by multiple threads, you need to have a mutex to avoid them all manipulating the connection at the same time.
As long as any single connection is only used by one thread at a time (which in most applications is the normal case), you don't need any further locking.
Related
I know it is forbidden in the OpenSSL API to call SSL_read and SSL_write from two different threads on the same SSL context, but it's important in my application to have secure full-duplex communication. I thought of some solutions, none of which I really like:
Use two SSL contexts per connection. I don't like this because it uses more resources, and it would complicate my implementation. However, I would be fine using this if I could just "duplicate" an existing SSL context rather than creating a whole new connection from scratch.
Use non-blocking sockets with a mutex controlling access to an SSL context. This would require resource-hogging polling, and I heard the non-blocking implementation is just not very good.
This seems like it would be a rather common thing to do, so what is an accepted solution to this problem?
Use non-blocking sockets with a mutex controlling access to an SSL context.
With non-blocking sockets inside a single thread you would not need mutexes, because you only either read or write (because of single thread).
This would require resource-hogging polling, ...
You would not need "resource-hogging" polling. I assume you mean here busy polling instead of using the usual facilities of the system (like select) to wait (not loop) until data are available or data can be send. But contrary to read/write on plain sockets, SSL sockets can need a read if they want to write and a write if they want to read and they might have data inside even if the socket is not readable. Look out for SSL_WANT_READ, SSL_WANT_WRITE and SSL_pending.
...and I heard the non-blocking implementation is just not very good.
It looks more complex if you are used to using threads. But did you ever wonder why high performance servers like nginx don't use threads but non-blocking I/O? That is because it needs less resources and has not the problems associated with threads, like needing to mutex your way around critical sections (overhead) and getting strange and sporadic errors when forgetting to mutex something. nginx also uses openssl with non-blocking I/O.
I personally use non-blocking I/O all the time and while it is harder to do correctly with SSL because of the protocol itself and not the OpenSSL implementation it is doable and fast.
This means, that non-blocking I/O within a single thread is a way you could go to solve your problem. The other way would be to let SSL only work with memory BIOs instead of real file descriptors and do all the reading and writing yourself. But this is probably even more complex than non-blocking I/O.
BTW, usually SSL context means the SSL_CTX object which can be shared between multiple SSL connections and which has probably no problems with multiple threads. What you mean is that the same SSL connection (the SSL object) should not be used from multiple threads.
We have a multi-threaded network application that has been using sockets for 10 years and now we're trying to secure the application with OpenSSL 0.9.8L. Over the years, the application's network protocols have been designed to take advantage of the duplex nature of a single socket connection; the application concurrently reads and writes on the same socket. The application manages the underlying socket itself and passes the socket descriptor to OpenSSL via SSL_set_fd.
We configured OpenSSL for multithread support, setting up both the static and dynamic locking callbacks e.g. CRYPTO_set_id_callback(), CRYPTO_set_locking_callback(), etc. For the most part, the application functions well but we're seeing some anomalies. To help us determine the cause, definitive answers to a few questions would help.
The OpenSSL Frequently Asked Questions page states that OpenSSL is thread safe, but maintains that a single "SSL connection may not concurrently be used by multiple threads."
http://www.openssl.org/support/faq.html#PROG1
True or False. OpenSSL connection API calls (SSL_Read, SSL_Write, etc.) may execute concurrently on the same SSL instance (pointer-to-SSL returned by a SSL_new call)?
True or False. For blocking sockets where SSL_MODE_AUTO_RETRY is enabled, thread A can call SSL_Read() on SSL instance X while thread B concurrently calls SSL_Write() on SSL instance X?
True or False. OpenSSL works error free when an application uses non-blocking sockets and prevents concurrent execution of SSL_Read and SSL_Write (as well as other connection API calls) on the same SSL instance?
True or False. OpenSSL SSL instance's returned by SSL_new are bound to the single thread which called SSL_new; bound meaning that the SSL instance may not be shared with any other threads, the SSL instance is only valid for use on the thread which called SSL_new?
True or False. If thread A i) calls SSL_new, obtaining an SSL instance X and ii) calls SSL_Read using the SSL instance X. A failure will eventually occur if thread B non-concurrently calls SSL_Read/SSL_Write using the same SSL instance X?
1.True or False. OpenSSL connection API calls (SSL_Read, SSL_Write, etc.) may execute concurrently on the same SSL instance (pointer-to-SSL returned by a SSL_new call)?
*False. No, you cannot use SSL_read / SSL_write concurrently on the same SSL instance.*
2.True or False. For blocking sockets where SSL_MODE_AUTO_RETRY is enabled, thread A can call SSL_Read() on SSL instance X while thread B concurrently calls SSL_Write() on SSL instance X?
*Same answer as above. With or Without SSL_MODE_AUTO_RETRY, you cannot use the same SSL instance X concurrently to do SSL_read and SSL_write parallelly*
3.True or False. OpenSSL works error free when an application uses non-blocking sockets and prevents concurrent execution of SSL_Read and SSL_Write (as well as other connection API calls) on the same SSL instance?
True. If no concurrent execution is there, then OpenSSL works fine for Blocking as well as Non-Blocking Sockets.
4.True or False. OpenSSL SSL instance's returned by SSL_new are bound to the single thread which called SSL_new; bound meaning that the SSL instance may not be shared with any other threads, the SSL instance is only valid for use on the thread which called SSL_new?
False. The SSL instance is not bound to any thread by OpenSSL itself. You can use the SSL instance created in one thread in another thread as long as only one thread is using a single SSL instance at any one point of time.
5.True or False. If thread A i) calls SSL_new, obtaining an SSL instance X and ii) calls SSL_Read using the SSL instance X. A failure will eventually occur if thread B non-concurrently calls SSL_Read/SSL_Write using the same SSL instance X?
False. Both Thread A and Thread B can use the same SSL instance X, as long both don't do concurrent operations on SSL instance X.
Experimentally, if the SSL connection has passed the negociation stage, and there is no renegotiation afterwards, then the use of SSL_read and SSL_write concurrently proved to cause no harm.
This is according to my tests where I integrated OpenSSL with Push Framework, a multi-threaded network library.
However, everywhere we read, OpenSSL professionals insist that the same context can not be used by multiple threads in same time.
I have some legacy code using a CAsyncSocket derived class. This class overrides OnReceive and it also has a wrapper around SendTo. The code is in a dll which multiple applications will be using on the same PC, all ports are hard coded.
I'm guessing that I need to provide synchronization in the form of a named mutex (CMutex in MFC) class bit I'm not sure.
Should I lock a named mutex in the OnReceive and a different named mutex in the Send methods of CMyAsyncSocket?
Do I need synchronization at all or will the MFC CAsyncSocket do that for me? Worried about accessing a socket on multiple processes.
The underlying socket will provide connection isolation so you don't need to worry about protecting each processes connection. Assuming you just have one thread using the socket in each process you just need to handle the blocking issues which can occur with AsyncSocket, ie when the socket is not ready to deal with the request ?
I'm building a multi-threaded service application in Delphi XE2. Each thread serves its own purpose apart from the other ones. The main service thread is only responsible for keeping the other threads going and saving a log file, etc. Each of these threads reports back to the main service thread through synchronized event triggers. These threads are created when the service starts and destroyed when the service ends.
I'd like to introduce a separate thread as a centralized database connection to avoid having to create many instances of TADOConnection. My service code can call standard functions such as UserListDataSet := DBThread.GetUserList(SomeUserListDataSet); or it would also be nice if I could send direct SQL statements like SomeDataSet := DBThread.Get(MySqlText);. I'd also like to avoid too many occasions of CoInitialize() etc.
The job threads will need to use this db thread. I need to figure out how to "ask" it for certain data, "wait" for a response, and "acquire" that response back in the thread which requested it. I'm sure there are many approaches to this, but I need to know which one is best suited for my scenario. Windows messages? Events? Should I have some sort of queue? Should it send data sets or something else? Is there already something that can do this? I need to figure out how to structure this DB thread in a way that it can be re-used from other threads.
The structure looks like this:
+ SvcThread
+ DBThread
+ TADOConnection
+ Thread1
+ Thread2
+ Thread3
I need threads 1 2 and 3 to send requests to the DBThread. When a thread sends any request to it, it needs to wait until it gets a response. Once there's a response, the DB Thread needs to notify the asking thread. Each of the threads might send a request to this DB Thread at the same time too.
A good tutorial on how to accomplish this would be perfect - it just needs to be a suitable fit for my scenario. I don't need to know just "how to make two threads talk together" but rather "how to make many threads talk to a centralized database thread". These job threads are created as children of the main service thread, and are not owned by the db thread. The db thread has no knowledge of the job threads.
Normally, you'd have a request queue where all the requests are stored. Your database thread reads a request from the queue, handles it, then invokes a callback routine specified by the requester to handle the result. Not sure how this maps to Delphi paradigms, but the basics should be the same.
Do any of the "requesting" threads have anything profitable that they could be doing while they are waiting for a response to be obtained from the database? If the answer is "no," as I suspect that it is quite likely to be, then perhaps you can simplify your situation quite a bit by eliminating the need for "a DB thread" completely. Perhaps all of the threads can simply share a single database-connection in turn, employing a mutual-exclusion object to cause them to "wait their turn."
Under this scenario, there would be one database-connection, and any thread which needed to use it would do so. But they would be obliged to obtain a mutex object first, hold on to the mutex during the time they were doing database queries, and then release the mutex so that the next thread could have its turn.
If you decide that it is somehow advantageous (or a necessity...) to dedicate a thread to managing the connection, then perhaps you could achieve the result using (a) a mutex to serialize the requests, as before; and (b) one event-object to signal the DB-thread that a new request has been posted, and (c) another event-object to signal the requester that the request has been completed.
In either case, if you have indeed determined that the requester threads have nothing useful that they could be doing in the meantime, you have the threads "simply sleeping" until their turn comes up. Then, they do their business, either directly or indirectly. There are no "queues," no complicated shared data-structures, simply because you have (say...) determined that there is no need for them.
I think using a DB connection pool would be a better fit for your problem. This would also allow you to scale your application later on without having to then create additional DB thread and then having to manage "load balancing" for those DB threads.
Since you are mentioning using TADOConnection please have a look at this implementation made by Cary Jensen http://cc.embarcadero.com/item/19975.
I am successfully using this DB connection pool in several applications. I have modified it in several ways, including using an ini file to control: maximum number of connections, cleanup time, timeout times etc.
Cary has written several articles that serves as documentation for it. One is here http://edn.embarcadero.com/article/30027.
It seems like the classical way to handle transactions with JDBC is to set auto-commit to false. This creates a new transaction, and each call to commit marks the beginning the next transactions.
On multithreading app, I understand that it is common practice to open a new connection for each thread.
I am writing a RMI based multi-client server application, so that basically my server is seamlessly spawning one thread for each new connection.
To handle transactions correctly should I go and create a new connection for each of those thread ?
Isn't the cost of such an architecture prohibitive?
Yes, in general you need to create a new connection for each thread. You don't have control over how the operating system timeslices execution of threads (notwithstanding defining your own critical sections), so you could inadvertently have multiple threads trying to send data down that one pipe.
Note the same applies to any network communications. If you had two threads trying to share one socket with an HTTP connection, for instance.
Thread 1 makes a request
Thread 2 makes a request
Thread 1 reads bytes from the socket, unwittingly reading the response from thread 2's request
If you wrapped all your transactions in critical sections, and therefore lock out any other threads for an entire begin/commit cycle, then you might be able to share a database connection between threads. But I wouldn't do that even then, unless you really have innate knowledge of the JDBC protocol.
If most of your threads have infrequent need for database connections (or no need at all), you might be able to designate one thread to do your database work, and have other threads queue their requests to that one thread. That would reduce the overhead of so many connections. But you'll have to figure out how to manage connections per thread in your environment (or ask another specific question about that on StackOverflow).
update: To answer your question in the comment, most database brands don't support multiple concurrent transactions on a single connection (InterBase/Firebird is the only exception I know of).
It'd be nice to have a separate transaction object, and to be able to start and commit multiple transactions per connection. But vendors simply don't support it.
Likewise, standard vendor-independent APIs like JDBC and ODBC make the same assumption, that transaction state is merely a property of the connection object.
It's uncommon practice to open a new connection for each thread.
Usually you use a connection pool like c3po library.
If you are in an application server, or using Hibernate for example, look at the documentation and you will find how to configure the connection pool.
The same connection object can be used to create multiple statement objects and these statement objects can then used by different threads concurrently. Most modern DBs interfaced by JDBC can do that. The JDBC is thus able to make use of concurrent cursors as follows. PostgreSQL is no exception here, see for example:
http://doc.postgresintl.com/jdbc/ch10.html
This allows connection pooling where the connection are only used for a short time, namely to created the statement object and but after that returned to the pool. This short time pooling is only recommended when the JDBC connection does also parallelization of statement operations, otherwise normal connection pooling might show better results. Anyhow the thread can continue work with the statement object and close it later, but not the connection.
1. Thread 1 opens statement
3. Thread 2 opens statement
4. Thread 1 does something Thread 2 does something
5. ... ...
6. Thread 1 closes statement ...
7. Thread 2 closes statement
The above only works in auto commit mode. If transactions are needed there is still no need to tie the transaction to a thread. You can just partition the pooling along the transactions that is all and use the same approach as above. But this is only needed not because of some socket connection limitation but because the JDBC then equates the session ID with the transaction ID.
If I remember well there should be APIs and products around with a less simplistic design, where teh session ID and the transaction ID are not equated. In this APIs you could write your server with one single database connection object, even when it does
transactions. Will need to check and tell you later what this APIs and products are.