⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sbinetsslsocket.cpp

📁 sloedgy open sip stack source code
💻 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 + -