/* -*- C++ -*- */ //============================================================================= /** * @file Asynch_Acceptor.h * * @author Irfan Pyarali (irfan@cs.wustl.edu) */ //============================================================================= #ifndef ACE_ASYNCH_ACCEPTOR_H #define ACE_ASYNCH_ACCEPTOR_H #include /**/ "ace/pre.h" #include /**/ "ace/config-all.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ #if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS) // This only works on platforms that support async i/o. #include "ace/Default_Constants.h" #include "ace/Asynch_IO.h" ACE_BEGIN_VERSIONED_NAMESPACE_DECL // Forward declarations class ACE_Message_Block; class ACE_INET_Addr; /** * @class ACE_Asynch_Acceptor * * @brief This class is an example of the Acceptor Pattern. This class * will accept new connections and create new HANDLER to handle * the new connections. * * Unlike the ACE_Acceptor, however, this class is designed to * be used asynchronously. */ template class ACE_Asynch_Acceptor : public ACE_Handler { public: /// A do nothing constructor. ACE_Asynch_Acceptor (void); /// Virtual destruction virtual ~ACE_Asynch_Acceptor (void); /** * @c open starts one or more asynchronous accept requests on a * @a address. Each accept operation may optionally read an * initial buffer from the new connection when accepted. * * @param address The address to listen/accept connections on. * If the address does not specify a port, a random * port is selected and bound. * @param bytes_to_read Optional, specifies the maximum number of bytes * to read with the accept. The buffer for the initial * data is allocated internally and passed to the * @c ACE_Service_Handler::open() hook method. It is * legitimate only during the @c open() method and must * be copied if required after @c open() returns. * This pre-read function works only on Windows. * @param pass_addresses Optional, a non-zero value indicates that * the local and peer addresses should be passed to the * associated @c ACE_Service_Handler::addresses() method * after any call to @c validate_new_connection() and prior * to the @c open() hook method call. * @param backlog Optional, defaulting to @c ACE_DEFAULT_ASYNCH_BACKLOG (which * can be adjusted in your platform's @c config.h file). * Specifies the listening backlog for the listening socket. * @param reuse_addr Optional, indicates whether the @c SO_REUSEADDR * option is set on the listening socket or not. * @param proactor Optional, pointer to the @c ACE_Proactor to use for * demultiplexing asynchronous accepts. If 0, the * process's singleton @c ACE_Proactor is used. * @param validate_new_connection Optional, if true, this object's * @c validate_connection() method is called after * the accept completes, but before the service handler's * @c open() hook method is called. If @c * validate_connection() returns -1, the newly-accepted * socket is immediately closed, and the @c addresses() * method is not called. * @param reissue_accept Optional, if non-zero (the default), a new * asynchronous accept operation is started after each * completion, whether the completion is for success or * failure, and whether or not a successfully-accepted * connection is subsequently refused. * @param number_of_initial_accepts Optional, the number of asynchronous * accepts that are started immediately. If -1 (the * default), the value of @a backlog is used. * * @note On Windows, the peer address is only available at the time * the connection is accepted. Therefore, if you require the peer * address on Windows, do not rely on the * @c ACE_SOCK::get_remote_addr() method - it won't work. You must * supply a non-zero value for @a pass_addresses and obtain the * peer address in the @c ACE_Service_Handler::addresses() method. * * @see ACE_INET_Addr * @see ACE_Service_Handler */ virtual int open (const ACE_INET_Addr &address, size_t bytes_to_read = 0, bool pass_addresses = false, int backlog = ACE_DEFAULT_ASYNCH_BACKLOG, int reuse_addr = 1, ACE_Proactor *proactor = 0, bool validate_new_connection = false, int reissue_accept = 1, int number_of_initial_accepts = -1); /// Get the underlying handle. virtual ACE_HANDLE get_handle () const; /** * Set the underlying listen handle. It is the user's responsibility * to make sure that the old listen handle has been appropriately * closed and the all outstanding asynchronous operations have * either completed or have been canceled on the old listen handle. */ virtual int set_handle (ACE_HANDLE handle); /// This initiates a new asynchronous accept operation. /** * You need only call this method if the @a reissue_accept argument * passed to @c open() was 0. */ virtual int accept (size_t bytes_to_read = 0, const void *act = 0); /** * Cancels all pending accepts operations issued by this object. * * @note On Windows, only accept operations initiated by the calling thread * are canceled. */ virtual int cancel (void); /** * Template method to validate peer before service is opened. * This method is called after a new connection is accepted if the * @a validate_connection argument to @c open() was non-zero or * the @c validate_new_connection() method is called to turn this * feature on. The default implementation returns 0. Users can * reimplement this method to perform validation of the peer * using it's address, running an authentication procedure (such as * SSL) or anything else necessary or desireable. The return value * from this method determines whether or not ACE will continue * opening the service or abort the connection. * * @param result Result of the connection acceptance. * @param remote Peer's address. * @param local Local address connection was accepted at. * * @retval -1 ACE_Asynch_Acceptor will close the connection, and * the service will not be opened. * @retval 0 Service opening will proceeed. */ virtual int validate_connection (const ACE_Asynch_Accept::Result& result, const ACE_INET_Addr &remote, const ACE_INET_Addr& local); /** * Template method for deciding whether to reissue accept. * * This hook method is called after each accept completes to decide if * another accept should be initiated. If the method returns a non-zero * value, another accept is initiated. * * The default implementation always returns the value passed as the * @c open() method's @a reissue_accept argument. That value can also * be changed using the @c reissue_accept() method. */ virtual int should_reissue_accept (void); // // These are low level tweaking methods // /// Get flag that indicates if parsing and passing of addresses to /// the service_handler is necessary. virtual bool pass_addresses () const; /// Set flag that indicates if parsing and passing of addresses to /// the service_handler is necessary. virtual void pass_addresses (bool new_value); /// Get flag that indicates if address validation is required. virtual bool validate_new_connection () const; /// Set flag that indicates if address validation is required. virtual void validate_new_connection (bool new_value); /// Get flag that indicates if a new accept should be reissued when a accept /// completes. virtual int reissue_accept () const; /// Set flag that indicates if a new accept should be reissued when a accept /// completes. virtual void reissue_accept (int new_value); /// Get bytes to be read with the call. virtual size_t bytes_to_read () const; /// Set bytes to be read with the call. virtual void bytes_to_read (size_t new_value); protected: /// This is called when an outstanding accept completes. virtual void handle_accept (const ACE_Asynch_Accept::Result &result); /// Return the listen handle. ACE_HANDLE handle () const; /// Set the listen handle. void handle (ACE_HANDLE h); /// This parses the address from read buffer. void parse_address (const ACE_Asynch_Accept::Result &result, ACE_INET_Addr &remote_address, ACE_INET_Addr &local_address); /// Return the asynch accept object. ACE_Asynch_Accept &asynch_accept (void); /** * This is the template method used to create new handler. * Subclasses must overwrite this method if a new handler creation * strategy is required. */ virtual HANDLER *make_handler (void); private: /// Handle used to listen for new connections. ACE_HANDLE listen_handle_; /// Asynch_Accept used to make life easier :-) ACE_Asynch_Accept asynch_accept_; /// Flag that indicates if parsing of addresses is necessary. bool pass_addresses_; /// Flag that indicates if address validation is required. bool validate_new_connection_; /// Flag that indicates if a new accept should be reissued when a /// accept completes. int reissue_accept_; /// Bytes to be read with the call. size_t bytes_to_read_; /// Address family used to open this object. Obtained from @a address passed /// to @c open(). int addr_family_; }; ACE_END_VERSIONED_NAMESPACE_DECL #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) #include "ace/Asynch_Acceptor.cpp" #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) #pragma implementation ("Asynch_Acceptor.cpp") #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ #endif /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_AIO_CALLS */ #include /**/ "ace/post.h" #endif /* ACE_ASYNCH_ACCEPTOR_H */