Asynch_Acceptor.cpp

Go to the documentation of this file.
00001 /* -*- C++ -*- */
00002 // Asynch_Acceptor.cpp,v 4.66 2005/12/22 11:41:48 shuston Exp
00003 
00004 #ifndef ACE_ASYNCH_ACCEPTOR_C
00005 #define ACE_ASYNCH_ACCEPTOR_C
00006 
00007 #include "ace/Asynch_Acceptor.h"
00008 
00009 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00010 # pragma once
00011 #endif /* ACE_LACKS_PRAGMA_ONCE */
00012 
00013 ACE_RCSID(ace, Asynch_Acceptor, "Asynch_Acceptor.cpp,v 4.66 2005/12/22 11:41:48 shuston Exp")
00014 
00015 #if (defined (ACE_WIN32) || defined (ACE_HAS_AIO_CALLS)) && !defined(ACE_HAS_WINCE)
00016 // This only works on platforms that support async i/o.
00017 
00018 #include "ace/OS_Errno.h"
00019 #include "ace/OS_Memory.h"
00020 #include "ace/OS_NS_sys_socket.h"
00021 #include "ace/Log_Msg.h"
00022 #include "ace/Message_Block.h"
00023 #include "ace/INET_Addr.h"
00024 #include "ace/SOCK_Stream.h"
00025 #include "ace/Sock_Connect.h"
00026 
00027 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00028 
00029 template <class HANDLER>
00030 ACE_Asynch_Acceptor<HANDLER>::ACE_Asynch_Acceptor (void)
00031   : listen_handle_ (ACE_INVALID_HANDLE),
00032     pass_addresses_ (0),
00033     validate_new_connection_ (0),
00034     reissue_accept_ (1),
00035     bytes_to_read_ (0)
00036 {
00037 }
00038 
00039 template <class HANDLER>
00040 ACE_Asynch_Acceptor<HANDLER>::~ACE_Asynch_Acceptor (void)
00041 {
00042   // Close down the listen socket
00043   if (this->listen_handle_ != ACE_INVALID_HANDLE)
00044     {
00045       ACE_OS::closesocket (this->listen_handle_);
00046       this->listen_handle_ = ACE_INVALID_HANDLE;
00047     }
00048 }
00049 
00050 template <class HANDLER> int
00051 ACE_Asynch_Acceptor<HANDLER>::open (const ACE_INET_Addr &address,
00052                                     size_t bytes_to_read,
00053                                     int pass_addresses,
00054                                     int backlog,
00055                                     int reuse_addr,
00056                                     ACE_Proactor *proactor,
00057                                     int validate_new_connection,
00058                                     int reissue_accept,
00059                                     int number_of_initial_accepts)
00060 {
00061   ACE_TRACE ("ACE_Asynch_Acceptor<>::open");
00062 
00063   this->proactor (proactor);
00064   this->pass_addresses_ = pass_addresses;
00065   this->bytes_to_read_ = bytes_to_read;
00066   this->validate_new_connection_ = validate_new_connection;
00067   this->reissue_accept_ = reissue_accept;
00068   this->addr_family_ = address.get_type ();
00069 
00070   // Create the listener socket
00071   this->listen_handle_ = ACE_OS::socket (address.get_type (), SOCK_STREAM, 0);
00072   if (this->listen_handle_ == ACE_INVALID_HANDLE)
00073     ACE_ERROR_RETURN ((LM_ERROR,
00074                        ACE_LIB_TEXT ("%p\n"),
00075                        ACE_LIB_TEXT ("ACE_OS::socket")),
00076                       -1);
00077   // Initialize the ACE_Asynch_Accept
00078   if (this->asynch_accept_.open (*this,
00079                                  this->listen_handle_,
00080                                  0,
00081                                  this->proactor ()) == -1)
00082     {
00083       ACE_Errno_Guard g (errno);
00084       ACE_ERROR ((LM_ERROR,
00085                   ACE_LIB_TEXT ("%p\n"),
00086                   ACE_LIB_TEXT ("ACE_Asynch_Accept::open")));
00087       ACE_OS::closesocket (this->listen_handle_);
00088       this->listen_handle_ = ACE_INVALID_HANDLE;
00089       return -1;
00090     }
00091 
00092   if (reuse_addr)
00093     {
00094       // Reuse the address
00095       int one = 1;
00096       if (ACE_OS::setsockopt (this->listen_handle_,
00097                               SOL_SOCKET,
00098                               SO_REUSEADDR,
00099                               (const char*) &one,
00100                               sizeof one) == -1)
00101         {
00102           ACE_Errno_Guard g (errno);
00103           ACE_ERROR ((LM_ERROR,
00104                       ACE_LIB_TEXT ("%p\n"),
00105                       ACE_LIB_TEXT ("ACE_OS::setsockopt")));
00106           ACE_OS::closesocket (this->listen_handle_);
00107           this->listen_handle_ = ACE_INVALID_HANDLE;
00108           return -1;
00109         }
00110     }
00111 
00112   // If port is not specified, bind to any port.
00113   static ACE_INET_Addr sa (ACE_sap_any_cast (const ACE_INET_Addr &));
00114 
00115   if (address == sa &&
00116       ACE::bind_port (this->listen_handle_,
00117                       INADDR_ANY,
00118                       address.get_type()) == -1)
00119     {
00120       ACE_Errno_Guard g (errno);
00121       ACE_ERROR ((LM_ERROR,
00122                   ACE_LIB_TEXT ("%p\n"),
00123                   ACE_LIB_TEXT ("ACE::bind_port")));
00124       ACE_OS::closesocket (this->listen_handle_);
00125       this->listen_handle_ = ACE_INVALID_HANDLE;
00126       return -1;
00127     }
00128 
00129   // Bind to the specified port.
00130   if (ACE_OS::bind (this->listen_handle_,
00131                     reinterpret_cast<sockaddr *> (address.get_addr ()),
00132                     address.get_size ()) == -1)
00133     {
00134       ACE_Errno_Guard g (errno);
00135       ACE_ERROR ((LM_ERROR,
00136                   ACE_LIB_TEXT ("%p\n"),
00137                   ACE_LIB_TEXT ("ACE_OS::bind")));
00138       ACE_OS::closesocket (this->listen_handle_);
00139       this->listen_handle_ = ACE_INVALID_HANDLE;
00140       return -1;
00141     }
00142 
00143   // Start listening.
00144   if (ACE_OS::listen (this->listen_handle_, backlog) == -1)
00145     {
00146       ACE_Errno_Guard g (errno);
00147       ACE_ERROR ((LM_ERROR,
00148                   ACE_LIB_TEXT ("%p\n"),
00149                   ACE_LIB_TEXT ("ACE_OS::listen")));
00150       ACE_OS::closesocket (this->listen_handle_);
00151       this->listen_handle_ = ACE_INVALID_HANDLE;
00152       return -1;
00153     }
00154 
00155   // For the number of <intial_accepts>.
00156   if (number_of_initial_accepts == -1)
00157     number_of_initial_accepts = backlog;
00158 
00159   for (int i = 0; i < number_of_initial_accepts; i++)
00160     {
00161       // Initiate accepts.
00162       if (this->accept (bytes_to_read) == -1)
00163         {
00164           ACE_Errno_Guard g (errno);
00165           ACE_ERROR ((LM_ERROR,
00166                       ACE_LIB_TEXT ("%p\n"),
00167                       ACE_LIB_TEXT ("ACE_Asynch_Acceptor::accept")));
00168           ACE_OS::closesocket (this->listen_handle_);
00169           this->listen_handle_ = ACE_INVALID_HANDLE;
00170           return -1;
00171         }
00172     }
00173 
00174   return 0;
00175 }
00176 
00177 template <class HANDLER> int
00178 ACE_Asynch_Acceptor<HANDLER>::set_handle (ACE_HANDLE listen_handle)
00179 {
00180   ACE_TRACE ("ACE_Asynch_Acceptor<>::set_handle");
00181 
00182   // Take ownership of the <listen_handle>
00183   this->listen_handle_ = listen_handle;
00184 
00185   // Reinitialize the ACE_Asynch_Accept
00186   if (this->asynch_accept_.open (*this,
00187                                  this->listen_handle_,
00188                                  0,
00189                                  this->proactor ()) == -1)
00190     ACE_ERROR_RETURN ((LM_ERROR,
00191                        ACE_LIB_TEXT ("%p\n"),
00192                        ACE_LIB_TEXT ("ACE_Asynch_Accept::open")),
00193                       -1);
00194   return 0;
00195 }
00196 
00197 template <class HANDLER> ACE_HANDLE
00198 ACE_Asynch_Acceptor<HANDLER>::get_handle (void) const
00199 {
00200   return this->listen_handle_;
00201 }
00202 
00203 template <class HANDLER> int
00204 ACE_Asynch_Acceptor<HANDLER>::accept (size_t bytes_to_read, const void *act)
00205 {
00206   ACE_TRACE ("ACE_Asynch_Acceptor<>::accept");
00207 
00208   ACE_Message_Block *message_block = 0;
00209   // The space_needed calculation is drive by needs of Windows. POSIX doesn't
00210   // need to extra 16 bytes, but it doesn't hurt.
00211   size_t space_needed = sizeof (sockaddr_in) + 16;
00212 #if defined (ACE_HAS_IPV6)
00213   if (PF_INET6 == this->addr_family_)
00214     space_needed = sizeof (sockaddr_in6) + 16;
00215 #endif /* ACE_HAS_IPV6 */
00216   space_needed = (2 * space_needed) + bytes_to_read;
00217 
00218   // Create a new message block big enough for the addresses and data
00219   ACE_NEW_RETURN (message_block,
00220                   ACE_Message_Block (space_needed),
00221                   -1);
00222 
00223   // Initiate asynchronous accepts
00224   if (this->asynch_accept_.accept (*message_block,
00225                                    bytes_to_read,
00226                                    ACE_INVALID_HANDLE,
00227                                    act,
00228                                    0,
00229                                    ACE_SIGRTMIN,
00230                                    this->addr_family_) == -1)
00231     {
00232       // Cleanup on error
00233       message_block->release ();
00234       return -1;
00235     }
00236   return 0;
00237 }
00238 
00239 template <class HANDLER> void
00240 ACE_Asynch_Acceptor<HANDLER>::handle_accept (const ACE_Asynch_Accept::Result &result)
00241 {
00242 #if (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) || (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)) || defined (ACE_HAS_AIO_CALLS)
00243 
00244   ACE_TRACE ("ACE_Asynch_Acceptor<>::handle_accept");
00245 
00246   // Variable for error tracking
00247   int error = 0;
00248 
00249   // If the asynchronous accept fails.
00250   if (!result.success () || result.accept_handle () == ACE_INVALID_HANDLE)
00251     {
00252       error = 1;
00253     }
00254 
00255 #if !defined (ACE_HAS_AIO_CALLS)
00256   // In order to use accept handle with other Window Sockets 1.1
00257   // functions, we call the setsockopt function with the
00258   // SO_UPDATE_ACCEPT_CONTEXT option. This option initializes the
00259   // socket so that other Windows Sockets routines to access the
00260   // socket correctly.
00261   if (!error &&
00262       ACE_OS::setsockopt (result.accept_handle (),
00263                           SOL_SOCKET,
00264                           SO_UPDATE_ACCEPT_CONTEXT,
00265                           (char *) &this->listen_handle_,
00266                           sizeof (this->listen_handle_)) == -1)
00267     {
00268       error = 1;
00269     }
00270 #endif /* ACE_HAS_AIO_CALLS */
00271 
00272   // Parse address.
00273   ACE_INET_Addr local_address;
00274   ACE_INET_Addr remote_address;
00275   if (!error &&
00276       (this->validate_new_connection_ || this->pass_addresses_))
00277     // Parse the addresses.
00278     this->parse_address (result,
00279                          remote_address,
00280                          local_address);
00281 
00282   // Validate remote address
00283   if (!error &&
00284       this->validate_new_connection_ &&
00285       (this->validate_connection (result, remote_address, local_address) == -1
00286        || this->validate_new_connection (remote_address) == -1))
00287     {
00288       error = 1;
00289     }
00290 
00291   HANDLER *new_handler = 0;
00292   if (!error)
00293     {
00294       // The Template method
00295       new_handler = this->make_handler ();
00296       if (new_handler == 0)
00297         {
00298           error = 1;
00299         }
00300     }
00301 
00302   // If no errors
00303   if (!error)
00304     {
00305       // Update the Proactor.
00306       new_handler->proactor (this->proactor ());
00307 
00308       // Pass the addresses
00309       if (this->pass_addresses_)
00310         new_handler->addresses (remote_address,
00311                                 local_address);
00312 
00313       // Pass the ACT
00314       if (result.act () != 0)
00315         new_handler->act (result.act ());
00316 
00317       // Set up the handler's new handle value
00318       new_handler->handle (result.accept_handle ());
00319 
00320       // Initiate the handler
00321       new_handler->open (result.accept_handle (),
00322                          result.message_block ());
00323     }
00324 
00325   // On failure, no choice but to close the socket
00326   if (error &&
00327       result.accept_handle() != ACE_INVALID_HANDLE )
00328     ACE_OS::closesocket (result.accept_handle ());
00329 
00330   // Delete the dynamically allocated message_block
00331   result.message_block ().release ();
00332 
00333   // Start off another asynchronous accept to keep the backlog going,
00334   // unless we closed the listen socket already (from the destructor),
00335   // or this callback is the result of a canceled/aborted accept.
00336   if (this->should_reissue_accept () &&
00337       this->listen_handle_ != ACE_INVALID_HANDLE
00338 #if defined (ACE_WIN32)
00339       && result.error () != ERROR_OPERATION_ABORTED
00340 #else
00341       && result.error () != ECANCELED
00342 #endif
00343       )
00344     this->accept (this->bytes_to_read_);
00345 #endif /* (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) || (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)) || defined (ACE_HAS_AIO_CALLS */
00346 }
00347 
00348 template <class HANDLER> int
00349 ACE_Asynch_Acceptor<HANDLER>::validate_connection
00350   (const ACE_Asynch_Accept::Result& /* result */,
00351    const ACE_INET_Addr& /* remote */,
00352    const ACE_INET_Addr& /* local */)
00353 {
00354   // Default implementation always validates the remote address.
00355   return 0;
00356 }
00357 
00358 template <class HANDLER> int
00359 ACE_Asynch_Acceptor<HANDLER>::validate_new_connection (const ACE_INET_Addr&)
00360 {
00361   // Default implementation always validates the remote address.
00362   return 0;
00363 }
00364 
00365 template <class HANDLER> int
00366 ACE_Asynch_Acceptor<HANDLER>::cancel (void)
00367 {
00368   ACE_TRACE ("ACE_Asynch_Acceptor<>::cancel");
00369 
00370   // All I/O operations that are canceled will complete with the error
00371   // ERROR_OPERATION_ABORTED. All completion notifications for the I/O
00372   // operations will occur normally.
00373 #if (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) \
00374     && (    defined (_MSC_VER) || (defined (__BORLANDC__)))
00375   return (int) ::CancelIo (this->listen_handle_);
00376 #else
00377   // Supported now
00378   return this->asynch_accept_.cancel();
00379 
00380 #endif /* (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) && ((defined (_MSC_VER)) || (defined (__BORLANDC__))) */
00381 }
00382 
00383 template <class HANDLER> void
00384 ACE_Asynch_Acceptor<HANDLER>::parse_address (const
00385                                              ACE_Asynch_Accept::Result &result,
00386                                              ACE_INET_Addr &remote_address,
00387                                              ACE_INET_Addr &local_address)
00388 {
00389   ACE_TRACE ("ACE_Asynch_Acceptor<>::parse_address");
00390 
00391 #if defined (ACE_HAS_AIO_CALLS)
00392 
00393   // Use an ACE_SOCK to get the addresses - it knows how to deal with
00394   // ACE_INET_Addr objects and get IPv4/v6 addresses.
00395   ACE_SOCK_Stream str (result.accept_handle ());
00396   str.get_local_addr (local_address);
00397   str.get_remote_addr (remote_address);
00398 
00399 #elif (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) || (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
00400 
00401   ACE_Message_Block &message_block = result.message_block ();
00402 
00403   sockaddr *local_addr = 0;
00404   sockaddr *remote_addr = 0;
00405   int local_size = 0;
00406   int remote_size = 0;
00407   // This matches setup in accept().
00408   size_t addr_size = sizeof (sockaddr_in) + 16;
00409 #if defined (ACE_HAS_IPV6)
00410   if (this->addr_family_ == PF_INET6)
00411     addr_size = sizeof (sockaddr_in6) + 16;
00412 #endif /* ACE_HAS_IPV6 */
00413 
00414   ::GetAcceptExSockaddrs (message_block.rd_ptr (),
00415                           static_cast<DWORD> (this->bytes_to_read_),
00416                           static_cast<DWORD> (addr_size),
00417                           static_cast<DWORD> (addr_size),
00418                           &local_addr,
00419                           &local_size,
00420                           &remote_addr,
00421                           &remote_size);
00422 
00423   local_address.set (reinterpret_cast<sockaddr_in *> (local_addr),
00424                      local_size);
00425   remote_address.set (reinterpret_cast<sockaddr_in *> (remote_addr),
00426                       remote_size);
00427 #else
00428   // just in case
00429   errno = ENOTSUP;
00430 #endif /* (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) || (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)) */
00431   return;
00432 }
00433 
00434 template <class HANDLER> ACE_HANDLE
00435 ACE_Asynch_Acceptor<HANDLER>::handle (void) const
00436 {
00437   return this->listen_handle_;
00438 }
00439 
00440 template <class HANDLER> void
00441 ACE_Asynch_Acceptor<HANDLER>::handle (ACE_HANDLE h)
00442 {
00443   ACE_Handler::handle (h);
00444 }
00445 
00446 template <class HANDLER> ACE_Asynch_Accept &
00447 ACE_Asynch_Acceptor<HANDLER>::asynch_accept (void)
00448 {
00449   return this->asynch_accept_;
00450 }
00451 
00452 template <class HANDLER> HANDLER *
00453 ACE_Asynch_Acceptor<HANDLER>::make_handler (void)
00454 {
00455   // Default behavior
00456   HANDLER *handler = 0;
00457   ACE_NEW_RETURN (handler,
00458                   HANDLER,
00459                   0);
00460   return handler;
00461 }
00462 
00463 /* static */
00464 template <class HANDLER> size_t
00465 ACE_Asynch_Acceptor<HANDLER>::address_size (void)
00466 {
00467   return sizeof (sockaddr) + sizeof (sockaddr_in);
00468 }
00469 
00470 template <class HANDLER> int
00471 ACE_Asynch_Acceptor<HANDLER>::pass_addresses (void) const
00472 {
00473   return this->pass_addresses_;
00474 }
00475 
00476 template <class HANDLER> void
00477 ACE_Asynch_Acceptor<HANDLER>::pass_addresses (int new_value)
00478 {
00479   this->pass_addresses_ = new_value;
00480 }
00481 
00482 template <class HANDLER> int
00483 ACE_Asynch_Acceptor<HANDLER>::validate_new_connection (void) const
00484 {
00485   return this->validate_new_connection_;
00486 }
00487 
00488 template <class HANDLER> void
00489 ACE_Asynch_Acceptor<HANDLER>::validate_new_connection (int new_value)
00490 {
00491   this->validate_new_connection_ = new_value;
00492 }
00493 
00494 template <class HANDLER> int
00495 ACE_Asynch_Acceptor<HANDLER>::reissue_accept (void) const
00496 {
00497   return this->reissue_accept_;
00498 }
00499 
00500 template <class HANDLER> void
00501 ACE_Asynch_Acceptor<HANDLER>::reissue_accept (int new_value)
00502 {
00503   this->reissue_accept_ = new_value;
00504 }
00505 
00506 template <class HANDLER> size_t
00507 ACE_Asynch_Acceptor<HANDLER>::bytes_to_read (void) const
00508 {
00509   return this->bytes_to_read_;
00510 }
00511 
00512 template <class HANDLER> void
00513 ACE_Asynch_Acceptor<HANDLER>::bytes_to_read (size_t new_value)
00514 {
00515   this->bytes_to_read_ = new_value;
00516 }
00517 
00518 template <class HANDLER> int
00519 ACE_Asynch_Acceptor<HANDLER>::should_reissue_accept (void)
00520 {
00521   return this->reissue_accept_;
00522 }
00523 
00524 ACE_END_VERSIONED_NAMESPACE_DECL
00525 
00526 #endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS */
00527 #endif /* ACE_ASYNCH_ACCEPTOR_C */

Generated on Thu Nov 9 09:41:46 2006 for ACE by doxygen 1.3.6