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 == ACE_Time_Value::zero)
00247 error = EWOULDBLOCK;
00248
00249 else if (this->complete (new_association,
00250 0,
00251 timeout) == -1)
00252 error = errno;
00253 else
00254 return 0;
00255 }
00256 }
00257
00258
00259
00260 if (result != -1 || error == EISCONN)
00261
00262 new_association.disable (ACE_NONBLOCK);
00263 else if (!(error == EWOULDBLOCK || error == ETIMEDOUT))
00264 new_association.close ();
00265
00266 return result;
00267 }
00268
00269
00270
00271
00272 int
00273 ACE_SOCK_SEQPACK_Connector::connect (ACE_SOCK_SEQPACK_Association &new_association,
00274 const ACE_Addr &remote_sap,
00275 const ACE_Time_Value *timeout,
00276 const ACE_Addr &local_sap,
00277 int reuse_addr,
00278 int ,
00279 int ,
00280 int protocol)
00281 {
00282 ACE_TRACE ("ACE_SOCK_SEQPACK_Connector::connect");
00283
00284 if (this->shared_open (new_association,
00285 remote_sap.get_type (),
00286 protocol,
00287 reuse_addr) == -1)
00288 return -1;
00289 else if (this->shared_connect_start (new_association,
00290 timeout,
00291 local_sap) == -1)
00292 return -1;
00293
00294 int result = ACE_OS::connect (new_association.get_handle (),
00295 reinterpret_cast<sockaddr *> (remote_sap.get_addr ()),
00296 remote_sap.get_size ());
00297
00298 return this->shared_connect_finish (new_association,
00299 timeout,
00300 result);
00301 }
00302
00303
00304 int
00305 ACE_SOCK_SEQPACK_Connector::connect (ACE_SOCK_SEQPACK_Association &new_association,
00306 const ACE_Addr &remote_sap,
00307 const ACE_Time_Value *timeout,
00308 const ACE_Multihomed_INET_Addr &local_sap,
00309 int reuse_addr,
00310 int ,
00311 int ,
00312 int protocol)
00313 {
00314 ACE_TRACE ("ACE_SOCK_SEQPACK_Connector::connect");
00315
00316 if (this->shared_open (new_association,
00317 remote_sap.get_type (),
00318 protocol,
00319 reuse_addr) == -1)
00320 return -1;
00321 else if (this->shared_connect_start (new_association,
00322 timeout,
00323 local_sap) == -1)
00324 return -1;
00325
00326 int result = ACE_OS::connect (new_association.get_handle (),
00327 reinterpret_cast<sockaddr *> (remote_sap.get_addr ()),
00328 remote_sap.get_size ());
00329
00330 return this->shared_connect_finish (new_association,
00331 timeout,
00332 result);
00333 }
00334
00335
00336
00337 int
00338 ACE_SOCK_SEQPACK_Connector::complete (ACE_SOCK_SEQPACK_Association &new_association,
00339 ACE_Addr *remote_sap,
00340 const ACE_Time_Value *tv)
00341 {
00342 ACE_TRACE ("ACE_SOCK_SEQPACK_Connector::complete");
00343 ACE_HANDLE h = ACE::handle_timed_complete (new_association.get_handle (),
00344 tv);
00345
00346 if (h == ACE_INVALID_HANDLE)
00347 {
00348 #if defined (ACE_WIN32)
00349
00350
00351
00352
00353 ACE_Time_Value time (0, ACE_NON_BLOCKING_BUG_DELAY);
00354 ACE_OS::sleep (time);
00355 h = ACE::handle_timed_complete (new_association.get_handle (),
00356 tv);
00357 if (h == ACE_INVALID_HANDLE)
00358 {
00359 #endif
00360
00361 ACE_Errno_Guard error (errno);
00362 new_association.close ();
00363 return -1;
00364 #if defined (ACE_WIN32)
00365 }
00366 #endif
00367 }
00368
00369 if (remote_sap != 0)
00370 {
00371 int len = remote_sap->get_size ();
00372 sockaddr *addr = reinterpret_cast<sockaddr *> (remote_sap->get_addr ());
00373 if (ACE_OS::getpeername (h,
00374 addr,
00375 &len) == -1)
00376 {
00377
00378 ACE_Errno_Guard error (errno);
00379 new_association.close ();
00380 return -1;
00381 }
00382 }
00383
00384
00385 new_association.disable (ACE_NONBLOCK);
00386 return 0;
00387 }
00388
00389 ACE_SOCK_SEQPACK_Connector::ACE_SOCK_SEQPACK_Connector (ACE_SOCK_SEQPACK_Association &new_association,
00390 const ACE_Addr &remote_sap,
00391 const ACE_Time_Value *timeout,
00392 const ACE_Addr &local_sap,
00393 int reuse_addr,
00394 int flags,
00395 int perms,
00396 int protocol)
00397 {
00398 ACE_TRACE ("ACE_SOCK_SEQPACK_Connector::ACE_SOCK_SEQPACK_Connector");
00399
00400 if (this->connect (new_association,
00401 remote_sap,
00402 timeout,
00403 local_sap,
00404 reuse_addr,
00405 flags,
00406 perms,
00407 protocol) == -1
00408 && timeout != 0
00409 && !(errno == EWOULDBLOCK || errno == ETIME || errno == ETIMEDOUT))
00410 ACE_ERROR ((LM_ERROR,
00411 ACE_TEXT ("%p\n"),
00412 ACE_TEXT ("ACE_SOCK_SEQPACK_Connector::ACE_SOCK_SEQPACK_Connector")));
00413 }
00414
00415
00416 ACE_SOCK_SEQPACK_Connector::ACE_SOCK_SEQPACK_Connector (ACE_SOCK_SEQPACK_Association &new_association,
00417 const ACE_Addr &remote_sap,
00418 const ACE_Time_Value *timeout,
00419 const ACE_Multihomed_INET_Addr &local_sap,
00420 int reuse_addr,
00421 int flags,
00422 int perms,
00423 int protocol)
00424 {
00425 ACE_TRACE ("ACE_SOCK_SEQPACK_Connector::ACE_SOCK_SEQPACK_Connector");
00426
00427 if (this->connect (new_association,
00428 remote_sap,
00429 timeout,
00430 local_sap,
00431 reuse_addr,
00432 flags,
00433 perms,
00434 protocol) == -1
00435 && timeout != 0
00436 && !(errno == EWOULDBLOCK || errno == ETIME || errno == ETIMEDOUT))
00437 ACE_ERROR ((LM_ERROR,
00438 ACE_TEXT ("%p\n"),
00439 ACE_TEXT ("ACE_SOCK_SEQPACK_Connector::ACE_SOCK_SEQPACK_Connector")));
00440 }
00441
00442 ACE_END_VERSIONED_NAMESPACE_DECL