00001
00002
00003 #include "ace/SOCK_SEQPACK_Connector.h"
00004
00005 #include "ace/INET_Addr.h"
00006 #include "ace/Log_Msg.h"
00007 #include "ace/Time_Value.h"
00008 #include "ace/OS_Memory.h"
00009 #include "ace/OS_NS_string.h"
00010 #include "ace/OS_NS_sys_socket.h"
00011 #include "ace/os_include/os_fcntl.h"
00012
00013 #if defined (ACE_WIN32)
00014 #include "ace/OS_NS_unistd.h"
00015 #endif
00016
00017 #if !defined (__ACE_INLINE__)
00018 #include "ace/SOCK_SEQPACK_Connector.inl"
00019 #endif
00020
00021 ACE_RCSID(ace, SOCK_SEQPACK_Connector, "SOCK_SEQPACK_Connector.cpp,v 4.35 2002/03/08 23:18:09 spark Exp")
00022
00023 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00024
00025 ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_SEQPACK_Connector)
00026
00027 void
00028 ACE_SOCK_SEQPACK_Connector::dump (void) const
00029 {
00030 #if defined (ACE_HAS_DUMP)
00031 ACE_TRACE ("ACE_SOCK_SEQPACK_Connector::dump");
00032 #endif
00033 }
00034
00035 int
00036 ACE_SOCK_SEQPACK_Connector::shared_open (ACE_SOCK_SEQPACK_Association &new_association,
00037 int protocol_family,
00038 int protocol,
00039 int reuse_addr)
00040 {
00041 ACE_TRACE ("ACE_SOCK_SEQPACK_Connector::shared_open");
00042
00043
00044
00045
00046 if (new_association.get_handle () == ACE_INVALID_HANDLE &&
00047 #if defined (ACE_HAS_LKSCTP)
00048 new_association.open (SOCK_STREAM,
00049 #else
00050 new_association.open (SOCK_SEQPACKET,
00051 #endif
00052 protocol_family,
00053 protocol,
00054 reuse_addr) == -1)
00055 return -1;
00056 else
00057 return 0;
00058 }
00059
00060 int
00061 ACE_SOCK_SEQPACK_Connector::shared_open (ACE_SOCK_SEQPACK_Association &new_association,
00062 int protocol_family,
00063 int protocol,
00064 ACE_Protocol_Info *protocolinfo,
00065 ACE_SOCK_GROUP g,
00066 u_long flags,
00067 int reuse_addr)
00068 {
00069 ACE_TRACE ("ACE_SOCK_SEQPACK_Connector::shared_open");
00070
00071
00072 if (new_association.get_handle () == ACE_INVALID_HANDLE &&
00073 #if defined (ACE_HAS_LKSCTP)
00074 new_association.open (SOCK_STREAM,
00075 #else
00076 new_association.open (SOCK_SEQPACKET,
00077 #endif
00078 protocol_family,
00079 protocol,
00080 protocolinfo,
00081 g,
00082 flags,
00083 reuse_addr) == -1)
00084 return -1;
00085 else
00086 return 0;
00087 }
00088
00089 int
00090 ACE_SOCK_SEQPACK_Connector::shared_connect_start (ACE_SOCK_SEQPACK_Association &new_association,
00091 const ACE_Time_Value *timeout,
00092 const ACE_Addr &local_sap)
00093 {
00094 ACE_TRACE ("ACE_SOCK_SEQPACK_Connector::shared_connect_start");
00095
00096 if (local_sap != ACE_Addr::sap_any)
00097 {
00098 sockaddr *laddr = reinterpret_cast<sockaddr *> (local_sap.get_addr ());
00099 int size = local_sap.get_size ();
00100
00101 if (ACE_OS::bind (new_association.get_handle (),
00102 laddr,
00103 size) == -1)
00104 {
00105
00106 ACE_Errno_Guard error (errno);
00107 new_association.close ();
00108 return -1;
00109 }
00110 }
00111
00112
00113 if (timeout != 0
00114 && new_association.enable (ACE_NONBLOCK) == -1)
00115 return -1;
00116 else
00117 return 0;
00118 }
00119
00120
00121 int
00122 ACE_SOCK_SEQPACK_Connector::shared_connect_start (ACE_SOCK_SEQPACK_Association &new_association,
00123 const ACE_Time_Value *timeout,
00124 const ACE_Multihomed_INET_Addr &local_sap)
00125 {
00126 ACE_TRACE ("ACE_SOCK_SEQPACK_Connector::shared_connect_start");
00127
00128 if (local_sap.ACE_Addr::operator!= (ACE_Addr::sap_any))
00129 {
00130
00131
00132 size_t num_addresses = local_sap.get_num_secondary_addresses() + 1;
00133
00134
00135
00136
00137 sockaddr_in* local_inet_addrs = 0;
00138 ACE_NEW_NORETURN (local_inet_addrs, sockaddr_in[num_addresses]);
00139 if (!local_inet_addrs)
00140 return -1;
00141
00142
00143
00144 local_sap.get_addresses(local_inet_addrs, num_addresses);
00145
00146 #if defined (ACE_HAS_LKSCTP)
00147 sockaddr_in *local_sockaddr = 0;
00148 sockaddr_in portst;
00149 int sn = sizeof(sockaddr);
00150
00151
00152 if (ACE_OS::bind(new_association.get_handle (),
00153 reinterpret_cast<sockaddr *> (&(local_inet_addrs[0])),
00154 sizeof(sockaddr)))
00155 {
00156 ACE_Errno_Guard error (errno);
00157 new_association.close ();
00158 return -1;
00159 }
00160
00161
00162 if (num_addresses > 1)
00163 {
00164
00165 ACE_NEW_NORETURN(local_sockaddr,
00166 sockaddr_in[num_addresses - 1]);
00167
00168
00169 if (ACE_OS::getsockname(new_association.get_handle (),
00170 reinterpret_cast<sockaddr *> (&portst),
00171 &sn))
00172 {
00173 ACE_Errno_Guard error (errno);
00174 new_association.close ();
00175 return -1;
00176 }
00177
00178
00179 for (size_t i = 1; i < num_addresses; i++)
00180 {
00181 local_inet_addrs[i].sin_port = portst.sin_port;
00182 }
00183
00184
00185 for (size_t i = 0; i < num_addresses - 1; i++)
00186 {
00187 ACE_OS::memcpy(&(local_sockaddr[i]),
00188 &(local_inet_addrs[i + 1]),
00189 sizeof(sockaddr_in));
00190 }
00191
00192
00193 if (sctp_bindx(new_association.get_handle(),
00194 reinterpret_cast<sockaddr *> (local_sockaddr),
00195 num_addresses - 1,
00196 SCTP_BINDX_ADD_ADDR))
00197 {
00198 ACE_Errno_Guard error (errno);
00199 new_association.close ();
00200 return -1;
00201 }
00202
00203 delete [] local_sockaddr;
00204 }
00205 #else
00206
00207
00208 size_t name_len = (sizeof (sockaddr_in)) * num_addresses;
00209 if (ACE_OS::bind (new_association.get_handle (),
00210 reinterpret_cast<sockaddr *> (local_inet_addrs),
00211 static_cast<int> (name_len)) == -1)
00212 {
00213
00214 ACE_Errno_Guard error (errno);
00215 new_association.close ();
00216 return -1;
00217 }
00218 #endif
00219
00220 delete [] local_inet_addrs;
00221 }
00222
00223
00224 if (timeout != 0
00225 && new_association.enable (ACE_NONBLOCK) == -1)
00226 return -1;
00227 else
00228 return 0;
00229 }
00230
00231 int
00232 ACE_SOCK_SEQPACK_Connector::shared_connect_finish (ACE_SOCK_SEQPACK_Association &new_association,
00233 const ACE_Time_Value *timeout,
00234 int result)
00235 {
00236 ACE_TRACE ("ACE_SOCK_SEQPACK_Connector::shared_connect_finish");
00237
00238 ACE_Errno_Guard error (errno);
00239
00240 if (result == -1 && timeout != 0)
00241 {
00242
00243 if (error == EINPROGRESS || error == EWOULDBLOCK)
00244 {
00245
00246 if (timeout->sec () == 0
00247 && timeout->usec () == 0)
00248 error = EWOULDBLOCK;
00249
00250 else if (this->complete (new_association,
00251 0,
00252 timeout) == -1)
00253 error = errno;
00254 else
00255 return 0;
00256 }
00257 }
00258
00259
00260
00261 if (result != -1 || error == EISCONN)
00262
00263 new_association.disable (ACE_NONBLOCK);
00264 else if (!(error == EWOULDBLOCK || error == ETIMEDOUT))
00265 new_association.close ();
00266
00267 return result;
00268 }
00269
00270
00271
00272
00273 int
00274 ACE_SOCK_SEQPACK_Connector::connect (ACE_SOCK_SEQPACK_Association &new_association,
00275 const ACE_Addr &remote_sap,
00276 const ACE_Time_Value *timeout,
00277 const ACE_Addr &local_sap,
00278 int reuse_addr,
00279 int ,
00280 int ,
00281 int protocol)
00282 {
00283 ACE_TRACE ("ACE_SOCK_SEQPACK_Connector::connect");
00284
00285 if (this->shared_open (new_association,
00286 remote_sap.get_type (),
00287 protocol,
00288 reuse_addr) == -1)
00289 return -1;
00290 else if (this->shared_connect_start (new_association,
00291 timeout,
00292 local_sap) == -1)
00293 return -1;
00294
00295 int result = ACE_OS::connect (new_association.get_handle (),
00296 reinterpret_cast<sockaddr *> (remote_sap.get_addr ()),
00297 remote_sap.get_size ());
00298
00299 return this->shared_connect_finish (new_association,
00300 timeout,
00301 result);
00302 }
00303
00304
00305 int
00306 ACE_SOCK_SEQPACK_Connector::connect (ACE_SOCK_SEQPACK_Association &new_association,
00307 const ACE_Addr &remote_sap,
00308 const ACE_Time_Value *timeout,
00309 const ACE_Multihomed_INET_Addr &local_sap,
00310 int reuse_addr,
00311 int ,
00312 int ,
00313 int protocol)
00314 {
00315 ACE_TRACE ("ACE_SOCK_SEQPACK_Connector::connect");
00316
00317 if (this->shared_open (new_association,
00318 remote_sap.get_type (),
00319 protocol,
00320 reuse_addr) == -1)
00321 return -1;
00322 else if (this->shared_connect_start (new_association,
00323 timeout,
00324 local_sap) == -1)
00325 return -1;
00326
00327 int result = ACE_OS::connect (new_association.get_handle (),
00328 reinterpret_cast<sockaddr *> (remote_sap.get_addr ()),
00329 remote_sap.get_size ());
00330
00331 return this->shared_connect_finish (new_association,
00332 timeout,
00333 result);
00334 }
00335
00336
00337
00338 int
00339 ACE_SOCK_SEQPACK_Connector::complete (ACE_SOCK_SEQPACK_Association &new_association,
00340 ACE_Addr *remote_sap,
00341 const ACE_Time_Value *tv)
00342 {
00343 ACE_TRACE ("ACE_SOCK_SEQPACK_Connector::complete");
00344 ACE_HANDLE h = ACE::handle_timed_complete (new_association.get_handle (),
00345 tv);
00346
00347 if (h == ACE_INVALID_HANDLE)
00348 {
00349 #if defined (ACE_WIN32)
00350
00351
00352
00353
00354 ACE_Time_Value time (0, ACE_NON_BLOCKING_BUG_DELAY);
00355 ACE_OS::sleep (time);
00356 h = ACE::handle_timed_complete (new_association.get_handle (),
00357 tv);
00358 if (h == ACE_INVALID_HANDLE)
00359 {
00360 #endif
00361
00362 ACE_Errno_Guard error (errno);
00363 new_association.close ();
00364 return -1;
00365 #if defined (ACE_WIN32)
00366 }
00367 #endif
00368 }
00369
00370 if (remote_sap != 0)
00371 {
00372 int len = remote_sap->get_size ();
00373 sockaddr *addr = reinterpret_cast<sockaddr *> (remote_sap->get_addr ());
00374 if (ACE_OS::getpeername (h,
00375 addr,
00376 &len) == -1)
00377 {
00378
00379 ACE_Errno_Guard error (errno);
00380 new_association.close ();
00381 return -1;
00382 }
00383 }
00384
00385
00386 new_association.disable (ACE_NONBLOCK);
00387 return 0;
00388 }
00389
00390 ACE_SOCK_SEQPACK_Connector::ACE_SOCK_SEQPACK_Connector (ACE_SOCK_SEQPACK_Association &new_association,
00391 const ACE_Addr &remote_sap,
00392 const ACE_Time_Value *timeout,
00393 const ACE_Addr &local_sap,
00394 int reuse_addr,
00395 int flags,
00396 int perms,
00397 int protocol)
00398 {
00399 ACE_TRACE ("ACE_SOCK_SEQPACK_Connector::ACE_SOCK_SEQPACK_Connector");
00400
00401 if (this->connect (new_association,
00402 remote_sap,
00403 timeout,
00404 local_sap,
00405 reuse_addr,
00406 flags,
00407 perms,
00408 protocol) == -1
00409 && timeout != 0
00410 && !(errno == EWOULDBLOCK || errno == ETIME || errno == ETIMEDOUT))
00411 ACE_ERROR ((LM_ERROR,
00412 ACE_LIB_TEXT ("%p\n"),
00413 ACE_LIB_TEXT ("ACE_SOCK_SEQPACK_Connector::ACE_SOCK_SEQPACK_Connector")));
00414 }
00415
00416
00417 ACE_SOCK_SEQPACK_Connector::ACE_SOCK_SEQPACK_Connector (ACE_SOCK_SEQPACK_Association &new_association,
00418 const ACE_Addr &remote_sap,
00419 const ACE_Time_Value *timeout,
00420 const ACE_Multihomed_INET_Addr &local_sap,
00421 int reuse_addr,
00422 int flags,
00423 int perms,
00424 int protocol)
00425 {
00426 ACE_TRACE ("ACE_SOCK_SEQPACK_Connector::ACE_SOCK_SEQPACK_Connector");
00427
00428 if (this->connect (new_association,
00429 remote_sap,
00430 timeout,
00431 local_sap,
00432 reuse_addr,
00433 flags,
00434 perms,
00435 protocol) == -1
00436 && timeout != 0
00437 && !(errno == EWOULDBLOCK || errno == ETIME || errno == ETIMEDOUT))
00438 ACE_ERROR ((LM_ERROR,
00439 ACE_LIB_TEXT ("%p\n"),
00440 ACE_LIB_TEXT ("ACE_SOCK_SEQPACK_Connector::ACE_SOCK_SEQPACK_Connector")));
00441 }
00442
00443 ACE_END_VERSIONED_NAMESPACE_DECL