diff options
Diffstat (limited to 'util/net')
-rw-r--r-- | util/net/sock.cpp | 85 | ||||
-rw-r--r-- | util/net/sock.h | 2 |
2 files changed, 78 insertions, 9 deletions
diff --git a/util/net/sock.cpp b/util/net/sock.cpp index 69c42f2..ac565c3 100644 --- a/util/net/sock.cpp +++ b/util/net/sock.cpp @@ -342,6 +342,67 @@ namespace mongo { // ------------ SSLManager ----------------- #ifdef MONGO_SSL + static unsigned long _ssl_id_callback(); + static void _ssl_locking_callback(int mode, int type, const char *file, int line); + + class SSLThreadInfo { + public: + + SSLThreadInfo() { + _id = ++_next; + CRYPTO_set_id_callback(_ssl_id_callback); + CRYPTO_set_locking_callback(_ssl_locking_callback); + } + + ~SSLThreadInfo() { + CRYPTO_set_id_callback(0); + } + + unsigned long id() const { return _id; } + + void lock_callback( int mode, int type, const char *file, int line ) { + if ( mode & CRYPTO_LOCK ) { + _mutex[type]->lock(); + } + else { + _mutex[type]->unlock(); + } + } + + static void init() { + while ( (int)_mutex.size() < CRYPTO_num_locks() ) + _mutex.push_back( new SimpleMutex("SSLThreadInfo") ); + } + + static SSLThreadInfo* get() { + SSLThreadInfo* me = _thread.get(); + if ( ! me ) { + me = new SSLThreadInfo(); + _thread.reset( me ); + } + return me; + } + + private: + unsigned _id; + + static AtomicUInt _next; + static vector<SimpleMutex*> _mutex; + static boost::thread_specific_ptr<SSLThreadInfo> _thread; + }; + + static unsigned long _ssl_id_callback() { + return SSLThreadInfo::get()->id(); + } + static void _ssl_locking_callback(int mode, int type, const char *file, int line) { + SSLThreadInfo::get()->lock_callback( mode , type , file , line ); + } + + AtomicUInt SSLThreadInfo::_next; + vector<SimpleMutex*> SSLThreadInfo::_mutex; + boost::thread_specific_ptr<SSLThreadInfo> SSLThreadInfo::_thread; + + SSLManager::SSLManager( bool client ) { _client = client; SSL_library_init(); @@ -352,6 +413,8 @@ namespace mongo { massert( 15864 , mongoutils::str::stream() << "can't create SSL Context: " << ERR_error_string(ERR_get_error(), NULL) , _context ); SSL_CTX_set_options( _context, SSL_OP_ALL); + SSLThreadInfo::init(); + SSLThreadInfo::get(); } void SSLManager::setupPubPriv( const string& privateKeyFile , const string& publicKeyFile ) { @@ -387,6 +450,7 @@ namespace mongo { } SSL * SSLManager::secure( int fd ) { + SSLThreadInfo::get(); SSL * ssl = SSL_new( _context ); massert( 15861 , "can't create SSL" , ssl ); SSL_set_fd( ssl , fd ); @@ -415,13 +479,18 @@ namespace mongo { _bytesOut = 0; _bytesIn = 0; #ifdef MONGO_SSL + _ssl = 0; _sslAccepted = 0; #endif } void Socket::close() { #ifdef MONGO_SSL - _ssl.reset(); + if ( _ssl ) { + SSL_shutdown( _ssl ); + SSL_free( _ssl ); + _ssl = 0; + } #endif if ( _fd >= 0 ) { closesocket( _fd ); @@ -433,8 +502,8 @@ namespace mongo { void Socket::secure( SSLManager * ssl ) { assert( ssl ); assert( _fd >= 0 ); - _ssl.reset( ssl->secure( _fd ) ); - SSL_connect( _ssl.get() ); + _ssl = ssl->secure( _fd ); + SSL_connect( _ssl ); } void Socket::secureAccepted( SSLManager * ssl ) { @@ -446,8 +515,8 @@ namespace mongo { #ifdef MONGO_SSL if ( _sslAccepted ) { assert( _fd ); - _ssl.reset( _sslAccepted->secure( _fd ) ); - SSL_accept( _ssl.get() ); + _ssl = _sslAccepted->secure( _fd ); + SSL_accept( _ssl ); _sslAccepted = 0; } #endif @@ -510,7 +579,7 @@ namespace mongo { int Socket::_send( const char * data , int len ) { #ifdef MONGO_SSL if ( _ssl ) { - return SSL_write( _ssl.get() , data , len ); + return SSL_write( _ssl , data , len ); } #endif return ::send( _fd , data , len , portSendFlags ); @@ -524,7 +593,7 @@ namespace mongo { #ifdef MONGO_SSL if ( _ssl ) { - log() << "SSL Error ret: " << ret << " err: " << SSL_get_error( _ssl.get() , ret ) + log() << "SSL Error ret: " << ret << " err: " << SSL_get_error( _ssl , ret ) << " " << ERR_error_string(ERR_get_error(), NULL) << endl; } @@ -679,7 +748,7 @@ namespace mongo { int Socket::_recv( char *buf, int max ) { #ifdef MONGO_SSL if ( _ssl ){ - return SSL_read( _ssl.get() , buf , max ); + return SSL_read( _ssl , buf , max ); } #endif return ::recv( _fd , buf , max , portRecvFlags ); diff --git a/util/net/sock.h b/util/net/sock.h index 1cd5133..f91c288 100644 --- a/util/net/sock.h +++ b/util/net/sock.h @@ -243,7 +243,7 @@ namespace mongo { long long _bytesOut; #ifdef MONGO_SSL - shared_ptr<SSL> _ssl; + SSL* _ssl; SSLManager * _sslAccepted; #endif |