SOCK_Connector.cpp

Go to the documentation of this file.
00001 // SOCK_Connector.cpp,v 4.49 2005/10/28 16:14:55 ossama Exp
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 /* __ACE_INLINE__ */
00017 
00018 ACE_RCSID(ace, SOCK_Connector, "SOCK_Connector.cpp,v 4.49 2005/10/28 16:14:55 ossama Exp")
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 /* ACE_HAS_DUMP */
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   // Only open a new socket if we don't already have a valid handle.
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   // Only open a new socket if we don't already have a valid handle.
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           // Save/restore errno.
00093           ACE_Errno_Guard error (errno);
00094           new_stream.close ();
00095           return -1;
00096         }
00097     }
00098 
00099   // Enable non-blocking, if required.
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   // Save/restore errno.
00114   ACE_Errno_Guard error (errno);
00115 
00116   if (result == -1 && timeout != 0)
00117     {
00118       // Check whether the connection is in progress.
00119       if (error == EINPROGRESS || error == EWOULDBLOCK)
00120         {
00121           // This expression checks if we were polling.
00122           if (timeout->sec () == 0
00123               && timeout->usec () == 0)
00124             error = EWOULDBLOCK;
00125           // Wait synchronously using timeout.
00126           else if (this->complete (new_stream,
00127                                    0,
00128                                    timeout) == -1)
00129             error = errno;
00130           else
00131             return 0;
00132         }
00133     }
00134 
00135   // EISCONN is treated specially since this routine may be used to
00136   // check if we are already connected.
00137   if (result != -1 || error == EISCONN)
00138     // Start out with non-blocking disabled on the <new_stream>.
00139     new_stream.disable (ACE_NONBLOCK);
00140   else if (!(error == EWOULDBLOCK || error == ETIMEDOUT))
00141     new_stream.close ();
00142 
00143   return result;
00144 }
00145 
00146 // Actively connect and produce a new ACE_SOCK_Stream if things go well...
00147 
00148 int
00149 ACE_SOCK_Connector::connect (ACE_SOCK_Stream &new_stream,
00150                              const ACE_Addr &remote_sap,
00151                              const ACE_Time_Value *timeout,
00152                              const ACE_Addr &local_sap,
00153                              int reuse_addr,
00154                              int /* flags */,
00155                              int /* perms */,
00156                              int protocol)
00157 {
00158   ACE_TRACE ("ACE_SOCK_Connector::connect");
00159 
00160   if (this->shared_open (new_stream,
00161                          remote_sap.get_type (),
00162                          protocol,
00163                          reuse_addr) == -1)
00164     return -1;
00165   else if (this->shared_connect_start (new_stream,
00166                                        timeout,
00167                                        local_sap) == -1)
00168     return -1;
00169 
00170   int result = ACE_OS::connect (new_stream.get_handle (),
00171                                 reinterpret_cast<sockaddr *> (remote_sap.get_addr ()),
00172                                 remote_sap.get_size ());
00173 
00174   return this->shared_connect_finish (new_stream,
00175                                       timeout,
00176                                       result);
00177 }
00178 
00179 #if !defined (ACE_HAS_WINCE)
00180 int
00181 ACE_SOCK_Connector::connect (ACE_SOCK_Stream &new_stream,
00182                              const ACE_Addr &remote_sap,
00183                              ACE_QoS_Params qos_params,
00184                              const ACE_Time_Value *timeout,
00185                              const ACE_Addr &local_sap,
00186                              ACE_Protocol_Info * protocolinfo,
00187                              ACE_SOCK_GROUP g,
00188                              u_long flags,
00189                              int reuse_addr,
00190                              int /* perms */)
00191 {
00192   ACE_TRACE ("ACE_SOCK_Connector::connect");
00193 
00194   if (this->shared_open (new_stream,
00195                          remote_sap.get_type (),
00196                          0,
00197                          protocolinfo,
00198                          g,
00199                          flags,
00200                          reuse_addr) == -1)
00201     return -1;
00202   else if (this->shared_connect_start (new_stream,
00203                                        timeout,
00204                                        local_sap) == -1)
00205     return -1;
00206 
00207   int result = ACE_OS::connect (new_stream.get_handle (),
00208                                 reinterpret_cast<sockaddr *> (remote_sap.get_addr ()),
00209                                 remote_sap.get_size (),
00210                                 qos_params);
00211 
00212   return this->shared_connect_finish (new_stream,
00213                                       timeout,
00214                                       result);
00215 }
00216 #endif  // ACE_HAS_WINCE
00217 
00218 // Try to complete a non-blocking connection.
00219 
00220 int
00221 ACE_SOCK_Connector::complete (ACE_SOCK_Stream &new_stream,
00222                               ACE_Addr *remote_sap,
00223                               const ACE_Time_Value *tv)
00224 {
00225   ACE_TRACE ("ACE_SOCK_Connector::complete");
00226   ACE_HANDLE h = ACE::handle_timed_complete (new_stream.get_handle (),
00227                                              tv);
00228   // We failed to get connected.
00229   if (h == ACE_INVALID_HANDLE)
00230     {
00231 #if defined (ACE_WIN32)
00232       // Win32 has a timing problem - if you check to see if the
00233       // connection has completed too fast, it will fail - so wait
00234       // <ACE_NON_BLOCKING_BUG_DELAY> microseconds to let it catch up
00235       // then retry to see if it's a real failure.
00236       ACE_Time_Value time (0, ACE_NON_BLOCKING_BUG_DELAY);
00237       ACE_OS::sleep (time);
00238       h = ACE::handle_timed_complete (new_stream.get_handle (),
00239                                       tv);
00240       if (h == ACE_INVALID_HANDLE)
00241         {
00242 #endif /* ACE_WIN32 */
00243       // Save/restore errno.
00244       ACE_Errno_Guard error (errno);
00245       new_stream.close ();
00246       return -1;
00247 #if defined (ACE_WIN32)
00248         }
00249 #endif /* ACE_WIN32 */
00250     }
00251 
00252   if (remote_sap != 0)
00253     {
00254       int len = remote_sap->get_size ();
00255       sockaddr *addr = reinterpret_cast<sockaddr *> (remote_sap->get_addr ());
00256       if (ACE_OS::getpeername (h,
00257                                addr,
00258                                &len) == -1)
00259         {
00260           // Save/restore errno.
00261           ACE_Errno_Guard error (errno);
00262           new_stream.close ();
00263           return -1;
00264         }
00265     }
00266 
00267   // Start out with non-blocking disabled on the <new_stream>.
00268   new_stream.disable (ACE_NONBLOCK);
00269   return 0;
00270 }
00271 
00272 ACE_SOCK_Connector::ACE_SOCK_Connector (ACE_SOCK_Stream &new_stream,
00273                                         const ACE_Addr &remote_sap,
00274                                         const ACE_Time_Value *timeout,
00275                                         const ACE_Addr &local_sap,
00276                                         int reuse_addr,
00277                                         int flags,
00278                                         int perms,
00279                                         int protocol)
00280 {
00281   ACE_TRACE ("ACE_SOCK_Connector::ACE_SOCK_Connector");
00282 
00283   if (this->connect (new_stream,
00284                      remote_sap,
00285                      timeout,
00286                      local_sap,
00287                      reuse_addr,
00288                      flags,
00289                      perms,
00290                      protocol) == -1
00291       && timeout != 0
00292       && !(errno == EWOULDBLOCK || errno == ETIME || errno == ETIMEDOUT))
00293     ACE_ERROR ((LM_ERROR,
00294                 ACE_LIB_TEXT ("%p\n"),
00295                 ACE_LIB_TEXT ("ACE_SOCK_Connector::ACE_SOCK_Connector")));
00296 }
00297 
00298 #if !defined (ACE_HAS_WINCE)
00299 ACE_SOCK_Connector::ACE_SOCK_Connector (ACE_SOCK_Stream &new_stream,
00300                                         const ACE_Addr &remote_sap,
00301                                         ACE_QoS_Params qos_params,
00302                                         const ACE_Time_Value *timeout,
00303                                         const ACE_Addr &local_sap,
00304                                         ACE_Protocol_Info *protocolinfo,
00305                                         ACE_SOCK_GROUP g,
00306                                         u_long flags,
00307                                         int reuse_addr,
00308                                         int perms)
00309 {
00310   ACE_TRACE ("ACE_SOCK_Connector::ACE_SOCK_Connector");
00311 
00312   if (this->connect (new_stream,
00313                      remote_sap,
00314                      qos_params,
00315                      timeout,
00316                      local_sap,
00317                      protocolinfo,
00318                      g,
00319                      flags,
00320                      reuse_addr,
00321                      perms) == -1
00322       && timeout != 0
00323       && !(errno == EWOULDBLOCK || errno == ETIME || errno == ETIMEDOUT))
00324     ACE_ERROR ((LM_ERROR,
00325                 ACE_LIB_TEXT ("%p\n"),
00326                 ACE_LIB_TEXT ("ACE_SOCK_Connector::ACE_SOCK_Connector")));
00327 }
00328 #endif  // ACE_HAS_WINCE
00329 
00330 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 09:42:04 2006 for ACE by doxygen 1.3.6