Go to the documentation of this file.00001
00002
00003 #include "ace/INet/SSL_Proxy_Connector.h"
00004 #include "ace/INet/INet_Log.h"
00005
00006 #include "ace/OS_NS_errno.h"
00007 #include "ace/Handle_Set.h"
00008 #include "ace/Log_Msg.h"
00009 #include "ace/Countdown_Time.h"
00010 #include "ace/Truncate.h"
00011
00012 #include <openssl/err.h>
00013
00014 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00015
00016 namespace ACE
00017 {
00018 namespace INet
00019 {
00020
00021 SSL_Proxy_Connector::SSL_Proxy_Connector () {}
00022
00023 SSL_Proxy_Connector::~SSL_Proxy_Connector () {}
00024
00025
00026
00027
00028 int
00029 SSL_Proxy_Connector::ssl_connect (ACE_SSL_SOCK_Stream &new_stream,
00030 const ACE_Time_Value *timeout)
00031 {
00032 SSL *ssl = new_stream.ssl ();
00033
00034 if (SSL_is_init_finished (ssl))
00035 return 0;
00036
00037
00038
00039 if (!SSL_in_connect_init (ssl))
00040 ::SSL_set_connect_state (ssl);
00041
00042 ACE_HANDLE handle = new_stream.get_handle ();
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 int reset_blocking_mode = 0;
00053 if (timeout != 0)
00054 {
00055 reset_blocking_mode = ACE_BIT_DISABLED (ACE::get_flags (handle),
00056 ACE_NONBLOCK);
00057
00058
00059 if (reset_blocking_mode
00060 && ACE::set_flags (handle,
00061 ACE_NONBLOCK) == -1)
00062 return -1;
00063 }
00064
00065 ACE_Time_Value t;
00066 if (timeout != 0)
00067 t = *timeout;
00068
00069
00070 ACE_Countdown_Time countdown ((timeout == 0 ? 0 : &t));
00071
00072 int status;
00073
00074 do
00075 {
00076
00077
00078 ACE_Handle_Set rd_handle;
00079 ACE_Handle_Set wr_handle;
00080
00081 status = ::SSL_connect (ssl);
00082 switch (::SSL_get_error (ssl, status))
00083 {
00084 case SSL_ERROR_NONE:
00085
00086 new_stream.disable (ACE_NONBLOCK);
00087 status = 0;
00088 break;
00089
00090 case SSL_ERROR_WANT_WRITE:
00091 wr_handle.set_bit (handle);
00092 status = 1;
00093 break;
00094
00095 case SSL_ERROR_WANT_READ:
00096 rd_handle.set_bit (handle);
00097 status = 1;
00098 break;
00099
00100 case SSL_ERROR_ZERO_RETURN:
00101
00102
00103
00104 status = -1;
00105 break;
00106
00107 case SSL_ERROR_SYSCALL:
00108
00109
00110
00111
00112
00113
00114
00115
00116 if (ACE_OS::set_errno_to_last_error () == EWOULDBLOCK &&
00117 status == -1)
00118 {
00119
00120
00121
00122 status = 1;
00123 if (SSL_want_write (ssl))
00124 {
00125 wr_handle.set_bit (handle);
00126 }
00127 else if (SSL_want_read (ssl))
00128 {
00129 rd_handle.set_bit (handle);
00130 }
00131 else
00132 {
00133 status = -1;
00134 }
00135 }
00136 else
00137 {
00138 status = -1;
00139 }
00140 break;
00141
00142 default:
00143 ACE_SSL_Context::report_error ();
00144 status = -1;
00145 break;
00146 }
00147
00148 if (status == 1)
00149 {
00150
00151 ACE_ASSERT (rd_handle.num_set () == 1 || wr_handle.num_set () == 1);
00152
00153
00154 status = ACE::select (int (handle) + 1,
00155 &rd_handle,
00156 &wr_handle,
00157 0,
00158 (timeout == 0 ? 0 : &t));
00159
00160 (void) countdown.update ();
00161
00162
00163
00164
00165 if (status >= 1)
00166 {
00167 status = 1;
00168 }
00169 else
00170 {
00171 status = -1;
00172 }
00173 }
00174
00175 } while (status == 1 && !SSL_is_init_finished (ssl));
00176
00177 if (reset_blocking_mode)
00178 {
00179 ACE_Errno_Guard eguard (errno);
00180 ACE::clr_flags (handle, ACE_NONBLOCK);
00181 }
00182
00183 return (status == -1 ? -1 : 0);
00184 }
00185
00186 int
00187 SSL_Proxy_Connector::connect (ACE_SSL_SOCK_Stream &new_stream,
00188 ACE_HANDLE proxy_handle,
00189 const ACE_Time_Value *timeout)
00190 {
00191 INET_TRACE ("SSL_Proxy_Connector::connect");
00192
00193 if (new_stream.get_handle () != ACE_INVALID_HANDLE)
00194 return -1;
00195
00196
00197
00198 new_stream.set_handle (proxy_handle);
00199
00200
00201 int result = this->ssl_connect (new_stream, timeout);
00202
00203 if (result == -1)
00204 new_stream.close ();
00205
00206 return result;
00207 }
00208
00209 }
00210 }
00211
00212 ACE_END_VERSIONED_NAMESPACE_DECL