bool ConnectionCache::release_connection(const ConnectionKey& key, connection_type* connection) { INET_TRACE ("ConnectionCache::release_connection"); INET_DEBUG (9, (LM_INFO, DLINFO ACE_TEXT ("ConnectionCache::release_connection - ") ACE_TEXT ("releasing connection\n"))); ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, guard_, this->lock_, false)); ConnectionCacheValue cacheval; if (this->find_connection (key, cacheval) && cacheval.connection () == connection && cacheval.state () == ConnectionCacheValue::CST_BUSY) { cacheval.state (ConnectionCacheValue::CST_IDLE); if (this->set_connection (key, cacheval)) { // signal other threads about free connection this->condition_.broadcast (); return true; } else { INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("ConnectionCache::release_connection - ") ACE_TEXT ("failed to release connection entry"))); return false; } } else return false; }
bool ConnectionCache::claim_existing_connection(const ConnectionKey& key, connection_type*& connection, ConnectionCacheValue::State& state) { INET_TRACE ("ConnectionCache::claim_existing_connection"); ConnectionCacheValue cacheval; if (this->find_connection (key, cacheval)) { state = cacheval.state (); if (state == ConnectionCacheValue::CST_IDLE) { cacheval.state (ConnectionCacheValue::CST_BUSY); if (this->set_connection (key, cacheval)) { connection = cacheval.connection (); return true; } else { INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("ConnectionCache::claim_existing_connection - ") ACE_TEXT ("failed to claim connection entry"))); } } } return false; }
bool Session_T<ACE_SYNCH_USE>::connect (bool use_reactor) { INET_TRACE ("ACE_FTP_Session::connect"); typedef ACE_Connector<connection_type, ACE_SOCK_CONNECTOR> connector_type; this->close (); unsigned long f_reactor = use_reactor ? ACE_Synch_Options::USE_REACTOR : 0; ACE_Synch_Options sync_opt (ACE_Synch_Options::USE_TIMEOUT | f_reactor, this->ftp_timeout_); connector_type connector; connection_type* new_connection = 0; ACE_NEW_RETURN (new_connection, connection_type(sync_opt), false); if (connector.connect (new_connection, ACE_INET_Addr (this->port_, this->host_.c_str ()), ACE_Synch_Options (0,this->ftp_timeout_)) == -1) { INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("(%d) ACE_FTP_Session::connect - ") ACE_TEXT ("failed to connect; host=%C, port=%d"), ACE_OS::last_error (), this->host_.c_str (), this->port_)); // as the connection was dynamically allocated // the connector causes it to be destroyed after // the connection failure return false; } this->connection_ = new_connection; this->connection_->reference_counting_policy ().value ( ACE_Event_Handler::Reference_Counting_Policy::ENABLED); ACE_NEW_NORETURN (this->sock_stream_, sock_stream_type (this->connection_)); if (this->sock_stream_) { this->new_connect_ = true; this->cannot_reconnect_ = false; this->reactive_ = use_reactor; return true; } else { this->close (); return false; } }
bool Session_T<ACE_SYNCH_USE>::connect_i (const ACE_Synch_Options& sync_opt) { INET_TRACE ("ACE_HTTP_Session::connect_i"); typedef ACE_Connector<connection_type, ACE_SOCK_CONNECTOR> connector_type; connector_type connector; connection_type* new_connection = 0; ACE_NEW_RETURN (new_connection, connection_type(sync_opt), false); if (connector.connect (new_connection, ACE_INET_Addr (this->port_, this->host_.c_str ()), ACE_Synch_Options (0,this->http_timeout_)) == -1) { INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("(%d) ACE_HTTP_Session::connect_i - ") ACE_TEXT ("failed to connect; host=%C, port=%d\n"), ACE_OS::last_error (), this->host_.c_str (), this->port_)); // as the connection was dynamically allocated // the connector causes it to be destroyed after // the connection failure return false; } this->connection_ = new_connection; this->connection_->reference_counting_policy ().value ( ACE_Event_Handler::Reference_Counting_Policy::ENABLED); ACE_NEW_NORETURN (this->sock_stream_, sock_stream_type (this->connection_)); if (this->sock_stream_) { this->cannot_reconnect_ = false; this->reactive_ = sync_opt[ACE_Synch_Options::USE_REACTOR]; // reset reconnect timer this->reconnect_timer_ = this->keep_alive_timeout_; this->reconnect_countdown_.start (); return true; } else { this->close (); return false; } }
bool Session_T<ACE_SYNCH_USE>::connect (connection_type* connection) { INET_TRACE ("ACE_FTP_Session::connect(connection)"); this->close (); if (connection->is_connected ()) { ACE_INET_Addr remote; connection->peer ().get_remote_addr (remote); this->host_ = remote.get_host_name (); this->port_ = remote.get_port_number (); } else { typedef ACE_Connector<connection_type, ACE_SOCK_CONNECTOR> connector_type; connector_type connector; if (connector.connect (connection, ACE_INET_Addr (this->host_.c_str (), this->port_)) == -1) { INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("(%d) ACE_FTP_Session::connect(connection) - ") ACE_TEXT ("failed to connect; host=%C, port=%d"), ACE_OS::last_error (), this->host_.c_str (), this->port_)); return false; } } this->connection_ = connection; this->connection_->add_reference (); ACE_NEW_NORETURN (this->sock_stream_, sock_stream_type (this->connection_)); if (this->sock_stream_) { this->new_connect_ = true; this->cannot_reconnect_ = true; return true; } else { this->close (); return false; } }
bool ClientRequestHandler::initialize_connection (const ACE_CString& scheme, const ACE_CString& host, u_short port, bool proxy_conn, const ACE_CString& proxy_host, u_short proxy_port) { SessionFactory* session_factory = SessionFactoryRegistry::instance ().find_session_factory (scheme); if (session_factory == 0) { INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("ClientRequestHandler::initialize_connection - ") ACE_TEXT ("unable to find session factory for scheme [%C]\n"), scheme.c_str ())); return false; } ACE::INet::ConnectionHolder* pch = 0; if (proxy_conn) { if (!this->connection_cache ().claim_connection (HttpConnectionKey (proxy_host, proxy_port, host, port), pch, *session_factory)) return false; } else { if (!this->connection_cache ().claim_connection (HttpConnectionKey (host, port), pch, *session_factory)) return false; } this->session (dynamic_cast<SessionHolder*> (pch)); return true; }
void SSL_CallbackManager::initialize_callbacks (ACE_SSL_Context* ssl_ctx) { if (ssl_ctx_mngr_index_ < -1) { ssl_ctx_mngr_index_ = ::SSL_CTX_get_ex_new_index (0, 0, 0,0,0); if (ssl_ctx_mngr_index_ < 0) { INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("SSL_CallbackManager::initialize_callbacks - ") ACE_TEXT ("failed to allocate SSL_CTX ex_data index.\n"))); return; } } this->ssl_ctx_ = ssl_ctx == 0 ? ACE_SSL_Context::instance () : ssl_ctx; ::SSL_CTX_set_ex_data (this->ssl_ctx_->context (), ssl_ctx_mngr_index_, this); this->ssl_ctx_->default_verify_callback (verify_certificate_callback); ::SSL_CTX_set_default_passwd_cb (ssl_ctx->context(), passwd_callback); ::SSL_CTX_set_default_passwd_cb_userdata (ssl_ctx->context(), this); }
bool Session_T<ACE_SYNCH_USE>::send_request (Request& request) { INET_TRACE ("ACE_FTP_Session::send_request"); if (!this->is_connected ()) { if (this->cannot_reconnect_ || !this->connect(this->reactive_)) { if (!this->cannot_reconnect_) INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("(%d) FTP_Session::send_request - ") ACE_TEXT ("reconnect failed\n"), ACE_OS::last_error ())); return ACE::IOS::Null::out_stream_; } } this->new_connect_ = false; request.write (*this->sock_stream_); return this->is_connected () && this->sock_stream_->good (); }
bool ConnectionCache::claim_connection(const ConnectionKey& key, connection_type*& connection, const factory_type& connection_factory, bool wait) { INET_TRACE ("ConnectionCache::claim_connection"); while (1) { bool create_connection = false; ConnectionCacheValue::State state = ConnectionCacheValue::CST_NONE; do { ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, guard_, this->lock_, false)); if (this->claim_existing_connection (key, connection, state)) { INET_DEBUG (9, (LM_INFO, DLINFO ACE_TEXT ("%P|%t) ConnectionCache::claim_connection - ") ACE_TEXT ("successfully claimed existing connection\n"))); return true; } if ((state == ConnectionCacheValue::CST_BUSY || state == ConnectionCacheValue::CST_INIT) && !wait) return false; if (state == ConnectionCacheValue::CST_CLOSED || state == ConnectionCacheValue::CST_NONE) { if (!this->set_connection (key, ConnectionCacheValue ())) { INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("ConnectionCache::claim_connection - ") ACE_TEXT ("failed to initialize connection entry"))); return false; } create_connection = true; } else { INET_DEBUG (9, (LM_INFO, DLINFO ACE_TEXT ("ConnectionCache::claim_connection - ") ACE_TEXT ("waiting for connection to become available\n"))); // wait for connection to become ready/free if (this->condition_.wait () != 0) { INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("(%P|%t) ConnectionCache::claim_connection - ") ACE_TEXT ("error waiting for connection condition (%p)\n"))); return false; } INET_DEBUG (9, (LM_INFO, DLINFO ACE_TEXT ("ConnectionCache::claim_connection - ") ACE_TEXT ("awoken and retrying to claim connection\n"))); } } while (0); if (create_connection) { connection = connection_factory.create_connection (key); if (connection) { INET_DEBUG (9, (LM_INFO, DLINFO ACE_TEXT ("ConnectionCache::claim_connection - ") ACE_TEXT ("successfully created new connection\n"))); ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, guard_, this->lock_, false)); ConnectionCacheValue cacheval (connection); cacheval.state (ConnectionCacheValue::CST_BUSY); return this->set_connection (key, cacheval); } else return false; } } }
ClientRequestHandler::stream_type* ClientRequestHandler::open_data_connection (const ACE_CString& cmd, const ACE_CString& arg) { if (this->use_passive_mode_) { // get address for passive data connection ACE_INET_Addr data_addr; if (this->get_passive_address (data_addr)) { // establish data connection // copy sync settings from session unsigned long f_reactor = this->session ()->is_reactive() ? ACE_Synch_Options::USE_REACTOR : 0; ACE_Synch_Options sync_opt (ACE_Synch_Options::USE_TIMEOUT | f_reactor, this->session ()->timeout ()); typedef ACE_Connector<SessionHolder::session_type::connection_type, ACE_SOCK_CONNECTOR> connector_type; connector_type connector; // create connection object (stream handler) SessionHolder::session_type::connection_type* data_connection = 0; ACE_NEW_NORETURN (data_connection, SessionHolder::session_type::connection_type(sync_opt)); if (data_connection == 0) { return 0; } // connect to data connection address if (connector.connect (data_connection, data_addr, ACE_Synch_Options (0, this->session ()->timeout ())) == -1) { INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("(%d) ACE_FTP_ClientRequestHandler::open_data_connection - ") ACE_TEXT ("failed to connect to %C:%d\n"), ACE_OS::last_error (), data_addr.get_host_name (), data_addr.get_port_number ())); // as the connection was dynamically allocated // the connector causes it to be destroyed after // the connection failure return 0; } // enable ref counting so we can control when to destroy data_connection->reference_counting_policy ().value ( ACE_Event_Handler::Reference_Counting_Policy::ENABLED); // create io stream for connection stream_type* data_stream = 0; ACE_NEW_NORETURN (data_stream, stream_type (data_connection)); if (data_stream) { if (this->process_command (cmd, arg) == Response::PRELIM_OK) return data_stream; delete data_stream; // decreases ref count on connection } // remove last ref count -> delete data_connection->remove_reference (); } } else { // address for active data connection ACE_INET_Addr data_addr; this->session ()->get_local_addr (data_addr); data_addr.set_port_number (this->active_port_); // copy sync settings from session unsigned long f_reactor = this->session ()->is_reactive() ? ACE_Synch_Options::USE_REACTOR : 0; ACE_Synch_Options sync_opt (ACE_Synch_Options::USE_TIMEOUT | f_reactor, this->session ()->timeout ()); typedef ACE_Oneshot_Acceptor<SessionHolder::session_type::connection_type, ACE_SOCK_ACCEPTOR> acceptor_type; acceptor_type acceptor; // start data connection acceptor listening and retrieve actual listening address if (acceptor.open (data_addr) == 0 && acceptor.acceptor ().get_local_addr (data_addr) == 0) { // send listen address to peer followed by data command to execute if (this->send_active_address (data_addr) && this->process_command (cmd, arg) == Response::PRELIM_OK) { // create connection object (stream handler) SessionHolder::session_type::connection_type* data_connection = 0; ACE_NEW_NORETURN (data_connection, SessionHolder::session_type::connection_type(sync_opt)); if (data_connection == 0) { return 0; } // accept data connection from peer if (acceptor.accept (data_connection, 0, ACE_Synch_Options (ACE_Synch_Options::USE_TIMEOUT, this->session ()->timeout ())) == -1) { INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("(%d) ACE_FTP_ClientRequestHandler::open_data_connection - ") ACE_TEXT ("failed to accept connection to %C:%d\n"), ACE_OS::last_error (), data_addr.get_host_name (), data_addr.get_port_number ())); // as the connection was dynamically allocated // the acceptor causes it to be destroyed after // the connection failure return 0; } // enable ref counting so we can control when to destroy data_connection->reference_counting_policy ().value ( ACE_Event_Handler::Reference_Counting_Policy::ENABLED); // create io stream for connection stream_type* data_stream = 0; ACE_NEW_NORETURN (data_stream, stream_type (data_connection)); if (data_stream) { return data_stream; } // remove last ref count -> delete data_connection->remove_reference (); } } } return 0; }