📄 sbinetsslsocket.cpp
字号:
/****************License************************************************
*
* Copyright 2000-2003. ScanSoft, Inc.
*
* Use of this software is subject to notices and obligations set forth
* in the SpeechWorks Public License - Software Version 1.2 which is
* included with this software.
*
* ScanSoft is a registered trademark of ScanSoft, Inc., and OpenSpeech,
* SpeechWorks and the SpeechWorks logo are registered trademarks or
* trademarks of SpeechWorks International, Inc. in the United States
* and other countries.
*
***********************************************************************/
#include <vxibuildopts.h>
#if P_VXI
#include "SBinetSSLsocket.hpp"
#include "vxi/VXItrd.h"
SSL_CTX *SBinetSSLsocket::_ctx = NULL;
SSL_METHOD *SBinetSSLsocket::_meth = NULL;
static VXItrdMutex ** sslMutex = NULL;
static void ssl_locking_callback(int mode, int type,
char *file, int line)
{
if (mode & CRYPTO_LOCK)
VXItrdMutexLock(sslMutex[type]);
else
VXItrdMutexUnlock(sslMutex[type]);
}
struct CRYPTO_dynlock_value
{
public:
CRYPTO_dynlock_value():_mutex(NULL)
{}
~CRYPTO_dynlock_value()
{
if (_mutex) VXItrdMutexDestroy(&_mutex);
}
VXItrdMutex *_mutex;
};
static CRYPTO_dynlock_value *dyn_create_function(const char *file,
int line)
{
CRYPTO_dynlock_value *p = new CRYPTO_dynlock_value;
if (VXItrdMutexCreate(&p->_mutex) != VXItrd_RESULT_SUCCESS)
{
delete p;
p = NULL;
}
return p;
}
static void dyn_lock_function(int mode,
CRYPTO_dynlock_value *p,
const char *file,
int line)
{
if (mode & CRYPTO_LOCK)
VXItrdMutexLock(p->_mutex);
else
VXItrdMutexUnlock(p->_mutex);
}
static void dyn_destroy_function(CRYPTO_dynlock_value *p,
const char *file,
int line)
{
delete p;
}
static int thread_cleanup()
{
for (int i = CRYPTO_num_locks() - 1; i >= 0; i--)
{
VXItrdMutexDestroy(&sslMutex[i]);
sslMutex[i] = NULL;
}
delete [] sslMutex;
sslMutex = NULL;
CRYPTO_set_locking_callback(NULL);
CRYPTO_set_id_callback(NULL);
CRYPTO_set_dynlock_create_callback(NULL);
CRYPTO_set_dynlock_lock_callback(NULL);
CRYPTO_set_dynlock_destroy_callback(NULL);
return 0;
}
static int thread_setup()
{
int n = CRYPTO_num_locks();
sslMutex = new VXItrdMutex *[n];
int i;
for (i = 0; i < n; i++) sslMutex[i] = NULL;
for (i = 0; i < n; i++)
{
if (VXItrdMutexCreate(&sslMutex[i]) != VXItrd_RESULT_SUCCESS)
goto failure;
}
CRYPTO_set_locking_callback((void (*)(int,int, const char *,int))
ssl_locking_callback);
CRYPTO_set_id_callback((unsigned long(*)()) VXItrdThreadGetID);
CRYPTO_set_dynlock_create_callback((CRYPTO_dynlock_value *
(*)(const char *, int))
dyn_create_function);
CRYPTO_set_dynlock_lock_callback((void (*)(int,
CRYPTO_dynlock_value *,
const char *,
int))
dyn_lock_function);
CRYPTO_set_dynlock_destroy_callback((void (*)(CRYPTO_dynlock_value *,
const char *,
int))
dyn_destroy_function);
return 0;
failure:
thread_cleanup();
return -1;
}
int SBinetSSLsocket::initialize()
{
SSLeay_add_ssl_algorithms();
_meth = SSLv23_client_method();
SSL_load_error_strings();
_ctx = SSL_CTX_new (_meth);
if (_ctx == NULL) return -1;
SSL_CTX_set_mode(_ctx, SSL_MODE_AUTO_RETRY);
return thread_setup();
}
int SBinetSSLsocket::shutdown()
{
thread_cleanup();
SSL_CTX_free(_ctx);
return 0;
}
// SBinetSSLsocket::SBinetSSLsocket
// Refer to SBinetSSLsocket.hpp for doc.
SBinetSSLsocket::SBinetSSLsocket(Type socktype, SWIutilLogger *logger):
SWIsocket(socktype, logger),_ssl(NULL)
{}
// SBinetSSLsocket::~SBinetSSLsocket
// Refer to SBinetSSLsocket.hpp for doc.
SBinetSSLsocket::~SBinetSSLsocket()
{
close();
if (_ssl) SSL_free(_ssl);
}
SWIstream::Result SBinetSSLsocket::connect(const SWIipAddress& endpoint, long timeout)
{
SWIstream::Result rc = SWIsocket::connect(endpoint, timeout);
if (rc != SWIstream::SUCCESS) return rc;
rc = SWIstream::FAILURE;
if ((_ssl = SSL_new(_ctx)) == NULL)
error(L"SSL_new", 700);
else if (SSL_set_fd(_ssl, getSD()) == 0)
error(L"SSL_set_fd", 700);
else if (SSL_connect(_ssl) == -1)
error(L"SSL_connect", 700);
else
rc = SWIstream::SUCCESS;
if (rc != SWIstream::SUCCESS && _ssl != NULL)
{
SSL_free(_ssl);
_ssl = NULL;
}
return rc;
}
int SBinetSSLsocket::read(void* buf, int len)
{
return recv(buf, len);
}
int SBinetSSLsocket::recv(void* buf, int len, int msgf)
{
for (;;)
{
int rc1 = SSL_read(_ssl, buf, len);
int rc2 = SSL_get_error(_ssl, rc1);
switch (rc2)
{
case SSL_ERROR_NONE:
return rc1;
case SSL_ERROR_ZERO_RETURN:
return SWIstream::END_OF_FILE;
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
// should not really happend because of the SSL_MODE_AUTO_RETRY.
// Do nothing, just try again.
// Maybe we should yield the thread or sleep to avoid CPU hog
error(L"SSL_read", 701, L"SSL_get_error", rc2);
break;
default:
error(L"SSL_read", 700, L"SSL_get_error", rc2);
return SWIstream::READ_ERROR;
}
}
}
int SBinetSSLsocket::recvfrom(SWIipAddress& sa, void* buf, int len, int msgf)
{
int rc = recv(buf, len, msgf);
#if 0
if (rc >= 0)
{
const SWIipAddress *p = getRemoteAddress();
//if (p != NULL) sa = *p;
}
#endif
return rc;
}
int SBinetSSLsocket::write(const void* buf, int len)
{
return send(buf, len);
}
int SBinetSSLsocket::send(const void* buf, int len, int msgf)
{
for (;;)
{
int rc1 = SSL_write(_ssl, const_cast<void *>(buf), len);
int rc2 = SSL_get_error(_ssl, rc1);
switch (rc2)
{
case SSL_ERROR_NONE:
return rc1;
case SSL_ERROR_ZERO_RETURN:
return SWIstream::END_OF_FILE;
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
// should not really happend because of the SSL_MODE_AUTO_RETRY.
// Do nothing, just try again.
// Maybe we should yield the thread or sleep to avoid CPU hog
error(L"SSL_write", 701, L"SSL_get_error", rc2);
break;
default:
error(L"SSL_write", 700, L"SSL_get_error", rc2);
return SWIstream::READ_ERROR;
}
}
}
int SBinetSSLsocket::sendto(const SWIipAddress& sa, const void* buf, int len, int msgf)
{
return send(buf,len,msgf);
}
SWIstream::Result SBinetSSLsocket::shutdown(shuthow sh)
{
// Not sure how to handler shutdown in SSL context. However, shutdown
// should not be used in SBinet.
error(L"SBinetSSLsocket::shutdown", 701);
return SWIstream::FAILURE;
}
SWIstream::Result SBinetSSLsocket::close()
{
if (_ssl != NULL)
{
SSL_shutdown(_ssl);
SSL_free(_ssl);
_ssl = NULL;
}
return SWIsocket::close();
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -