summaryrefslogtreecommitdiff
path: root/ACE/examples/IPC_SAP/SSL_SAP
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/examples/IPC_SAP/SSL_SAP')
-rw-r--r--ACE/examples/IPC_SAP/SSL_SAP/Makefile.am196
-rw-r--r--ACE/examples/IPC_SAP/SSL_SAP/README17
-rw-r--r--ACE/examples/IPC_SAP/SSL_SAP/SSL-client-simple.cpp379
-rw-r--r--ACE/examples/IPC_SAP/SSL_SAP/SSL-client-simple.h98
-rw-r--r--ACE/examples/IPC_SAP/SSL_SAP/SSL-client.cpp420
-rw-r--r--ACE/examples/IPC_SAP/SSL_SAP/SSL-client.h111
-rw-r--r--ACE/examples/IPC_SAP/SSL_SAP/SSL-server-fancy.cpp610
-rw-r--r--ACE/examples/IPC_SAP/SSL_SAP/SSL-server-fancy.h44
-rw-r--r--ACE/examples/IPC_SAP/SSL_SAP/SSL-server-poll.cpp212
-rw-r--r--ACE/examples/IPC_SAP/SSL_SAP/SSL-server-simple.cpp366
-rw-r--r--ACE/examples/IPC_SAP/SSL_SAP/SSL-server.cpp430
-rw-r--r--ACE/examples/IPC_SAP/SSL_SAP/SSL_SAP.mpc50
-rw-r--r--ACE/examples/IPC_SAP/SSL_SAP/dummy.pem15
-rw-r--r--ACE/examples/IPC_SAP/SSL_SAP/key.pem15
-rw-r--r--ACE/examples/IPC_SAP/SSL_SAP/local_data1
-rwxr-xr-xACE/examples/IPC_SAP/SSL_SAP/summarize45
16 files changed, 3009 insertions, 0 deletions
diff --git a/ACE/examples/IPC_SAP/SSL_SAP/Makefile.am b/ACE/examples/IPC_SAP/SSL_SAP/Makefile.am
new file mode 100644
index 00000000000..5a0e4bc3dfb
--- /dev/null
+++ b/ACE/examples/IPC_SAP/SSL_SAP/Makefile.am
@@ -0,0 +1,196 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## ./bin/mwc.pl -type automake -noreldefs ACE.mwc
+
+ACE_BUILDDIR = $(top_builddir)
+ACE_ROOT = $(top_srcdir)
+
+noinst_PROGRAMS =
+
+## Makefile.SSL_SAP_Client.am
+
+if BUILD_SSL
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += client
+
+client_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -DACE_HAS_SSL=1 \
+ @ACE_TLS_CPPFLAGS@
+
+client_SOURCES = \
+ SSL-client.cpp \
+ SSL-client.h
+
+client_LDFLAGS = \
+ @ACE_TLS_LDFLAGS@
+
+client_LDADD = \
+ $(ACE_BUILDDIR)/ace/SSL/libACE_SSL.la \
+ $(ACE_BUILDDIR)/ace/libACE.la \
+ @ACE_TLS_LIBS@
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_SSL
+
+## Makefile.SSL_SAP_Client_Simple.am
+
+if BUILD_SSL
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += client-simple
+
+client_simple_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -DACE_HAS_SSL=1 \
+ @ACE_TLS_CPPFLAGS@
+
+client_simple_SOURCES = \
+ SSL-client-simple.cpp \
+ SSL-client-simple.h
+
+client_simple_LDFLAGS = \
+ @ACE_TLS_LDFLAGS@
+
+client_simple_LDADD = \
+ $(ACE_BUILDDIR)/ace/SSL/libACE_SSL.la \
+ $(ACE_BUILDDIR)/ace/libACE.la \
+ @ACE_TLS_LIBS@
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_SSL
+
+## Makefile.SSL_SAP_Server.am
+
+if BUILD_SSL
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += server
+
+server_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -DACE_HAS_SSL=1 \
+ @ACE_TLS_CPPFLAGS@
+
+server_SOURCES = \
+ SSL-server.cpp \
+ SSL-client-simple.h \
+ SSL-client.h \
+ SSL-server-fancy.h
+
+server_LDFLAGS = \
+ @ACE_TLS_LDFLAGS@
+
+server_LDADD = \
+ $(ACE_BUILDDIR)/ace/SSL/libACE_SSL.la \
+ $(ACE_BUILDDIR)/ace/libACE.la \
+ @ACE_TLS_LIBS@
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_SSL
+
+## Makefile.SSL_SAP_Server_Fancy.am
+
+if BUILD_SSL
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += server-fancy
+
+server_fancy_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -DACE_HAS_SSL=1 \
+ @ACE_TLS_CPPFLAGS@
+
+server_fancy_SOURCES = \
+ SSL-server-fancy.cpp \
+ SSL-server-fancy.h
+
+server_fancy_LDFLAGS = \
+ @ACE_TLS_LDFLAGS@
+
+server_fancy_LDADD = \
+ $(ACE_BUILDDIR)/ace/SSL/libACE_SSL.la \
+ $(ACE_BUILDDIR)/ace/libACE.la \
+ @ACE_TLS_LIBS@
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_SSL
+
+## Makefile.SSL_SAP_Server_Poll.am
+
+if BUILD_SSL
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += server-poll
+
+server_poll_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -DACE_HAS_SSL=1 \
+ @ACE_TLS_CPPFLAGS@
+
+server_poll_SOURCES = \
+ SSL-server-poll.cpp \
+ SSL-client-simple.h \
+ SSL-client.h \
+ SSL-server-fancy.h
+
+server_poll_LDFLAGS = \
+ @ACE_TLS_LDFLAGS@
+
+server_poll_LDADD = \
+ $(ACE_BUILDDIR)/ace/SSL/libACE_SSL.la \
+ $(ACE_BUILDDIR)/ace/libACE.la \
+ @ACE_TLS_LIBS@
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_SSL
+
+## Makefile.SSL_SAP_Server_Simple.am
+
+if BUILD_SSL
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += server-simple
+
+server_simple_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -DACE_HAS_SSL=1 \
+ @ACE_TLS_CPPFLAGS@
+
+server_simple_SOURCES = \
+ SSL-server-simple.cpp \
+ SSL-client-simple.h \
+ SSL-client.h \
+ SSL-server-fancy.h
+
+server_simple_LDFLAGS = \
+ @ACE_TLS_LDFLAGS@
+
+server_simple_LDADD = \
+ $(ACE_BUILDDIR)/ace/SSL/libACE_SSL.la \
+ $(ACE_BUILDDIR)/ace/libACE.la \
+ @ACE_TLS_LIBS@
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_SSL
+
+## Clean up template repositories, etc.
+clean-local:
+ -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.*
+ -rm -f gcctemp.c gcctemp so_locations *.ics
+ -rm -rf cxx_repository ptrepository ti_files
+ -rm -rf templateregistry ir.out
+ -rm -rf ptrepository SunWS_cache Templates.DB
diff --git a/ACE/examples/IPC_SAP/SSL_SAP/README b/ACE/examples/IPC_SAP/SSL_SAP/README
new file mode 100644
index 00000000000..43f4640e75a
--- /dev/null
+++ b/ACE/examples/IPC_SAP/SSL_SAP/README
@@ -0,0 +1,17 @@
+# $Id$
+
+This directory contains groups of client and server test programs that
+exercise the various C++ wrappers for SSL sockets. In general, the
+test programs do more or less the same thing -- the client establishes
+a connection with the server and then transfers data to the server,
+which keeps printing the data until EOF is reached (e.g., user types
+^D).
+
+Unless noted differently, the server is implemented as an "iterative
+server," i.e., it only deals with one client at a time. The following
+describes each set of tests in more detail:
+
+ . SSL-{client,server}.cpp -- This test allows you to test
+ oneway and twoway socket communication latency and
+ throughput over SSL between two processes on the same
+ machine or on different machines.
diff --git a/ACE/examples/IPC_SAP/SSL_SAP/SSL-client-simple.cpp b/ACE/examples/IPC_SAP/SSL_SAP/SSL-client-simple.cpp
new file mode 100644
index 00000000000..42bdd76d4c8
--- /dev/null
+++ b/ACE/examples/IPC_SAP/SSL_SAP/SSL-client-simple.cpp
@@ -0,0 +1,379 @@
+// $Id$
+
+// This tests the features of the <ACE_SSL_SOCK_Connector> and
+// <ACE_SSL_SOCK_Stream> classes. In addition, it can be used to test the
+// oneway and twoway latency and throughput at the socket-level. This
+// is useful as a baseline to compare against ORB-level performance
+// for the same types of data.
+
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/INET_Addr.h"
+#include "ace/Log_Msg.h"
+#include "ace/Singleton.h"
+#include "ace/Get_Opt.h"
+#include "ace/High_Res_Timer.h"
+#include "ace/Null_Mutex.h"
+
+#include "ace/SSL/SSL_SOCK_Connector.h"
+
+#include "SSL-client-simple.h"
+
+ACE_RCSID (SSL_SAP,
+ SSL_client_simple,
+ "$Id$")
+
+
+Options::Options (void)
+ : host_ (ACE_DEFAULT_SERVER_HOST),
+ port_ (ACE_DEFAULT_SERVER_PORT),
+ sleep_time_ (0, 0), // By default, don't sleep between calls.
+ message_len_ (0),
+ message_buf_ (0),
+ io_source_ (ACE_INVALID_HANDLE), // Defaults to using the generator.
+ iterations_ (10000),
+ oneway_ (1) // Make oneway calls the default.
+{
+ ACE_OS::strcpy (quit_string_, "q");
+}
+
+Options::~Options (void)
+{
+ delete [] this->message_buf_;
+}
+
+// Options Singleton.
+typedef ACE_Singleton<Options, ACE_Null_Mutex> OPTIONS;
+
+int
+Options::init (void)
+{
+ // Check for default case.
+ if (this->message_len_ == 0)
+ this->message_len_ = ACE_OS::strlen ("TAO");
+
+ this->message_len_ += sizeof (ACE_UINT32);
+
+ ACE_NEW_RETURN (this->message_buf_,
+ char[this->message_len_],
+ -1);
+
+ // Copy the length into the beginning of the message.
+ ACE_UINT32 length = ntohl (this->message_len_);
+ ACE_OS::memcpy ((void *) this->message_buf_,
+ (void *) &length,
+ sizeof length);
+
+ ACE_OS::memset ((void *) (this->message_buf_ + sizeof (ACE_UINT32)),
+ 'a',
+ this->message_len_ - sizeof (ACE_UINT32));
+
+ return 0;
+}
+
+size_t
+Options::message_len (void) const
+{
+ return this->message_len_;
+}
+
+const void *
+Options::message_buf (void) const
+{
+ return this->message_buf_;
+}
+
+ssize_t
+Options::read (void *buf, size_t len, size_t &iteration)
+{
+ ACE_UNUSED_ARG (len);
+
+ if (this->io_source_ == ACE_STDIN)
+ return ACE_OS::read (ACE_STDIN, buf, len);
+ else if (iteration >= this->iterations_)
+ return 0;
+ else
+ {
+ ACE_OS::memcpy (buf,
+ this->message_buf (),
+ len);
+ iteration++;
+ return len;
+ }
+}
+
+int
+Options::parse_args (int argc, ACE_TCHAR *argv[])
+{
+ //FUZZ: disable check_for_lack_ACE_OS
+ ACE_Get_Opt getopt (argc, argv, ACE_TEXT ("2h:i:m:p:q:sT:"), 1);
+
+ for (int c; (c = getopt ()) != -1; )
+ //FUZZ: enable check_for_lack_ACE_OS
+ switch (c)
+ {
+ case '2': // Disable the oneway client.
+ this->oneway_ = 0;
+ break;
+ case 'h':
+ this->host_ = getopt.opt_arg ();
+ break;
+ case 'i':
+ this->iterations_ = ACE_OS::atoi (getopt.opt_arg ());
+ break;
+ case 'm':
+ this->message_len_ = ACE_OS::atoi (getopt.opt_arg ());
+ break;
+ case 'p':
+ this->port_ = ACE_OS::atoi (getopt.opt_arg ());
+ break;
+ case 'q':
+ ACE_OS::strncpy (this->quit_string_,
+ ACE_TEXT_ALWAYS_CHAR (getopt.opt_arg ()),
+ QUIT_STRING_SIZE);
+ break;
+ case 's':
+ this->io_source_ = ACE_STDIN;
+ break;
+ case 'T':
+ this->sleep_time_.set (0, ACE_OS::atoi (getopt.opt_arg ()));
+ break;
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) usage: %n [-2] [-h <host>] ")
+ ACE_TEXT ("[-i iterations] [-m message-size] ")
+ ACE_TEXT ("[-p <port>] [-q <quit string>] ")
+ ACE_TEXT ("[-s] [-T <sleep_time>]\n")),
+ -1);
+ }
+
+ return this->init ();
+}
+
+u_short
+Options::port (void) const
+{
+ return this->port_;
+}
+
+const ACE_TCHAR *
+Options::host (void) const
+{
+ return this->host_;
+}
+
+const char *
+Options::quit_string (void) const
+{
+ return this->quit_string_;
+}
+
+const ACE_Time_Value &
+Options::sleep_time (void) const
+{
+ return this->sleep_time_;
+}
+
+char *
+Options::shared_client_test (u_short port,
+ ACE_SSL_SOCK_Stream &cli_stream)
+{
+ ACE_INET_Addr remote_addr (port, this->host_);
+
+ ACE_SSL_SOCK_Connector con;
+
+ if (con.connect (cli_stream,
+ remote_addr) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) %p\n"),
+ ACE_TEXT ("connection failed")),
+ 0);
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) connected to %C at port %d\n"),
+ remote_addr.get_host_name (),
+ remote_addr.get_port_number ()));
+
+ char *buf;
+ ACE_NEW_RETURN (buf,
+ char[this->message_len ()],
+ 0);
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) waiting...\n")));
+
+ return buf;
+}
+// Static function entry point to the oneway client service.
+
+void
+Options::oneway_client_test (void)
+{
+ ACE_SSL_SOCK_Stream cli_stream;
+
+ // Add 1 to the port to trigger the oneway test!
+ char *request = this->shared_client_test (this->port () + 1,
+ cli_stream);
+ if (request == 0)
+ return;
+
+ // This variable is allocated off the stack to obviate the need for
+ // locking.
+ size_t iteration = 0;
+
+ // Keep track of return value.
+ int result = 0;
+ ACE_INT32 len = this->message_len ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) starting oneway transmission\n")));
+
+ // Perform oneway transmission of data to server (correctly handles
+ // "incomplete writes").
+
+ for (ssize_t r_bytes;
+ (r_bytes = this->read (request, len, iteration)) > 0;
+ // Transmit at the proper rate.
+ ACE_OS::sleep (this->sleep_time ()))
+ if (ACE_OS::memcmp (request,
+ this->quit_string (),
+ ACE_OS::strlen (this->quit_string ())) == 0)
+ break;
+ else if (cli_stream.send_n (request, r_bytes) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) %p\n"),
+ ACE_TEXT ("send_n")));
+ result = -1;
+ break;
+ }
+
+ // Close the connection.
+ cli_stream.close ();
+
+ delete [] request;
+}
+
+// Static function entry point to the twoway client service.
+
+void
+Options::twoway_client_test (void)
+{
+ ACE_SSL_SOCK_Stream cli_stream;
+
+ char *request = this->shared_client_test (this->port (),
+ cli_stream);
+ if (request == 0)
+ return;
+
+ // This variable is allocated off the stack to obviate the need for
+ // locking.
+ size_t iteration = 0;
+
+ // Keep track of return value.
+ int result = 0;
+
+ // Timer business.
+ ACE_High_Res_Timer timer;
+
+ ACE_INT32 len = this->message_len ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) starting twoway transmission\n")));
+
+ // Perform twoway transmission of data to server (correctly handles
+ // "incomplete writes").
+
+ for (ssize_t r_bytes;
+ (r_bytes = this->read (request, len, iteration)) > 0;
+ // Transmit at the proper rate.
+ ACE_OS::sleep (this->sleep_time ()))
+ if (ACE_OS::memcmp (request,
+ this->quit_string (),
+ ACE_OS::strlen (this->quit_string ())) == 0)
+ break;
+
+ // Transmit <request> to the server.
+ else
+ {
+ // Note that we use the incremental feature of the
+ // <ACE_High_Res_Timer> so that we don't get "charged" for the
+ // <ACE_OS::sleep> used to control the rate at which requests
+ // are sent.
+ timer.start_incr ();
+
+ if (cli_stream.send_n (request, r_bytes) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) %p\n"),
+ ACE_TEXT ("send_n")));
+ result = -1;
+ break;
+ }
+ // Receive the reply from the server. Normally, it just sends
+ // back 24 bytes, which is typical for an IIOP reply.
+ else if (cli_stream.recv (request, r_bytes) <= 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) %p\n"),
+ ACE_TEXT ("recv")));
+ result = -1;
+ break;
+ }
+
+ timer.stop_incr ();
+ }
+
+ ACE_Time_Value tv;
+
+ timer.elapsed_time_incr (tv);
+ double real_time = tv.sec () * ACE_ONE_SECOND_IN_USECS + tv.usec ();
+ double messages_per_sec = iteration * double (ACE_ONE_SECOND_IN_USECS) / real_time;
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%t) messages = %d\n(%t) usec-per-message = %f\n(%t) messages-per-second = %0.00f\n"),
+ iteration,
+ real_time / double (iteration),
+ messages_per_sec < 0 ? 0 : messages_per_sec));
+
+ // Close the connection.
+ cli_stream.close ();
+
+ delete [] request;
+}
+
+void
+Options::run (void)
+{
+ if (this->oneway_ == 0)
+ this->twoway_client_test ();
+ else
+ this->oneway_client_test ();
+}
+
+static int
+run_client (void)
+{
+ // Raise the socket handle limit to the maximum.
+ ACE::set_handle_limit ();
+
+ OPTIONS::instance ()->run ();
+
+ return 0;
+}
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ // Initialize the logger.
+ ACE_LOG_MSG->open (argv[0]);
+
+ if (OPTIONS::instance ()->parse_args (argc, argv) == -1)
+ return -1;
+
+ // Run the client
+ run_client ();
+
+ return 0;
+}
+
diff --git a/ACE/examples/IPC_SAP/SSL_SAP/SSL-client-simple.h b/ACE/examples/IPC_SAP/SSL_SAP/SSL-client-simple.h
new file mode 100644
index 00000000000..4ec6b815a4c
--- /dev/null
+++ b/ACE/examples/IPC_SAP/SSL_SAP/SSL-client-simple.h
@@ -0,0 +1,98 @@
+// -*- C++ -*-
+// $Id$
+
+// This file defines the Options class for SSL-client-simple. IBM C++
+// compiler's template auto-instantiator needs this in a separate file.
+
+#ifndef ACE_SSL_CLIENT_SIMPLE_H
+#define ACE_SSL_CLIENT_SIMPLE_H
+
+#include "ace/SSL/SSL_SOCK_Stream.h"
+#include "ace/Time_Value.h"
+
+class Options
+ // = TITLE
+ // Define the options for this test.
+{
+public:
+ Options (void);
+ // Constructor.
+
+ ~Options (void);
+ // Destructor.
+
+ int parse_args (int argc, ACE_TCHAR *argv[]);
+ // Parse the command-line arguments.
+
+ const ACE_Time_Value &sleep_time (void) const;
+ // Return the amount of time to sleep in order to implement the
+ // proper transmission rates.
+
+ u_short port (void) const;
+ // Port of the server.
+
+ const ACE_TCHAR *host (void) const;
+ // Host of the server.
+
+ const char *quit_string (void) const;
+ // String that shuts down the client/server.
+
+ ssize_t read (void *buf, size_t len, size_t &iterations);
+ // Read from the appropriate location.
+
+ size_t message_len (void) const;
+ // Returns the length of the message to send.
+
+ const void *message_buf (void) const;
+ // Returns a pointer to the message.
+
+ void run (void);
+ // Run the test
+
+private:
+ int init (void);
+ // Initialize the message we're sending to the user and set up the
+ // barrier.
+
+ char *shared_client_test (u_short port,
+ ACE_SSL_SOCK_Stream &cli_stream);
+ // Performs the shared behavior of the oneway and twoway client
+ // tests.
+
+ void twoway_client_test (void);
+ // Performs the twoway test.
+
+ void oneway_client_test (void);
+ // Performs the oneway test.
+
+ const ACE_TCHAR *host_;
+ // Host of the server.
+
+ u_short port_;
+ // Port of the server.
+
+ ACE_Time_Value sleep_time_;
+ // Sleep_Time value.
+
+ enum {QUIT_STRING_SIZE = 128};
+ char quit_string_[QUIT_STRING_SIZE];
+ // String that shuts down the client/server.
+
+ size_t message_len_;
+ // Size of the message we send to the server.
+
+ char *message_buf_;
+ // Pointer to the message we send to the server.
+
+ ACE_HANDLE io_source_;
+ // Are we reading I/O from ACE_STDIN or from our generator?
+
+ size_t iterations_;
+ // Number of iterations.
+
+ char oneway_;
+ // Are we running oneway or twoway?
+
+};
+
+#endif /* ACE_SSL_CLIENT_SIMPLE_H */
diff --git a/ACE/examples/IPC_SAP/SSL_SAP/SSL-client.cpp b/ACE/examples/IPC_SAP/SSL_SAP/SSL-client.cpp
new file mode 100644
index 00000000000..829f8a5fe5e
--- /dev/null
+++ b/ACE/examples/IPC_SAP/SSL_SAP/SSL-client.cpp
@@ -0,0 +1,420 @@
+// $Id$
+
+// This tests the features of the <ACE_SSL_SOCK_Connector> and
+// <ACE_SSL_SOCK_Stream> classes. In addition, it can be used to test the
+// oneway and twoway latency and throughput at the socket-level. This
+// is useful as a baseline to compare against ORB-level performance
+// for the same types of data.
+
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/INET_Addr.h"
+#include "ace/Thread_Manager.h"
+#include "ace/Singleton.h"
+#include "ace/Get_Opt.h"
+#include "ace/High_Res_Timer.h"
+
+#include "ace/SSL/SSL_SOCK_Connector.h"
+
+#include "SSL-client.h"
+
+ACE_RCSID(SSL_SAP, SSL_client, "$Id$")
+
+Options::Options (void)
+ : host_ (ACE_DEFAULT_SERVER_HOST),
+ port_ (ACE_DEFAULT_SERVER_PORT),
+ sleep_time_ (0, 0), // By default, don't sleep between calls.
+ threads_ (10),
+ message_len_ (0),
+ message_buf_ (0),
+ io_source_ (ACE_INVALID_HANDLE), // Defaults to using the generator.
+ iterations_ (10000),
+ oneway_ (1) // Make oneway calls the default.
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ , barrier_ (0)
+#endif /* ACE_MT_SAFE */
+{
+ ACE_OS::strcpy (quit_string_, "q");
+}
+
+Options::~Options (void)
+{
+ ACE_MT (delete this->barrier_);
+ delete [] this->message_buf_;
+}
+
+// Options Singleton.
+typedef ACE_Singleton<Options, ACE_SYNCH_RECURSIVE_MUTEX> OPTIONS;
+
+int
+Options::init (void)
+{
+ // Check for default case.
+ if (this->message_len_ == 0)
+ this->message_len_ = ACE_OS::strlen ("TAO");
+
+ this->message_len_ += sizeof (ACE_UINT32);
+
+ ACE_NEW_RETURN (this->message_buf_,
+ char[this->message_len_],
+ -1);
+
+ // Copy the length into the beginning of the message.
+ ACE_UINT32 length = ntohl (this->message_len_);
+ ACE_OS::memcpy ((void *) this->message_buf_,
+ (void *) &length,
+ sizeof length);
+
+ ACE_OS::memset ((void *) (this->message_buf_ + sizeof (ACE_UINT32)),
+ 'a',
+ this->message_len_ - sizeof (ACE_UINT32));
+
+ // Allocate the barrier with the correct count.
+ ACE_MT (ACE_NEW_RETURN (this->barrier_,
+ ACE_Barrier (this->threads_),
+ -1));
+ return 0;
+}
+
+size_t
+Options::message_len (void) const
+{
+ return this->message_len_;
+}
+
+const void *
+Options::message_buf (void) const
+{
+ return this->message_buf_;
+}
+
+ssize_t
+Options::read (void *buf, size_t len, size_t &iteration)
+{
+ ACE_UNUSED_ARG (len);
+
+ if (this->io_source_ == ACE_STDIN)
+ return ACE_OS::read (ACE_STDIN, buf, len);
+ else if (iteration >= this->iterations_)
+ return 0;
+ else
+ {
+ ACE_OS::memcpy (buf,
+ this->message_buf (),
+ len);
+ iteration++;
+ return len;
+ }
+}
+
+int
+Options::parse_args (int argc, ACE_TCHAR *argv[])
+{
+ //FUZZ: disable check_for_lack_ACE_OS
+ ACE_Get_Opt getopt (argc, argv, ACE_TEXT ("2h:i:m:p:q:st:T:"), 1);
+
+ for (int c; (c = getopt ()) != -1; )
+ //FUZZ: enable check_for_lack_ACE_OS
+ switch (c)
+ {
+ case '2': // Disable the oneway client.
+ this->oneway_ = 0;
+ break;
+ case 'h':
+ this->host_ = getopt.opt_arg ();
+ break;
+ case 'i':
+ this->iterations_ = ACE_OS::atoi (getopt.opt_arg ());
+ break;
+ case 'm':
+ this->message_len_ = ACE_OS::atoi (getopt.opt_arg ());
+ break;
+ case 'p':
+ this->port_ = ACE_OS::atoi (getopt.opt_arg ());
+ break;
+ case 'q':
+ ACE_OS::strncpy (this->quit_string_,
+ ACE_TEXT_ALWAYS_CHAR (getopt.opt_arg ()),
+ QUIT_STRING_SIZE);
+ break;
+ case 's':
+ this->io_source_ = ACE_STDIN;
+ break;
+ case 't':
+ this->threads_ = (size_t) ACE_OS::atoi (getopt.opt_arg ());
+ break;
+ case 'T':
+ this->sleep_time_.set (0, ACE_OS::atoi (getopt.opt_arg ()));
+ break;
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) usage: %n [-2] [-h <host>] ")
+ ACE_TEXT ("[-i iterations] [-m message-size] ")
+ ACE_TEXT ("[-p <port>] [-q <quit string>] ")
+ ACE_TEXT ("[-s] [-t <threads>] [-T <sleep_time>]\n")),
+ -1);
+ }
+
+ return this->init ();
+}
+
+u_short
+Options::port (void) const
+{
+ return this->port_;
+}
+
+const ACE_TCHAR *
+Options::host (void) const
+{
+ return this->host_;
+}
+
+const char *
+Options::quit_string (void) const
+{
+ return this->quit_string_;
+}
+
+size_t
+Options::threads (void) const
+{
+ return this->threads_;
+}
+
+const ACE_Time_Value &
+Options::sleep_time (void) const
+{
+ return this->sleep_time_;
+}
+
+char *
+Options::shared_client_test (u_short port,
+ ACE_SSL_SOCK_Stream &cli_stream)
+{
+ ACE_INET_Addr remote_addr (port, this->host_);
+
+ ACE_SSL_SOCK_Connector con;
+
+ if (con.connect (cli_stream,
+ remote_addr) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) %p\n"),
+ ACE_TEXT ("connection failed")),
+ 0);
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) connected to %C at port %d\n"),
+ remote_addr.get_host_name (),
+ remote_addr.get_port_number ()));
+
+ // Allocate the transmit buffer.
+ char *buf;
+ ACE_NEW_RETURN (buf,
+ char[this->message_len ()],
+ 0);
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) waiting...\n")));
+
+ // Wait for all other threads to finish initialization.
+ ACE_MT (this->barrier_->wait ());
+ return buf;
+}
+// Static function entry point to the oneway client service.
+
+void *
+Options::oneway_client_test (void *)
+{
+ Options *options = OPTIONS::instance ();
+ ACE_SSL_SOCK_Stream cli_stream;
+
+ // Add 1 to the port to trigger the oneway test!
+ char *request = options->shared_client_test (options->port () + 1,
+ cli_stream);
+ if (request == 0)
+ return 0;
+
+ // This variable is allocated off the stack to obviate the need for
+ // locking.
+ size_t iteration = 0;
+
+ // Keep track of return value.
+ size_t result = 0;
+ ACE_INT32 len = options->message_len ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) starting oneway transmission\n")));
+
+ // Perform oneway transmission of data to server (correctly handles
+ // "incomplete writes").
+
+ for (ssize_t r_bytes;
+ (r_bytes = options->read (request, len, iteration)) > 0;
+ // Transmit at the proper rate.
+ ACE_OS::sleep (options->sleep_time ()))
+ if (ACE_OS::memcmp (request,
+ options->quit_string (),
+ ACE_OS::strlen (options->quit_string ())) == 0)
+ break;
+ else if (cli_stream.send_n (request, r_bytes) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) %p\n"),
+ ACE_TEXT ("send_n")));
+ result = size_t (-1);
+ break;
+ }
+
+ // Close the connection.
+ cli_stream.close ();
+
+ delete [] request;
+ return (void *) result;
+}
+
+// Static function entry point to the twoway client service.
+
+void *
+Options::twoway_client_test (void *)
+{
+ Options *options = OPTIONS::instance ();
+
+ ACE_SSL_SOCK_Stream cli_stream;
+
+ char *request = options->shared_client_test (options->port (),
+ cli_stream);
+ if (request == 0)
+ return 0;
+
+ // This variable is allocated off the stack to obviate the need for
+ // locking.
+ size_t iteration = 0;
+
+ // Keep track of return value.
+ size_t result = 0;
+
+ // Timer business.
+ ACE_High_Res_Timer timer;
+
+ ACE_INT32 len = options->message_len ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) starting twoway transmission\n")));
+
+ // Perform twoway transmission of data to server (correctly handles
+ // "incomplete writes").
+
+ for (ssize_t r_bytes;
+ (r_bytes = options->read (request, len, iteration)) > 0;
+ // Transmit at the proper rate.
+ ACE_OS::sleep (options->sleep_time ()))
+ if (ACE_OS::memcmp (request,
+ options->quit_string (),
+ ACE_OS::strlen (options->quit_string ())) == 0)
+ break;
+
+ // Transmit <request> to the server.
+ else
+ {
+ // Note that we use the incremental feature of the
+ // <ACE_High_Res_Timer> so that we don't get "charged" for the
+ // <ACE_OS::sleep> used to control the rate at which requests
+ // are sent.
+ timer.start_incr ();
+
+ if (cli_stream.send_n (request, r_bytes) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) %p\n"),
+ ACE_TEXT ("send_n")));
+ result = size_t (-1);
+ break;
+ }
+ // Receive the reply from the server. Normally, it just sends
+ // back 24 bytes, which is typical for an IIOP reply.
+ else if (cli_stream.recv (request, r_bytes) <= 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) %p\n"),
+ ACE_TEXT ("recv")));
+ result = size_t (-1);
+ break;
+ }
+
+ timer.stop_incr ();
+ }
+
+ ACE_Time_Value tv;
+
+ timer.elapsed_time_incr (tv);
+ double real_time = tv.sec () * ACE_ONE_SECOND_IN_USECS + tv.usec ();
+ double messages_per_sec =
+ iteration * double (ACE_ONE_SECOND_IN_USECS) / real_time;
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%t) messages = %d\n")
+ ACE_TEXT ("(%t) usec-per-message = %f\n")
+ ACE_TEXT ("(%t) messages-per-second = %0.00f\n"),
+ iteration,
+ real_time / double (iteration),
+ messages_per_sec < 0 ? 0 : messages_per_sec));
+
+ // Close the connection.
+ cli_stream.close ();
+
+ delete [] request;
+ return (void *) result;
+}
+
+ACE_THR_FUNC
+Options::thr_func (void)
+{
+ if (this->oneway_ == 0)
+ return ACE_THR_FUNC (&Options::twoway_client_test);
+ else
+ return ACE_THR_FUNC (&Options::oneway_client_test);
+}
+
+static int
+run_client (void)
+{
+ // Raise the socket handle limit to the maximum.
+ ACE::set_handle_limit ();
+
+#if defined (ACE_HAS_THREADS)
+ if (ACE_Thread_Manager::instance ()->spawn_n (
+ OPTIONS::instance ()->threads (),
+ OPTIONS::instance ()->thr_func ()) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) %p\n"),
+ ACE_TEXT ("spawn_n")),
+ 1);
+ else
+ ACE_Thread_Manager::instance ()->wait ();
+#else
+ *(OPTIONS::instance ()->thr_func) ();
+#endif /* ACE_HAS_THREADS */
+ return 0;
+}
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ ACE_SSL_Context *context = ACE_SSL_Context::instance ();
+
+ context->certificate ("./dummy.pem", SSL_FILETYPE_PEM);
+ context->private_key ("./key.pem", SSL_FILETYPE_PEM);
+
+ // Initialize the logger.
+ ACE_LOG_MSG->open (argv[0]);
+
+ if (OPTIONS::instance ()->parse_args (argc, argv) == -1)
+ return -1;
+
+ // Run the client
+ run_client ();
+
+ return 0;
+}
+
diff --git a/ACE/examples/IPC_SAP/SSL_SAP/SSL-client.h b/ACE/examples/IPC_SAP/SSL_SAP/SSL-client.h
new file mode 100644
index 00000000000..af081004368
--- /dev/null
+++ b/ACE/examples/IPC_SAP/SSL_SAP/SSL-client.h
@@ -0,0 +1,111 @@
+// -*- C++ -*-
+// $Id$
+
+// This file defines the Options class for SSL-client. IBM C++ compiler'd
+// template auto-instantiator needs this in a separate file.
+
+#ifndef __ACE_SSL_CLIENT_H
+#define __ACE_SSL_CLIENT_H
+
+#include "ace/Barrier.h"
+#include "ace/Time_Value.h"
+
+#include "ace/SSL/SSL_SOCK_Stream.h"
+
+class Options
+ // = TITLE
+ // Define the options for this test.
+{
+public:
+ Options (void);
+ // Constructor.
+
+ ~Options (void);
+ // Destructor.
+
+ int parse_args (int argc, ACE_TCHAR *argv[]);
+ // Parse the command-line arguments.
+
+ const ACE_Time_Value &sleep_time (void) const;
+ // Return the amount of time to sleep in order to implement the
+ // proper transmission rates.
+
+ u_short port (void) const;
+ // Port of the server.
+
+ const ACE_TCHAR *host (void) const;
+ // Host of the server.
+
+ size_t threads (void) const;
+ // Number of threads.
+
+ const char *quit_string (void) const;
+ // String that shuts down the client/server.
+
+ ssize_t read (void *buf, size_t len, size_t &iterations);
+ // Read from the appropriate location.
+
+ size_t message_len (void) const;
+ // Returns the length of the message to send.
+
+ const void *message_buf (void) const;
+ // Returns a pointer to the message.
+
+ ACE_THR_FUNC thr_func (void);
+ // Returns a pointer to the entry point into the thread that runs
+ // the client test function.
+
+private:
+ int init (void);
+ // Initialize the message we're sending to the user and set up the
+ // barrier.
+
+ char *shared_client_test (u_short port,
+ ACE_SSL_SOCK_Stream &cli_stream);
+ // Performs the shared behavior of the oneway and twoway client
+ // tests.
+
+ static void *twoway_client_test (void *);
+ // Performs the twoway test.
+
+ static void *oneway_client_test (void *);
+ // Performs the oneway test.
+
+ const ACE_TCHAR *host_;
+ // Host of the server.
+
+ u_short port_;
+ // Port of the server.
+
+ ACE_Time_Value sleep_time_;
+ // Sleep_Time value.
+
+ size_t threads_;
+ // Number of threads.
+
+ enum {QUIT_STRING_SIZE = 128};
+ char quit_string_[QUIT_STRING_SIZE];
+ // String that shuts down the client/server.
+
+ size_t message_len_;
+ // Size of the message we send to the server.
+
+ char *message_buf_;
+ // Pointer to the message we send to the server.
+
+ ACE_HANDLE io_source_;
+ // Are we reading I/O from ACE_STDIN or from our generator?
+
+ size_t iterations_;
+ // Number of iterations.
+
+ char oneway_;
+ // Are we running oneway or twoway?
+
+ // Please leave the ; inside the parenthesis to avoid Green Hills
+ // (and probably other) compiler warning about extra ;.
+ ACE_MT (ACE_Barrier *barrier_;)
+ // Barrier used to synchronize the start of all the threads.
+};
+
+#endif /* __ACE_SSL_CLIENT_H */
diff --git a/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-fancy.cpp b/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-fancy.cpp
new file mode 100644
index 00000000000..1ad03125e9d
--- /dev/null
+++ b/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-fancy.cpp
@@ -0,0 +1,610 @@
+// $Id$
+
+// This example tests the features of the <ACE_SSL_SOCK_Acceptor>,
+// <ACE_SSL_SOCK_Stream>, and <ACE_Svc_Handler> classes. If the platform
+// supports threads it uses a thread-per-connection concurrency model.
+// Otherwise, it uses a single-threaded iterative server model.
+
+#include "ace/Svc_Handler.h"
+#include "ace/Singleton.h"
+#include "ace/Profile_Timer.h"
+#include "ace/Get_Opt.h"
+#include "ace/OS_NS_sys_select.h"
+
+#include "ace/SSL/SSL_SOCK_Acceptor.h"
+
+#include "SSL-server-fancy.h"
+
+ACE_RCSID (SSL_SAP,
+ SSL_server_fancy,
+ "$Id$")
+
+// Forward declaration.
+class Handler;
+
+class Handler_Factory
+{
+ // = TITLE
+ // Creates the oneway or twoway handlers.
+public:
+ Handler_Factory (void);
+ // Constructor.
+
+ ~Handler_Factory (void);
+ // Destructor.
+
+ int handle_events (void);
+ // Run the main event loop.
+
+private:
+ int init_acceptors (void);
+ // Initialize the acceptors.
+
+ int create_handler (ACE_SSL_SOCK_Acceptor &acceptor,
+ Handler *(*handler_factory) (ACE_SSL_SOCK_Stream *),
+ const char *handler_type);
+ // Factory that creates the right kind of <Handler>.
+
+ // = Factory functions.
+
+ static Handler *make_twoway_handler (ACE_SSL_SOCK_Stream *);
+ // Create a twoway handler.
+
+ static Handler *make_oneway_handler (ACE_SSL_SOCK_Stream *);
+ // Create a oneway handler.
+
+ ACE_SSL_SOCK_Acceptor twoway_acceptor_;
+ // Twoway acceptor factory.
+
+ ACE_SSL_SOCK_Acceptor oneway_acceptor_;
+ // Oneway acceptor factory.
+};
+
+class Handler : public ACE_Svc_Handler<ACE_SSL_SOCK_STREAM, ACE_NULL_SYNCH>
+{
+ // = TITLE
+ // Base class for the oneway and twoway handlers.
+
+ friend class Handler_Factory;
+ // The factory has special permission. (to access svc ()).
+
+public:
+ //FUZZ: disable check_for_lack_ACE_OS
+ virtual int open (void * = 0);
+ // Generic initialization method.
+
+ virtual int close (u_long);
+ // Close down and delete this.
+ //FUZZ: enable check_for_lack_ACE_OS
+
+protected:
+
+ Handler (ACE_SSL_SOCK_Stream *ssl_stream);
+ // Constructor.
+
+ int parse_header_and_allocate_buffer (char *&buf,
+ ACE_INT32 *len);
+ // Implement the generic code that's called from any of the subclass
+ // <run> methods to get the header and the buffer to read the data.
+ // This method factors out common code.
+
+ virtual int run (void) = 0;
+ // Hook method called by the <svc> template method to do the actual
+ // protocol. Must be overridden by the subclass.
+
+ virtual int svc (void);
+ // Template method entry point into the handler task.
+
+ virtual void print_results (void);
+ // Print the results.
+
+ size_t total_bytes_;
+ // Total number of bytes received.
+
+ size_t message_count_;
+ // Number of messages received.
+
+ ACE_Profile_Timer timer_;
+ // Keeps track of how much time we're using.
+
+ ACE_SSL_SOCK_Stream *ssl_stream_;
+ //keep state information for a ssl_stream.
+};
+
+class Twoway_Handler : public Handler
+{
+ // = TITLE
+ // Performs the twoway protocol.
+public:
+
+ Twoway_Handler (ACE_SSL_SOCK_Stream *ssl_stream);
+ // Constructor.
+
+private:
+
+ virtual int run (void);
+ // Template Method hook called by <svc>.
+
+};
+
+class Oneway_Handler : public Handler
+{
+ // = TITLE
+public:
+ Oneway_Handler (ACE_SSL_SOCK_Stream *ssl_stream);
+ // Constructor.
+
+private:
+ virtual int run (void);
+ // Template Method hook called by <svc>.
+
+ virtual void print_results (void);
+ // Print the results.
+};
+
+u_short
+Options::port (void) const
+{
+ return this->port_;
+}
+
+int
+Options::verbose (void) const
+{
+ return this->verbose_;
+}
+
+int
+Options::reply_message_len (void) const
+{
+ return this->reply_message_len_;
+}
+
+Options::~Options (void)
+{
+}
+
+Options::Options (void)
+ : verbose_ (0),
+ port_ (ACE_DEFAULT_SERVER_PORT),
+ reply_message_len_ (24) // Default to the approximate size of an
+ // GIOP reply message.
+{
+}
+
+int
+Options::parse_args (int argc, ACE_TCHAR *argv[])
+{
+ //FUZZ: disable check_for_lack_ACE_OS
+ ACE_Get_Opt getopt (argc, argv, ACE_TEXT ("p:r:v"), 1);
+
+ for (int c; (c = getopt ()) != -1; )
+ //FUZZ: enable check_for_lack_ACE_OS
+ switch (c)
+ {
+ case 'p':
+ this->port_ = ACE_OS::atoi (getopt.opt_arg ());
+ break;
+ case 'r':
+ this->reply_message_len_ = ACE_OS::atoi (getopt.opt_arg ());
+ break;
+ case 'v':
+ this->verbose_ = 1;
+ break;
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) usage: %n [-p <port>] [-v]")),
+ -1);
+ }
+
+ return 0;
+}
+
+// Options Singleton.
+typedef ACE_Singleton<Options, ACE_SYNCH_RECURSIVE_MUTEX> OPTIONS;
+
+Handler::Handler (ACE_SSL_SOCK_Stream *ssl_stream)
+ : total_bytes_ (0),
+ message_count_ (0),
+ ssl_stream_ (ssl_stream)
+
+{
+}
+
+int
+Handler::open (void *)
+{
+ ACE_INET_Addr cli_addr;
+
+ // Make sure we're not in non-blocking mode.
+ if (this->ssl_stream_-> disable (ACE_NONBLOCK) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("disable")),
+ 0);
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) client %C connected from %d \n"),
+ cli_addr.get_host_name (),
+ cli_addr.get_port_number ()));
+
+ return 0;
+}
+
+int
+Handler::close (u_long)
+{
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) closing down %@\n"),
+ this));
+
+ delete this->ssl_stream_;
+ delete this;
+
+ return 0;
+}
+
+int
+Handler::svc (void)
+{
+ // Timer logic.
+ this->timer_.start ();
+
+ // Invoke the hook method to run the specific test.
+ int result = this->run ();
+
+ this->timer_.stop ();
+
+ this->print_results ();
+
+ return result;
+}
+
+int
+Handler::parse_header_and_allocate_buffer (char *&request,
+ ACE_INT32 *len)
+{
+ ssize_t result = this->ssl_stream_ -> recv_n ((void *) len,
+ sizeof (ACE_INT32));
+ if (result == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) connected closed\n")));
+ return -1;
+ }
+ else if (result == -1 || result != sizeof (ACE_INT32))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) %p\n"),
+ ACE_TEXT ("recv_n failed")),
+ -1);
+ else
+ {
+ *len = ntohl (*len);
+ ACE_NEW_RETURN (request,
+ char[*len],
+ -1);
+ }
+
+ return 0;
+}
+
+void
+Handler::print_results (void)
+{
+}
+
+Twoway_Handler::Twoway_Handler (ACE_SSL_SOCK_Stream* ssl_stream)
+ : Handler (ssl_stream)
+{
+}
+
+// Function entry point into the twoway server task.
+
+int
+Twoway_Handler::run (void)
+{
+ // Read data from client (terminate on error).
+
+ char *request = 0;
+
+ for (;;)
+ {
+ ACE_INT32 len = 0;
+
+ if (parse_header_and_allocate_buffer (request,
+ &len) == -1)
+ return -1;
+
+ // Subtract off the sizeof the length prefix.
+ ssize_t r_bytes =
+ this->ssl_stream_ -> recv_n (request,
+ len - sizeof (ACE_UINT32));
+
+ if (r_bytes == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("recv")));
+ break;
+ }
+ else if (r_bytes == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) reached end of input, connection ")
+ ACE_TEXT ("closed by client\n")));
+ break;
+ }
+ else if (OPTIONS::instance ()->verbose ()
+ && ACE::write_n (ACE_STDOUT,
+ request,
+ r_bytes) != r_bytes)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("ACE::write_n")));
+ else
+ {
+ ssize_t s_bytes =
+ (ssize_t) OPTIONS::instance ()->reply_message_len ();
+
+ // Don't try to send more than is in the request buffer!
+ if (s_bytes > r_bytes)
+ s_bytes = r_bytes;
+
+ if (this->ssl_stream_ -> send_n (request,
+ s_bytes) != s_bytes)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("send_n")));
+ }
+ this->total_bytes_ += size_t (r_bytes);
+ this->message_count_++;
+
+ delete [] request;
+ request = 0;
+ }
+
+ delete [] request;
+ return 0;
+}
+
+Oneway_Handler::Oneway_Handler (ACE_SSL_SOCK_Stream *ssl_stream)
+ : Handler (ssl_stream)
+{
+}
+
+void
+Oneway_Handler::print_results (void)
+{
+ ACE_Profile_Timer::ACE_Elapsed_Time et;
+ this->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));
+
+ 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"),
+ this->message_count_,
+ this->total_bytes_,
+ (((double) this->total_bytes_ * 8) / et.real_time) / (double) (1024 * 1024),
+ ((et.user_time + et.system_time) / (double) this->message_count_) * ACE_ONE_SECOND_IN_USECS));
+}
+
+// Function entry point into the oneway server task.
+
+int
+Oneway_Handler::run (void)
+{
+ // Read data from client (terminate on error).
+
+ char *request = 0;
+
+ for (;;)
+ {
+ ACE_INT32 len = 0;
+
+ if (parse_header_and_allocate_buffer (request,
+ &len) == -1)
+ return -1;
+
+ // Subtract off the sizeof the length prefix.
+ ssize_t r_bytes =
+ this->ssl_stream_ -> recv_n (request,
+ len - sizeof (ACE_UINT32));
+
+ if (r_bytes == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("recv")));
+ break;
+ }
+ else if (r_bytes == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) reached end of input, connection ")
+ ACE_TEXT ("closed by client\n")));
+ break;
+ }
+ else if (OPTIONS::instance ()->verbose ()
+ && ACE::write_n (ACE_STDOUT,
+ request,
+ r_bytes) != r_bytes)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("ACE::write_n")));
+
+ this->total_bytes_ += size_t (r_bytes);
+ this->message_count_++;
+ delete [] request;
+ request = 0;
+ }
+
+ delete [] request;
+ return 0;
+}
+
+// Create a twoway handler.
+
+Handler *
+Handler_Factory::make_twoway_handler (ACE_SSL_SOCK_Stream *ssl_stream)
+{
+ return new Twoway_Handler (ssl_stream);
+}
+
+// Create a oneway handler.
+
+Handler *
+Handler_Factory::make_oneway_handler (ACE_SSL_SOCK_Stream *ssl_stream)
+
+{
+ return new Oneway_Handler (ssl_stream);
+}
+
+int
+Handler_Factory::init_acceptors (void)
+{
+ // Create the oneway and twoway server addresses.
+ ACE_INET_Addr twoway_server_addr (OPTIONS::instance ()->port ());
+ ACE_INET_Addr oneway_server_addr (OPTIONS::instance ()->port () + 1);
+
+ // Create acceptors, reuse the address.
+ if (this->twoway_acceptor_.open (twoway_server_addr, 1) == -1
+ || this->oneway_acceptor_.open (oneway_server_addr, 1) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("open")),
+ -1);
+ else if (this->twoway_acceptor_.get_local_addr (twoway_server_addr) == -1
+ || this->oneway_acceptor_.get_local_addr (oneway_server_addr) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("get_local_addr")),
+ -1);
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) starting twoway server at port %d and oneway server at port %d\n"),
+ twoway_server_addr.get_port_number (),
+ oneway_server_addr.get_port_number ()));
+ return 0;
+}
+
+int
+Handler_Factory::create_handler (
+ ACE_SSL_SOCK_Acceptor &acceptor,
+ Handler * (*handler_factory) (ACE_SSL_SOCK_Stream* ),
+ const char *handler_type)
+{
+ ACE_SSL_SOCK_Stream* new_stream;
+
+ ACE_NEW_RETURN (new_stream, ACE_SSL_SOCK_Stream, -1);
+
+ if (acceptor.accept (*new_stream) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("accept")),
+ -1);
+
+ Handler *handler;
+
+ ACE_ALLOCATOR_RETURN (handler,
+ (*handler_factory) (new_stream),
+ -1);
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) spawning %s handler\n"),
+ handler_type));
+
+ if (handler->open () == -1)
+ return -1;
+
+#if defined (ACE_MT_SAFE)
+ // Spawn a new thread and run the new connection in that thread of
+ // control using the <server> function as the entry point.
+ return handler->activate ();
+#else
+ handler->svc ();
+ handler->close (0);
+ return 0;
+#endif /* ACE_HAS_THREADS */
+}
+
+Handler_Factory::Handler_Factory (void)
+{
+}
+
+Handler_Factory::~Handler_Factory (void)
+{
+ this->twoway_acceptor_.close ();
+ this->oneway_acceptor_.close ();
+}
+
+// Run the main event loop.
+
+int
+Handler_Factory::handle_events (void)
+{
+ if (this->init_acceptors () == -1)
+ return -1;
+
+ fd_set handles;
+
+ FD_ZERO (&handles);
+ FD_SET ((ACE_SOCKET) this->twoway_acceptor_.get_handle (), &handles);
+ FD_SET ((ACE_SOCKET) this->oneway_acceptor_.get_handle (), &handles);
+
+ // Performs the iterative server activities.
+
+ for (;;)
+ {
+ ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT);
+ fd_set temp = handles;
+
+ int result =
+ ACE_OS::select (int (this->oneway_acceptor_.get_handle ()) + 1,
+ (fd_set *) &temp,
+ 0,
+ 0,
+ timeout);
+ if (result == -1)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) %p\n"),
+ ACE_TEXT ("select")));
+ else if (result == 0 && OPTIONS::instance ()->verbose ())
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) select timed out\n")));
+ else
+ {
+ if (FD_ISSET (this->twoway_acceptor_.get_handle (),
+ &temp))
+ this->create_handler (this->twoway_acceptor_,
+ &Handler_Factory::make_twoway_handler,
+ "twoway");
+ if (FD_ISSET (this->oneway_acceptor_.get_handle (),
+ &temp))
+ this->create_handler (this->oneway_acceptor_,
+ &Handler_Factory::make_oneway_handler,
+ "oneway");
+ }
+ }
+
+ ACE_NOTREACHED (return 0;)
+}
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+
+ ACE_SSL_Context *context = ACE_SSL_Context::instance ();
+
+ context->certificate ("./dummy.pem", SSL_FILETYPE_PEM);
+ context->private_key ("./key.pem", SSL_FILETYPE_PEM);
+
+ OPTIONS::instance ()->parse_args (argc, argv);
+
+ Handler_Factory server;
+
+ return server.handle_events ();
+}
+
diff --git a/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-fancy.h b/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-fancy.h
new file mode 100644
index 00000000000..fed1b513f90
--- /dev/null
+++ b/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-fancy.h
@@ -0,0 +1,44 @@
+// -*- C++ -*-
+// $Id$
+
+// This file defines the Options class for SSL-server-fancy.
+// IBM C++ compiler'd template auto-instantiator needs this in a separate file.
+
+#ifndef __ACE_SSL_SERVER_FANCY_H
+#define __ACE_SSL_SERVER_FANCY_H
+
+class Options
+ // = TITLE
+ // Define the options for this test.
+{
+public:
+ Options (void);
+ // Constructor.
+
+ ~Options (void);
+ // Destructor.
+
+ int parse_args (int argc, ACE_TCHAR *argv[]);
+ // Parse the command-line arguments.
+
+ int verbose (void) const;
+ // Are we running in verbose mode?
+
+ u_short port (void) const;
+ // Port number that we are listening at.
+
+ int reply_message_len (void) const;
+ // Size of the reply message.
+
+private:
+ int verbose_;
+ // Are we running in verbose mode?
+
+ u_short port_;
+ // Port number we listen at.
+
+ size_t reply_message_len_;
+ // Size of the reply message.
+};
+
+#endif /* __ACE_SSL_SERVER_FANCY_H */
diff --git a/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-poll.cpp b/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-poll.cpp
new file mode 100644
index 00000000000..23a53a7e7c7
--- /dev/null
+++ b/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-poll.cpp
@@ -0,0 +1,212 @@
+// $Id$
+
+// IPC_SAP/poll server, which illustrates how to integrate the ACE
+// SSL socket wrappers with the SVR4 <poll> system call to create a
+// single-threaded concurrent server. This server program can be
+// driven by the oneway test mode of SSL-client.cpp.
+
+#include "ace/OS_NS_stdlib.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/Time_Value.h"
+#include "ace/SSL/SSL_SOCK_Acceptor.h"
+
+ACE_RCSID (SSL_SAP,
+ SSL_server_poll,
+ "$Id$")
+
+#if defined (ACE_HAS_POLL)
+
+#include "ace/SSL/SSL_SOCK_Stream.h"
+
+#include "ace/Log_Msg.h"
+#include "ace/INET_Addr.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_poll.h"
+
+
+// Should we be verbose?
+static int verbose = 0;
+
+// Max number of open handles.
+static const int MAX_HANDLES = 200;
+
+struct Buffer_Info
+{
+ void *buf_;
+ // Pointer to the buffer.
+
+ size_t len_;
+ // Length of the buffer.
+};
+
+// Array of <pollfd>'s.
+static struct pollfd poll_array[MAX_HANDLES];
+
+// Array of <Buffer_Info>.
+static Buffer_Info buffer_array[MAX_HANDLES];
+
+static void
+init_poll_array (void)
+{
+ int i;
+
+ for (i = 0; i < MAX_HANDLES; i++)
+ {
+ poll_array[i].fd = ACE_INVALID_HANDLE;
+ poll_array[i].events = POLLIN;
+ }
+}
+
+static int
+init_buffer (size_t index)
+{
+ ACE_INT32 len;
+
+ if (ACE::recv_n (poll_array[index].fd,
+ (void *) &len,
+ sizeof (ACE_INT32)) != sizeof (ACE_INT32))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) %p\n",
+ "recv_n failed"),
+ -1);
+ else
+ {
+ len = ntohl (len);
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) reading messages of size %d from handle %d\n",
+ len,
+ poll_array[index].fd));
+
+ ACE_ALLOCATOR_RETURN (buffer_array[index].buf_,
+ ACE_OS::malloc (len),
+ -1);
+ buffer_array[index].len_ = len;
+ }
+ return 0;
+}
+
+static void
+handle_data (size_t &n_handles)
+{
+ // Handle pending logging messages first (s_handle + 1 is guaranteed
+ // to be lowest client descriptor).
+
+ for (size_t index = 1; index < n_handles; index++)
+ {
+ if (ACE_BIT_ENABLED (poll_array[index].revents, POLLIN))
+ {
+ // First time in, we need to initialize the buffer.
+ if (buffer_array[index].buf_ == 0
+ && init_buffer (index) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "(%P|%t) %p\n",
+ "init_buffer"));
+ continue;
+ }
+
+ // Read data from client (terminate on error).
+
+ ssize_t n = ACE::recv (poll_array[index].fd,
+ buffer_array[index].buf_,
+ buffer_array[index].len_);
+ // <recv> will not block in this case!
+
+ if (n == -1)
+ ACE_ERROR ((LM_ERROR,
+ "%p\n",
+ "read failed"));
+ else if (n == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) closing oneway server at handle %d\n",
+ poll_array[index].fd));
+
+ // Handle client connection shutdown.
+ ACE_OS::close (poll_array[index].fd);
+ poll_array[index].fd = poll_array[--n_handles].fd;
+
+ ACE_OS::free ((void *) buffer_array[index].buf_);
+ buffer_array[index].buf_ = 0;
+ buffer_array[index].len_ = 0;
+ }
+ else if (verbose)
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) %*s",
+ n,
+ buffer_array[index].buf_));
+ }
+ }
+}
+
+static void
+handle_connections (ACE_SSL_SOCK_Acceptor &peer_acceptor,
+ size_t &n_handles)
+{
+ if (ACE_BIT_ENABLED (poll_array[0].revents, POLLIN))
+ {
+ ACE_SSL_SOCK_Stream new_stream;
+
+ ACE_INET_Addr client;
+ ACE_Time_Value nonblock (0, 0);
+
+ // Handle all pending connection requests (note use of "polling"
+ // feature that doesn't block).
+
+ while (ACE_OS::poll (poll_array, 1, nonblock) > 0)
+ if (peer_acceptor.accept (new_stream, &client) == -1)
+ ACE_OS::perror ("accept");
+ else
+ {
+ const char *s = client.get_host_name ();
+
+ ACE_ASSERT (s != 0);
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) client %s\n",
+ s));
+ poll_array[n_handles++].fd = new_stream.get_handle ();
+ }
+ }
+}
+
+int
+ACE_TMAIN (int, ACE_TCHAR *[])
+{
+ u_short port = ACE_DEFAULT_SERVER_PORT + 1;
+
+ // Create a server end-point.
+ ACE_INET_Addr addr (port);
+ ACE_SSL_SOCK_Acceptor peer_acceptor (addr);
+
+ ACE_HANDLE s_handle = peer_acceptor.get_handle ();
+
+ init_poll_array ();
+
+ poll_array[0].fd = s_handle;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) starting oneway server at port %d\n",
+ port));
+
+ for (size_t n_handles = 1;;)
+ {
+ // Wait for client I/O events (handle interrupts).
+ while (ACE_OS::poll (poll_array, n_handles) == -1
+ && errno == EINTR)
+ continue;
+
+ handle_data (n_handles);
+ handle_connections (peer_acceptor, n_handles);
+ }
+
+ /* NOTREACHED */
+ return 0;
+}
+#else
+#include "ace/OS_NS_stdio.h"
+int ACE_TMAIN (int, ACE_TCHAR *[])
+{
+ ACE_OS::fprintf (stderr, "This feature is not supported\n");
+ return 0;
+}
+#endif /* ACE_HAS_POLL */
diff --git a/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-simple.cpp b/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-simple.cpp
new file mode 100644
index 00000000000..6be3ce47b9e
--- /dev/null
+++ b/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-simple.cpp
@@ -0,0 +1,366 @@
+// $Id$
+
+// This example tests the features of the <ACE_SSL_SOCK_Acceptor>,
+// <ACE_SSL_SOCK_Stream>, and <ACE_Svc_Handler> classes.
+
+#include "ace/Thread_Manager.h"
+#include "ace/Handle_Set.h"
+#include "ace/Profile_Timer.h"
+#include "ace/OS_NS_sys_select.h"
+
+#include "ace/SSL/SSL_SOCK_Acceptor.h"
+
+ACE_RCSID(SSL_SAP, SSL_server_simple, "$Id$")
+
+// Are we running verbosely?
+static int verbose = 1;
+
+// Function entry point into the twoway server task.
+
+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;
+}
+
+// Function entry point into the oneway server task.
+
+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;
+}
+
+static int
+run_event_loop (u_short port)
+{
+ // Raise the socket handle limit to the maximum.
+ ACE::set_handle_limit ();
+
+ // Create the oneway and twoway acceptors.
+ ACE_SSL_SOCK_Acceptor twoway_acceptor;
+ ACE_SSL_SOCK_Acceptor oneway_acceptor;
+
+ // Create the oneway and twoway server addresses.
+ ACE_INET_Addr twoway_server_addr (port);
+ ACE_INET_Addr oneway_server_addr (port + 1);
+
+ // Create acceptors, reuse the address.
+ if (twoway_acceptor.open (twoway_server_addr, 1) == -1
+ || oneway_acceptor.open (oneway_server_addr, 1) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "%p\n",
+ "open"),
+ 1);
+ else if (twoway_acceptor.get_local_addr (twoway_server_addr) == -1
+ || oneway_acceptor.get_local_addr (oneway_server_addr) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "%p\n",
+ "get_local_addr"),
+ 1);
+
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) starting twoway server at port %d and oneway server at port %d\n",
+ twoway_server_addr.get_port_number (),
+ oneway_server_addr.get_port_number ()));
+
+ // Keep these objects out here to prevent excessive constructor
+ // calls within the loop.
+ ACE_SSL_SOCK_Stream new_stream;
+
+ ACE_Handle_Set handle_set;
+ handle_set.set_bit (twoway_acceptor.get_handle ());
+ handle_set.set_bit (oneway_acceptor.get_handle ());
+
+ // Performs the iterative server activities.
+
+ for (;;)
+ {
+ ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT);
+ ACE_Handle_Set temp = handle_set;
+
+ int maxfd = int(oneway_acceptor.get_handle ());
+ if (maxfd < int(twoway_acceptor.get_handle ()))
+ maxfd = int(twoway_acceptor.get_handle ());
+ int result = ACE_OS::select (maxfd + 1,
+ (fd_set *) temp,
+ 0,
+ 0,
+ timeout);
+ if (result == -1)
+ ACE_ERROR ((LM_ERROR,
+ "(%P|%t) %p\n",
+ "select"));
+ else if (result == 0 && verbose)
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) select timed out\n"));
+ else
+ {
+ if (temp.is_set (twoway_acceptor.get_handle ()))
+ {
+ int r = twoway_acceptor.accept (new_stream);
+ while (r == -1 && errno == EAGAIN)
+ r = twoway_acceptor.accept (new_stream);
+ if (r == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "%p\n",
+ "accept"));
+ continue;
+ }
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) spawning twoway server\n"));
+
+ // Run the twoway server.
+ twoway_server (new_stream);
+ }
+ if (temp.is_set (oneway_acceptor.get_handle ()))
+ {
+ if (oneway_acceptor.accept (new_stream) == -1)
+ {
+ ACE_ERROR ((LM_ERROR, "%p\n", "accept"));
+ continue;
+ }
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) spawning oneway server\n"));
+
+ // Run the oneway server.
+ oneway_server (new_stream);
+ }
+ }
+ }
+
+ /* NOTREACHED */
+}
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ u_short port = ACE_DEFAULT_SERVER_PORT;
+
+ if (argc > 1)
+ port = ACE_OS::atoi (argv[1]);
+
+ return run_event_loop (port);
+}
diff --git a/ACE/examples/IPC_SAP/SSL_SAP/SSL-server.cpp b/ACE/examples/IPC_SAP/SSL_SAP/SSL-server.cpp
new file mode 100644
index 00000000000..c1f173cd72f
--- /dev/null
+++ b/ACE/examples/IPC_SAP/SSL_SAP/SSL-server.cpp
@@ -0,0 +1,430 @@
+// $Id$
+
+// This example tests the features of the <ACE_SSL_SOCK_Acceptor>,
+// <ACE_SSL_SOCK_Stream>, and <ACE_Svc_Handler> classes. If the platform
+// supports threads it uses a thread-per-connection concurrency model.
+// Otherwise, it uses a single-threaded iterative server model.
+
+#include "ace/Thread_Manager.h"
+#include "ace/Handle_Set.h"
+#include "ace/Profile_Timer.h"
+#include "ace/OS_NS_sys_select.h"
+
+#include "ace/SSL/SSL_SOCK_Acceptor.h"
+
+ACE_RCSID(SSL_SAP, SSL_server, "$Id$")
+
+// Are we running verbosely?
+static int verbose = 0;
+
+static void
+run_server (ACE_THR_FUNC server,
+ ACE_SSL_SOCK_Stream * new_stream)
+{
+#if defined (ACE_HAS_THREADS)
+ // Spawn a new thread and run the new connection in that thread of
+ // control using the <server> function as the entry point.
+ if (ACE_Thread_Manager::instance ()->spawn (server,
+ (void *) new_stream,
+ THR_DETACHED) == -1)
+ ACE_ERROR ((LM_ERROR,
+ "(%P|%t) %p\n",
+ "spawn"));
+#else
+ (*server) ((void *) new_stream);
+#endif /* ACE_HAS_THREADS */
+}
+
+// Function entry point into the twoway server task.
+
+static ACE_THR_FUNC_RETURN
+twoway_server (void *arg)
+{
+ ACE_INET_Addr cli_addr;
+ ACE_SSL_SOCK_Stream * new_stream = (ACE_SSL_SOCK_Stream *) arg;
+
+ // Make sure we're not in non-blocking mode.
+ if (new_stream->disable (ACE_NONBLOCK) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "%p\n",
+ "disable"),
+ 0);
+ else if (new_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 = new_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 = new_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 (new_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).
+ new_stream->close ();
+
+ delete new_stream;
+
+ delete [] request;
+
+ return 0;
+}
+
+// Function entry point into the oneway server task.
+
+static ACE_THR_FUNC_RETURN
+oneway_server (void *arg)
+{
+ ACE_INET_Addr cli_addr;
+ ACE_SSL_SOCK_Stream * new_stream = (ACE_SSL_SOCK_Stream *) arg;
+
+ // Make sure we're not in non-blocking mode.
+ if (new_stream->disable (ACE_NONBLOCK) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "%p\n",
+ "disable"),
+ 0);
+ else if (new_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 = new_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 = new_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")
+ ACE_TEXT ("\t\tuser time = %f secs \n")
+ ACE_TEXT ("\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")
+ ACE_TEXT ("\t\ttotal bytes = %d\n")
+ ACE_TEXT ("\t\tmbits/sec = %f\n")
+ ACE_TEXT ("\t\tusec-per-message = %f\n")
+ ACE_TEXT ("\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).
+ new_stream->close ();
+
+ delete new_stream;
+
+ delete [] request;
+
+ return 0;
+}
+
+static int
+run_event_loop (u_short port)
+{
+ // Raise the socket handle limit to the maximum.
+ ACE::set_handle_limit ();
+
+ // Create the oneway and twoway acceptors.
+ ACE_SSL_SOCK_Acceptor twoway_acceptor;
+ ACE_SSL_SOCK_Acceptor oneway_acceptor;
+
+ // Create the oneway and twoway server addresses.
+ ACE_INET_Addr twoway_server_addr (port);
+ ACE_INET_Addr oneway_server_addr (port + 1);
+
+ // Create acceptors, reuse the address.
+ if (twoway_acceptor.open (twoway_server_addr, 1) == -1
+ || oneway_acceptor.open (oneway_server_addr, 1) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "%p\n",
+ "open"),
+ 1);
+ else if (twoway_acceptor.get_local_addr (twoway_server_addr) == -1
+ || oneway_acceptor.get_local_addr (oneway_server_addr) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "%p\n",
+ "get_local_addr"),
+ 1);
+
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) starting twoway server at port %d and oneway server at port %d\n",
+ twoway_server_addr.get_port_number (),
+ oneway_server_addr.get_port_number ()));
+
+ // Keep these objects out here to prevent excessive constructor
+ // calls within the loop.
+
+ ACE_Handle_Set handle_set;
+ handle_set.set_bit (twoway_acceptor.get_handle ());
+ handle_set.set_bit (oneway_acceptor.get_handle ());
+
+ ACE_SSL_SOCK_Stream * new_stream = 0;
+
+ // Performs the iterative server activities.
+ for (;;)
+ {
+ ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT);
+ ACE_Handle_Set temp = handle_set;
+
+ int result = ACE_OS::select (int (oneway_acceptor.get_handle ()) + 1,
+ (fd_set *) temp,
+ 0,
+ 0,
+ timeout);
+ if (result == -1)
+ ACE_ERROR ((LM_ERROR,
+ "(%P|%t) %p\n",
+ "select"));
+ else if (result == 0 && verbose)
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) select timed out\n"));
+ else
+ {
+ // A new ACE_SSL_SOCK_Stream must be initialized for each
+ // connection. However, it retains (SSL) state so simply
+ // initializing a new ACE_SSL_SOCK_Stream by passing it a
+ // handle isn't enough, nor is it allowed. Such a scheme is
+ // is sometimes done with the non-SSL aware
+ // ACE_SOCK_Stream. An ACE_SSL_SOCK_Stream should only be
+ // initialized by an ACE_SSL_SOCK_Acceptor (server side), or an
+ // ACE_SSL_SOCK_Connector (client side).
+ //
+ // It is also possible to copy or assign an
+ // ACE_SSL_SOCK_Stream since it implements both
+ // methods/operators. However, the user must ensure that
+ // the copy or assignment is atomic.
+
+ if (temp.is_set (twoway_acceptor.get_handle ()))
+ {
+ ACE_NEW_RETURN (new_stream,
+ ACE_SSL_SOCK_Stream,
+ -1);
+
+ if (twoway_acceptor.accept (*new_stream) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "%p\n",
+ "accept"));
+
+ delete new_stream;
+
+ continue;
+ }
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) spawning twoway server\n"));
+
+ // Run the twoway server.
+ run_server (twoway_server,
+ new_stream);
+ }
+ if (temp.is_set (oneway_acceptor.get_handle ()))
+ {
+ ACE_NEW_RETURN (new_stream,
+ ACE_SSL_SOCK_Stream,
+ -1);
+
+ if (oneway_acceptor.accept (*new_stream) == -1)
+ {
+ ACE_ERROR ((LM_ERROR, "%p\n", "accept"));
+
+ delete new_stream;
+
+ continue;
+ }
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) spawning oneway server\n"));
+
+ // Run the oneway server.
+ run_server (oneway_server,
+ new_stream);
+ }
+ }
+ }
+
+ /* NOTREACHED */
+}
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ ACE_SSL_Context *context = ACE_SSL_Context::instance ();
+
+ context->certificate ("./dummy.pem", SSL_FILETYPE_PEM);
+ context->private_key ("./key.pem", SSL_FILETYPE_PEM);
+
+ u_short port = ACE_DEFAULT_SERVER_PORT;
+
+ if (argc > 1)
+ port = ACE_OS::atoi (argv[1]);
+
+ return run_event_loop (port);
+}
diff --git a/ACE/examples/IPC_SAP/SSL_SAP/SSL_SAP.mpc b/ACE/examples/IPC_SAP/SSL_SAP/SSL_SAP.mpc
new file mode 100644
index 00000000000..f67fdb7c2a0
--- /dev/null
+++ b/ACE/examples/IPC_SAP/SSL_SAP/SSL_SAP.mpc
@@ -0,0 +1,50 @@
+// -*- MPC -*-
+// $Id$
+
+project(*client) : aceexe, ssl {
+ avoids += ace_for_tao
+ exename = client
+ Source_Files {
+ SSL-client.cpp
+ }
+}
+
+project(*client_simple) : aceexe, ssl {
+ avoids += ace_for_tao
+ exename = client-simple
+ Source_Files {
+ SSL-client-simple.cpp
+ }
+}
+
+project(*server) : aceexe, ssl {
+ avoids += ace_for_tao
+ exename = server
+ Source_Files {
+ SSL-server.cpp
+ }
+}
+
+project(*server_fancy) : aceexe, ssl {
+ avoids += ace_for_tao
+ exename = server-fancy
+ Source_Files {
+ SSL-server-fancy.cpp
+ }
+}
+
+project(*server_poll) : aceexe, ssl {
+ avoids += ace_for_tao
+ exename = server-poll
+ Source_Files {
+ SSL-server-poll.cpp
+ }
+}
+
+project(*server_simple) : aceexe, ssl {
+ avoids += ace_for_tao
+ exename = server-simple
+ Source_Files {
+ SSL-server-simple.cpp
+ }
+}
diff --git a/ACE/examples/IPC_SAP/SSL_SAP/dummy.pem b/ACE/examples/IPC_SAP/SSL_SAP/dummy.pem
new file mode 100644
index 00000000000..d631a33b956
--- /dev/null
+++ b/ACE/examples/IPC_SAP/SSL_SAP/dummy.pem
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE-----
+MIICaTCCAdICAQAwDQYJKoZIhvcNAQEEBQAwcjELMAkGA1UEBhMCVVMxCzAJBgNV
+BAgTAkNBMQ8wDQYDVQQHEwZJcnZpbmUxDDAKBgNVBAoTA09DSTEMMAoGA1UECxMD
+VEFPMREwDwYDVQQDEwhwcml5YW5rYTEWMBQGCSqGSIb3DQEJARYHcGdvbnRsYTAe
+Fw0wMTAzMjkwNDM4NDZaFw0wMTA0MjgwNDM4NDZaMIGHMQswCQYDVQQGEwJVUzEL
+MAkGA1UECBMCQ0ExDzANBgNVBAcTBklydmluZTEdMBsGA1UEChMUT2JqZWN0IENv
+bXB1dGluZyBJbmMxEDAOBgNVBAsTB09DSStUQU8xETAPBgNVBAMTCHByaXlhbmth
+MRYwFAYJKoZIhvcNAQkBFgdwZ29udGxhMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQClC6z/bX1JHF1Hg06NCnBmsikEjViEdJFuqLOH3rXSGbm+2Eo+IO4dHlFS
+u6+Ntk4olBZTuf0DqzyEgrOiN7cnKXpxJzb1cwCmVkvDQISMygf4o66+CHtF8o8Z
+Sbi9F5u9W+MILaoCexEIVZqfHffcGxvm5O2MorBSQNka3NcC3wIDAQABMA0GCSqG
+SIb3DQEBBAUAA4GBADuKX6kllE2sNdQYMbSzt5C/lcpgcsK0BR6L01cQA95b5TvL
+HsKMeeeRj2npR4EPXY2gqgWTrKHZvf01aoKE5LuyzSQ+qfFMuEfo7+p9SYIuIrLD
+5+J0wOwN0R0YZAEY5gCAqRGw26dwWDai+PASPsx0YXV1y9jBB1FFtUFgrpR8
+-----END CERTIFICATE-----
diff --git a/ACE/examples/IPC_SAP/SSL_SAP/key.pem b/ACE/examples/IPC_SAP/SSL_SAP/key.pem
new file mode 100644
index 00000000000..54ff8f0f488
--- /dev/null
+++ b/ACE/examples/IPC_SAP/SSL_SAP/key.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQClC6z/bX1JHF1Hg06NCnBmsikEjViEdJFuqLOH3rXSGbm+2Eo+
+IO4dHlFSu6+Ntk4olBZTuf0DqzyEgrOiN7cnKXpxJzb1cwCmVkvDQISMygf4o66+
+CHtF8o8ZSbi9F5u9W+MILaoCexEIVZqfHffcGxvm5O2MorBSQNka3NcC3wIDAQAB
+AoGALYq/PexUeewdwTH2ZuzOf0gCEYN/PW19A/ABOii2OzdmDcdZFTO5AMfw4Mdx
+dcUsY/4Y+xmDO5Pwqw/1yXleTDqvEKCgIEHN4NWnYYSiZOy3LBzQ8XaMZ7/2PCqc
+s4EtesuRB2kZ7PH2R1vJfyGIxZPaO5MOFbs3QFnpBUjqOmECQQDQCYgnBcshCEro
+gsrTjxtZiVHjmXEo0Uo2m4CBQW1PLJmmUXBzivGkVFfhjKULjwvso3BePfmzy9wP
+7YFjVXN9AkEAyxjBXi2kYCcXfGQiNuIrLkyVXeGR2YWnhzS2nL1TjNngmCBbnj48
+qvoqOUQgFK0AeTe/x7lb4Cf24ejWF5vmiwJALensorAkpKWv4qD7IrXy00/7QsAa
+uWd3eZXYRq6p8U9mmc5fgyCnNB1pR95CjsqDVza7FhGXipbzepBwffveAQJBAMKc
+mxYyqDMW4nNoxDxRJs17xxkpwAdvAiQWB/JTnQ737DX5s7EDtECl7PXo6NDHIhAF
+srigToCR6wl4gkYnNpcCQHmlfa9Duf3VJI/XeHE9ZU8vS4qgx0Ikfh01xCqWlsaq
+nPRmtfktt4P8gxlryZCEPpRs9l/XwQY6tnpHr5EmV2Y=
+-----END RSA PRIVATE KEY-----
diff --git a/ACE/examples/IPC_SAP/SSL_SAP/local_data b/ACE/examples/IPC_SAP/SSL_SAP/local_data
new file mode 100644
index 00000000000..c0119859a28
--- /dev/null
+++ b/ACE/examples/IPC_SAP/SSL_SAP/local_data
@@ -0,0 +1 @@
+I am Iron man!
diff --git a/ACE/examples/IPC_SAP/SSL_SAP/summarize b/ACE/examples/IPC_SAP/SSL_SAP/summarize
new file mode 100755
index 00000000000..ee8ffd2df25
--- /dev/null
+++ b/ACE/examples/IPC_SAP/SSL_SAP/summarize
@@ -0,0 +1,45 @@
+eval '(exit $?0)' && eval 'exec perl -w -S $0 ${1+"$@"}'
+ & eval 'exec perl -w -S $0 $argv:q'
+ if 0;
+
+# $Id$
+#
+# Summarizes results from a series of runs of run_test, with
+# different numbers of clients. Example usage:
+#
+# $ for i in 1 2 5 10 15 20 25 30 35 40 45 50; do ./run_test $i; done
+# $ ./summarize
+#
+# The first three lines above let this script run without specifying the
+# full path to perl, as long as it is in the user's PATH.
+# Taken from perlrun man page.
+
+@files = glob 'client-*.log';
+@total_threads = ();
+
+foreach $file (@files) {
+ my ($i);
+ ($i = $file) =~ s/client-(\d+).log/$1/;
+ push @total_threads, $i;
+}
+
+print "No.of threads\t\tAverage Latency\n\n";
+
+foreach $total_threads (sort {$a <=> $b} @total_threads) {
+ undef $high_latency;
+
+ $high_latency = 0;
+ open (FILE, "client-${total_threads}.log") ||
+ die "$0: unable to open \"client-${total_threads}.log\"\n";
+ while ($line = <FILE>) {
+ if ($line =~ /.*usec-per-message = ([\d\.]+)/)
+ {
+ $high_latency += $1 ;
+ $number++;
+ }
+ }
+ close FILE;
+
+ printf "%3d\t\t\t%8f\n",
+ $total_threads, $high_latency/$number;
+}