SSL_Asynch_BIO.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 #include "SSL_Asynch_BIO.h"
00004 
00005 #if OPENSSL_VERSION_NUMBER > 0x0090581fL && ((defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || (defined (ACE_HAS_AIO_CALLS)))
00006 
00007 #include "SSL_Asynch_Stream.h"
00008 #include "ace/OS_NS_string.h"
00009 
00010 
00011 ACE_RCSID (ACE_SSL,
00012            SSL_Asynch_BIO,
00013            "SSL_Asynch_BIO.cpp,v 1.13 2006/04/19 13:18:16 jwillemsen Exp")
00014 
00015 
00016 #if (defined (ACE_HAS_VERSIONED_NAMESPACE) && ACE_HAS_VERSIONED_NAMESPACE == 1)
00017 # define ACE_ASYNCH_BIO_WRITE_NAME ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ACE_Asynch_BIO_write)
00018 # define ACE_ASYNCH_BIO_READ_NAME  ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ACE_Asynch_BIO_read)
00019 # define ACE_ASYNCH_BIO_PUTS_NAME  ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ACE_Asynch_BIO_puts)
00020 # define ACE_ASYNCH_BIO_CTRL_NAME  ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ACE_Asynch_BIO_ctrl)
00021 # define ACE_ASYNCH_BIO_NEW_NAME   ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ACE_Asynch_BIO_new)
00022 # define ACE_ASYNCH_BIO_FREE_NAME  ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ACE_Asynch_BIO_free)
00023 #else
00024 # define ACE_ASYNCH_BIO_WRITE_NAME ACE_Asynch_BIO_write
00025 # define ACE_ASYNCH_BIO_READ_NAME  ACE_Asynch_BIO_read
00026 # define ACE_ASYNCH_BIO_PUTS_NAME  ACE_Asynch_BIO_puts
00027 # define ACE_ASYNCH_BIO_CTRL_NAME  ACE_Asynch_BIO_ctrl
00028 # define ACE_ASYNCH_BIO_NEW_NAME   ACE_Asynch_BIO_new
00029 # define ACE_ASYNCH_BIO_FREE_NAME  ACE_Asynch_BIO_free
00030 #endif  /* ACE_HAS_VERSIONED_NAMESPACE == 1 */
00031 
00032 /**
00033  * @name OpenSSL BIO Helper Methods for use with ACE's Asynchronous
00034  *       SSL I/O support.
00035  */
00036 //@{
00037 extern "C"
00038 {
00039   int  ACE_ASYNCH_BIO_WRITE_NAME (BIO *pBIO, const char *buf, int len);
00040   int  ACE_ASYNCH_BIO_READ_NAME  (BIO *pBIO, char *buf, int len);
00041   int  ACE_ASYNCH_BIO_PUTS_NAME  (BIO *pBIO, const char *str);
00042   long ACE_ASYNCH_BIO_CTRL_NAME  (BIO *pBIO, int cmd, long arg1, void *arg2);
00043   int  ACE_ASYNCH_BIO_NEW_NAME   (BIO *pBIO);
00044   int  ACE_ASYNCH_BIO_FREE_NAME  (BIO *pBIO);
00045 }
00046 //@}
00047 
00048 #define BIO_TYPE_ACE  ( 21 | BIO_TYPE_SOURCE_SINK )
00049 
00050 static BIO_METHOD methods_ACE =
00051   {
00052     BIO_TYPE_ACE, // BIO_TYPE_PROXY_SERVER,
00053     "ACE_Asynch_BIO",
00054     ACE_ASYNCH_BIO_WRITE_NAME,
00055     ACE_ASYNCH_BIO_READ_NAME,
00056     ACE_ASYNCH_BIO_PUTS_NAME,
00057     NULL, /* ACE_ASYNCH_BIO_GETS_NAME, */
00058     ACE_ASYNCH_BIO_CTRL_NAME,
00059     ACE_ASYNCH_BIO_NEW_NAME,
00060     ACE_ASYNCH_BIO_FREE_NAME,
00061     NULL
00062   };
00063 
00064 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00065 
00066 BIO *
00067 ACE_SSL_make_BIO (void * ssl_asynch_stream)
00068 {
00069   BIO * const pBIO = BIO_new (&methods_ACE);
00070 
00071   if (pBIO)
00072     BIO_ctrl (pBIO,
00073               BIO_C_SET_FILE_PTR,
00074               0,
00075               ssl_asynch_stream);
00076 
00077   return pBIO;
00078 }
00079 
00080 /**
00081  * @struct @c ACE_SSL_Asynch_Stream_Accessor
00082  *
00083  * @brief Privileged @c ACE_SSL_Asynch_Stream accessor.
00084  *
00085  * This structure is a @c friend to the @c ACE_SSL_Asynch_Stream
00086  * class so that it can gain access to the protected
00087  * ssl_bio_{read,write}() methods in that class.  It is full declared
00088  * in this implementation file to hide its interface from users to
00089  * prevent potential abuse of the friend relationship between it and
00090  * the @c ACE_SSL_Asynch_Stream class.
00091  */
00092 struct ACE_SSL_Asynch_Stream_Accessor
00093 {
00094   static int read (ACE_SSL_Asynch_Stream * stream,
00095                char * buf,
00096                size_t len,
00097                int & errval)
00098   {
00099     return stream->ssl_bio_read (buf, len, errval);
00100   }
00101 
00102   static int write (ACE_SSL_Asynch_Stream * stream,
00103                     const char * buf,
00104                     size_t len,
00105                     int & errval)
00106   {
00107     return stream->ssl_bio_write (buf, len, errval);
00108   }
00109 };
00110 
00111 ACE_END_VERSIONED_NAMESPACE_DECL
00112 
00113 int
00114 ACE_ASYNCH_BIO_NEW_NAME (BIO * pBIO)
00115 {
00116   pBIO->init  = 0;    // not initialized
00117   pBIO->num   = 0;    // still zero ( we can use it )
00118   pBIO->ptr   = 0;    // will be pointer to ACE_SSL_Asynch_Stream
00119   pBIO->flags = 0;    //
00120 
00121   return 1;
00122 }
00123 
00124 int
00125 ACE_ASYNCH_BIO_FREE_NAME (BIO * pBIO)
00126 {
00127   if (pBIO && pBIO->shutdown)
00128     {
00129       pBIO->ptr   = 0;
00130       pBIO->init  = 0;
00131       pBIO->num   = 0;
00132       pBIO->flags = 0;
00133 
00134       return 1;
00135     }
00136 
00137   return 0;
00138 }
00139 
00140 int
00141 ACE_ASYNCH_BIO_READ_NAME (BIO * pBIO, char * buf, int len)
00142 {
00143   BIO_clear_retry_flags (pBIO);
00144 
00145   ACE_SSL_Asynch_Stream * const p_stream =
00146     static_cast<ACE_SSL_Asynch_Stream *> (pBIO->ptr);
00147 
00148   if (pBIO->init == 0 || p_stream == 0 || buf == 0 || len <= 0)
00149     return -1;
00150 
00151   BIO_clear_retry_flags (pBIO);
00152 
00153   int errval = 0;
00154 
00155   int retval =
00156     ACE_SSL_Asynch_Stream_Accessor::read (p_stream,
00157                                           buf,
00158                                           len,
00159                                           errval);
00160 
00161   if (retval >= 0)
00162     return retval;
00163 
00164   if (errval == EINPROGRESS)
00165     BIO_set_retry_read (pBIO);
00166 
00167   return -1;
00168 }
00169 
00170 int
00171 ACE_ASYNCH_BIO_WRITE_NAME (BIO * pBIO, const char * buf, int len)
00172 {
00173   BIO_clear_retry_flags (pBIO);
00174 
00175   ACE_SSL_Asynch_Stream * p_stream =
00176     static_cast<ACE_SSL_Asynch_Stream *> (pBIO->ptr);
00177 
00178   if (pBIO->init == 0 || p_stream == 0 || buf == 0 || len <= 0)
00179     return -1;
00180 
00181   BIO_clear_retry_flags (pBIO);
00182 
00183   int errval = 0;
00184 
00185   int retval =
00186     ACE_SSL_Asynch_Stream_Accessor::write (p_stream,
00187                                            buf,
00188                                            len,
00189                                            errval);
00190 
00191   if (retval >= 0)
00192     return retval;
00193 
00194   if (errval == EINPROGRESS)
00195     BIO_set_retry_write (pBIO);
00196 
00197   return -1;
00198 }
00199 
00200 long
00201 ACE_ASYNCH_BIO_CTRL_NAME (BIO * pBIO, int cmd, long num, void *ptr)
00202 {
00203   long ret = 1;
00204 
00205   switch (cmd)
00206     {
00207     case BIO_C_SET_FILE_PTR:
00208       pBIO->shutdown = static_cast<int> (num);
00209       pBIO->ptr = ptr;
00210       pBIO->init = 1;
00211       break;
00212 
00213     case BIO_CTRL_INFO:
00214       ret = 0;
00215       break;
00216 
00217     case BIO_CTRL_GET_CLOSE:
00218       ret = pBIO->shutdown;
00219       break;
00220 
00221     case BIO_CTRL_SET_CLOSE:
00222       pBIO->shutdown = static_cast<int> (num);
00223       break;
00224 
00225     case BIO_CTRL_PENDING:
00226     case BIO_CTRL_WPENDING:
00227       ret = 0;
00228       break;
00229 
00230     case BIO_CTRL_DUP:
00231     case BIO_CTRL_FLUSH:
00232       ret = 1;
00233       break;
00234 
00235     default:
00236       ret = 0;
00237       break;
00238   }
00239 
00240   return ret;
00241 }
00242 
00243 int
00244 ACE_ASYNCH_BIO_PUTS_NAME (BIO *pBIO, const char *str)
00245 {
00246   size_t const n = ACE_OS::strlen (str);
00247 
00248   return ACE_ASYNCH_BIO_WRITE_NAME (pBIO, str, n);
00249 }
00250 
00251 #endif  /* OPENSSL_VERSION_NUMBER > 0x0090581fL && (ACE_WIN32 ||
00252            ACE_HAS_AIO_CALLS) */

Generated on Thu Nov 9 11:41:56 2006 for ACE_SSL by doxygen 1.3.6