fixed race condition of openssl calls

pull/317/head
orignal 9 years ago
parent 8daa7561fa
commit ef4dc3cbc9

@ -1,9 +1,13 @@
#include <string.h>
#include <string>
#include <vector>
#include <mutex>
#include <openssl/sha.h>
#include <openssl/dh.h>
#include <openssl/md5.h>
#include <openssl/rand.h>
#include <openssl/ssl.h>
#include <openssl/crypto.h>
#include "Log.h"
//#include "TunnelBase.h"
#include "Crypto.h"
@ -677,6 +681,33 @@ namespace crypto
m_IVDecryption.Decrypt ((ChipherBlock *)out, (ChipherBlock *)out); // double iv
#endif
}
std::vector <std::unique_ptr<std::mutex> > m_OpenSSLMutexes;
static void OpensslLockingCallback(int mode, int type, const char * file, int line)
{
if (type > 0 && (size_t)type < m_OpenSSLMutexes.size ())
{
if (mode & CRYPTO_LOCK)
m_OpenSSLMutexes[type]->lock ();
else
m_OpenSSLMutexes[type]->unlock ();
}
}
void InitCrypto ()
{
SSL_library_init ();
auto numLocks = CRYPTO_num_locks();
for (int i = 0; i < numLocks; i++)
m_OpenSSLMutexes.emplace_back (new std::mutex);
CRYPTO_set_locking_callback (OpensslLockingCallback);
}
void TerminateCrypto ()
{
CRYPTO_set_locking_callback (nullptr);
m_OpenSSLMutexes.clear ();
}
}
}

@ -272,6 +272,9 @@ namespace crypto
CBCDecryption m_LayerDecryption;
#endif
};
void InitCrypto ();
void TerminateCrypto ();
}
}

@ -19,8 +19,7 @@
#include "HTTPServer.h"
#include "I2PControl.h"
#include "ClientContext.h"
// ssl.h somehow pulls Windows.h stuff that has to go after asio
#include <openssl/ssl.h>
#include "Crypto.h"
#ifdef USE_UPNP
#include "UPnP.h"
@ -60,7 +59,7 @@ namespace i2p
bool Daemon_Singleton::init(int argc, char* argv[])
{
SSL_library_init ();
i2p::crypto::InitCrypto ();
i2p::util::config::OptionParser(argc, argv);
i2p::context.Init ();
@ -171,6 +170,7 @@ namespace i2p
d.m_I2PControlService->Stop ();
d.m_I2PControlService = nullptr;
}
i2p::crypto::TerminateCrypto ();
StopLog ();
return true;

@ -7,6 +7,7 @@
#include "RouterContext.h"
#include "Identity.h"
#include "Destination.h"
#include "Crypto.h"
#include "util.h"
#include "api.h"
@ -18,9 +19,15 @@ namespace api
{
i2p::util::filesystem::SetAppName (appName);
i2p::util::config::OptionParser(argc, argv);
i2p::crypto::InitCrypto ();
i2p::context.Init ();
}
void TerminateI2P ()
{
i2p::crypto::TerminateCrypto ();
}
void StartI2P (std::ostream * logStream)
{
if (logStream)

@ -13,6 +13,7 @@ namespace api
{
// initialization start and stop
void InitI2P (int argc, char* argv[], const char * appName);
void TerminateI2P ();
void StartI2P (std::ostream * logStream = nullptr);
// write system log to logStream, if not specified to <appName>.log in application's folder
void StopI2P ();

Loading…
Cancel
Save