template <class HANDLER> void ACE_Asynch_Acceptor<HANDLER>::parse_address (const ACE_Asynch_Accept::Result &result, ACE_INET_Addr &remote_address, ACE_INET_Addr &local_address) { ACE_TRACE ("ACE_Asynch_Acceptor<>::parse_address"); #if defined (ACE_HAS_AIO_CALLS) // Use an ACE_SOCK to get the addresses - it knows how to deal with // ACE_INET_Addr objects and get IPv4/v6 addresses. ACE_SOCK_Stream str (result.accept_handle ()); str.get_local_addr (local_address); str.get_remote_addr (remote_address); #elif defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) ACE_Message_Block &message_block = result.message_block (); sockaddr *local_addr = 0; sockaddr *remote_addr = 0; int local_size = 0; int remote_size = 0; // This matches setup in accept(). size_t addr_size = sizeof (sockaddr_in) + 16; #if defined (ACE_HAS_IPV6) if (this->addr_family_ == PF_INET6) addr_size = sizeof (sockaddr_in6) + 16; #endif /* ACE_HAS_IPV6 */ ::GetAcceptExSockaddrs (message_block.rd_ptr (), static_cast<DWORD> (this->bytes_to_read_), static_cast<DWORD> (addr_size), static_cast<DWORD> (addr_size), &local_addr, &local_size, &remote_addr, &remote_size); local_address.set (reinterpret_cast<sockaddr_in *> (local_addr), local_size); remote_address.set (reinterpret_cast<sockaddr_in *> (remote_addr), remote_size); #else // just in case errno = ENOTSUP; #endif /* defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) */ return; }
template <class HANDLER> void ACE_Asynch_Acceptor<HANDLER>::handle_accept (const ACE_Asynch_Accept::Result &result) { ACE_TRACE ("ACE_Asynch_Acceptor<>::handle_accept"); // Variable for error tracking int error = 0; // If the asynchronous accept fails. if (!result.success () || result.accept_handle () == ACE_INVALID_HANDLE) { error = 1; } #if defined (ACE_WIN32) // In order to use accept handle with other Window Sockets 1.1 // functions, we call the setsockopt function with the // SO_UPDATE_ACCEPT_CONTEXT option. This option initializes the // socket so that other Windows Sockets routines to access the // socket correctly. if (!error && ACE_OS::setsockopt (result.accept_handle (), SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char *) &this->listen_handle_, sizeof (this->listen_handle_)) == -1) { error = 1; } #endif /* ACE_WIN32 */ // Parse address. ACE_INET_Addr local_address; ACE_INET_Addr remote_address; if (!error && (this->validate_new_connection_ || this->pass_addresses_)) // Parse the addresses. this->parse_address (result, remote_address, local_address); // Validate remote address if (!error && this->validate_new_connection_ && (this->validate_connection (result, remote_address, local_address) == -1)) { error = 1; } HANDLER *new_handler = 0; if (!error) { // The Template method new_handler = this->make_handler (); if (new_handler == 0) { error = 1; } } // If no errors if (!error) { // Update the Proactor. new_handler->proactor (this->proactor ()); // Pass the addresses if (this->pass_addresses_) new_handler->addresses (remote_address, local_address); // Pass the ACT if (result.act () != 0) new_handler->act (result.act ()); // Set up the handler's new handle value new_handler->handle (result.accept_handle ()); // Initiate the handler new_handler->open (result.accept_handle (), result.message_block ()); } // On failure, no choice but to close the socket if (error && result.accept_handle() != ACE_INVALID_HANDLE ) ACE_OS::closesocket (result.accept_handle ()); // Delete the dynamically allocated message_block result.message_block ().release (); // Start off another asynchronous accept to keep the backlog going, // unless we closed the listen socket already (from the destructor), // or this callback is the result of a canceled/aborted accept. if (this->should_reissue_accept () && this->listen_handle_ != ACE_INVALID_HANDLE #if defined (ACE_WIN32) && result.error () != ERROR_OPERATION_ABORTED #else && result.error () != ECANCELED #endif ) this->accept (this->bytes_to_read_, result.act ()); }