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