SBinetSSLsocket.cpp
上传用户:xqtpzdz
上传日期:2022-05-21
资源大小:1764k
文件大小:8k
源码类别:

xml/soap/webservice

开发平台:

Visual C++

  1. /****************License************************************************
  2.  * Vocalocity OpenVXI
  3.  * Copyright (C) 2004-2005 by Vocalocity, Inc. All Rights Reserved.
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *  
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  * Vocalocity, the Vocalocity logo, and VocalOS are trademarks or 
  18.  * registered trademarks of Vocalocity, Inc. 
  19.  * OpenVXI is a trademark of Scansoft, Inc. and used under license 
  20.  * by Vocalocity.
  21.  ***********************************************************************/
  22. #include "SBinetSSLsocket.hpp"
  23. #include "VXItrd.h"
  24. SSL_CTX *SBinetSSLsocket::_ctx = NULL;
  25. SSL_METHOD *SBinetSSLsocket::_meth = NULL;
  26. static VXItrdMutex ** sslMutex = NULL;
  27. static void ssl_locking_callback(int mode, int type,
  28.                                  char *file, int line)
  29. {
  30.   if (mode & CRYPTO_LOCK)
  31.     VXItrdMutexLock(sslMutex[type]);
  32.   else
  33.     VXItrdMutexUnlock(sslMutex[type]);
  34. }
  35. struct CRYPTO_dynlock_value
  36. {
  37.  public:
  38.   CRYPTO_dynlock_value():_mutex(NULL)
  39.   {}
  40.   ~CRYPTO_dynlock_value()
  41.   {
  42.     if (_mutex) VXItrdMutexDestroy(&_mutex);
  43.   }
  44.   VXItrdMutex *_mutex;
  45. };
  46. static CRYPTO_dynlock_value *dyn_create_function(const char *file,
  47.                                                  int line)
  48. {
  49.   CRYPTO_dynlock_value *p = new CRYPTO_dynlock_value;
  50.   if (VXItrdMutexCreate(&p->_mutex) != VXItrd_RESULT_SUCCESS)
  51.   {
  52.     delete p;
  53.     p = NULL;
  54.   }
  55.   return p;
  56. }
  57. static void dyn_lock_function(int mode,
  58.                               CRYPTO_dynlock_value *p,
  59.                               const char *file,
  60.                               int line)
  61. {
  62.   if (mode & CRYPTO_LOCK)
  63.     VXItrdMutexLock(p->_mutex);
  64.   else
  65.     VXItrdMutexUnlock(p->_mutex);
  66. }
  67. static void dyn_destroy_function(CRYPTO_dynlock_value *p,
  68.                                  const char *file,
  69.                                  int line)
  70. {
  71.   delete p;
  72. }
  73. static int thread_cleanup()
  74. {
  75.   for (int i = CRYPTO_num_locks() - 1; i >= 0; i--)
  76.   {
  77.     VXItrdMutexDestroy(&sslMutex[i]);
  78.     sslMutex[i] = NULL;
  79.   }
  80.   delete [] sslMutex;
  81.   sslMutex = NULL;
  82.   CRYPTO_set_locking_callback(NULL);
  83.   CRYPTO_set_id_callback(NULL);
  84.   CRYPTO_set_dynlock_create_callback(NULL);
  85.   CRYPTO_set_dynlock_lock_callback(NULL);
  86.   CRYPTO_set_dynlock_destroy_callback(NULL);
  87.   return 0;
  88. }
  89. static int thread_setup()
  90. {
  91.   int n = CRYPTO_num_locks();
  92.   sslMutex = new VXItrdMutex *[n];
  93.   int i;
  94.   for (i = 0; i < n; i++) sslMutex[i] = NULL;
  95.   for (i = 0; i < n; i++)
  96.   {
  97.     if (VXItrdMutexCreate(&sslMutex[i]) != VXItrd_RESULT_SUCCESS)
  98.       goto failure;
  99.   }
  100.   CRYPTO_set_locking_callback((void (*)(int,int, const char *,int))
  101.                               ssl_locking_callback);
  102.   CRYPTO_set_id_callback((unsigned long(*)()) VXItrdThreadGetID);
  103.   CRYPTO_set_dynlock_create_callback((CRYPTO_dynlock_value *
  104.                                       (*)(const char *, int))
  105.                                      dyn_create_function);
  106.   CRYPTO_set_dynlock_lock_callback((void (*)(int,
  107.                                              CRYPTO_dynlock_value *,
  108.                                              const char *,
  109.                                              int))
  110.                                    dyn_lock_function);
  111.   CRYPTO_set_dynlock_destroy_callback((void (*)(CRYPTO_dynlock_value *,
  112.                                                 const char *,
  113.                                                 int))
  114.                                       dyn_destroy_function);
  115.   return 0;
  116.  failure:
  117.   thread_cleanup();
  118.   return -1;
  119. }
  120. int SBinetSSLsocket::initialize()
  121. {
  122.   SSLeay_add_ssl_algorithms();
  123.   _meth = SSLv23_client_method();
  124.   SSL_load_error_strings();
  125.   _ctx = SSL_CTX_new (_meth);
  126.   if (_ctx == NULL) return -1;
  127.   SSL_CTX_set_mode(_ctx, SSL_MODE_AUTO_RETRY);
  128.   return thread_setup();
  129. }
  130. int SBinetSSLsocket::shutdown()
  131. {
  132.   thread_cleanup();
  133.   SSL_CTX_free(_ctx);
  134.   return 0;
  135. }
  136. // SBinetSSLsocket::SBinetSSLsocket
  137. // Refer to SBinetSSLsocket.hpp for doc.
  138. SBinetSSLsocket::SBinetSSLsocket(Type socktype, SWIutilLogger *logger):
  139.   SWIsocket(socktype, logger),_ssl(NULL)
  140. {}
  141. // SBinetSSLsocket::~SBinetSSLsocket
  142. // Refer to SBinetSSLsocket.hpp for doc.
  143. SBinetSSLsocket::~SBinetSSLsocket()
  144. {
  145.   close();
  146.   if (_ssl) SSL_free(_ssl);
  147. }
  148. SWIstream::Result SBinetSSLsocket::connect(const SWIipAddress& endpoint, long timeout)
  149. {
  150.   SWIstream::Result rc = SWIsocket::connect(endpoint, timeout);
  151.   if (rc != SWIstream::SUCCESS) return rc;
  152.   rc = SWIstream::FAILURE;
  153.   if ((_ssl = SSL_new(_ctx)) == NULL)
  154.     error(L"SSL_new", 700);
  155.   else if (SSL_set_fd(_ssl, getSD()) == 0)
  156.     error(L"SSL_set_fd", 700);
  157.   else if (SSL_connect(_ssl) == -1)
  158.     error(L"SSL_connect", 700);
  159.   else
  160.     rc = SWIstream::SUCCESS;
  161.   if (rc != SWIstream::SUCCESS && _ssl != NULL)
  162.   {
  163.     SSL_free(_ssl);
  164.     _ssl = NULL;
  165.   }
  166.   return rc;
  167. }
  168. int SBinetSSLsocket::read(void* buf, int len)
  169. {
  170.   return recv(buf, len);
  171. }
  172. int SBinetSSLsocket::recv(void* buf, int len, int msgf)
  173. {
  174.   for (;;)
  175.   {
  176.     int rc1 = SSL_read(_ssl, buf, len);
  177.     int rc2 = SSL_get_error(_ssl, rc1);
  178.     switch (rc2)
  179.     {
  180.      case SSL_ERROR_NONE:
  181.        return rc1;
  182.      case SSL_ERROR_ZERO_RETURN:
  183.        return SWIstream::END_OF_FILE;
  184.      case SSL_ERROR_WANT_READ:
  185.      case SSL_ERROR_WANT_WRITE:
  186.        // should not really happend because of the SSL_MODE_AUTO_RETRY.
  187.        // Do nothing, just try again.
  188.        // Maybe we should yield the thread or sleep to avoid CPU hog
  189.        error(L"SSL_read", 701, L"SSL_get_error", rc2);
  190.        break;
  191.      default:
  192.        error(L"SSL_read", 700, L"SSL_get_error", rc2);
  193.        return SWIstream::READ_ERROR;
  194.     }
  195.   }
  196. }
  197. int SBinetSSLsocket::recvfrom(SWIipAddress& sa, void* buf, int len, int msgf)
  198. {
  199.   int rc = recv(buf, len, msgf);
  200.   if (rc >= 0)
  201.   {
  202.     const SWIipAddress *p = getRemoteAddress();
  203.     //if (p != NULL) sa = *p;
  204.   }
  205.   return rc;
  206. }
  207. int SBinetSSLsocket::write(const void* buf, int len)
  208. {
  209.   return send(buf, len);
  210. }
  211. int SBinetSSLsocket::send(const void* buf, int len, int msgf)
  212. {
  213.   for (;;)
  214.   {
  215.     int rc1 = SSL_write(_ssl, const_cast<void *>(buf), len);
  216.     int rc2 = SSL_get_error(_ssl, rc1);
  217.     switch (rc2)
  218.     {
  219.      case SSL_ERROR_NONE:
  220.        return rc1;
  221.      case SSL_ERROR_ZERO_RETURN:
  222.        return SWIstream::END_OF_FILE;
  223.      case SSL_ERROR_WANT_READ:
  224.      case SSL_ERROR_WANT_WRITE:
  225.        // should not really happend because of the SSL_MODE_AUTO_RETRY.
  226.        // Do nothing, just try again.
  227.        // Maybe we should yield the thread or sleep to avoid CPU hog
  228.        error(L"SSL_write", 701, L"SSL_get_error", rc2);
  229.        break;
  230.      default:
  231.        error(L"SSL_write", 700, L"SSL_get_error", rc2);
  232.        return SWIstream::READ_ERROR;
  233.     }
  234.   }
  235. }
  236. int SBinetSSLsocket::sendto(const SWIipAddress& sa, const void* buf, int len, int msgf)
  237. {
  238.   return send(buf,len,msgf);
  239. }
  240. SWIstream::Result SBinetSSLsocket::shutdown(shuthow sh)
  241. {
  242.   // Not sure how to handler shutdown in SSL context.  However, shutdown
  243.   // should not be used in SBinet.
  244.   error(L"SBinetSSLsocket::shutdown", 701);
  245.   return SWIstream::FAILURE;
  246. }
  247. SWIstream::Result SBinetSSLsocket::close()
  248. {
  249.   if (_ssl != NULL)
  250.   {
  251.     SSL_shutdown(_ssl);
  252.     SSL_free(_ssl);
  253.     _ssl = NULL;
  254.   }
  255.   return SWIsocket::close();
  256. }