00001
00002
00003
00004
00005 #include "SSL_SOCK_Connector.h"
00006
00007 #include "ace/OS_NS_errno.h"
00008 #include "ace/Handle_Set.h"
00009 #include "ace/INET_Addr.h"
00010 #include "ace/Log_Msg.h"
00011 #include "ace/Countdown_Time.h"
00012
00013 #include <openssl/err.h>
00014
00015 #if !defined (__ACE_INLINE__)
00016 #include "SSL_SOCK_Connector.i"
00017 #endif
00018
00019 ACE_RCSID (ACE_SSL,
00020 SSL_SOCK_Connector,
00021 "SSL_SOCK_Connector.cpp,v 1.48 2005/10/28 16:14:56 ossama Exp")
00022
00023 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00024
00025 ACE_ALLOC_HOOK_DEFINE(ACE_SSL_SOCK_Connector)
00026
00027 ACE_SSL_SOCK_Connector::~ACE_SSL_SOCK_Connector (void)
00028 {
00029 ACE_TRACE ("ACE_SSL_SOCK_Connector::~ACE_SSL_SOCK_Connector");
00030 }
00031
00032 int
00033 ACE_SSL_SOCK_Connector::ssl_connect (ACE_SSL_SOCK_Stream &new_stream,
00034 const ACE_Time_Value *timeout)
00035 {
00036 SSL *ssl = new_stream.ssl ();
00037
00038 if (SSL_is_init_finished (ssl))
00039 return 0;
00040
00041
00042
00043 if (!SSL_in_connect_init (ssl))
00044 ::SSL_set_connect_state (ssl);
00045
00046 ACE_HANDLE handle = new_stream.get_handle ();
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 int reset_blocking_mode = 0;
00057 if (timeout != 0)
00058 {
00059 reset_blocking_mode = ACE_BIT_DISABLED (ACE::get_flags (handle),
00060 ACE_NONBLOCK);
00061
00062
00063 if (reset_blocking_mode
00064 && ACE::set_flags (handle,
00065 ACE_NONBLOCK) == -1)
00066 return -1;
00067 }
00068
00069 ACE_Time_Value t;
00070 if (timeout != 0)
00071 t = *timeout;
00072
00073
00074 ACE_Countdown_Time countdown ((timeout == 0 ? 0 : &t));
00075
00076 int status;
00077 do
00078 {
00079
00080
00081 ACE_Handle_Set rd_handle;
00082 ACE_Handle_Set wr_handle;
00083
00084 status = ::SSL_connect (ssl);
00085 switch (::SSL_get_error (ssl, status))
00086 {
00087 case SSL_ERROR_NONE:
00088
00089 new_stream.disable (ACE_NONBLOCK);
00090 status = 0;
00091 break;
00092
00093 case SSL_ERROR_WANT_WRITE:
00094 wr_handle.set_bit (handle);
00095 status = 1;
00096 break;
00097
00098 case SSL_ERROR_WANT_READ:
00099 rd_handle.set_bit (handle);
00100 status = 1;
00101 break;
00102
00103 case SSL_ERROR_ZERO_RETURN:
00104
00105
00106
00107 status = -1;
00108 break;
00109
00110 case SSL_ERROR_SYSCALL:
00111
00112
00113
00114
00115
00116
00117
00118
00119 if (ACE_OS::set_errno_to_last_error () == EWOULDBLOCK &&
00120 status == -1)
00121 {
00122
00123
00124
00125 status = 1;
00126 if (SSL_want_write (ssl))
00127 wr_handle.set_bit (handle);
00128 else if (SSL_want_read (ssl))
00129 rd_handle.set_bit (handle);
00130 else
00131 status = -1;
00132 }
00133 else
00134 status = -1;
00135 break;
00136
00137 default:
00138 ACE_SSL_Context::report_error ();
00139 status = -1;
00140 break;
00141 }
00142
00143 if (status == 1)
00144 {
00145
00146 ACE_ASSERT (rd_handle.num_set () == 1 || wr_handle.num_set () == 1);
00147
00148
00149 status = ACE::select (int (handle) + 1,
00150 &rd_handle,
00151 &wr_handle,
00152 0,
00153 (timeout == 0 ? 0 : &t));
00154
00155 (void) countdown.update ();
00156
00157
00158
00159
00160 if (status >= 1)
00161 status = 1;
00162 else
00163 status = -1;
00164 }
00165
00166 } while (status == 1 && !SSL_is_init_finished (ssl));
00167
00168 if (reset_blocking_mode)
00169 {
00170 ACE_Errno_Guard eguard (errno);
00171 ACE::clr_flags (handle, ACE_NONBLOCK);
00172 }
00173
00174 return (status == -1 ? -1 : 0);
00175
00176 }
00177
00178 int
00179 ACE_SSL_SOCK_Connector::connect (ACE_SSL_SOCK_Stream &new_stream,
00180 const ACE_Addr &remote_sap,
00181 const ACE_Time_Value *timeout,
00182 const ACE_Addr &local_sap,
00183 int reuse_addr,
00184 int flags,
00185 int perms)
00186 {
00187 ACE_TRACE ("ACE_SSL_SOCK_Connector::connect");
00188
00189
00190
00191 ACE_Time_Value time_copy;
00192 ACE_Countdown_Time countdown (&time_copy);
00193 if (timeout != 0)
00194 {
00195 time_copy += *timeout;
00196 countdown.start ();
00197 }
00198
00199 int result =
00200 this->connector_.connect (new_stream.peer (),
00201 remote_sap,
00202 timeout,
00203 local_sap,
00204 reuse_addr,
00205 flags,
00206 perms);
00207
00208 int error = 0;
00209 if (result == -1)
00210 error = errno;
00211
00212
00213
00214
00215
00216
00217 if (new_stream.get_handle () == ACE_INVALID_HANDLE
00218 && (result == 0
00219 || (result == -1 && (error == EWOULDBLOCK
00220 || error == EINPROGRESS))))
00221 new_stream.set_handle (new_stream.peer ().get_handle ());
00222
00223 if (result == -1)
00224 return result;
00225
00226
00227
00228
00229 if (timeout != 0)
00230 {
00231 countdown.update ();
00232 timeout = &time_copy;
00233 }
00234
00235 result = this->ssl_connect (new_stream, timeout);
00236
00237 if (result == -1)
00238 new_stream.close ();
00239
00240 return result;
00241 }
00242
00243 int
00244 ACE_SSL_SOCK_Connector::connect (ACE_SSL_SOCK_Stream &new_stream,
00245 const ACE_Addr &remote_sap,
00246 ACE_QoS_Params qos_params,
00247 const ACE_Time_Value *timeout,
00248 const ACE_Addr &local_sap,
00249 ACE_Protocol_Info *protocolinfo,
00250 ACE_SOCK_GROUP g,
00251 u_long flags,
00252 int reuse_addr,
00253 int perms)
00254 {
00255 ACE_TRACE ("ACE_SSL_SOCK_Connector::connect");
00256
00257
00258
00259 ACE_Time_Value time_copy;
00260 ACE_Countdown_Time countdown (&time_copy);
00261 if (timeout != 0)
00262 {
00263 time_copy += *timeout;
00264 countdown.start ();
00265 }
00266
00267 int result = this->connector_.connect (new_stream.peer (),
00268 remote_sap,
00269 qos_params,
00270 timeout,
00271 local_sap,
00272 protocolinfo,
00273 g,
00274 flags,
00275 reuse_addr,
00276 perms);
00277
00278 int error = 0;
00279 if (result == -1)
00280 error = errno;
00281
00282
00283
00284
00285
00286
00287 if (new_stream.get_handle () == ACE_INVALID_HANDLE
00288 && (result == 0
00289 || (result == -1 && (error == EWOULDBLOCK
00290 || error == EINPROGRESS))))
00291 new_stream.set_handle (new_stream.peer ().get_handle ());
00292
00293 if (result == -1)
00294 return result;
00295
00296
00297
00298
00299 if (timeout != 0)
00300 {
00301 countdown.update ();
00302 timeout = &time_copy;
00303 }
00304
00305 result = this->ssl_connect (new_stream, timeout);
00306
00307 if (result == -1)
00308 new_stream.close ();
00309
00310 return result;
00311 }
00312
00313
00314
00315 int
00316 ACE_SSL_SOCK_Connector::complete (ACE_SSL_SOCK_Stream &new_stream,
00317 ACE_Addr *remote_sap,
00318 const ACE_Time_Value *tv)
00319 {
00320 ACE_TRACE ("ACE_SSL_SOCK_Connector::complete");
00321
00322
00323
00324 ACE_Time_Value time_copy;
00325 ACE_Countdown_Time countdown (&time_copy);
00326 if (tv != 0)
00327 {
00328 time_copy += *tv;
00329 countdown.start ();
00330 }
00331
00332
00333
00334 ACE_INET_Addr raddr;
00335 if (new_stream.peer ().get_remote_addr (raddr) != 0
00336 && this->connector_.complete (new_stream.peer (),
00337 remote_sap,
00338 tv) == -1)
00339 return -1;
00340
00341
00342
00343
00344
00345
00346
00347 if (tv != 0)
00348 {
00349 countdown.update ();
00350 tv = &time_copy;
00351 }
00352
00353 if (this->ssl_connect (new_stream, tv) == -1)
00354 {
00355 new_stream.close ();
00356 return -1;
00357 }
00358
00359 return 0;
00360
00361 }
00362
00363
00364 ACE_SSL_SOCK_Connector::ACE_SSL_SOCK_Connector (
00365 ACE_SSL_SOCK_Stream &new_stream,
00366 const ACE_Addr &remote_sap,
00367 const ACE_Time_Value *timeout,
00368 const ACE_Addr &local_sap,
00369 int reuse_addr,
00370 int flags,
00371 int perms)
00372 : connector_ ()
00373 {
00374 ACE_TRACE ("ACE_SSL_SOCK_Connector::ACE_SSL_SOCK_Connector");
00375 this->connect (new_stream,
00376 remote_sap,
00377 timeout,
00378 local_sap,
00379 reuse_addr,
00380 flags,
00381 perms);
00382 }
00383
00384 ACE_SSL_SOCK_Connector::ACE_SSL_SOCK_Connector (
00385 ACE_SSL_SOCK_Stream &new_stream,
00386 const ACE_Addr &remote_sap,
00387 ACE_QoS_Params qos_params,
00388 const ACE_Time_Value *timeout,
00389 const ACE_Addr &local_sap,
00390 ACE_Protocol_Info *protocolinfo,
00391 ACE_SOCK_GROUP g,
00392 u_long flags,
00393 int reuse_addr,
00394 int perms)
00395 : connector_ ()
00396 {
00397 ACE_TRACE ("ACE_SSL_SOCK_Connector::ACE_SSL_SOCK_Connector");
00398
00399 this->connect (new_stream,
00400 remote_sap,
00401 qos_params,
00402 timeout,
00403 local_sap,
00404 protocolinfo,
00405 g,
00406 flags,
00407 reuse_addr,
00408 perms);
00409 }
00410
00411 ACE_END_VERSIONED_NAMESPACE_DECL