00001
00002
00003 #include "ace/SOCK_Connector.h"
00004 #include "ace/INET_Addr.h"
00005 #include "ace/Log_Msg.h"
00006 #include "ace/OS_NS_unistd.h"
00007 #include "ace/OS_NS_sys_socket.h"
00008 #include "ace/os_include/os_fcntl.h"
00009
00010 #if !defined (ACE_HAS_WINCE)
00011 #include "ace/OS_QoS.h"
00012 #endif // ACE_HAS_WINCE
00013
00014 #if !defined (__ACE_INLINE__)
00015 #include "ace/SOCK_Connector.inl"
00016 #endif
00017
00018 ACE_RCSID(ace, SOCK_Connector, "$Id: SOCK_Connector.cpp 83891 2008-11-28 11:01:50Z johnnyw $")
00019
00020 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00021
00022 ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_Connector)
00023
00024 void
00025 ACE_SOCK_Connector::dump (void) const
00026 {
00027 #if defined (ACE_HAS_DUMP)
00028 ACE_TRACE ("ACE_SOCK_Connector::dump");
00029 #endif
00030 }
00031
00032 int
00033 ACE_SOCK_Connector::shared_open (ACE_SOCK_Stream &new_stream,
00034 int protocol_family,
00035 int protocol,
00036 int reuse_addr)
00037 {
00038 ACE_TRACE ("ACE_SOCK_Connector::shared_open");
00039
00040
00041 if (new_stream.get_handle () == ACE_INVALID_HANDLE
00042 && new_stream.open (SOCK_STREAM,
00043 protocol_family,
00044 protocol,
00045 reuse_addr) == -1)
00046 return -1;
00047 else
00048 return 0;
00049 }
00050
00051 int
00052 ACE_SOCK_Connector::shared_open (ACE_SOCK_Stream &new_stream,
00053 int protocol_family,
00054 int protocol,
00055 ACE_Protocol_Info *protocolinfo,
00056 ACE_SOCK_GROUP g,
00057 u_long flags,
00058 int reuse_addr)
00059 {
00060 ACE_TRACE ("ACE_SOCK_Connector::shared_open");
00061
00062
00063 if (new_stream.get_handle () == ACE_INVALID_HANDLE
00064 && new_stream.open (SOCK_STREAM,
00065 protocol_family,
00066 protocol,
00067 protocolinfo,
00068 g,
00069 flags,
00070 reuse_addr) == -1)
00071 return -1;
00072 else
00073 return 0;
00074 }
00075
00076 int
00077 ACE_SOCK_Connector::shared_connect_start (ACE_SOCK_Stream &new_stream,
00078 const ACE_Time_Value *timeout,
00079 const ACE_Addr &local_sap)
00080 {
00081 ACE_TRACE ("ACE_SOCK_Connector::shared_connect_start");
00082
00083 if (local_sap != ACE_Addr::sap_any)
00084 {
00085 sockaddr *laddr = reinterpret_cast<sockaddr *> (local_sap.get_addr ());
00086 int size = local_sap.get_size ();
00087
00088 if (ACE_OS::bind (new_stream.get_handle (),
00089 laddr,
00090 size) == -1)
00091 {
00092
00093 ACE_Errno_Guard error (errno);
00094 new_stream.close ();
00095 return -1;
00096 }
00097 }
00098
00099
00100 if (timeout != 0 && new_stream.enable (ACE_NONBLOCK) == -1)
00101 return -1;
00102 else
00103 return 0;
00104 }
00105
00106 int
00107 ACE_SOCK_Connector::shared_connect_finish (ACE_SOCK_Stream &new_stream,
00108 const ACE_Time_Value *timeout,
00109 int result)
00110 {
00111 ACE_TRACE ("ACE_SOCK_Connector::shared_connect_finish");
00112
00113 ACE_Errno_Guard error (errno);
00114
00115 if (result == -1 && timeout != 0)
00116 {
00117
00118 if (error == EINPROGRESS || error == EWOULDBLOCK)
00119 {
00120
00121 if (*timeout == ACE_Time_Value::zero)
00122 {
00123 #if defined(ACE_WIN32)
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 if(ACE::handle_timed_complete (new_stream.get_handle (),
00136 timeout) == ACE_INVALID_HANDLE)
00137 {
00138 int const tmp = errno;
00139 if (tmp != ETIME)
00140 {
00141 error = tmp;
00142 }
00143 else
00144 error = EWOULDBLOCK;
00145 }
00146 else
00147 result = 0;
00148 #else
00149 error = EWOULDBLOCK;
00150 #endif
00151 }
00152
00153 else if (this->complete (new_stream,
00154 0,
00155 timeout) == -1)
00156 error = errno;
00157 else
00158 return 0;
00159 }
00160 }
00161
00162
00163
00164 if (result != -1 || error == EISCONN)
00165 {
00166
00167 result = new_stream.disable (ACE_NONBLOCK);
00168 if (result == -1)
00169 {
00170 new_stream.close ();
00171 }
00172 }
00173 else if (!(error == EWOULDBLOCK || error == ETIMEDOUT))
00174 {
00175 new_stream.close ();
00176 }
00177
00178 return result;
00179 }
00180
00181
00182
00183 int
00184 ACE_SOCK_Connector::connect (ACE_SOCK_Stream &new_stream,
00185 const ACE_Addr &remote_sap,
00186 const ACE_Time_Value *timeout,
00187 const ACE_Addr &local_sap,
00188 int reuse_addr,
00189 int ,
00190 int ,
00191 int protocol)
00192 {
00193 ACE_TRACE ("ACE_SOCK_Connector::connect");
00194
00195 if (this->shared_open (new_stream,
00196 remote_sap.get_type (),
00197 protocol,
00198 reuse_addr) == -1)
00199 return -1;
00200 else if (this->shared_connect_start (new_stream,
00201 timeout,
00202 local_sap) == -1)
00203 return -1;
00204
00205 int result = ACE_OS::connect (new_stream.get_handle (),
00206 reinterpret_cast<sockaddr *> (remote_sap.get_addr ()),
00207 remote_sap.get_size ());
00208
00209 return this->shared_connect_finish (new_stream,
00210 timeout,
00211 result);
00212 }
00213
00214 #if !defined (ACE_HAS_WINCE)
00215 int
00216 ACE_SOCK_Connector::connect (ACE_SOCK_Stream &new_stream,
00217 const ACE_Addr &remote_sap,
00218 ACE_QoS_Params qos_params,
00219 const ACE_Time_Value *timeout,
00220 const ACE_Addr &local_sap,
00221 ACE_Protocol_Info * protocolinfo,
00222 ACE_SOCK_GROUP g,
00223 u_long flags,
00224 int reuse_addr,
00225 int )
00226 {
00227 ACE_TRACE ("ACE_SOCK_Connector::connect");
00228
00229 if (this->shared_open (new_stream,
00230 remote_sap.get_type (),
00231 0,
00232 protocolinfo,
00233 g,
00234 flags,
00235 reuse_addr) == -1)
00236 return -1;
00237 else if (this->shared_connect_start (new_stream,
00238 timeout,
00239 local_sap) == -1)
00240 return -1;
00241
00242 int result = ACE_OS::connect (new_stream.get_handle (),
00243 reinterpret_cast<sockaddr *> (remote_sap.get_addr ()),
00244 remote_sap.get_size (),
00245 qos_params);
00246
00247 return this->shared_connect_finish (new_stream,
00248 timeout,
00249 result);
00250 }
00251 #endif // ACE_HAS_WINCE
00252
00253
00254
00255 int
00256 ACE_SOCK_Connector::complete (ACE_SOCK_Stream &new_stream,
00257 ACE_Addr *remote_sap,
00258 const ACE_Time_Value *tv)
00259 {
00260 ACE_TRACE ("ACE_SOCK_Connector::complete");
00261 ACE_HANDLE h = ACE::handle_timed_complete (new_stream.get_handle (),
00262 tv);
00263
00264 if (h == ACE_INVALID_HANDLE)
00265 {
00266 #if defined (ACE_WIN32)
00267
00268
00269
00270
00271 ACE_Time_Value time (0, ACE_NON_BLOCKING_BUG_DELAY);
00272 ACE_OS::sleep (time);
00273 h = ACE::handle_timed_complete (new_stream.get_handle (),
00274 tv);
00275 if (h == ACE_INVALID_HANDLE)
00276 {
00277 #endif
00278
00279 ACE_Errno_Guard error (errno);
00280 new_stream.close ();
00281 return -1;
00282 #if defined (ACE_WIN32)
00283 }
00284 #endif
00285 }
00286
00287 if (remote_sap != 0)
00288 {
00289 int len = remote_sap->get_size ();
00290 sockaddr *addr = reinterpret_cast<sockaddr *> (remote_sap->get_addr ());
00291 if (ACE_OS::getpeername (h,
00292 addr,
00293 &len) == -1)
00294 {
00295
00296 ACE_Errno_Guard error (errno);
00297 new_stream.close ();
00298 return -1;
00299 }
00300 }
00301
00302
00303 new_stream.disable (ACE_NONBLOCK);
00304 return 0;
00305 }
00306
00307 ACE_SOCK_Connector::ACE_SOCK_Connector (ACE_SOCK_Stream &new_stream,
00308 const ACE_Addr &remote_sap,
00309 const ACE_Time_Value *timeout,
00310 const ACE_Addr &local_sap,
00311 int reuse_addr,
00312 int flags,
00313 int perms,
00314 int protocol)
00315 {
00316 ACE_TRACE ("ACE_SOCK_Connector::ACE_SOCK_Connector");
00317
00318 if (this->connect (new_stream,
00319 remote_sap,
00320 timeout,
00321 local_sap,
00322 reuse_addr,
00323 flags,
00324 perms,
00325 protocol) == -1
00326 && timeout != 0
00327 && !(errno == EWOULDBLOCK || errno == ETIME || errno == ETIMEDOUT))
00328 ACE_ERROR ((LM_ERROR,
00329 ACE_TEXT ("%p\n"),
00330 ACE_TEXT ("ACE_SOCK_Connector::ACE_SOCK_Connector")));
00331 }
00332
00333 #if !defined (ACE_HAS_WINCE)
00334 ACE_SOCK_Connector::ACE_SOCK_Connector (ACE_SOCK_Stream &new_stream,
00335 const ACE_Addr &remote_sap,
00336 ACE_QoS_Params qos_params,
00337 const ACE_Time_Value *timeout,
00338 const ACE_Addr &local_sap,
00339 ACE_Protocol_Info *protocolinfo,
00340 ACE_SOCK_GROUP g,
00341 u_long flags,
00342 int reuse_addr,
00343 int perms)
00344 {
00345 ACE_TRACE ("ACE_SOCK_Connector::ACE_SOCK_Connector");
00346
00347 if (this->connect (new_stream,
00348 remote_sap,
00349 qos_params,
00350 timeout,
00351 local_sap,
00352 protocolinfo,
00353 g,
00354 flags,
00355 reuse_addr,
00356 perms) == -1
00357 && timeout != 0
00358 && !(errno == EWOULDBLOCK || errno == ETIME || errno == ETIMEDOUT))
00359 ACE_ERROR ((LM_ERROR,
00360 ACE_TEXT ("%p\n"),
00361 ACE_TEXT ("ACE_SOCK_Connector::ACE_SOCK_Connector")));
00362 }
00363 #endif // ACE_HAS_WINCE
00364
00365 ACE_END_VERSIONED_NAMESPACE_DECL