Created SILC Runtime Toolkit git repository Part I.
[runtime.git] / apps / silcstress / silcstress.c
diff --git a/apps/silcstress/silcstress.c b/apps/silcstress/silcstress.c
deleted file mode 100644 (file)
index 874c5b1..0000000
+++ /dev/null
@@ -1,631 +0,0 @@
-/*
-
-  silcstress.c
-
-  Author: Pekka Riikonen <priikone@silcnet.org>
-
-  Copyright (C) 2005 Pekka Riikonen
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; version 2 of the License.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-*/
-
-/*
-  TODO:
-
-  - join to created clients with another client, to get the sent messages
-    as reply (channel message).
-  - create x clients
-
-*/
-
-/*
-  Results:
-
-  SILC Server 0.9.20 (release), Linux 2.6.11, RAM 512 MB:
-
-    - 3000 channels == silcd size 6 MB (-c 3000 -n)
-    - 10000 channels == silcd size 17 MB (-c 10000 -n)
-    - 30000 channels == silcd size 48 MB (-c 30000 -n)
-      (creating 30000 channels take 14 minutes, because JOIN is LAG_STRICT
-       command, which prevents one client flooding server with commands +
-       Qos was enabled too)
-
-
-  SILC Server 0.9.20 (debug, stack-trace), Linux 2.6.11, RAM 512 MB:
-
-    - 3000 channels == silcd size 10 MB (-c 3000 -n)
-    - 10000 channels == silcd size 37 MB (-c 10000 -n)
-
-    - 1 channel, default data flood, QoS == silcd load < 1.0%
-    - 10 channels, default data flood, QoS == silcd load < 4.0%
-    - 100 channels, default data flood, QoS == silcd load < 5.0%
-      (Qos: rate=20, bytes_limit=500B, usec_limit=200000)
-
-*/
-
-#include "silcincludes.h"
-#include "silcclient.h"
-
-typedef struct {
-  SilcClient client;
-  SilcClientConnection conn;
-  int msize;
-  int loops;
-  int flood;
-  int channels;
-  int threads;
-  bool nosend;
-  SilcMutex m;
-} *SilcStress;
-
-typedef struct {
-  SilcStress sc;
-  SilcDList channels;
-} *SilcStressWorker;
-
-SilcClientOperations ops;
-
-/* Long command line options */
-static struct option long_opts[] =
-{
-  { "server", 1, NULL,'s' },
-  { "port", 1, NULL,'p' },
-  { "channels", 1, NULL,'c' },
-  { "msize", 1, NULL,'m' },
-  { "loops", 1, NULL,'l' },
-  { "flood", 1, NULL,'f' },
-  { "nosend", 0, NULL,'n' },
-  { "threads", 1, NULL,'t' },
-  { "debug", 2, NULL, 'd' },
-  { "help", 0, NULL, 'h' },
-  { "version", 0, NULL,'V' },
-
-  { NULL, 0, NULL, 0 }
-};
-
-static void silc_stress_usage(void)
-{
-  printf(""
-"Usage: silcstress [options]\n"
-"\n"
-"  Generic Options:\n"
-"  -s  --server=server           Server to connect\n"
-"  -p  --port=NUMBER             Server port to connect (def: 706)\n"
-"  -c  --channels=NUMBER         Number of channels to create (def: 1)\n"
-"  -m  --msize=NUMBER            Size of message in bytes (def: 512)\n"
-"  -l  --loops=NUMBER            Number of loops to send data (def: 1024)\n"
-"  -f  --flood=NUMBER            Send message in every usec (def: 50000)\n"
-"  -n  --nosend                  Don't send any data\n"
-"  -t  --threads=NUMBER          Number of threads to use (def: 1)\n"
-"  -d  --debug=string            Enable debugging\n"
-"  -h  --help                    Display this message and exit\n"
-"  -V  --version                 Display version and exit\n"
-"\n");
-  exit(0);
-}
-
-int main(int argc, char **argv)
-{
-  int opt, option_index;
-  int c = 1, port = 706, b = 512, l = 1024, f = 50000, n = FALSE, t = 1;
-  char *server = NULL;
-  SilcStress sc;
-
-  if (argc > 1) {
-    while ((opt = getopt_long(argc, argv, "d:hVc:s:p:m:l:f:nt:",
-                             long_opts, &option_index)) != EOF) {
-      switch(opt) {
-       case 'h':
-         silc_stress_usage();
-         break;
-       case 'V':
-         printf("SILC Stress, version %s\n", silc_dist_version);
-         printf("(c) 2005 Pekka Riikonen <priikone@silcnet.org>\n");
-         exit(0);
-         break;
-       case 'd':
-#ifdef SILC_DEBUG
-         silc_log_debug(TRUE);
-         silc_log_debug_hexdump(TRUE);
-         silc_log_quick(TRUE);
-         if (optarg)
-           silc_log_set_debug_string(optarg);
-#else
-         fprintf(stderr,
-                 "Run-time debugging is not enabled. To enable it recompile\n"
-                 "the server with --enable-debug configuration option.\n");
-#endif
-         break;
-       case 'c':
-         c = atoi(optarg);
-         break;
-       case 'l':
-         l = atoi(optarg);
-         break;
-       case 'f':
-         f = atoi(optarg);
-         break;
-       case 'm':
-         b = atoi(optarg);
-         break;
-       case 't':
-         t = atoi(optarg);
-         break;
-       case 'p':
-         port = atoi(optarg);
-         break;
-       case 's':
-         server = strdup(optarg);
-         break;
-       case 'n':
-         n = TRUE;
-         break;
-       default:
-         silc_stress_usage();
-         break;
-      }
-    }
-  }
-
-  if (!server)
-    silc_stress_usage();
-
-  sc = silc_calloc(1, sizeof(*sc));
-  if (!sc)
-    return 1;
-  sc->channels = c;
-  sc->msize = b;
-  sc->loops = l;
-  sc->flood = f;
-  sc->nosend = n;
-  sc->threads = t;
-
-  sc->client = silc_client_alloc(&ops, NULL, sc, NULL);
-  if (!sc->client)
-    return 1;
-
-  sc->client->username = silc_get_username();
-  sc->client->hostname = silc_net_localhost();
-  sc->client->realname = strdup("SILC STRESS");
-
-  if (!silc_client_init(sc->client))
-    return 1;
-
-  if (!silc_load_key_pair("silcstress.pub", "silcstress.prv", "",
-                         &sc->client->pkcs,
-                         &sc->client->public_key,
-                         &sc->client->private_key)) {
-    if (!silc_create_key_pair("rsa", 2048, "silcstress.pub",
-                             "silcstress.prv", NULL, "",
-                             &sc->client->pkcs,
-                             &sc->client->public_key,
-                             &sc->client->private_key, FALSE)) {
-      return 1;
-    }
-  }
-
-  silc_mutex_alloc(&sc->m);
-
-  silc_client_connect_to_server(sc->client, NULL, port, server, sc);
-
-  silc_client_run(sc->client);
-
-  silc_mutex_free(sc->m);
-  silc_client_free(sc->client);
-  silc_free(sc);
-  silc_free(server);
-
-  return 0;
-}
-
-/* Worker thread */
-
-static void *
-silc_stress_worker(void *context)
-{
-  SilcStressWorker w = context;
-  SilcClient client = w->sc->client;
-  SilcClientConnection conn = w->sc->conn;
-  SilcChannelEntry channel;
-  char *tmp;
-  int i;
-
-  tmp = silc_calloc(w->sc->msize, sizeof(*tmp));
-  if (!tmp) {
-    fprintf(stderr, "out of mem\n");
-    silc_dlist_uninit(w->channels);
-    return NULL;
-  }
-
-  memset(tmp, 'M', w->sc->msize);
-
-  for (i = 0; i < w->sc->loops; i++) {
-    silc_dlist_start(w->channels);
-    while ((channel = silc_dlist_get(w->channels)) != SILC_LIST_END) {
-      /* Our packet routines don't like threads, so let's lock :( */
-      silc_mutex_lock(w->sc->m);
-      if (!w->sc->conn) {
-       silc_dlist_uninit(w->channels);
-       return NULL;
-      }
-      silc_client_send_channel_message(client, conn, channel, NULL, 0,
-                                      tmp, w->sc->msize, TRUE);
-      silc_mutex_unlock(w->sc->m);
-    }
-    usleep(w->sc->flood);
-  }
-
-  silc_dlist_uninit(w->channels);
-  silc_free(tmp);
-
-  return NULL;
-}
-
-
-/* "say" client operation is a message from the client library to the
-   application.  It may include error messages or something else.  We
-   just dump them to screen. */
-
-static void
-silc_say(SilcClient client, SilcClientConnection conn,
-        SilcClientMessageType type, char *msg, ...)
-{
-  char str[200];
-  va_list va;
-  va_start(va, msg);
-  vsnprintf(str, sizeof(str) - 1, msg, va);
-  fprintf(stdout, "%s\n", str);
-  va_end(va);
-}
-
-
-/* Message for a channel. The `sender' is the sender of the message
-   The `channel' is the channel. The `message' is the message.  Note
-   that `message' maybe NULL.  The `flags' indicates message flags
-   and it is used to determine how the message can be interpreted
-   (like it may tell the message is multimedia message). */
-
-static void
-silc_channel_message(SilcClient client, SilcClientConnection conn,
-                    SilcClientEntry sender, SilcChannelEntry channel,
-                    SilcMessagePayload payload,
-                    SilcChannelPrivateKey key,
-                    SilcMessageFlags flags, const unsigned char *message,
-                    SilcUInt32 message_len)
-{
-
-}
-
-
-/* Private message to the client. The `sender' is the sender of the
-   message. The message is `message'and maybe NULL.  The `flags'
-   indicates message flags  and it is used to determine how the message
-   can be interpreted (like it may tell the message is multimedia
-   message). */
-
-static void
-silc_private_message(SilcClient client, SilcClientConnection conn,
-                    SilcClientEntry sender, SilcMessagePayload payload,
-                    SilcMessageFlags flags,
-                    const unsigned char *message,
-                    SilcUInt32 message_len)
-{
-}
-
-
-/* Notify message to the client. The notify arguments are sent in the
-   same order as servers sends them. The arguments are same as received
-   from the server except for ID's.  If ID is received application receives
-   the corresponding entry to the ID. For example, if Client ID is received
-   application receives SilcClientEntry.  Also, if the notify type is
-   for channel the channel entry is sent to application (even if server
-   does not send it because client library gets the channel entry from
-   the Channel ID in the packet's header). */
-
-static void
-silc_notify(SilcClient client, SilcClientConnection conn,
-           SilcNotifyType type, ...)
-{
-
-}
-
-
-/* Command handler. This function is called always in the command function.
-   If error occurs it will be called as well. `conn' is the associated
-   client connection. `cmd_context' is the command context that was
-   originally sent to the command. `success' is FALSE if error occurred
-   during command. `command' is the command being processed. It must be
-   noted that this is not reply from server. This is merely called just
-   after application has called the command. Just to tell application
-   that the command really was processed. */
-
-static void
-silc_command(SilcClient client, SilcClientConnection conn,
-            SilcClientCommandContext cmd_context, bool success,
-            SilcCommand command, SilcStatus status)
-{
-  /* If error occurred in client library with our command, print the error */
-  if (status != SILC_STATUS_OK)
-    fprintf(stderr, "COMMAND %s: %s\n",
-           silc_get_command_name(command),
-           silc_get_status_message(status));
-}
-
-
-/* Command reply handler. This function is called always in the command reply
-   function. If error occurs it will be called as well. Normal scenario
-   is that it will be called after the received command data has been parsed
-   and processed. The function is used to pass the received command data to
-   the application.
-
-   `conn' is the associated client connection. `cmd_payload' is the command
-   payload data received from server and it can be ignored. It is provided
-   if the application would like to re-parse the received command data,
-   however, it must be noted that the data is parsed already by the library
-   thus the payload can be ignored. `success' is FALSE if error occurred.
-   In this case arguments are not sent to the application. The `status' is
-   the command reply status server returned. The `command' is the command
-   reply being processed. The function has variable argument list and each
-   command defines the number and type of arguments it passes to the
-   application (on error they are not sent). */
-
-static void
-silc_command_reply(SilcClient client, SilcClientConnection conn,
-                  SilcCommandPayload cmd_payload, bool success,
-                  SilcCommand command, SilcStatus status, ...)
-{
-  SilcStress sc = client->application;
-  va_list va;
-
-  /* If error occurred in client library with our command, print the error */
-  if (status != SILC_STATUS_OK)
-    fprintf(stderr, "COMMAND REPLY %s: %s\n",
-           silc_get_command_name(command),
-           silc_get_status_message(status));
-
-  va_start(va, status);
-
-  /* Check for successful JOIN */
-  if (command == SILC_COMMAND_JOIN && sc->nosend == FALSE &&
-      silc_hash_table_count(conn->local_entry->channels) == sc->channels) {
-    /* Create worker threads for data sending */
-    SilcStressWorker w;
-    SilcHashTableList htl;
-    SilcChannelUser chu;
-    int i, k;
-
-    printf("Creating %d threads (%d channels/thread)\n",
-          sc->threads, silc_hash_table_count(conn->local_entry->channels) /
-          sc->threads);
-
-    silc_hash_table_list(conn->local_entry->channels, &htl);
-    for (i = 0; i < sc->threads; i++) {
-
-      w = silc_calloc(1, sizeof(*w));
-      if (!w) {
-       fprintf(stderr, "out of mem\n");
-       exit(1);
-      }
-
-      w->sc = sc;
-      w->channels = silc_dlist_init();
-      if (!w->channels) {
-       fprintf(stderr, "out of mem\n");
-       exit(1);
-      }
-
-      for (k = 0; k < (silc_hash_table_count(conn->local_entry->channels) /
-                      sc->threads); k++)
-       while (silc_hash_table_get(&htl, NULL, (void *)&chu))
-         silc_dlist_add(w->channels, chu->channel);
-
-      silc_thread_create(silc_stress_worker, w, FALSE);
-    }
-    silc_hash_table_list_reset(&htl);
-  }
-
-  va_end(va);
-}
-
-
-/* Called to indicate that connection was either successfully established
-   or connecting failed.  This is also the first time application receives
-   the SilcClientConnection objecet which it should save somewhere.
-   If the `success' is FALSE the application must always call the function
-   silc_client_close_connection. */
-
-static void
-silc_connected(SilcClient client, SilcClientConnection conn,
-              SilcClientConnectionStatus status)
-{
-  SilcStress sc = client->application;
-  char tmp[16];
-  int i;
-
-  if (status != SILC_CLIENT_CONN_SUCCESS) {
-    fprintf(stderr, "Could not connect to server\n");
-    silc_client_close_connection(client, conn);
-    return;
-  }
-
-  fprintf(stdout, "Connected to server.\n");
-
-  /* Save the connection context */
-  sc->conn = conn;
-
-  /* Join channels */
-  for (i = 0; i < sc->channels; i++) {
-    memset(tmp, 0, sizeof(tmp));
-    snprintf(tmp, sizeof(tmp) - 1, "JOIN %d", i);
-
-    /* Our packet routines don't like threads, so let's lock :( */
-    silc_mutex_lock(sc->m);
-    silc_client_command_call(client, conn, tmp);
-    silc_mutex_unlock(sc->m);
-    usleep(50000);
-  }
-}
-
-
-/* Called to indicate that connection was disconnected to the server.
-   The `status' may tell the reason of the disconnection, and if the
-   `message' is non-NULL it may include the disconnection message
-   received from server. */
-
-static void
-silc_disconnected(SilcClient client, SilcClientConnection conn,
-                 SilcStatus status, const char *message)
-{
-  SilcStress sc = client->application;
-
-  /* We got disconnected from server */
-  sc->conn = NULL;
-  fprintf(stdout, "%s:%s\n", silc_get_status_message(status),
-         message);
-}
-
-
-/* Find authentication method and authentication data by hostname and
-   port. The hostname may be IP address as well. When the authentication
-   method has been resolved the `completion' callback with the found
-   authentication method and authentication data is called. The `conn'
-   may be NULL. */
-
-static void
-silc_get_auth_method(SilcClient client, SilcClientConnection conn,
-                    char *hostname, SilcUInt16 port,
-                    SilcGetAuthMeth completion,
-                    void *context)
-{
-  completion(TRUE, SILC_AUTH_NONE, NULL, 0, context);
-}
-
-
-/* Verifies received public key. The `conn_type' indicates which entity
-   (server, client etc.) has sent the public key. If user decides to trust
-   the application may save the key as trusted public key for later
-   use. The `completion' must be called after the public key has been
-   verified. */
-
-static void
-silc_verify_public_key(SilcClient client, SilcClientConnection conn,
-                      SilcSocketType conn_type, unsigned char *pk,
-                      SilcUInt32 pk_len, SilcSKEPKType pk_type,
-                      SilcVerifyPublicKey completion, void *context)
-{
-  completion(TRUE, context);
-}
-
-
-/* Ask (interact, that is) a passphrase from user. The passphrase is
-   returned to the library by calling the `completion' callback with
-   the `context'. The returned passphrase SHOULD be in UTF-8 encoded,
-   if not then the library will attempt to encode. */
-
-static void
-silc_ask_passphrase(SilcClient client, SilcClientConnection conn,
-                   SilcAskPassphrase completion, void *context)
-{
-  completion(NULL, 0, context);
-}
-
-
-/* Notifies application that failure packet was received.  This is called
-   if there is some protocol active in the client.  The `protocol' is the
-   protocol context.  The `failure' is opaque pointer to the failure
-   indication.  Note, that the `failure' is protocol dependant and
-   application must explicitly cast it to correct type.  Usually `failure'
-   is 32 bit failure type (see protocol specs for all protocol failure
-   types). */
-
-static void
-silc_failure(SilcClient client, SilcClientConnection conn,
-            SilcProtocol protocol, void *failure)
-{
-  fprintf(stderr, "Connecting failed (protocol failure)\n");
-}
-
-
-/* Asks whether the user would like to perform the key agreement protocol.
-   This is called after we have received an key agreement packet or an
-   reply to our key agreement packet. This returns TRUE if the user wants
-   the library to perform the key agreement protocol and FALSE if it is not
-   desired (application may start it later by calling the function
-   silc_client_perform_key_agreement). If TRUE is returned also the
-   `completion' and `context' arguments must be set by the application. */
-
-static bool
-silc_key_agreement(SilcClient client, SilcClientConnection conn,
-                  SilcClientEntry client_entry, const char *hostname,
-                  SilcUInt16 port, SilcKeyAgreementCallback *completion,
-                  void **context)
-{
-  return FALSE;
-}
-
-
-/* Notifies application that file transfer protocol session is being
-   requested by the remote client indicated by the `client_entry' from
-   the `hostname' and `port'. The `session_id' is the file transfer
-   session and it can be used to either accept or reject the file
-   transfer request, by calling the silc_client_file_receive or
-   silc_client_file_close, respectively. */
-
-static void
-silc_ftp(SilcClient client, SilcClientConnection conn,
-        SilcClientEntry client_entry, SilcUInt32 session_id,
-        const char *hostname, SilcUInt16 port)
-{
-
-}
-
-
-/* Delivers SILC session detachment data indicated by `detach_data' to the
-   application.  If application has issued SILC_COMMAND_DETACH command
-   the client session in the SILC network is not quit.  The client remains
-   in the network but is detached.  The detachment data may be used later
-   to resume the session in the SILC Network.  The appliation is
-   responsible of saving the `detach_data', to for example in a file.
-
-   The detachment data can be given as argument to the functions
-   silc_client_connect_to_server, or silc_client_add_connection when
-   creating connection to remote server, inside SilcClientConnectionParams
-   structure.  If it is provided the client library will attempt to resume
-   the session in the network.  After the connection is created
-   successfully, the application is responsible of setting the user
-   interface for user into the same state it was before detaching (showing
-   same channels, channel modes, etc).  It can do this by fetching the
-   information (like joined channels) from the client library. */
-
-static void
-silc_detach(SilcClient client, SilcClientConnection conn,
-           const unsigned char *detach_data, SilcUInt32 detach_data_len)
-{
-
-}
-
-SilcClientOperations ops = {
-  silc_say,
-  silc_channel_message,
-  silc_private_message,
-  silc_notify,
-  silc_command,
-  silc_command_reply,
-  silc_connected,
-  silc_disconnected,
-  silc_get_auth_method,
-  silc_verify_public_key,
-  silc_ask_passphrase,
-  silc_failure,
-  silc_key_agreement,
-  silc_ftp,
-  silc_detach
-};