Ejemplo n.º 1
0
static ACE_THR_FUNC_RETURN
start_clients (void *)
{
  // Client thread function.
  ACE_INET_Addr addr (rendezvous);
  ACE_SSL_SOCK_Connector connect;

  for (size_t i = 0 ; i < cli_conn_no; i++)
    {
      ACE_SSL_SOCK_Stream stream;
      if (connect.connect (stream, addr) < 0)
        {
          ACE_ERROR ((LM_ERROR,
                      ACE_TEXT ("(%t) %p\n"),
                      ACE_TEXT ("connect")));
          continue;
        }

      Client_Handler *new_handler = 0;
      ACE_NEW_RETURN (new_handler, Client_Handler, (ACE_THR_FUNC_RETURN)-1);
      if (new_handler->open (stream.get_handle ()) != 0)
        {
          delete new_handler;
          stream.close ();
        }
    }

  return 0;
}
Ejemplo n.º 2
0
int
ACE_SSL_SOCK_Acceptor::accept (ACE_SSL_SOCK_Stream &new_stream,
                               ACE_Accept_QoS_Params qos_params,
                               ACE_Addr *remote_addr,
                               ACE_Time_Value *timeout,
                               int restart,
                               int reset_new_handle) const
{
  ACE_TRACE ("ACE_SSL_SOCK_Acceptor::accept");

  int in_blocking_mode = 0;
  if (this->shared_accept_start (timeout,
                                 restart,
                                 in_blocking_mode) == -1)
    return -1;
  else
    {
      // On Win32 the third parameter to <accept> must be a NULL
      // pointer if we want to ignore the client's address.
      int *len_ptr = 0;
      sockaddr *addr = 0;
      int len = 0;

      if (remote_addr != 0)
        {
          len = remote_addr->get_size ();
          len_ptr = &len;
          addr = (sockaddr *) remote_addr->get_addr ();
        }

      ACE_HANDLE handle;
      do
        handle = ACE_OS::accept (this->get_handle (),
                                 addr,
                                 len_ptr,
                                 qos_params);
      while (handle == ACE_INVALID_HANDLE
             && restart != 0
             && errno == EINTR
             && timeout == 0);

      // Reset the size of the addr, which is only necessary for UNIX
      // domain sockets.
      if (handle != ACE_INVALID_HANDLE
          && remote_addr != 0)
        remote_addr->set_size (len);

      new_stream.set_handle (handle);
    }

  if (this->shared_accept_finish (new_stream,
                                  in_blocking_mode,
                                  reset_new_handle) != 0)
    return -1;

  if (in_blocking_mode)
    return this->ssl_accept (new_stream);

  return this->ssl_accept (new_stream, timeout);
}
Ejemplo n.º 3
0
static ACE_THR_FUNC_RETURN
worker (void *)
{
  ACE_OS::sleep (3);
  const ACE_TCHAR *msg = ACE_TEXT ("Message from Connection worker");
  ACE_TCHAR buf [BUFSIZ];
  buf[0] = ACE_OS::strlen (msg) + 1;
  ACE_OS::strcpy (&buf[1], msg);

  ACE_INET_Addr addr (rendezvous);

  ACE_DEBUG((LM_DEBUG,
             "(%t) Spawning %d client threads...\n",
             cli_thrno));
  int grp = ACE_Thread_Manager::instance ()->spawn_n (cli_thrno,
                                                      &cli_worker,
                                                      buf);
  ACE_ASSERT (grp != -1);

  ACE_Thread_Manager::instance ()->wait_grp (grp);

  ACE_DEBUG ((LM_DEBUG,
              "(%t) Client threads done; shutting down...\n"));
  ACE_SSL_SOCK_Stream stream;
  ACE_SSL_SOCK_Connector connect;

  if (connect.connect (stream, addr) == -1)
    ACE_ERROR ((LM_ERROR,
                "(%t) %p Error while connecting\n",
                "connect"));

  const ACE_TCHAR *sbuf = ACE_TEXT ("\011shutdown");

  ACE_DEBUG ((LM_DEBUG,
              "shutdown stream handle = %x\n",
              stream.get_handle ()));

  if (stream.send_n (sbuf, (ACE_OS::strlen (sbuf) + 1) * sizeof (ACE_TCHAR)) == -1)
    ACE_ERROR ((LM_ERROR,
                "(%t) %p\n",
                "send_n"));

  stream.close ();

  return 0;
}
Ejemplo n.º 4
0
static ACE_THR_FUNC_RETURN
cli_worker (void *arg)
{
  // Client thread function.
  ACE_INET_Addr addr (rendezvous);
  ACE_SSL_SOCK_Stream stream;
  ACE_SSL_SOCK_Connector connect;
  ACE_Time_Value delay (0, req_delay);
  size_t len = * reinterpret_cast<ACE_TCHAR *> (arg);

  for (size_t i = 0 ; i < cli_conn_no; i++)
    {
      if (connect.connect (stream, addr) < 0)
        {
          ACE_ERROR ((LM_ERROR,
                      "(%t) %p\n",
                      "connect"));
          continue;
        }

      for (size_t j = 0; j < cli_req_no; j++)
        {
          ACE_DEBUG ((LM_DEBUG,
                      "(%t) conn_worker handle 0x%x, req %d\n",
                      stream.get_handle (),
                      j+1));
          if (stream.send_n (arg,
                             (len + 1) * sizeof (ACE_TCHAR)) == -1)
            {
              ACE_ERROR ((LM_ERROR,
                          "(%t) %p\n",
                          "send_n"));
              continue;
            }
          ACE_OS::sleep (delay);
        }

      stream.close ();
    }

  return 0;
}
Ejemplo n.º 5
0
int
ACE_SSL_SOCK_Acceptor::ssl_accept (ACE_SSL_SOCK_Stream &new_stream) const
{
  if (SSL_is_init_finished (new_stream.ssl ()))
    return 0;

  if (!SSL_in_accept_init (new_stream.ssl ()))
    ::SSL_set_accept_state (new_stream.ssl ());

  int status = ::SSL_accept (new_stream.ssl ());

  switch (::SSL_get_error (new_stream.ssl (), status))
    {
    case SSL_ERROR_NONE:
      break;
    case SSL_ERROR_ZERO_RETURN:
      // The peer has notified us that it is shutting down via
      // the SSL "close_notify" message so we need to
      // shutdown, too.
      (void) new_stream.close ();
      return -1;
    default:
      ACE_SSL_Context::report_error ();

      return -1;
    }

  return 0;
}
Ejemplo n.º 6
0
int
ACE_SSL_SOCK_Acceptor::accept (ACE_SSL_SOCK_Stream &new_stream,
                               ACE_Accept_QoS_Params qos_params,
                               ACE_Addr *remote_addr,
                               ACE_Time_Value *timeout,
                               int restart,
                               int reset_new_handle) const
{
  ACE_TRACE ("ACE_SSL_SOCK_Acceptor::accept");

  // Take into account the time to complete the basic TCP handshake
  // and the SSL handshake.
  ACE_Countdown_Time countdown (timeout);

  ACE_SOCK_Stream temp_stream;
  if (-1 == this->acceptor_.accept (temp_stream,
                                    qos_params,
                                    remote_addr,
                                    timeout,
                                    restart,
                                    reset_new_handle))
    return -1;

  (void) countdown.update ();

  new_stream.set_handle (temp_stream.get_handle ());
  temp_stream.set_handle (ACE_INVALID_HANDLE);

  if (this->ssl_accept (new_stream, timeout) == -1)
    {
      new_stream.close ();
      new_stream.set_handle (ACE_INVALID_HANDLE);
      return -1;
    }

  return 0;

}
Ejemplo n.º 7
0
int
ACE_SSL_SOCK_Acceptor::shared_accept_finish (ACE_SSL_SOCK_Stream& new_stream,
                                             int in_blocking_mode,
                                             int reset_new_handle) const
{
  ACE_TRACE ("ACE_SSL_SOCK_Acceptor::shared_accept_finish ()");

  ACE_HANDLE new_handle = new_stream.get_handle ();

  // Check to see if we were originally in blocking mode, and if so,
  // set the <new_stream>'s handle and <this> handle to be in blocking
  // mode.
  if (in_blocking_mode)
    {
      // Save/restore errno.
      ACE_Errno_Guard error (errno);

      // Only disable ACE_NONBLOCK if we weren't in non-blocking mode
      // originally.
      ACE::clr_flags (this->get_handle (),
                      ACE_NONBLOCK);
      ACE::clr_flags (new_handle,
                      ACE_NONBLOCK);
    }

#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
  if (reset_new_handle)
    // Reset the event association inherited by the new handle.
    ::WSAEventSelect ((SOCKET) new_handle, 0, 0);
#else
  ACE_UNUSED_ARG (reset_new_handle);
#endif /* ACE_WIN32 */

  if (new_handle == ACE_INVALID_HANDLE)
    return -1;

  return 0;
}
Ejemplo n.º 8
0
int
twoway_server (ACE_SSL_SOCK_Stream &stream)
{
  ACE_INET_Addr cli_addr;

  // Make sure we're not in non-blocking mode.
  if (stream.disable (ACE_NONBLOCK) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "%p\n",
                       "disable"),
                       0);
  else if (stream.get_remote_addr (cli_addr) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "%p\n",
                       "get_remote_addr"),
                       0);

  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t) client %s connected from %d\n",
              cli_addr.get_host_name (),
              cli_addr.get_port_number ()));

  size_t total_bytes = 0;
  size_t message_count = 0;

  char *request = 0;

  // Read data from client (terminate on error).

  for (;;)
    {
      ACE_INT32 len;

      ssize_t r_bytes = stream.recv_n ((void *) &len,
                                       sizeof (ACE_INT32));
      if (r_bytes == -1)
        {
          ACE_ERROR ((LM_ERROR,
                      "%p\n",
                      "recv"));
          break;
        }
      else if (r_bytes == 0)
        {
          ACE_DEBUG ((LM_DEBUG,
                      "(%P|%t) reached end of input, connection closed by client\n"));
          break;
        }
      else if (r_bytes != sizeof (ACE_INT32))
        {
          ACE_ERROR ((LM_ERROR,
                      "(%P|%t) %p\n",
                      "recv_n failed"));
          break;
        }
      else
        {
          len = ntohl (len);
          ACE_NEW_RETURN (request,
                          char [len],
                          0);
        }

      // Subtract off the sizeof the length prefix.
      r_bytes = stream.recv_n (request,
                               len - sizeof (ACE_UINT32));
      if (r_bytes == -1)
        {
          ACE_ERROR ((LM_ERROR,
                      "%p\n",
                      "recv"));
          break;
        }
      else if (r_bytes == 0)
        {
          ACE_DEBUG ((LM_DEBUG,
                      "(%P|%t) reached end of input, connection closed by client\n"));
          break;
        }
      else if (verbose
               && ACE::write_n (ACE_STDOUT,
                                request,
                                r_bytes) != r_bytes)
        ACE_ERROR ((LM_ERROR,
                    "%p\n",
                    "ACE::write_n"));
      else if (stream.send_n (request,
                              r_bytes) != r_bytes)
        ACE_ERROR ((LM_ERROR,
                    "%p\n",
                    "send_n"));

      total_bytes += size_t (r_bytes);
      message_count++;

      delete [] request;
      request = 0;
    }

  // Close new endpoint (listening endpoint stays open).
  stream.close ();

  delete [] request;
  return 0;
}
Ejemplo n.º 9
0
static int
oneway_server (ACE_SSL_SOCK_Stream &stream)
{
  ACE_INET_Addr cli_addr;

  // Make sure we're not in non-blocking mode.
  if (stream.disable (ACE_NONBLOCK) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "%p\n",
                       "disable"),
                       0);
  else if (stream.get_remote_addr (cli_addr) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "%p\n",
                       "get_remote_addr"),
                       0);

  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t) client %s connected from %d\n",
              cli_addr.get_host_name (),
              cli_addr.get_port_number ()));

  // Timer business
  ACE_Profile_Timer timer;
  timer.start ();

  size_t total_bytes = 0;
  size_t message_count = 0;

  char *request = 0;

  // Read data from client (terminate on error).

  for (;;)
    {
      ACE_INT32 len;

      ssize_t r_bytes = stream.recv_n ((void *) &len,
                                       sizeof (ACE_INT32));
      if (r_bytes == -1)
        {
          ACE_ERROR ((LM_ERROR,
                      "%p\n",
                      "recv"));
          break;
        }
      else if (r_bytes == 0)
        {
          ACE_DEBUG ((LM_DEBUG,
                      "(%P|%t) reached end of input, connection closed by client\n"));
          break;
        }
      else if (r_bytes != sizeof (ACE_INT32))
        {
          ACE_ERROR ((LM_ERROR,
                      "(%P|%t) %p\n",
                      "recv_n failed"));
          break;
        }
      else
        {
          len = ntohl (len);
          ACE_NEW_RETURN (request,
                          char [len],
                          0);
        }

      // Subtract off the sizeof the length prefix.
      r_bytes = stream.recv_n (request,
                               len - sizeof (ACE_UINT32));

      if (r_bytes == -1)
        {
          ACE_ERROR ((LM_ERROR,
                      "%p\n",
                      "recv"));
          break;
        }
      else if (r_bytes == 0)
        {
          ACE_DEBUG ((LM_DEBUG,
                      "(%P|%t) reached end of input, connection closed by client\n"));
          break;
        }
      else if (verbose
               && ACE::write_n (ACE_STDOUT, request, r_bytes) != r_bytes)
        ACE_ERROR ((LM_ERROR,
                    "%p\n",
                    "ACE::write_n"));

      total_bytes += size_t (r_bytes);
      message_count++;

      delete [] request;
      request = 0;
    }

  timer.stop ();

  ACE_Profile_Timer::ACE_Elapsed_Time et;
  timer.elapsed_time (et);

  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("\t\treal time = %f secs \n\t\tuser time = %f secs \n\t\tsystem time = %f secs\n"),
              et.real_time,
              et.user_time,
              et.system_time));

  double messages_per_sec = double (message_count) / et.real_time;

  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("\t\tmessages = %d\n\t\ttotal bytes = %d\n\t\tmbits/sec = %f\n\t\tusec-per-message = %f\n\t\tmessages-per-second = %0.00f\n"),
              message_count,
              total_bytes,
              (((double) total_bytes * 8) / et.real_time) / (double) (1024 * 1024),
              (et.real_time / (double) message_count) * 1000000,
              messages_per_sec < 0 ? 0 : messages_per_sec));

  // Close new endpoint (listening endpoint stays open).
  stream.close ();

  delete [] request;
  return 0;
}
Ejemplo n.º 10
0
int
ACE_SSL_SOCK_Acceptor::ssl_accept (ACE_SSL_SOCK_Stream &new_stream,
                                   ACE_Time_Value *timeout) const
{
  SSL *ssl = new_stream.ssl ();

  if (SSL_is_init_finished (ssl))
    return 0;

  if (!SSL_in_accept_init (ssl))
    ::SSL_set_accept_state (ssl);

  // Register an event handler to complete the non-blocking SSL
  // accept.  A specialized event handler is necessary since since
  // the ACE Acceptor strategies are not designed for protocols
  // that require additional handshakes after the initial accept.
  ACE_SSL_Accept_Handler eh (new_stream);

  const ACE_Reactor_Mask reactor_mask =
    ACE_Event_Handler::READ_MASK |
    ACE_Event_Handler::WRITE_MASK;

  // In case a thread other than the one running the Reactor event
  // loop performs the passive SSL connection establishment, transfer
  // ownership of the Reactor to the current thread.  Control will be
  // passed back to the previous owner when accepting or rejecting the
  // passive SSL connection.
  ACE_thread_t old_owner;

  if (this->reactor_->owner (ACE_Thread::self (),
                             &old_owner) != 0)
    return -1;  // Failed to transfer ownership!  Should never happen!

  if (this->reactor_->register_handler (
        new_stream.get_handle (),
        &eh,
        reactor_mask) == -1)
    return -1;

  // Have the Reactor complete the SSL passive connection.  Run the
  // event loop until the passive connection is completed.  Since
  // the Reactor is used, this isn't a busy wait.
  while (!SSL_is_init_finished (ssl))
    {
      // Before blocking in the Reactor, do an SSL_accept() in case
      // OpenSSL buffered additional data sent within an SSL record
      // during session negotiation.  The buffered data must be
      // handled prior to entering the Reactor event loop since the
      // Reactor may end up waiting indefinitely for data that has
      // already arrived.
      int status = ::SSL_accept (ssl);

      switch (::SSL_get_error (ssl, status))
        {
        case SSL_ERROR_NONE:
          break;

        case SSL_ERROR_WANT_WRITE:
        case SSL_ERROR_WANT_READ:
          // No data buffered by OpenSSL, so wait for data in the
          // Reactor.
          if (this->reactor_->handle_events (timeout) == -1
              || new_stream.get_handle () == ACE_INVALID_HANDLE)
            {
              (void) this->reactor_->remove_handler (&eh, reactor_mask);
              (void) this->reactor_->owner (old_owner);
              return -1;
            }

          break;

        case SSL_ERROR_ZERO_RETURN:
          // The peer has notified us that it is shutting down via
          // the SSL "close_notify" message so we need to
          // shutdown, too.
          //
          // Removing the event handler from the Reactor causes the
          // SSL stream to be shutdown.
          (void) this->reactor_->remove_handler (&eh, reactor_mask);
          (void) this->reactor_->owner (old_owner);

          return -1;

        case SSL_ERROR_SYSCALL:
          // On some platforms (e.g. MS Windows) OpenSSL does not
          // store the last error in errno so explicitly do so.
          ACE_OS::set_errno_to_last_error ();

        default:

          ACE_SSL_Context::report_error ();

          (void) this->reactor_->remove_handler (&eh, reactor_mask);
          (void) this->reactor_->owner (old_owner);

          return -1;
        }

    }

  // SSL passive connection was completed.  Deregister the event
  // handler from the Reactor, but don't close it.
  (void) this->reactor_->remove_handler (&eh,
                                         reactor_mask |
                                         ACE_Event_Handler::DONT_CALL);

  // Transfer control of the Reactor to the previous owner.
  return this->reactor_->owner (old_owner);
}
Ejemplo n.º 11
0
int
ACE_SSL_SOCK_Acceptor::ssl_accept (ACE_SSL_SOCK_Stream &new_stream,
                                   ACE_Time_Value *timeout) const
{
  SSL *ssl = new_stream.ssl ();

  if (SSL_is_init_finished (ssl))
    return 0;

  if (!SSL_in_accept_init (ssl))
    ::SSL_set_accept_state (ssl);

  ACE_HANDLE handle = new_stream.get_handle ();

  // We're going to call SSL_accept, optionally doing ACE::select and
  // retrying the SSL_accept, until the SSL handshake is done or
  // it fails.
  // To get the timeout affect, set the socket to nonblocking mode
  // before beginning if there is a timeout specified. If the timeout
  // is 0 (wait as long as it takes) then don't worry about the blocking
  // status; we'll block in SSL_accept if the socket is blocking, and
  // block in ACE::select if not.
  int reset_blocking_mode = 0;
  if (timeout != 0)
    {
      reset_blocking_mode = ACE_BIT_DISABLED (ACE::get_flags (handle),
                                              ACE_NONBLOCK);
          // Set the handle into non-blocking mode if it's not already
          // in it.
          if (reset_blocking_mode
              && ACE::set_flags (handle,
                                 ACE_NONBLOCK) == -1)
            return -1;
    }

  // Take into account the time between each select() call below.
  ACE_Countdown_Time countdown (timeout);

  int status;
  do
    {
      // These handle sets are used to set up for whatever SSL_accept
      // says it wants next. They're reset on each pass around the loop.
      ACE_Handle_Set rd_handle;
      ACE_Handle_Set wr_handle;

      status = ::SSL_accept (ssl);
      switch (::SSL_get_error (ssl, status))
        {
        case SSL_ERROR_NONE:
          status = 0;               // To tell caller about success
          break;                    // Done

        case SSL_ERROR_WANT_WRITE:
          wr_handle.set_bit (handle);
          status = 1;               // Wait for more activity
          break;

        case SSL_ERROR_WANT_READ:
          rd_handle.set_bit (handle);
          status = 1;               // Wait for more activity
          break;

        case SSL_ERROR_ZERO_RETURN:
          // The peer has notified us that it is shutting down via
          // the SSL "close_notify" message so we need to
          // shutdown, too.
          status = -1;
          break;

        case SSL_ERROR_SYSCALL:
          // On some platforms (e.g. MS Windows) OpenSSL does not
          // store the last error in errno so explicitly do so.
          //
          // Explicitly check for EWOULDBLOCK since it doesn't get
          // converted to an SSL_ERROR_WANT_{READ,WRITE} on some
          // platforms. If SSL_accept failed outright, though, don't
          // bother checking more. This can happen if the socket gets
          // closed during the handshake.
          if (ACE_OS::set_errno_to_last_error () == EWOULDBLOCK &&
              status == -1)
            {
              // Although the SSL_ERROR_WANT_READ/WRITE isn't getting
              // set correctly, the read/write state should be valid.
              // Use that to decide what to do.
              status = 1;               // Wait for more activity
              if (SSL_want_write (ssl))
                wr_handle.set_bit (handle);
              else if (SSL_want_read (ssl))
                rd_handle.set_bit (handle);
              else
                status = -1;            // Doesn't want anything - bail out
            }
          else
            status = -1;
          break;

        default:
          ACE_SSL_Context::report_error ();
          status = -1;
          break;
        }

      if (status == 1)
        {
          // Must have at least one handle to wait for at this point.
          ACE_ASSERT (rd_handle.num_set() == 1 || wr_handle.num_set () == 1);
          status = ACE::select (int (handle) + 1,
                                &rd_handle,
                                &wr_handle,
                                0,
                                timeout);

          (void) countdown.update ();

          // 0 is timeout, so we're done.
          // -1 is error, so we're done.
          // Could be both handles set (same handle in both masks) so
          // set to 1.
          if (status >= 1)
            status = 1;
          else                   // Timeout or failure
            status = -1;
        }

    } while (status == 1 && !SSL_is_init_finished (ssl));

  if (reset_blocking_mode)
    {
      ACE_Errno_Guard eguard (errno);
      ACE::clr_flags (handle, ACE_NONBLOCK);
    }

  return (status == -1 ? -1 : 0);

}