Created SILC Crypto Toolkit git repository.
[crypto.git] / lib / silcclient / client_register.c
diff --git a/lib/silcclient/client_register.c b/lib/silcclient/client_register.c
deleted file mode 100644 (file)
index 72f10c1..0000000
+++ /dev/null
@@ -1,724 +0,0 @@
-/*
-
-  client_register.c
-
-  Author: Pekka Riikonen <priikone@silcnet.org>
-
-  Copyright (C) 2006 - 2007 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.
-
-*/
-
-#include "silc.h"
-#include "silcclient.h"
-#include "client_internal.h"
-
-/************************** Types and definitions ***************************/
-
-/* Resume session context */
-typedef struct {
-  SilcClient client;
-  SilcClientConnection conn;
-  SilcBufferStruct detach;
-  SilcBuffer auth;
-  char *nickname;
-  unsigned char *id;
-  SilcUInt32 id_len;
-  SilcUInt32 channel_count;
-} *SilcClientResumeSession;
-
-/************************ Static utility functions **************************/
-
-/* Continues resuming after resolving.  Continue after last reply. */
-
-static SilcBool
-silc_client_resume_continue(SilcClient client,
-                           SilcClientConnection conn,
-                           SilcCommand command,
-                           SilcStatus status,
-                           SilcStatus error,
-                           void *context,
-                           va_list ap)
-{
-  if (status == SILC_STATUS_OK || status == SILC_STATUS_LIST_END ||
-      SILC_STATUS_IS_ERROR(status)) {
-    silc_fsm_continue(&conn->internal->event_thread);
-    return FALSE;
-  }
-
-  return TRUE;
-}
-
-/* Function used to call command replies back to application in resuming. */
-
-static void
-silc_client_resume_command_callback(SilcClient client,
-                                   SilcClientConnection conn,
-                                   SilcCommand command, ...)
-{
-  va_list ap;
-  va_start(ap, command);
-  client->internal->ops->command_reply(client, conn, command,
-                                      SILC_STATUS_OK, SILC_STATUS_OK, ap);
-  va_end(ap);
-}
-
-/* Resume authentication data generation callback */
-
-static void silc_client_resume_auth_generated(const SilcBuffer data,
-                                             void *context)
-{
-  SilcClientConnection conn = context;
-  SilcClientResumeSession resume =
-    silc_fsm_get_state_context(&conn->internal->event_thread);
-
-  if (!data)
-    silc_fsm_next(&conn->internal->event_thread, silc_client_st_resume_error);
-  else
-    resume->auth = silc_buffer_copy(data);
-
-  SILC_FSM_CALL_CONTINUE_SYNC(&conn->internal->event_thread);
-}
-
-
-/****************************** NEW_ID packet *******************************/
-
-/* Received new ID packet from server during registering to SILC network */
-
-SILC_FSM_STATE(silc_client_new_id)
-{
-  SilcClientConnection conn = fsm_context;
-  SilcClient client = conn->client;
-  SilcPacket packet = state_context;
-  char *nick;
-  SilcID id;
-
-  if (conn->local_id)
-    goto out;
-
-  SILC_LOG_DEBUG(("New ID received from server"));
-
-  if (!silc_id_payload_parse_id(silc_buffer_data(&packet->buffer),
-                               silc_buffer_len(&packet->buffer), &id))
-    goto out;
-
-  SILC_LOG_DEBUG(("New ID %s", silc_id_render(&id.u.client_id,
-                                             SILC_ID_CLIENT)));
-
-  /* From SILC protocol version 1.3, nickname is in NEW_CLIENT packet */
-  if (conn->internal->remote_version >= 13)
-    nick = (conn->internal->params.nickname ?
-           conn->internal->params.nickname : client->username);
-  else
-    nick = client->username;
-
-  /* Create local client entry */
-  conn->local_entry = silc_client_add_client(client, conn, nick,
-                                            client->username,
-                                            client->realname,
-                                            &id.u.client_id, 0);
-  if (!conn->local_entry)
-    goto out;
-
-  /* Save the ID.  Take reference to conn->local_id. */
-  conn->local_id = &conn->local_entry->id;
-  conn->internal->local_idp = silc_buffer_copy(&packet->buffer);
-
-  /* Save remote ID */
-  if (packet->src_id_len) {
-    conn->internal->remote_idp =
-      silc_id_payload_encode_data(packet->src_id,
-                                 packet->src_id_len,
-                                 packet->src_id_type);
-    if (!conn->internal->remote_idp)
-      goto out;
-    silc_id_payload_parse_id(silc_buffer_data(conn->internal->remote_idp),
-                            silc_buffer_len(conn->internal->remote_idp),
-                            &conn->remote_id);
-  }
-
-  /* Set IDs to the packet stream */
-  silc_packet_set_ids(conn->stream, SILC_ID_CLIENT, conn->local_id,
-                     conn->remote_id.type, SILC_ID_GET_ID(conn->remote_id));
-
-  /* Signal connection that new ID was received so it can continue
-     with the registering. */
-  if (conn->internal->registering)
-    silc_fsm_continue_sync(&conn->internal->event_thread);
-
- out:
-  /** Packet processed */
-  silc_packet_free(packet);
-  return SILC_FSM_FINISH;
-}
-
-
-/************************ Register to SILC network **************************/
-
-/* Register to network */
-
-SILC_FSM_STATE(silc_client_st_register)
-{
-  SilcClientConnection conn = fsm_context;
-  SilcClient client = conn->client;
-  char *nick = NULL;
-
-  SILC_LOG_DEBUG(("Register to network"));
-
-  /* From SILC protocol version 1.3, nickname is in NEW_CLIENT packet */
-  if (conn->internal->remote_version >= 13)
-    nick = (conn->internal->params.nickname ?
-           conn->internal->params.nickname : client->username);
-
-  /* Send NEW_CLIENT packet to register to network */
-  if (!silc_packet_send_va(conn->stream, SILC_PACKET_NEW_CLIENT, 0,
-                          SILC_STR_UI_SHORT(strlen(client->username)),
-                          SILC_STR_DATA(client->username,
-                                        strlen(client->username)),
-                          SILC_STR_UI_SHORT(strlen(client->realname)),
-                          SILC_STR_DATA(client->realname,
-                                        strlen(client->realname)),
-                          SILC_STR_UI_SHORT(nick ? strlen(nick) : 0),
-                          SILC_STR_DATA(nick, nick ? strlen(nick) : 0),
-                          SILC_STR_END)) {
-    /** Error sending packet */
-    silc_fsm_next(fsm, silc_client_st_register_error);
-    return SILC_FSM_CONTINUE;
-  }
-
-  /** Wait for new ID */
-  conn->internal->registering = TRUE;
-  silc_fsm_next_later(fsm, silc_client_st_register_complete,
-                     conn->internal->retry_timer, 0);
-  return SILC_FSM_WAIT;
-}
-
-/* Wait for NEW_ID packet to arrive */
-
-SILC_FSM_STATE(silc_client_st_register_complete)
-{
-  SilcClientConnection conn = fsm_context;
-  SilcClient client = conn->client;
-
-  if (conn->internal->disconnected) {
-    /** Disconnected */
-    silc_fsm_next(fsm, silc_client_st_register_error);
-    return SILC_FSM_CONTINUE;
-  }
-
-  if (!conn->local_id) {
-    if (conn->internal->retry_count++ >= SILC_CLIENT_RETRY_COUNT) {
-      /** Timeout, ID not received */
-      conn->internal->registering = FALSE;
-      conn->internal->retry_count = 0;
-      conn->internal->retry_timer = SILC_CLIENT_RETRY_MIN;
-      silc_fsm_next(fsm, silc_client_st_register_error);
-      return SILC_FSM_CONTINUE;
-    }
-
-    /** Resend registering packet */
-    silc_fsm_next(fsm, silc_client_st_register);
-    conn->internal->retry_timer = ((conn->internal->retry_timer *
-                                   SILC_CLIENT_RETRY_MUL) +
-                                  (silc_rng_get_rn16(client->rng) %
-                                   SILC_CLIENT_RETRY_RAND));
-    return SILC_FSM_CONTINUE;
-  }
-
-  SILC_LOG_DEBUG(("Registered to network"));
-
-  /* Issue IDENTIFY command for itself to get resolved hostname
-     correctly from server. */
-  silc_client_command_send(client, conn, SILC_COMMAND_IDENTIFY,
-                          silc_client_command_called_dummy, NULL,
-                          1, 5, silc_buffer_data(conn->internal->local_idp),
-                          silc_buffer_len(conn->internal->local_idp));
-
-  /* With SILC protocol version 1.2 call NICK command if the nickname was
-     set by the application. */
-  if (conn->internal->params.nickname && conn->internal->remote_version < 13 &&
-      !silc_utf8_strcasecmp(conn->internal->params.nickname, client->username))
-    silc_client_command_call(client, conn, NULL,
-                            "NICK", conn->internal->params.nickname, NULL);
-
-  /* Issue INFO command to fetch the real server name and server
-     information and other stuff. */
-  silc_client_command_send(client, conn, SILC_COMMAND_INFO,
-                          silc_client_command_called_dummy, NULL,
-                          1, 2, silc_buffer_data(conn->internal->remote_idp),
-                          silc_buffer_len(conn->internal->remote_idp));
-
-  /* Call connection callback.  We are now inside SILC network. */
-  conn->callback(client, conn, SILC_CLIENT_CONN_SUCCESS, 0, NULL,
-                conn->callback_context);
-
-  conn->internal->registering = FALSE;
-  silc_schedule_task_del_by_all(conn->internal->schedule, 0,
-                               silc_client_connect_timeout, conn);
-  silc_async_free(conn->internal->cop);
-  conn->internal->cop = NULL;
-
-  return SILC_FSM_FINISH;
-}
-
-/* Error registering to network */
-
-SILC_FSM_STATE(silc_client_st_register_error)
-{
-  SilcClientConnection conn = fsm_context;
-
-  SILC_LOG_DEBUG(("Error registering to network"));
-
-  /* Signal to close connection */
-  conn->internal->status = SILC_CLIENT_CONN_ERROR;
-  if (!conn->internal->disconnected) {
-    conn->internal->disconnected = TRUE;
-    SILC_FSM_EVENT_SIGNAL(&conn->internal->wait_event);
-  }
-
-  silc_schedule_task_del_by_all(conn->internal->schedule, 0,
-                               silc_client_connect_timeout, conn);
-
-  return SILC_FSM_FINISH;
-}
-
-/************************* Resume detached session **************************/
-
-/* Resume detached session */
-
-SILC_FSM_STATE(silc_client_st_resume)
-{
-  SilcClientConnection conn = fsm_context;
-  SilcClient client = conn->client;
-  SilcClientResumeSession resume;
-  unsigned char *id;
-  SilcUInt16 id_len;
-  SilcClientID client_id;
-  int ret;
-
-  SILC_LOG_DEBUG(("Resuming detached session"));
-
-  resume = silc_calloc(1, sizeof(*resume));
-  if (!resume) {
-    /** Out of memory */
-    silc_fsm_next(fsm, silc_client_st_resume_error);
-    return SILC_FSM_CONTINUE;
-  }
-  silc_fsm_set_state_context(fsm, resume);
-
-  silc_buffer_set(&resume->detach, conn->internal->params.detach_data,
-                 conn->internal->params.detach_data_len);
-  SILC_LOG_HEXDUMP(("Detach data"), silc_buffer_data(&resume->detach),
-                  silc_buffer_len(&resume->detach));
-
-  /* Take the old client ID from the detachment data */
-  ret = silc_buffer_unformat(&resume->detach,
-                            SILC_STR_ADVANCE,
-                            SILC_STR_UI16_NSTRING_ALLOC(&resume->nickname,
-                                                        NULL),
-                            SILC_STR_UI16_NSTRING(&id, &id_len),
-                            SILC_STR_UI_INT(NULL),
-                            SILC_STR_UI_INT(&resume->channel_count),
-                            SILC_STR_END);
-  if (ret < 0) {
-    /** Malformed detach data */
-    SILC_LOG_DEBUG(("Malformed detachment data"));
-    silc_fsm_next(fsm, silc_client_st_resume_error);
-    return SILC_FSM_CONTINUE;
-  }
-
-  if (!silc_id_str2id(id, id_len, SILC_ID_CLIENT, &client_id,
-                     sizeof(client_id))) {
-    /** Malformed ID */
-    SILC_LOG_DEBUG(("Malformed ID"));
-    silc_fsm_next(fsm, silc_client_st_resume_error);
-    return SILC_FSM_CONTINUE;
-  }
-  resume->id = id;
-  resume->id_len = id_len;
-
-  /* Generate authentication data that server will verify */
-  silc_fsm_next(fsm, silc_client_st_resume_send);
-  SILC_FSM_CALL(silc_auth_public_key_auth_generate(
-                                conn->public_key, conn->private_key,
-                                client->rng, conn->internal->hash,
-                                &client_id, SILC_ID_CLIENT,
-                                silc_client_resume_auth_generated, conn));
-  /* NOT REACHED */
-}
-
-/* Send RESUME_CLIENT packet */
-
-SILC_FSM_STATE(silc_client_st_resume_send)
-{
-  SilcClientConnection conn = fsm_context;
-  SilcClientResumeSession resume = state_context;
-
-  SILC_LOG_DEBUG(("Send RESUME_CLIENT packet"));
-
-  /* Send RESUME_CLIENT packet to resume to network */
-  if (!silc_packet_send_va(conn->stream, SILC_PACKET_RESUME_CLIENT, 0,
-                          SILC_STR_UI_SHORT(resume->id_len),
-                          SILC_STR_DATA(resume->id, resume->id_len),
-                          SILC_STR_DATA(silc_buffer_data(resume->auth),
-                                        silc_buffer_len(resume->auth)),
-                          SILC_STR_END)) {
-    /** Error sending packet */
-    SILC_LOG_DEBUG(("Error sending packet"));
-    silc_fsm_next(fsm, silc_client_st_resume_error);
-    return SILC_FSM_CONTINUE;
-  }
-
-  /** Wait for new ID */
-  conn->internal->registering = TRUE;
-  silc_fsm_next_later(fsm, silc_client_st_resume_resolve_channels, 15, 0);
-  return SILC_FSM_WAIT;
-}
-
-/* Resolve the old session information, user mode and joined channels. */
-
-SILC_FSM_STATE(silc_client_st_resume_resolve_channels)
-{
-  SilcClientConnection conn = fsm_context;
-  SilcClient client = conn->client;
-  SilcClientResumeSession resume = state_context;
-  SilcUInt32 *res_argv_lens = NULL, *res_argv_types = NULL, res_argc = 0;
-  unsigned char **res_argv = NULL;
-  int i;
-
-  if (conn->internal->disconnected) {
-    /** Disconnected */
-    silc_fsm_next(fsm, silc_client_st_resume_error);
-    return SILC_FSM_CONTINUE;
-  }
-
-  if (!conn->local_id) {
-    /** Timeout, ID not received */
-    conn->internal->registering = FALSE;
-    silc_fsm_next(fsm, silc_client_st_resume_error);
-    return SILC_FSM_CONTINUE;
-  }
-
-  /** Wait for channels */
-  silc_fsm_next(fsm, silc_client_st_resume_resolve_cmodes);
-
-  /* Change our nickname */
-  silc_client_change_nickname(client, conn, conn->local_entry,
-                             resume->nickname, NULL, NULL, 0);
-
-  /* Send UMODE command to get our own user mode in the network */
-  SILC_LOG_DEBUG(("Resolving user mode"));
-  silc_client_command_send(client, conn, SILC_COMMAND_UMODE,
-                          silc_client_command_called_dummy, NULL,
-                          1, 1, silc_buffer_data(conn->internal->local_idp),
-                          silc_buffer_len(conn->internal->local_idp));
-
-  if (!resume->channel_count)
-    return SILC_FSM_YIELD;
-
-  /* Send IDENTIFY command for all channels we know about.  These are the
-     channels we've joined to according our detachment data. */
-  for (i = 0; i < resume->channel_count; i++) {
-    SilcChannelEntry channel;
-    unsigned char *chid;
-    SilcUInt16 chid_len;
-    SilcBuffer idp;
-    SilcChannelID channel_id;
-    char *name;
-
-    if (silc_buffer_unformat(&resume->detach,
-                            SILC_STR_ADVANCE,
-                            SILC_STR_UI16_NSTRING(&name, NULL),
-                            SILC_STR_UI16_NSTRING(&chid, &chid_len),
-                            SILC_STR_UI_INT(NULL),
-                            SILC_STR_END) < 0)
-      continue;
-
-    if (!silc_id_str2id(chid, chid_len, SILC_ID_CHANNEL, &channel_id,
-                       sizeof(channel_id)))
-      continue;
-    idp = silc_id_payload_encode_data(chid, chid_len, SILC_ID_CHANNEL);
-    if (!idp)
-      continue;
-
-    /* Add the channel to cache */
-    channel = silc_client_get_channel_by_id(client, conn, &channel_id);
-    if (!channel)
-      silc_client_add_channel(client, conn, name, 0, &channel_id);
-    else
-      silc_client_unref_channel(client, conn, channel);
-
-    res_argv = silc_realloc(res_argv, sizeof(*res_argv) * (res_argc + 1));
-    res_argv_lens = silc_realloc(res_argv_lens, sizeof(*res_argv_lens) *
-                                (res_argc + 1));
-    res_argv_types = silc_realloc(res_argv_types, sizeof(*res_argv_types) *
-                                 (res_argc + 1));
-    res_argv[res_argc] = silc_buffer_steal(idp, &res_argv_lens[res_argc]);
-    res_argv_types[res_argc] = res_argc + 5;
-    res_argc++;
-    silc_buffer_free(idp);
-  }
-
-  /* Send IDENTIFY command */
-  SILC_LOG_DEBUG(("Resolving joined channels"));
-  silc_client_command_send_argv(client, conn, SILC_COMMAND_IDENTIFY,
-                               silc_client_resume_continue, conn,
-                               res_argc, res_argv, res_argv_lens,
-                               res_argv_types);
-
-  for (i = 0; i < resume->channel_count; i++)
-    silc_free(res_argv[i]);
-  silc_free(res_argv);
-  silc_free(res_argv_lens);
-  silc_free(res_argv_types);
-
-  return SILC_FSM_WAIT;
-}
-
-/* Resolve joined channel modes, users and topics. */
-
-SILC_FSM_STATE(silc_client_st_resume_resolve_cmodes)
-{
-  SilcClientConnection conn = fsm_context;
-  SilcClient client = conn->client;
-  SilcClientResumeSession resume = state_context;
-  SilcIDCacheEntry entry;
-  SilcChannelEntry channel;
-  SilcList channels;
-  SilcBuffer idp;
-
-  if (conn->internal->disconnected) {
-    /** Disconnected */
-    silc_fsm_next(fsm, silc_client_st_resume_error);
-    return SILC_FSM_CONTINUE;
-  }
-
-  SILC_LOG_DEBUG(("Resolving channel details"));
-
-  /** Wait for channel modes */
-  silc_fsm_next(fsm, silc_client_st_resume_completed);
-
-  if (!silc_idcache_get_all(conn->internal->channel_cache, &channels))
-    return SILC_FSM_YIELD;
-
-  /* Resolve channels' mode, users and topic */
-  resume->channel_count = silc_list_count(channels) * 3;
-  silc_list_start(channels);
-  while ((entry = silc_list_get(channels))) {
-    channel = entry->context;
-    idp = silc_id_payload_encode(&channel->id, SILC_ID_CHANNEL);
-    if (!idp)
-      continue;
-
-    silc_client_command_send(client, conn, SILC_COMMAND_CMODE,
-                            silc_client_resume_continue, conn, 1,
-                            1, silc_buffer_data(idp),
-                            silc_buffer_len(idp));
-    silc_client_command_send(client, conn, SILC_COMMAND_USERS,
-                            silc_client_resume_continue, conn, 1,
-                            1, silc_buffer_data(idp),
-                            silc_buffer_len(idp));
-    silc_client_command_send(client, conn, SILC_COMMAND_TOPIC,
-                            silc_client_resume_continue, conn, 1,
-                            1, silc_buffer_data(idp),
-                            silc_buffer_len(idp));
-    silc_buffer_free(idp);
-  }
-
-  return SILC_FSM_WAIT;
-}
-
-/* Resuming completed */
-
-SILC_FSM_STATE(silc_client_st_resume_completed)
-{
-  SilcClientConnection conn = fsm_context;
-  SilcClient client = conn->client;
-  SilcClientResumeSession resume = state_context;
-  SilcIDCacheEntry entry;
-  SilcChannelEntry channel;
-  SilcList channels;
-
-  if (conn->internal->disconnected) {
-    /** Disconnected */
-    silc_fsm_next(fsm, silc_client_st_resume_error);
-    return SILC_FSM_CONTINUE;
-  }
-
-  if (resume->channel_count > 0) {
-    resume->channel_count--;
-    if (resume->channel_count)
-      return SILC_FSM_WAIT;
-  }
-
-  SILC_LOG_DEBUG(("Resuming completed"));
-
-  /* Issue IDENTIFY command for itself to get resolved hostname
-     correctly from server. */
-  silc_client_command_send(client, conn, SILC_COMMAND_IDENTIFY,
-                          silc_client_command_called_dummy, NULL,
-                          1, 5, silc_buffer_data(conn->internal->local_idp),
-                          silc_buffer_len(conn->internal->local_idp));
-
-  /* Issue INFO command to fetch the real server name and server
-     information and other stuff. */
-  silc_client_command_send(client, conn, SILC_COMMAND_INFO,
-                          silc_client_command_called_dummy, NULL,
-                          1, 2, silc_buffer_data(conn->internal->remote_idp),
-                          silc_buffer_len(conn->internal->remote_idp));
-
-  /* Call connection callback.  We have now resumed to SILC network. */
-  conn->callback(client, conn, SILC_CLIENT_CONN_SUCCESS_RESUME, 0, NULL,
-                conn->callback_context);
-
-  /* Call UMODE command reply. */
-  if (conn->local_entry->mode)
-    silc_client_resume_command_callback(client, conn, SILC_COMMAND_UMODE,
-                                       conn->local_entry->mode);
-
-  /* Call NICK command reply. */
-  silc_client_resume_command_callback(client, conn, SILC_COMMAND_NICK,
-                                     conn->local_entry,
-                                     conn->local_entry->nickname,
-                                     &conn->local_entry->id);
-
-  /* Call JOIN command replies for all joined channel */
-  silc_idcache_get_all(conn->internal->channel_cache, &channels);
-  silc_list_start(channels);
-  while ((entry = silc_list_get(channels))) {
-    SilcHashTableList htl;
-    const char *cipher, *hmac;
-
-    channel = entry->context;
-    cipher = (channel->internal.send_key ?
-             silc_cipher_get_name(channel->internal.send_key) : NULL);
-    hmac = (channel->internal.hmac ?
-           silc_hmac_get_name(channel->internal.hmac) : NULL);
-    silc_hash_table_list(channel->user_list, &htl);
-    silc_client_resume_command_callback(client, conn, SILC_COMMAND_JOIN,
-                                       channel->channel_name, channel,
-                                       channel->mode, &htl, channel->topic,
-                                       cipher, hmac, channel->founder_key,
-                                       channel->channel_pubkeys,
-                                       channel->user_limit);
-    silc_hash_table_list_reset(&htl);
-  }
-
-  conn->internal->registering = FALSE;
-  silc_schedule_task_del_by_all(conn->internal->schedule, 0,
-                               silc_client_connect_timeout, conn);
-  silc_free(resume->nickname);
-  silc_free(resume);
-  silc_async_free(conn->internal->cop);
-  conn->internal->cop = NULL;
-
-  return SILC_FSM_FINISH;
-}
-
-/* Error resuming to network */
-
-SILC_FSM_STATE(silc_client_st_resume_error)
-{
-  SilcClientConnection conn = fsm_context;
-  SilcClientResumeSession resume = state_context;
-
-  if (conn->internal->disconnected) {
-    if (resume) {
-      silc_free(resume->nickname);
-      silc_free(resume);
-    }
-    return SILC_FSM_FINISH;
-  }
-
-  SILC_LOG_DEBUG(("Error resuming to network"));
-
-  /* Signal to close connection */
-  conn->internal->status = SILC_CLIENT_CONN_ERROR;
-  if (!conn->internal->disconnected) {
-    conn->internal->disconnected = TRUE;
-    SILC_FSM_EVENT_SIGNAL(&conn->internal->wait_event);
-  }
-
-  silc_schedule_task_del_by_all(conn->internal->schedule, 0,
-                               silc_client_connect_timeout, conn);
-
-  if (resume) {
-    silc_free(resume->nickname);
-    silc_free(resume);
-  }
-
-  return SILC_FSM_FINISH;
-}
-
-/* Generates the session detachment data. This data can be used later
-   to resume back to the server. */
-
-SilcBuffer silc_client_get_detach_data(SilcClient client,
-                                      SilcClientConnection conn)
-{
-  SilcBuffer detach;
-  SilcHashTableList htl;
-  SilcChannelUser chu;
-  unsigned char id[64];
-  SilcUInt32 id_len;
-  int ret, ch_count;
-
-  SILC_LOG_DEBUG(("Creating detachment data"));
-
-  ch_count = silc_hash_table_count(conn->local_entry->channels);
-  silc_id_id2str(conn->local_id, SILC_ID_CLIENT, id, sizeof(id), &id_len);
-
-  /* Save the nickname, Client ID and user mode in SILC network */
-  detach = silc_buffer_alloc(0);
-  if (!detach)
-    return NULL;
-  ret =
-    silc_buffer_format(detach,
-                      SILC_STR_ADVANCE,
-                      SILC_STR_UI_SHORT(strlen(conn->local_entry->nickname)),
-                      SILC_STR_DATA(conn->local_entry->nickname,
-                                    strlen(conn->local_entry->nickname)),
-                      SILC_STR_UI_SHORT(id_len),
-                      SILC_STR_DATA(id, id_len),
-                      SILC_STR_UI_INT(conn->local_entry->mode),
-                      SILC_STR_UI_INT(ch_count),
-                      SILC_STR_END);
-  if (ret < 0) {
-    silc_buffer_free(detach);
-    return NULL;
-  }
-
-  /* Save all joined channels */
-  silc_hash_table_list(conn->local_entry->channels, &htl);
-  while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
-    unsigned char chid[32];
-    SilcUInt32 chid_len;
-
-    silc_id_id2str(&chu->channel->id, SILC_ID_CHANNEL, chid, sizeof(chid),
-                  &chid_len);
-    silc_buffer_format(detach,
-                      SILC_STR_ADVANCE,
-                      SILC_STR_UI_SHORT(strlen(chu->channel->channel_name)),
-                      SILC_STR_DATA(chu->channel->channel_name,
-                                    strlen(chu->channel->channel_name)),
-                      SILC_STR_UI_SHORT(chid_len),
-                      SILC_STR_DATA(chid, chid_len),
-                      SILC_STR_UI_INT(chu->channel->mode),
-                      SILC_STR_END);
-  }
-  silc_hash_table_list_reset(&htl);
-
-  silc_buffer_start(detach);
-  SILC_LOG_HEXDUMP(("Detach data"), silc_buffer_data(detach),
-                  silc_buffer_len(detach));
-
-  return detach;
-}