示例#1
0
    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;
      }
示例#2
0
    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;
      }
示例#3
0
    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;
          }
      }
示例#4
0
    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;
          }
      }
示例#5
0
    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;
          }
      }
示例#6
0
    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;
      }
示例#7
0
    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);
      }
示例#8
0
    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 ();
      }
示例#9
0
    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;
              }
          }
      }
示例#10
0
    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;
      }