Handle command reply lists in threads.
authorPekka Riikonen <priikone@silcnet.org>
Fri, 15 Dec 2006 15:22:09 +0000 (15:22 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Fri, 15 Dec 2006 15:22:09 +0000 (15:22 +0000)
Removed unnecessary abort handling.

lib/silcclient/client.c
lib/silcclient/client_channel.c
lib/silcclient/client_connect.c
lib/silcclient/client_entry.c
lib/silcclient/client_internal.h
lib/silcclient/client_register.c
lib/silcclient/command_reply.c

index 0c001e82d4f4df6e537bcfc1f2e28461bffe8e65..c7e4e6d8cacb1807739d68c48ed94231efdd3b22 100644 (file)
@@ -185,7 +185,6 @@ static void silc_client_connect_abort(SilcAsyncOperation op, void *context)
   SilcClientConnection conn = context;
 
   SILC_LOG_DEBUG(("Connection %p aborted by application", conn));
-  conn->internal->aborted = TRUE;
 
   /* Signal to close connection */
   if (!conn->internal->disconnected) {
@@ -408,7 +407,7 @@ SILC_FSM_STATE(silc_client_connection_st_close)
     return SILC_FSM_YIELD;
   }
 
-  /* Abort ongoing events */
+  /* Abort ongoing event */
   if (conn->internal->op) {
     SILC_LOG_DEBUG(("Abort event"));
     silc_async_abort(conn->internal->op, NULL, NULL);
@@ -626,6 +625,7 @@ silc_client_add_connection(SilcClient client,
                 struct SilcClientCommandContextStruct, next);
   silc_list_init(conn->internal->thread_pool, SilcFSMThreadStruct, next);
 
+  /* Allocate client, channel and serve caches */
   conn->internal->client_cache = silc_idcache_alloc(0, SILC_ID_CLIENT,
                                                    NULL, NULL);
   conn->internal->channel_cache = silc_idcache_alloc(0, SILC_ID_CHANNEL,
@@ -640,8 +640,8 @@ silc_client_add_connection(SilcClient client,
 
   conn->internal->ftp_sessions = silc_dlist_init();
 
-  /* Initiatlize our async operation so that application may abort us
-     while were connecting. */
+  /* Initialize our async operation so that application may abort us
+     while we're connecting. */
   conn->internal->cop = silc_async_alloc(silc_client_connect_abort,
                                         NULL, conn);
   if (!conn->internal->cop) {
@@ -727,7 +727,6 @@ void silc_client_del_connection(SilcClient client, SilcClientConnection conn)
   silc_free(conn);
 }
 
-
 /******************************* Client API *********************************/
 
 /* Connects to remote server.  This is the main routine used to connect
@@ -745,6 +744,8 @@ silc_client_connect_to_server(SilcClient client,
 {
   SilcClientConnection conn;
 
+  SILC_LOG_DEBUG(("Connecting to server"));
+
   if (!client || !remote_host)
     return NULL;
 
@@ -780,6 +781,8 @@ silc_client_connect_to_client(SilcClient client,
 {
   SilcClientConnection conn;
 
+  SILC_LOG_DEBUG(("Connecting to client"));
+
   if (!client || !remote_host)
     return NULL;
 
@@ -814,6 +817,8 @@ silc_client_key_exchange(SilcClient client,
   const char *host;
   SilcUInt16 port;
 
+  SILC_LOG_DEBUG(("Performing key exchange"));
+
   if (!client || !stream)
     return NULL;
 
@@ -853,164 +858,6 @@ void silc_client_close_connection(SilcClient client,
 }
 
 #if 0
-/* Finalizes the connection to the remote SILC server. This is called
-   after authentication protocol has been completed. This send our
-   user information to the server to receive our client ID from
-   server. */
-
-SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
-{
-  SilcProtocol protocol = (SilcProtocol)context;
-  SilcClientConnAuthInternalContext *ctx =
-    (SilcClientConnAuthInternalContext *)protocol->context;
-  SilcClient client = (SilcClient)ctx->client;
-  SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
-  SilcBuffer packet;
-
-  SILC_LOG_DEBUG(("Start"));
-
-  if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
-      protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
-    /* Error occured during protocol */
-    SILC_LOG_DEBUG(("Error during authentication protocol"));
-    ctx->status = SILC_CLIENT_CONN_ERROR_AUTH;
-    goto err;
-  }
-
-  if (conn->internal->params.detach_data) {
-    /* Send RESUME_CLIENT packet to the server, which is used to resume
-       old detached session back. */
-    SilcBuffer auth;
-    SilcClientID *old_client_id;
-    unsigned char *old_id;
-    SilcUInt16 old_id_len;
-
-    if (!silc_client_process_detach_data(client, conn, &old_id, &old_id_len)) {
-      ctx->status = SILC_CLIENT_CONN_ERROR_RESUME;
-      goto err;
-    }
-
-    old_client_id = silc_id_str2id(old_id, old_id_len, SILC_ID_CLIENT);
-    if (!old_client_id) {
-      silc_free(old_id);
-      ctx->status = SILC_CLIENT_CONN_ERROR_RESUME;
-      goto err;
-    }
-
-    /* Generate authentication data that server will verify */
-    auth = silc_auth_public_key_auth_generate(client->public_key,
-                                             client->private_key,
-                                             client->rng,
-                                             conn->internal->hash,
-                                             old_client_id, SILC_ID_CLIENT);
-    if (!auth) {
-      silc_free(old_client_id);
-      silc_free(old_id);
-      ctx->status = SILC_CLIENT_CONN_ERROR_RESUME;
-      goto err;
-    }
-
-    packet = silc_buffer_alloc_size(2 + old_id_len + auth->len);
-    silc_buffer_format(packet,
-                      SILC_STR_UI_SHORT(old_id_len),
-                      SILC_STR_UI_XNSTRING(old_id, old_id_len),
-                      SILC_STR_UI_XNSTRING(auth->data, auth->len),
-                      SILC_STR_END);
-
-    /* Send the packet */
-    silc_client_packet_send(client, ctx->sock, SILC_PACKET_RESUME_CLIENT,
-                           NULL, 0, NULL, NULL,
-                           packet->data, packet->len, TRUE);
-    silc_buffer_free(packet);
-    silc_buffer_free(auth);
-    silc_free(old_client_id);
-    silc_free(old_id);
-  } else {
-    /* Send NEW_CLIENT packet to the server. We will become registered
-       to the SILC network after sending this packet and we will receive
-       client ID from the server. */
-    packet = silc_buffer_alloc(2 + 2 + strlen(client->username) +
-                              strlen(client->realname));
-    silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
-    silc_buffer_format(packet,
-                      SILC_STR_UI_SHORT(strlen(client->username)),
-                      SILC_STR_UI_XNSTRING(client->username,
-                                           strlen(client->username)),
-                      SILC_STR_UI_SHORT(strlen(client->realname)),
-                      SILC_STR_UI_XNSTRING(client->realname,
-                                           strlen(client->realname)),
-                      SILC_STR_END);
-
-    /* Send the packet */
-    silc_client_packet_send(client, ctx->sock, SILC_PACKET_NEW_CLIENT,
-                           NULL, 0, NULL, NULL,
-                           packet->data, packet->len, TRUE);
-    silc_buffer_free(packet);
-  }
-
-  /* Save remote ID. */
-  conn->remote_id = ctx->dest_id;
-  conn->remote_id_data = silc_id_id2str(ctx->dest_id, SILC_ID_SERVER);
-  conn->remote_id_data_len = silc_id_get_len(ctx->dest_id, SILC_ID_SERVER);
-
-  /* Register re-key timeout */
-  conn->internal->rekey->timeout = client->internal->params->rekey_secs;
-  conn->internal->rekey->context = (void *)client;
-  silc_schedule_task_add(client->schedule, conn->sock->sock,
-                        silc_client_rekey_callback,
-                        (void *)conn->sock, conn->internal->rekey->timeout, 0,
-                        SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
-
-  silc_protocol_free(protocol);
-  silc_free(ctx->auth_data);
-  silc_socket_free(ctx->sock);
-  silc_free(ctx);
-  conn->sock->protocol = NULL;
-  return;
-
- err:
-  silc_protocol_free(protocol);
-  silc_free(ctx->auth_data);
-  silc_free(ctx->dest_id);
-  conn->sock->protocol = NULL;
-  silc_socket_free(ctx->sock);
-
-  /* Notify application of failure */
-  silc_schedule_task_add(client->schedule, ctx->sock->sock,
-                        silc_client_connect_failure_auth, ctx,
-                        0, 1, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
-}
-
-/* Client session resuming callback.  If the session was resumed
-   this callback is called after the resuming is completed.  This
-   will call the `connect' client operation to the application
-   since it has not been called yet. */
-
-static void silc_client_resume_session_cb(SilcClient client,
-                                         SilcClientConnection conn,
-                                         SilcBool success,
-                                         void *context)
-{
-  SilcBuffer sidp;
-
-  /* Notify application that connection is created to server */
-  client->internal->ops->connected(client, conn, success ?
-                                  SILC_CLIENT_CONN_SUCCESS_RESUME :
-                                  SILC_CLIENT_CONN_ERROR_RESUME);
-
-  if (success) {
-    /* Issue INFO command to fetch the real server name and server
-       information and other stuff. */
-    silc_client_command_register(client, SILC_COMMAND_INFO, NULL, NULL,
-                                silc_client_command_reply_info_i, 0,
-                                ++conn->cmd_ident);
-    sidp = silc_id_payload_encode(conn->remote_id, SILC_ID_SERVER);
-    silc_client_command_send(client, conn, SILC_COMMAND_INFO,
-                            conn->cmd_ident, 1, 2, sidp->data, sidp->len);
-    silc_buffer_free(sidp);
-  }
-}
-
 /* Processes incoming connection authentication method request packet.
    It is a reply to our previously sent request. The packet can be used
    to resolve the authentication method for the current session if the
@@ -1118,7 +965,6 @@ silc_client_request_authentication_method(SilcClient client,
 }
 #endif /* 0 */
 
-
 /* Allocates new client object. This has to be done before client may
    work. After calling this one must call silc_client_init to initialize
    the client. The `application' is application specific user data pointer
@@ -1203,7 +1049,7 @@ SilcBool silc_client_init(SilcClient client, const char *username,
     return FALSE;
 
   if (!username || !hostname) {
-    SILC_LOG_ERROR(("Username, hostname and realname must be given to "
+    SILC_LOG_ERROR(("Username and hostname must be given to "
                    "silc_client_init"));
     return FALSE;
   }
@@ -1258,6 +1104,12 @@ SilcBool silc_client_init(SilcClient client, const char *username,
   if (!client->schedule)
     return FALSE;
 
+  /* Allocate client lock */
+  silc_mutex_alloc(&client->internal->lock);
+
+  /* Register commands */
+  silc_client_commands_register(client);
+
   /* Start packet engine */
   client->internal->packet_engine =
     silc_packet_engine_start(client->rng, FALSE, &silc_client_stream_cbs,
@@ -1265,12 +1117,6 @@ SilcBool silc_client_init(SilcClient client, const char *username,
   if (!client->internal->packet_engine)
     return FALSE;
 
-  /* Allocate client lock */
-  silc_mutex_alloc(&client->internal->lock);
-
-  /* Register commands */
-  silc_client_commands_register(client);
-
   /* Initialize and start the client FSM */
   client->internal->running = running;
   client->internal->running_context = context;
@@ -1296,8 +1142,7 @@ void silc_client_run(SilcClient client)
   silc_schedule(client->schedule);
 }
 
-/* Call scheduler one iteration and return.  This cannot be called if threads
-   are in use. */
+/* Call scheduler one iteration and return. */
 
 void silc_client_run_one(SilcClient client)
 {
index bb5c071e4c49eb69e8affdc51c5b8dc2e41fc4ab..51fc85471d11a358d2be3727a237c9bfc60957de 100644 (file)
@@ -202,6 +202,13 @@ SILC_FSM_STATE(silc_client_channel_message)
     return SILC_FSM_CONTINUE;
   }
 
+  /* Check that user is on channel */
+  if (!silc_client_on_channel(channel, client_entry)) {
+    /** User not on channel */
+    silc_fsm_next(fsm, silc_client_channel_message_error);
+    return SILC_FSM_CONTINUE;
+  }
+
   /* If there is no channel private key then just decrypt the message
      with the channel key. If private keys are set then just go through
      all private keys and check what decrypts correctly. */
index 8c1491943b9f91518a6a19c66528cd0923eebd97..ccf5793c20718a1fcf190787db03b7b88821863a 100644 (file)
@@ -32,12 +32,6 @@ static void silc_client_connect_callback(SilcNetStatus status,
   SilcClientConnection conn = silc_fsm_get_context(fsm);
   SilcClient client = conn->client;
 
-  if (conn->internal->aborted) {
-    silc_fsm_next(fsm, silc_client_st_connect_error);
-    SILC_FSM_CALL_CONTINUE(fsm);
-    return;
-  }
-
   conn->internal->op = NULL;
   if (conn->internal->verbose) {
     switch (status) {
@@ -127,14 +121,6 @@ static void silc_client_ke_verify_key(SilcSKE ske,
   SilcClient client = conn->client;
   VerifyKeyContext verify;
 
-  if (conn->internal->aborted) {
-    completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
-              completion_context);
-    silc_fsm_next(fsm, silc_client_st_connect_error);
-    SILC_FSM_CALL_CONTINUE(fsm);
-    return;
-  }
-
   /* If we provided repository for SKE and we got here the key was not
      found from the repository. */
   if (conn->internal->params.repository &&
@@ -178,13 +164,6 @@ static void silc_client_ke_completion(SilcSKE ske,
   SilcCipher send_key, receive_key;
   SilcHmac hmac_send, hmac_receive;
 
-  if (conn->internal->aborted) {
-    silc_ske_free_rekey_material(rekey);
-    silc_fsm_next(fsm, silc_client_st_connect_error);
-    SILC_FSM_CALL_CONTINUE(fsm);
-    return;
-  }
-
   conn->internal->op = NULL;
   if (status != SILC_SKE_STATUS_OK) {
     /* Key exchange failed */
@@ -328,12 +307,6 @@ static void silc_client_connect_auth_completion(SilcConnAuth connauth,
   SilcClientConnection conn = silc_fsm_get_context(fsm);
   SilcClient client = conn->client;
 
-  if (conn->internal->aborted) {
-    silc_fsm_next(fsm, silc_client_st_connect_error);
-    SILC_FSM_CALL_CONTINUE(fsm);
-    return;
-  }
-
   conn->internal->op = NULL;
   silc_connauth_free(connauth);
 
index 1d3189ba04f89791e06dfef82c9aeba0ed6f02f6..da8f0b246f7cdd49abb094969b0eb409f5e5507f 100644 (file)
@@ -934,19 +934,23 @@ void silc_client_nickname_format(SilcClient client,
   if (!clients && !client->internal->params->nickname_force_format)
     return;
 
-  len = 0;
-  freebase = TRUE;
-  while ((entry = silc_dlist_get(clients))) {
-    if (entry->internal.valid && entry != client_entry)
-      len++;
-    if (entry->internal.valid && entry != client_entry &&
-       silc_utf8_strcasecmp(entry->nickname, client_entry->nickname)) {
-      freebase = FALSE;
-      unformatted = entry;
+  if (clients) {
+    len = 0;
+    freebase = TRUE;
+    while ((entry = silc_dlist_get(clients))) {
+      if (entry->internal.valid && entry != client_entry)
+       len++;
+      if (entry->internal.valid && entry != client_entry &&
+         silc_utf8_strcasecmp(entry->nickname, client_entry->nickname)) {
+       freebase = FALSE;
+       unformatted = entry;
+      }
+    }
+    if (!len || freebase) {
+      silc_client_list_free(client, conn, clients);
+      return;
     }
   }
-  if (!len || freebase)
-    return;
 
   /* If we are changing nickname of our local entry we'll enforce
      that we will always get the unformatted nickname.  Give our
@@ -1012,18 +1016,20 @@ void silc_client_nickname_format(SilcClient client,
        char tmp[6];
        int num, max = 1;
 
-       if (silc_dlist_count(clients) == 1)
+       if (clients && silc_dlist_count(clients) == 1)
          break;
 
-       silc_dlist_start(clients);
-       while ((entry = silc_dlist_get(clients))) {
-         if (!silc_utf8_strncasecmp(entry->nickname, newnick, off))
-           continue;
-         if (strlen(entry->nickname) <= off)
-           continue;
-         num = atoi(&entry->nickname[off]);
-         if (num > max)
-           max = num;
+       if (clients) {
+         silc_dlist_start(clients);
+         while ((entry = silc_dlist_get(clients))) {
+           if (!silc_utf8_strncasecmp(entry->nickname, newnick, off))
+             continue;
+           if (strlen(entry->nickname) <= off)
+             continue;
+           num = atoi(&entry->nickname[off]);
+           if (num > max)
+             max = num;
+         }
        }
 
        memset(tmp, 0, sizeof(tmp));
index d3437edfc061c6cfd638c59688c2c8d7bd709ac3..7d42b470789c541559ba32d6d33687962573e83d 100644 (file)
@@ -186,7 +186,7 @@ struct SilcClientConnectionInternalStruct {
 
   /* Events */
   unsigned int connect            : 1;  /* Connect remote host */
-  unsigned int disconnected       : 1;  /* Disconnected by remote host */
+  unsigned int disconnected       : 1;  /* Disconnect remote connection */
   unsigned int key_exchange       : 1;   /* Start key exchange */
   unsigned int rekeying           : 1;   /* Start rekey */
 
@@ -195,7 +195,6 @@ struct SilcClientConnectionInternalStruct {
   unsigned int registering        : 1;  /* Set when registering to network */
   unsigned int rekey_responder    : 1;   /* Set when rekeying as responder */
   unsigned int callback_called    : 1;   /* Set when connect callback called */
-  unsigned int aborted            : 1;  /* Set when aborted by application */
 
   SilcClientAway *away;
   SilcClientConnAuthRequest connauth;
index 42cb36772e682fa5a670193c1126e7bb7cffb1ef..2b28d4542ddba38cbbbaa9e4802406630602fa91 100644 (file)
@@ -186,12 +186,6 @@ SILC_FSM_STATE(silc_client_st_register_complete)
   SilcClientConnection conn = fsm_context;
   SilcClient client = conn->client;
 
-  if (conn->internal->aborted) {
-    /** Aborted */
-    silc_fsm_next(fsm, silc_client_st_register_error);
-    return SILC_FSM_CONTINUE;
-  }
-
   if (conn->internal->disconnected) {
     /** Disconnected */
     silc_fsm_next(fsm, silc_client_st_register_error);
index 0e952e9fff8068c9768a5d8854bc78c2ee1ba9c4..236fb0f67674b23a236bea53b5b9a30fd8912d8f 100644 (file)
@@ -69,6 +69,7 @@ static inline void
 silc_client_command_callback(SilcClientCommandContext cmd, ...)
 {
   SilcClientCommandReplyCallback cb;
+  SilcList list;
   va_list ap, cp;
 
   va_start(ap, cmd);
@@ -83,8 +84,9 @@ silc_client_command_callback(SilcClientCommandContext cmd, ...)
   }
 
   /* Reply callback */
-  silc_list_start(cmd->reply_callbacks);
-  while ((cb = silc_list_get(cmd->reply_callbacks)))
+  list = cmd->reply_callbacks;
+  silc_list_start(list);
+  while ((cb = silc_list_get(list)))
     if (!cb->do_not_call) {
       silc_va_copy(cp, ap);
       cb->do_not_call = !cb->reply(cmd->conn->client, cmd->conn, cmd->cmd,