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 79134 2007-07-31 18:23: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
00101 && new_stream.enable (ACE_NONBLOCK) == -1)
00102 return -1;
00103 else
00104 return 0;
00105 }
00106
00107 int
00108 ACE_SOCK_Connector::shared_connect_finish (ACE_SOCK_Stream &new_stream,
00109 const ACE_Time_Value *timeout,
00110 int result)
00111 {
00112 ACE_TRACE ("ACE_SOCK_Connector::shared_connect_finish");
00113
00114 ACE_Errno_Guard error (errno);
00115
00116 if (result == -1 && timeout != 0)
00117 {
00118
00119 if (error == EINPROGRESS || error == EWOULDBLOCK)
00120 {
00121
00122 if (timeout->sec () == 0
00123 && timeout->usec () == 0)
00124 {
00125 #if defined(ACE_WIN32)
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 if(ACE::handle_timed_complete (new_stream.get_handle (),
00138 timeout) == ACE_INVALID_HANDLE)
00139 {
00140 int const tmp = errno;
00141 if (tmp != ETIME)
00142 {
00143 error = tmp;
00144 }
00145 else
00146 error = EWOULDBLOCK;
00147 }
00148 else
00149 result = 0;
00150 #else
00151 error = EWOULDBLOCK;
00152 #endif
00153 }
00154
00155 else if (this->complete (new_stream,
00156 0,
00157 timeout) == -1)
00158 error = errno;
00159 else
00160 return 0;
00161 }
00162 }
00163
00164
00165
00166 if (result != -1 || error == EISCONN)
00167
00168 new_stream.disable (ACE_NONBLOCK);
00169 else if (!(error == EWOULDBLOCK || error == ETIMEDOUT))
00170 new_stream.close ();
00171
00172 return result;
00173 }
00174
00175
00176
00177 int
00178 ACE_SOCK_Connector::connect (ACE_SOCK_Stream &new_stream,
00179 const ACE_Addr &remote_sap,
00180 const ACE_Time_Value *timeout,
00181 const ACE_Addr &local_sap,
00182 int reuse_addr,
00183 int ,
00184 int ,
00185 int protocol)
00186 {
00187 ACE_TRACE ("ACE_SOCK_Connector::connect");
00188
00189 if (this->shared_open (new_stream,
00190 remote_sap.get_type (),
00191 protocol,
00192 reuse_addr) == -1)
00193 return -1;
00194 else if (this->shared_connect_start (new_stream,
00195 timeout,
00196 local_sap) == -1)
00197 return -1;
00198
00199 int result = ACE_OS::connect (new_stream.get_handle (),
00200 reinterpret_cast<sockaddr *> (remote_sap.get_addr ()),
00201 remote_sap.get_size ());
00202
00203 return this->shared_connect_finish (new_stream,
00204 timeout,
00205 result);
00206 }
00207
00208 #if !defined (ACE_HAS_WINCE)
00209 int
00210 ACE_SOCK_Connector::connect (ACE_SOCK_Stream &new_stream,
00211 const ACE_Addr &remote_sap,
00212 ACE_QoS_Params qos_params,
00213 const ACE_Time_Value *timeout,
00214 const ACE_Addr &local_sap,
00215 ACE_Protocol_Info * protocolinfo,
00216 ACE_SOCK_GROUP g,
00217 u_long flags,
00218 int reuse_addr,
00219 int )
00220 {
00221 ACE_TRACE ("ACE_SOCK_Connector::connect");
00222
00223 if (this->shared_open (new_stream,
00224 remote_sap.get_type (),
00225 0,
00226 protocolinfo,
00227 g,
00228 flags,
00229 reuse_addr) == -1)
00230 return -1;
00231 else if (this->shared_connect_start (new_stream,
00232 timeout,
00233 local_sap) == -1)
00234 return -1;
00235
00236 int result = ACE_OS::connect (new_stream.get_handle (),
00237 reinterpret_cast<sockaddr *> (remote_sap.get_addr ()),
00238 remote_sap.get_size (),
00239 qos_params);
00240
00241 return this->shared_connect_finish (new_stream,
00242 timeout,
00243 result);
00244 }
00245 #endif // ACE_HAS_WINCE
00246
00247
00248
00249 int
00250 ACE_SOCK_Connector::complete (ACE_SOCK_Stream &new_stream,
00251 ACE_Addr *remote_sap,
00252 const ACE_Time_Value *tv)
00253 {
00254 ACE_TRACE ("ACE_SOCK_Connector::complete");
00255 ACE_HANDLE h = ACE::handle_timed_complete (new_stream.get_handle (),
00256 tv);
00257
00258 if (h == ACE_INVALID_HANDLE)
00259 {
00260 #if defined (ACE_WIN32)
00261
00262
00263
00264
00265 ACE_Time_Value time (0, ACE_NON_BLOCKING_BUG_DELAY);
00266 ACE_OS::sleep (time);
00267 h = ACE::handle_timed_complete (new_stream.get_handle (),
00268 tv);
00269 if (h == ACE_INVALID_HANDLE)
00270 {
00271 #endif
00272
00273 ACE_Errno_Guard error (errno);
00274 new_stream.close ();
00275 return -1;
00276 #if defined (ACE_WIN32)
00277 }
00278 #endif
00279 }
00280
00281 if (remote_sap != 0)
00282 {
00283 int len = remote_sap->get_size ();
00284 sockaddr *addr = reinterpret_cast<sockaddr *> (remote_sap->get_addr ());
00285 if (ACE_OS::getpeername (h,
00286 addr,
00287 &len) == -1)
00288 {
00289
00290 ACE_Errno_Guard error (errno);
00291 new_stream.close ();
00292 return -1;
00293 }
00294 }
00295
00296
00297 new_stream.disable (ACE_NONBLOCK);
00298 return 0;
00299 }
00300
00301 ACE_SOCK_Connector::ACE_SOCK_Connector (ACE_SOCK_Stream &new_stream,
00302 const ACE_Addr &remote_sap,
00303 const ACE_Time_Value *timeout,
00304 const ACE_Addr &local_sap,
00305 int reuse_addr,
00306 int flags,
00307 int perms,
00308 int protocol)
00309 {
00310 ACE_TRACE ("ACE_SOCK_Connector::ACE_SOCK_Connector");
00311
00312 if (this->connect (new_stream,
00313 remote_sap,
00314 timeout,
00315 local_sap,
00316 reuse_addr,
00317 flags,
00318 perms,
00319 protocol) == -1
00320 && timeout != 0
00321 && !(errno == EWOULDBLOCK || errno == ETIME || errno == ETIMEDOUT))
00322 ACE_ERROR ((LM_ERROR,
00323 ACE_TEXT ("%p\n"),
00324 ACE_TEXT ("ACE_SOCK_Connector::ACE_SOCK_Connector")));
00325 }
00326
00327 #if !defined (ACE_HAS_WINCE)
00328 ACE_SOCK_Connector::ACE_SOCK_Connector (ACE_SOCK_Stream &new_stream,
00329 const ACE_Addr &remote_sap,
00330 ACE_QoS_Params qos_params,
00331 const ACE_Time_Value *timeout,
00332 const ACE_Addr &local_sap,
00333 ACE_Protocol_Info *protocolinfo,
00334 ACE_SOCK_GROUP g,
00335 u_long flags,
00336 int reuse_addr,
00337 int perms)
00338 {
00339 ACE_TRACE ("ACE_SOCK_Connector::ACE_SOCK_Connector");
00340
00341 if (this->connect (new_stream,
00342 remote_sap,
00343 qos_params,
00344 timeout,
00345 local_sap,
00346 protocolinfo,
00347 g,
00348 flags,
00349 reuse_addr,
00350 perms) == -1
00351 && timeout != 0
00352 && !(errno == EWOULDBLOCK || errno == ETIME || errno == ETIMEDOUT))
00353 ACE_ERROR ((LM_ERROR,
00354 ACE_TEXT ("%p\n"),
00355 ACE_TEXT ("ACE_SOCK_Connector::ACE_SOCK_Connector")));
00356 }
00357 #endif // ACE_HAS_WINCE
00358
00359 ACE_END_VERSIONED_NAMESPACE_DECL