Rewrote detach/resuming.
[silc.git] / lib / silcclient / silcclient.h
index a819389688367d837a29aa6e1aae473d964a72de..a94648bcf58d9095f45127be5b0ac80ff6b1adee 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2000 - 2005 Pekka Riikonen
+  Copyright (C) 2000 - 2006 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
@@ -52,237 +52,175 @@ extern "C" {
 #endif
 
 #include "client.h"
+#include "silcclient_entry.h"
 
 /* General definitions */
 
-/****s* silcclient/SilcClientAPI/SilcClient
+/****d* silcclient/SilcClientAPI/SilcClientConnectionStatus
  *
  * NAME
  *
- *    typedef struct SilcClientStruct { ... } *SilcClient
+ *    typedef enum { ... } SilcClientConnectionStatus
  *
  * DESCRIPTION
  *
- *    This is the actual SILC Client structure which represents one
- *    SILC Client.  It is allocated with the silc_client_alloc function
- *    and given as argument to all SILC Client Library functions.  It
- *    is initialized with silc_client_init function, and freed with
- *    silc_client_free function.
+ *    This type is returned to the `connect' client operation to indicate
+ *    the status of the created connection.  It can indicate if it was
+ *    successful or whether an error occurred.
  *
  * SOURCE
  */
-struct SilcClientStruct {
-  /*
-   * The following fields are set by application. Strings MUST be UTF-8
-   * encoded strings.
-   */
-  char *nickname;               /* Nickname, MAY be set by application  */
-  char *username;               /* Username, MUST be set by application */
-  char *hostname;               /* hostname, MUST be set by application */
-  char *realname;               /* Real name, MUST be set be application */
-
-  SilcPublicKey public_key;     /* Public key of user, set by application */
-  SilcPrivateKey private_key;   /* Private key of user, set by application */
-  SilcPKCS pkcs;                /* PKCS allocated by application */
-
-  /*
-   * The following fields are set by the library
-   */
-
-  /* Scheduler, set by library.  Application may use this pointer. */
-  SilcSchedule schedule;
-
-  /* Random Number Generator. Application should use this as its primary
-     random number generator. */
-  SilcRng rng;
-
-  /* Application specific user data pointer. Client library does not
-     touch this.  This the context sent as argument to silc_client_alloc.
-     Application can use it freely. */
-  void *application;
-
-  /* Generic hash context for application usage */
-  SilcHash md5hash;
-  SilcHash sha1hash;
-
-  /* Internal data for client library. Application cannot access this
-     data at all. */
-  SilcClientInternal internal;
-};
+typedef enum {
+  SILC_CLIENT_CONN_SUCCESS,           /* Successfully connected */
+  SILC_CLIENT_CONN_SUCCESS_RESUME,     /* Successfully connected and
+                                         resumed old detached session */
+  SILC_CLIENT_CONN_DISCONNECTED,       /* Remote host disconnected */
+  SILC_CLIENT_CONN_ERROR,             /* Error occurred during connecting */
+  SILC_CLIENT_CONN_ERROR_KE,          /* Key Exchange failed */
+  SILC_CLIENT_CONN_ERROR_AUTH,        /* Authentication failed */
+  SILC_CLIENT_CONN_ERROR_RESUME,       /* Resuming failed */
+  SILC_CLIENT_CONN_ERROR_TIMEOUT,      /* Timeout during connecting */
+} SilcClientConnectionStatus;
 /***/
 
-/****s* silcclient/SilcClientAPI/SilcClientConnection
+/****f* silcclient/SilcClientAPI/SilcClientRunning
  *
- * NAME
+ * SYNOPSIS
  *
- *    typedef struct SilcClientConnectionStruct { ... }
- *                      *SilcClientConnection
+ *    typedef void (*SilcClientRunning)(SilcClient client, void *context);
  *
  * DESCRIPTION
  *
- *    This structure represents a connection.  When connection is created
- *    to server this is context is returned to the application in the
- *    "connected" client operation.  It includes all the important
- *    data for the session, such as nickname, local and remote IDs, and
- *    other information.  All strings in the structure are UTF-8 encoded.
+ *    The callback given as argument to silc_client_init function.  Once
+ *    this is called the client library is running and application may
+ *    start using the Client library API.
  *
- * SOURCE
- */
-struct SilcClientConnectionStruct {
-  /*
-   * Local data
-   */
-  char *nickname;                /* Current nickname */
-  SilcClientEntry local_entry;   /* Own Client Entry */
-  SilcClientID *local_id;        /* Current Client ID */
-  unsigned char *local_id_data;          /* Current Client ID decoded */
-  SilcUInt32 local_id_data_len;
-
-  /*
-   * Remote data
-   */
-  char *remote_host;             /* Remote host name, UTF-8 encoded */
-  int remote_port;               /* Remote port */
-  SilcServerID *remote_id;       /* Remote Server ID */
-  unsigned char *remote_id_data;  /* Remote Server ID decoded */
-  SilcUInt32 remote_id_data_len;
-
-  /*
-   * Common data
-   */
-
-  /* Current command identifier for a command that was sent last.
-     Application may get the value from this variable to find out the
-     command identifier for last command. */
-  SilcUInt16 cmd_ident;
-
-  /* User data context. Library does not touch this. Application may
-     freely set and use this pointer for its needs. */
-  void *context;
-
-  /* Pointer back to the SilcClient.  Application may use this. */
-  SilcClient client;
-
-  /* Current channel.  Application may use and set this pointer if needed. */
-  SilcChannelEntry current_channel;
+ ***/
+typedef void (*SilcClientRunning)(SilcClient client, void *context);
 
-  /* Socket connection object for this connection.  Application may
-     use this if needed.  The sock->user_data is back pointer to this
-     structure. */
-  SilcSocketConnection sock;
+/****f* silcclient/SilcClientAPI/SilcClientStopped
+ *
+ * SYNOPSIS
+ *
+ *    typedef void (*SilcClientStopped)(SilcClient client, void *context);
+ *
+ * DESCRIPTION
+ *
+ *    The callback given as argument to silc_client_stop.  Once this is
+ *    called the client library has stopped and can be freed by calling
+ *    silc_client_free.  Note that this won't be called if there are
+ *    active connections in the client.  Connections must first be closed
+ *    by calling silc_client_close_connection or by sending QUIT command to
+ *    the server connection.
+ *
+ ***/
+typedef void (*SilcClientStopped)(SilcClient client, void *context);
 
-  /* Internal data for client library. Application cannot access this
-     data at all. */
-  SilcClientConnectionInternal internal;
-};
-/***/
+/****f* silcclient/SilcClientAPI/SilcClientConnectCallback
+ *
+ * SYNOPSIS
+ *
+ *    void (*SilcClientConnectCallback)(SilcClient client,
+ *                                      SilcClientConnection conn,
+ *                                      SilcClientConnectionStatus status,
+ *                                      SilcStatus error,
+ *                                      const char *message,
+ *                                      void *context);
+ *
+ * DESCRIPTION
+ *
+ *    Connect callbak given as argument to silc_client_connect_to_server,
+ *    silc_client_connect_to_client and silc_client_key_exchange functions.
+ *    It is called to indicate the status of the connection, indicated
+ *    by the `status'.  It is called after the connection has been
+ *    established to the remote host and when connection is disconnected
+ *    by the remote host.  The `context' is the context given as argument
+ *    to the connecting function.
+ *
+ *    When the `status' is SILC_CLIENT_CONN_DISCONNECTED the `error' will
+ *    indicate the reason for disconnection.  If the `message' is non-NULL
+ *    it delivers error or disconnection message.
+ *
+ ***/
+typedef void (*SilcClientConnectCallback)(SilcClient client,
+                                         SilcClientConnection conn,
+                                         SilcClientConnectionStatus status,
+                                         SilcStatus error,
+                                         const char *message,
+                                         void *context);
 
-/****s* silcclient/SilcClientAPI/SilcClientEntry
+/****s* silcclient/SilcClientAPI/SilcClient
  *
  * NAME
  *
- *    typedef struct SilcClientEntryStruct { ... } *SilcClientEntry
+ *    typedef struct SilcClientStruct { ... } *SilcClient
  *
  * DESCRIPTION
  *
- *    This structure represents a client or a user in the SILC network.
- *    The local user has this structure also and it can be accessed from
- *    SilcClientConnection structure.  All other users in the SILC network
- *    that are accessed using the Client Library routines will have their
- *    own SilcClientEntry structure.  For example, when finding users by
- *    their nickname the Client Library returns this structure back to
- *    the application.  All strings in the structure are UTF-8 encoded.
+ *    This is the actual SILC Client structure which represents one
+ *    SILC Client.  It is allocated with the silc_client_alloc function
+ *    and given as argument to all SILC Client Library functions.  It
+ *    is initialized with silc_client_init function, and freed with
+ *    silc_client_free function.
+ *
+ *    This context represents the client.  Each connection to remote server
+ *    is represented by SilcClientConnection context.
  *
  * SOURCE
  */
-struct SilcClientEntryStruct {
-  /* General information */
-  char *nickname;              /* nickname */
-  char *username;              /* username */
-  char *hostname;              /* hostname */
-  char *server;                        /* SILC server name */
-  char *realname;              /* Realname (userinfo) */
-
-  /* Mode, ID and other information */
-  SilcUInt32 mode;             /* User mode in SILC, see SilcUserMode */
-  SilcClientID *id;            /* The Client ID */
-  SilcDList attrs;             /* Requested Attributes (maybe NULL) */
-  unsigned char *fingerprint;  /* Fingerprint of client's public key */
-  SilcUInt32 fingerprint_len;  /* Length of the fingerprint */
-  SilcPublicKey public_key;    /* User's public key, may be NULL */
-
-  /* Private message keys */
-  SilcCipher send_key;         /* Private message key for sending */
-  SilcCipher receive_key;      /* Private message key for receiving */
-  SilcHmac hmac_send;          /* Private mesage key HMAC for sending */
-  SilcHmac hmac_receive;       /* Private mesage key HMAC for receiving */
-  unsigned char *key;          /* Set only if application provided the
-                                  key material. NULL if the library
-                                  generated the key. */
-  SilcUInt32 key_len;          /* Key length */
-  SilcClientKeyAgreement ke;   /* Current key agreement context or NULL */
-
-  /* SilcClientEntry status information */
-  SilcEntryStatus status;      /* Status mask */
-  SilcHashTable channels;      /* All channels client has joined */
-  SilcUInt16 resolve_cmd_ident;        /* Command identifier when resolving */
-  unsigned int generated   : 1; /* TRUE if library generated `key' */
-  unsigned int valid       : 1;        /* FALSE if this entry is not valid */
-  unsigned int prv_resp    : 1; /* TRUE if private message key indicator
-                                  has been received (responder). */
-
-  /* Application specific data.  Application may set here whatever it wants. */
-  void *context;
+struct SilcClientStruct {
+  char *username;               /* Username */
+  char *hostname;               /* hostname */
+  char *realname;               /* Real name */
+  SilcSchedule schedule;       /* Client scheduler */
+  SilcRng rng;                 /* Random number generator */
+  void *application;           /* Application specific context, set with
+                                  silc_client_alloc. */
+
+  /* Internal data for client library.  Application cannot access this. */
+  SilcClientInternal internal;
 };
 /***/
 
-/****s* silcclient/SilcClientAPI/SilcChannelEntry
+/****s* silcclient/SilcClientAPI/SilcClientConnection
  *
  * NAME
  *
- *    typedef struct SilcChannelEntryStruct { ... } *SilcChannelEntry
+ *    typedef struct SilcClientConnectionStruct { ... }
+ *                      *SilcClientConnection
  *
  * DESCRIPTION
  *
- *    This structure represents a channel in the SILC network.  All
- *    channels that the client are aware of or have joined in will be
- *    represented as SilcChannelEntry.  The structure includes information
- *    about the channel.  All strings in the structure are UTF-8 encoded.
+ *    This structure represents a connection.  It is allocated and freed by
+ *    the library.  It is returned to application in SilcClientConnectCallback.
+ *    It includes all the important data for the session such as local
+ *    client entry (which includes current nickname), local and remote IDs,
+ *    and other information.  All strings in the structure are UTF-8 encoded.
  *
  * SOURCE
  */
-struct SilcChannelEntryStruct {
-  /* General information */
-  char *channel_name;                       /* Channel name */
-  SilcChannelID *id;                        /* Channel ID */
-  SilcUInt32 mode;                          /* Channel mode, ChannelModes. */
-  char *topic;                              /* Current topic, may be NULL */
-  SilcPublicKey founder_key;                /* Founder key, may be NULL */
-  SilcUInt32 user_limit;                    /* User limit on channel */
-
-  /* All clients that has joined this channel.  The key to the table is the
-     SilcClientEntry and the context is SilcChannelUser context. */
-  SilcHashTable user_list;
-
-  /* Channel keys */
-  SilcCipher channel_key;                    /* The channel key */
-  unsigned char *key;                       /* Raw key data */
-  SilcUInt32 key_len;                       /* Raw key data length */
-  unsigned char iv[SILC_CIPHER_MAX_IV_SIZE]; /* Current IV */
-  SilcHmac hmac;                            /* Current HMAC */
-
-  /* Channel private keys */
-  SilcDList private_keys;                   /* List of private keys or NULL */
-  SilcChannelPrivateKey curr_key;           /* Current private key */
-
-  /* SilcChannelEntry status information */
-  SilcDList old_channel_keys;
-  SilcDList old_hmacs;
-  SilcUInt16 resolve_cmd_ident;                     /* Command identifier when
-                                               resolving this entry */
+struct SilcClientConnectionStruct {
+  SilcClientEntry local_entry;        /* Our own Client Entry */
+  SilcClientID *local_id;             /* Our current Client ID */
+
+  char *remote_host;                  /* Remote host name */
+  int remote_port;                    /* Remote port */
+  SilcID remote_id;                   /* Remote ID */
+
+  SilcChannelEntry current_channel;    /* Current joined channel */
+  SilcPublicKey public_key;           /* Public key used in this connection */
+  SilcPrivateKey private_key;         /* Private key */
+  SilcPacketStream stream;            /* Connection to remote host */
+  SilcConnectionType type;            /* Connection type */
+  SilcClientConnectCallback callback;  /* Connection callback */
+  void *callback_context;             /* Connection context */
+  SilcClient client;                  /* Pointer back to SilcClient */
 
   /* Application specific data.  Application may set here whatever it wants. */
   void *context;
+
+  /* Internal data for client library.  Application cannot access this. */
+  SilcClientConnectionInternal internal;
 };
 /***/
 
@@ -310,32 +248,36 @@ struct SilcChannelUserStruct {
 };
 /***/
 
-/****s* silcclient/SilcClientAPI/SilcServerEntry
+/****s* silcclient/SilcClientAPI/SilcClientStats
  *
  * NAME
  *
- *    typedef struct SilcServerEntryStruct { ... } *SilcServerEntry
+ *    typedef struct { ... } SilcClientStats;
  *
  * DESCRIPTION
  *
- *    This structure represents a server in the SILC network.  All servers
- *    that the client is aware of and have for example resolved with
- *    SILC_COMMAND_INFO command have their on SilcServerEntry structure.
- *    All strings in the structure are UTF-8 encoded.
+ *    This structure holds SILC network statistics returned by the
+ *    SILC_COMMAND_STATS command reply to the application.
  *
  * SOURCE
  */
-struct SilcServerEntryStruct {
-  /* General information */
-  char *server_name;                        /* Server name */
-  char *server_info;                        /* Server info */
-  SilcServerID *server_id;                  /* Server ID */
-  SilcUInt16 resolve_cmd_ident;                     /* Command identifier when
-                                               resolving this entry */
-
-  /* Application specific data.  Application may set here whatever it wants. */
-  void *context;
-};
+typedef struct {
+  SilcUInt32 starttime;                /* SILC server start time */
+  SilcUInt32 uptime;           /* SILC server uptime*/
+  SilcUInt32 my_clients;       /* Number of clients in the server */
+  SilcUInt32 my_channels;      /* Number of channel in the server */
+  SilcUInt32 my_server_ops;    /* Number of server operators in the server */
+  SilcUInt32 my_router_ops;    /* Number of router operators in the router */
+  SilcUInt32 cell_clients;     /* Number of clients in the cell */
+  SilcUInt32 cell_channels;    /* Number of channels in the cell */
+  SilcUInt32 cell_servers;     /* Number of server in the cell */
+  SilcUInt32 clients;          /* All clients in SILC network */
+  SilcUInt32 channels;         /* All channels in SILC network */
+  SilcUInt32 servers;          /* All servers in SILC network */
+  SilcUInt32 routers;          /* All routers in SILC network */
+  SilcUInt32 server_ops;       /* All server operators in SILC network */
+  SilcUInt32 router_ops;       /* All router operators in SILC network */
+} SilcClientStats;
 /***/
 
 /****d* silcclient/SilcClientAPI/SilcKeyAgreementStatus
@@ -360,6 +302,7 @@ typedef enum {
   SILC_KEY_AGREEMENT_ABORTED,         /* The protocol aborted */
   SILC_KEY_AGREEMENT_ALREADY_STARTED,  /* Already started */
   SILC_KEY_AGREEMENT_SELF_DENIED,      /* Negotiationg with itself denied */
+  SILC_KEY_AGREEMENT_NO_MEMORY,        /* System out of memory */
 } SilcKeyAgreementStatus;
 /***/
 
@@ -389,7 +332,7 @@ typedef void (*SilcKeyAgreementCallback)(SilcClient client,
                                         SilcClientConnection conn,
                                         SilcClientEntry client_entry,
                                         SilcKeyAgreementStatus status,
-                                        SilcSKEKeyMaterial *key,
+                                        SilcSKEKeyMaterial key,
                                         void *context);
 
 /****s* silcclient/SilcClientAPI/SilcPrivateMessageKeys
@@ -400,8 +343,8 @@ typedef void (*SilcKeyAgreementCallback)(SilcClient client,
  *
  * DESCRIPTION
  *
- *    Structure to hold the list of private message keys. The array of this
- *    structure is returned by the silc_client_list_private_message_keys
+ *    Structure to hold the list of private message keys. The list of these
+ *    structures is returned by the silc_client_list_private_message_keys
  *    function.
  *
  * SOURCE
@@ -410,8 +353,7 @@ typedef struct {
   SilcClientEntry client_entry;       /* The remote client entry */
   char *cipher;                              /* The cipher name */
   unsigned char *key;                /* The original key, If the appliation
-                                        provided it. This is NULL if the
-                                        library generated the key or if
+                                        provided it. This is NULL if
                                         the SKE key material was used. */
   SilcUInt32 key_len;                /* The key length */
 } *SilcPrivateMessageKeys;
@@ -435,8 +377,6 @@ struct SilcChannelPrivateKeyStruct {
   char *name;                        /* Application given name */
   SilcCipher cipher;                 /* The cipher and key */
   SilcHmac hmac;                     /* The HMAC and hmac key */
-  unsigned char *key;                /* The key data */
-  SilcUInt32 key_len;                /* The key length */
 };
 /***/
 
@@ -465,7 +405,7 @@ typedef void (*SilcAskPassphrase)(unsigned char *passphrase,
  *
  * SYNOPSIS
  *
- *    typedef void (*SilcVerifyPublicKey)(bool success, void *context);
+ *    typedef void (*SilcVerifyPublicKey)(SilcBool success, void *context);
  *
  * DESCRIPTION
  *
@@ -474,16 +414,16 @@ typedef void (*SilcAskPassphrase)(unsigned char *passphrase,
  *    either success or failure.
  *
  ***/
-typedef void (*SilcVerifyPublicKey)(bool success, void *context);
+typedef void (*SilcVerifyPublicKey)(SilcBool success, void *context);
 
 /****f* silcclient/SilcClientAPI/SilcGetAuthMeth
  *
  * SYNOPSIS
  *
- *    typedef void (*SilcGetAuthMeth)(bool success,
- *                                    SilcProtocolAuthMeth auth_meth,
- *                                    const unsigned char *auth_data,
- *                                    SilcUInt32 auth_data_len, void *context);
+ *    typedef void (*SilcGetAuthMeth)(SilcBool success,
+ *                                    SilcAuthMethod auth_meth,
+ *                                    void *auth, SilcUInt32 auth_len,
+ *                                    void *context);
  *
  * DESCRIPTION
  *
@@ -497,10 +437,10 @@ typedef void (*SilcVerifyPublicKey)(bool success, void *context);
  *    context sent to the get_auth_method client operation.
  *
  ***/
-typedef void (*SilcGetAuthMeth)(bool success,
-                               SilcProtocolAuthMeth auth_meth,
-                               const unsigned char *auth_data,
-                               SilcUInt32 auth_data_len, void *context);
+typedef void (*SilcGetAuthMeth)(SilcBool success,
+                               SilcAuthMethod auth_meth,
+                               void *auth, SilcUInt32 auth_len,
+                               void *context);
 
 /****d* silcclient/SilcClientAPI/SilcClientMessageType
  *
@@ -523,33 +463,6 @@ typedef enum {
 } SilcClientMessageType;
 /***/
 
-/****d* silcclient/SilcClientAPI/SilcClientConnectionStatus
- *
- * NAME
- *
- *    typedef enum { ... } SilcClientConnectionStatus
- *
- * DESCRIPTION
- *
- *    This type is returned to the `connect' client operation to indicate
- *    the status of the created connection.  It can indicate if it was
- *    successful or whether an error occurred.
- *
- * SOURCE
- */
-typedef enum {
-  SILC_CLIENT_CONN_SUCCESS,           /* Successfully connected */
-  SILC_CLIENT_CONN_SUCCESS_RESUME,     /* Successfully connected and
-                                         resumed old detached session */
-  SILC_CLIENT_CONN_ERROR,             /* Unknown error occurred during
-                                         connecting */
-  SILC_CLIENT_CONN_ERROR_KE,          /* Key Exchange failed */
-  SILC_CLIENT_CONN_ERROR_AUTH,        /* Authentication failed */
-  SILC_CLIENT_CONN_ERROR_RESUME,       /* Resuming failed */
-  SILC_CLIENT_CONN_ERROR_TIMEOUT,      /* Timeout during connecting */
-} SilcClientConnectionStatus;
-/***/
-
 /****s* silcclient/SilcClientAPI/SilcClientOperations
  *
  * NAME
@@ -594,8 +507,7 @@ typedef struct {
      message). */
   void (*private_message)(SilcClient client, SilcClientConnection conn,
                          SilcClientEntry sender, SilcMessagePayload payload,
-                         SilcMessageFlags flags,
-                         const unsigned char *message,
+                         SilcMessageFlags flags, const unsigned char *message,
                          SilcUInt32 message_len);
 
   /* Notify message to the client. The notify arguments are sent in the
@@ -609,17 +521,18 @@ typedef struct {
   void (*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. */
+  /* Command handler. This function is called always after application has
+     called a command.  It will be called to indicate that the command
+     was processed.  It will also be called if error occurs while processing
+     the command.  The `success' indicates whether the command was sent
+     or if error occurred.  The `status' indicates the actual error.
+     The `argc' and `argv' are the command line arguments sent to the
+     command by application.  Note that, this is not reply to the command
+     from server, this is merely and indication to application that the
+     command was processed. */
   void (*command)(SilcClient client, SilcClientConnection conn,
-                 SilcClientCommandContext cmd_context, bool success,
-                 SilcCommand command, SilcStatus status);
+                 SilcBool success, SilcCommand command, SilcStatus status,
+                 SilcUInt32 argc, unsigned char **argv);
 
   /* Command reply handler. This function is called always in the command reply
      function. If error occurs it will be called as well. Normal scenario
@@ -644,26 +557,8 @@ typedef struct {
      ID. For example, if Client ID is receives application receives
      SilcClientEntry. */
   void (*command_reply)(SilcClient client, SilcClientConnection conn,
-                       SilcCommandPayload cmd_payload, bool success,
-                       SilcCommand command, SilcStatus status, ...);
-
-  /* Called to indicate that connection was either successfully established
-     or connecting failed.  This is also the first time application receives
-     the SilcClientConnection object which it should save somewhere.
-     The `status' indicated whether the connection were successful.  If it
-     is error value the application must always call the function
-     silc_client_close_connection. */
-  void (*connected)(SilcClient client, SilcClientConnection conn,
-                   SilcClientConnectionStatus status);
-
-  /* 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. Application must not call the
-     silc_client_close_connection in this callback.  The 'conn' is also
-     invalid after this function returns back to library. */
-  void (*disconnected)(SilcClient client, SilcClientConnection conn,
-                      SilcStatus status, const char *message);
+                       SilcCommand command, SilcStatus status,
+                       SilcStatus error, va_list ap);
 
   /* Find authentication method and authentication data by hostname and
      port. The hostname may be IP address as well. When the authentication
@@ -680,8 +575,8 @@ typedef struct {
      use. The `completion' must be called after the public key has been
      verified. */
   void (*verify_public_key)(SilcClient client, SilcClientConnection conn,
-                           SilcSocketType conn_type, unsigned char *pk,
-                           SilcUInt32 pk_len, SilcSKEPKType pk_type,
+                           SilcConnectionType conn_type,
+                           SilcPublicKey public_key,
                            SilcVerifyPublicKey completion, void *context);
 
   /* Ask (interact, that is) a passphrase from user. The passphrase is
@@ -691,27 +586,17 @@ typedef struct {
   void (*ask_passphrase)(SilcClient client, SilcClientConnection conn,
                         SilcAskPassphrase completion, void *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). */
-  void (*failure)(SilcClient client, SilcClientConnection conn,
-                 SilcProtocol protocol, void *failure);
-
-  /* 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. */
-  bool (*key_agreement)(SilcClient client, SilcClientConnection conn,
-                       SilcClientEntry client_entry, const char *hostname,
-                       SilcUInt16 port, SilcKeyAgreementCallback *completion,
-                       void **context);
+  /* Called to indicate that incoming key agreement request has been
+     received.  If the application wants to perform key agreement it may
+     call silc_client_perform_key_agreement to initiate key agreementn or
+     silc_client_send_key_agreement to provide connection point to the
+     remote client in case the `hostname' is NULL.  If key agreement is
+     not desired this request can be ignored.  The `protocol' is either
+     value 0 for TCP or value 1 for UDP. */
+  void (*key_agreement)(SilcClient client, SilcClientConnection conn,
+                       SilcClientEntry client_entry,
+                       const char *hostname, SilcUInt16 protocol,
+                       SilcUInt16 port);
 
   /* Notifies application that file transfer protocol session is being
      requested by the remote client indicated by the `client_entry' from
@@ -722,26 +607,6 @@ typedef struct {
   void (*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. */
-  void (*detach)(SilcClient client, SilcClientConnection conn,
-                const unsigned char *detach_data,
-                SilcUInt32 detach_data_len);
 } SilcClientOperations;
 /***/
 
@@ -779,15 +644,12 @@ typedef void (*SilcNicknameFormatParse)(const char *nickname,
  * SOURCE
  */
 typedef struct {
-  /* Number of maximum tasks the client library's scheduler can handle.
-     If set to zero, the default value will be used (200). For WIN32
-     systems this should be set to 64 as it is the hard limit dictated
-     by the WIN32. */
-  int task_max;
-
-  /* Rekey timeout in seconds. The client will perform rekey in this
-     time interval. If set to zero, the default value will be used. */
-  unsigned int rekey_secs;
+  /* If this boolean is set to TRUE then the client library will use
+     threads.  Any of the callback functions in the SilcClientOperations
+     and other callbacks may be called at any time in a thread.  The
+     application may need to employ appropriate concurrency control
+     in the callbacks to protect application specific data. */
+  SilcBool threads;
 
   /* Connection authentication method request timeout. If server does not
      reply back the current authentication method when we've requested it
@@ -833,7 +695,7 @@ typedef struct {
      is employed only if the library will receive a nickname that is
      already saved in the cache. It is recommended to leave this to FALSE
      value. */
-  bool nickname_force_format;
+  SilcBool nickname_force_format;
 
   /* A callback function provided by the application for the library to
      parse the nickname from the formatted nickname string. Even though
@@ -851,12 +713,12 @@ typedef struct {
      If your application does not support Requested Attributes or you do
      not want to use them set this to TRUE.  See SilcAttribute and
      silc_client_attribute_add for more information on attributes. */
-  bool ignore_requested_attributes;
+  SilcBool ignore_requested_attributes;
 
   /* If this is set to TRUE, the silcclient library will not register and
      deregister the cipher, pkcs, hash and hmac algorithms. The application
      itself will need to handle that. */
-  bool dont_register_crypto_library;
+  SilcBool dont_register_crypto_library;
 
 } SilcClientParams;
 /***/
@@ -908,7 +770,9 @@ void silc_client_free(SilcClient client);
  *
  * SYNOPSIS
  *
- *    bool silc_client_init(SilcClient client);
+ *    SilcBool silc_client_init(SilcClient client, const char *username,
+ *                              const char *hostname, const char *realname,
+ *                              SilcClientRunning running, void *context);
  *
  * DESCRIPTION
  *
@@ -916,8 +780,20 @@ void silc_client_free(SilcClient client);
  *    the client ready to be run. One must call silc_client_run to run the
  *    client. Returns FALSE if error occurred, TRUE otherwise.
  *
+ *    The `username', `hostname' and `realname' strings must be given and
+ *    they must be UTF-8 encoded.  The `username' is the client's username
+ *    in the operating system, `hostname' is the client's host name and
+ *    the `realname' is the user's real name.
+ *
+ *    The `running' callback is called after the client is running after
+ *    silc_client_run or silc_client_run_one has been called.  Application
+ *    may start using the Client library API after that.  Setting the
+ *    callback is optional, but recommended.
+ *
  ***/
-bool silc_client_init(SilcClient client);
+SilcBool silc_client_init(SilcClient client, const char *username,
+                         const char *hostname, const char *realname,
+                         SilcClientRunning running, void *context);
 
 /****f* silcclient/SilcClientAPI/silc_client_run
  *
@@ -927,8 +803,8 @@ bool silc_client_init(SilcClient client);
  *
  * DESCRIPTION
  *
- *    Runs the client. This starts the scheduler from the utility library.
- *    When this functions returns the execution of the appliation is over.
+ *    Runs the client.  This starts the scheduler from the utility library.
+ *    When this functions returns the execution of the application is over.
  *    The client must be initialized before calling this.
  *
  ***/
@@ -953,23 +829,32 @@ void silc_client_run(SilcClient client);
  ***/
 void silc_client_run_one(SilcClient client);
 
+
 /****f* silcclient/SilcClientAPI/silc_client_stop
  *
  * SYNOPSIS
  *
- *    void silc_client_stop(SilcClient client);
+ *    void silc_client_stop(SilcClient client, SilcClientStopped stopped,
+ *                          void *context);
  *
  * DESCRIPTION
  *
  *    Stops the client. This is called to stop the client and thus to stop
  *    the program.  The client context must be freed with the silc_client_free
- *    function.
+ *    function.  All connections that exist in this client must be closed
+ *    before calling this function.  Connections can be closed by calling
+ *    silc_client_close_connection.
+ *
+ *    The `stopped' will be called once the client and all connections have
+ *    finished.  The client may be freed after that.  Note that the `stopped'
+ *    won't be called before all connections have finished.  Setting the
+ *    callback is optional.
  *
  ***/
-void silc_client_stop(SilcClient client);
-
+void silc_client_stop(SilcClient client, SilcClientStopped stopped,
+                     void *context);
 
-/* Connecting functions (client.c) */
+/* Connecting functions */
 
 /****s* silcclient/SilcClientAPI/SilcClientConnectionParams
  *
@@ -980,26 +865,90 @@ void silc_client_stop(SilcClient client);
  * DESCRIPTION
  *
  *    Client connection parameters.  This can be filled by the application
- *    and given as argument to silc_client_connect_to_server or to
- *    silc_client_add_connection.
+ *    and given as argument to silc_client_connect_to_server,
+ *    silc_client_connect_to_client, silc_client_key_exchange or
+ *    silc_client_send_key_agreement.
  *
  * SOURCE
  */
 typedef struct {
-  /* The SILC session detachment data that was returned by `detach' client
-     operation when the application detached from the network.  Application
-     is responsible of saving the data and giving it as argument here
-     for resuming the session in the SILC network.
-
-     If this is provided here 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. */
+  /* If this is provided the user's nickname in the network will be the
+     string given here.  If it is given, it must be UTF-8 encoded.  If this
+     string is not given, the user's username by default is used as nickname.
+     The nickname may later be changed by using NICK command.  The maximum
+     length for the nickname string is 128 bytes. */
+  char *nickname;
+
+  /* If this key repository pointer is non-NULL then public key received in
+     the key exchange protocol will be verified from this repository.  If
+     this is not provided then the `verify_public_key' client operation will
+     be called back to application.  If the boolean `verify_notfound' is set
+     to TRUE then the `verify_public_key' client operation will be called
+     in case the public key is not found in `repository'.  Only public keys
+     added with at least SILC_SKR_USAGE_KEY_AGREEMENT in the repository will
+     be checked, other keys will be ignored. */
+  SilcSKR repository;
+  SilcBool verify_notfound;
+
+  /* Authentication data.  Application may set here the authentication data
+     and authentication method to be used in connecting.  If `auth_set'
+     boolean is TRUE then authentication data is provided by application.
+     If the authentication method is public key authentication then the key
+     pair given as argument when connecting will be used and `auth' field
+     is NULL.  If it is passphrase authentication, it can be provided in
+     `auth' and `auth_len' fields.  If `auth_set' is FALSE
+     the `get_auth_method' client operation will be called to get the
+     authentication method and data from application. */
+  SilcBool auth_set;
+  SilcAuthMethod auth_method;
+  void *auth;
+  SilcUInt32 auth_len;
+
+  /* If this boolean is set to TRUE then the connection will use UDP instead
+     of TCP.  If UDP is set the also the next `local_ip' and `local_port'
+     must be set. */
+  SilcBool udp;
+
+  /* The `local_ip' specifies the local IP address used with the connection.
+     It must be non-NULL if `udp' boolean is TRUE.  If the `local_port' is
+     non-zero it will be used as local port with UDP connection.  The remote
+     host will also send packets to the specified address and port.  If the
+     `bind_ip' is non-NULL a listener is bound to that address instead of
+     `local_ip'. */
+  char *local_ip;
+  char *bind_ip;
+  int local_port;
+
+  /* If this boolean is set to TRUE then the key exchange is done with
+     perfect forward secrecy. */
+  SilcBool pfs;
+
+  /* If this boolean is set to TRUE then connection authentication protocol
+     is not performed during connecting.  Only key exchange protocol is
+     performed.  This usually must be set to TRUE when connecting to another
+     client, but must be FALSE with server connections. */
+  SilcBool no_authentication;
+
+  /* The SILC session detachment data that was returned in the `command_reply'
+     client operation for SILC_COMMAND_DETACH command.  If this is provided
+     here the client library will attempt to resume the session in the network.
+     After the connection is created and the session has been resumed the
+     client will receive SILC_COMMAND_NICK command_reply for the client's
+     nickname in the network and SILC_COMMAND_JOIN command reply for all the
+     channels that the client has joined in the network.  It may also receive
+     SILC_COMMAND_UMODE command reply to set user's mode on the network. */
   unsigned char *detach_data;
   SilcUInt32 detach_data_len;
 
+  /* Connection timeout.  If non-zero, the connection will timeout unless
+     the SILC connection is completed in the specified amount of time. */
+  SilcUInt32 timeout_secs;
+
+  /* Rekey timeout in seconds.  The client will perform rekey in this
+     time interval.  If set to zero, the default value will be used
+     (3600 seconds, 1 hour). */
+  unsigned int rekey_secs;
+
 } SilcClientConnectionParams;
 /***/
 
@@ -1007,136 +956,159 @@ typedef struct {
  *
  * SYNOPSIS
  *
- *    int silc_client_connect_to_server(SilcClient client,
- *                                      SilcClientConnectionParams *params,
- *                                      int port, char *host, void *context);
+ *    SilcAsyncOperation
+ *    silc_client_connect_to_server(SilcClient client,
+ *                                  SilcClientConnectionParams *params,
+ *                                  SilcPublicKey public_key,
+ *                                  char *remote_host, int port,
+ *                                  SilcClientConnectCallback callback,
+ *                                  void *context);
  *
  * DESCRIPTION
  *
- *    Connects to remote server. This is the main routine used to connect
- *    to SILC server. Returns -1 on error and the created socket otherwise.
- *    The `context' is user context that is saved into the SilcClientConnection
- *    that is created after the connection is created. Note that application
- *    may handle the connecting process outside the library. If this is the
- *    case then this function is not used at all. When the connecting is
- *    done the `connect' client operation is called, and the `context' is
- *    accessible with conn->context, conn being SilcClientConnection.
- *    If the `params' is provided they are used by the routine.
- *
- ***/
-int silc_client_connect_to_server(SilcClient client,
-                                 SilcClientConnectionParams *params,
-                                 int port, char *host, void *context);
-
-/****f* silcclient/SilcClientAPI/silc_client_add_connection
- *
- * SYNOPSIS
+ *    Connects to remote server `remote_host' at port `port'.  This function
+ *    can be used to create connection to remote SILC server and start
+ *    SILC session in the SILC network.  The `params' may be provided
+ *    to provide various connection parameters.  The `public_key' and the
+ *    `private_key' is your identity used in this connection.  When
+ *    authentication method is based on digital signatures, this key pair
+ *    will be used.  The `callback' with `context' will be called after the
+ *    connection has been created.  It will also be called later when remote
+ *    host disconnects.
  *
+ *    If application wishes to create the network connection itself, use
+ *    the silc_client_key_exchange after creating the connection to start
+ *    key exchange and authentication with the server.
  *
- *    SilcClientConnection
- *    silc_client_add_connection(SilcClient client,
- *                               SilcClientConnectionParams *params,
- *                               char *hostname, int port, void *context);
- *
- * DESCRIPTION
- *
- *    Allocates and adds new connection to the client. This adds the allocated
- *    connection to the connection table and returns a pointer to it. A client
- *    can have multiple connections to multiple servers. Every connection must
- *    be added to the client using this function. User data `context' may
- *    be sent as argument.  If the `params' is provided they are used by
- *    the routine.
- *
- * NOTES
- *
- *    This function is normally used only if the application performed
- *    the connecting outside the library, and did not called the
- *    silc_client_connect_to_server function at all. The library
- *    however may use this internally.
+ *    Returns SilcAsyncOperation which can be used to cancel the connecting,
+ *    or NULL on error.  Note that the returned pointer becomes invalid
+ *    after the `callback' is called.
  *
  ***/
-SilcClientConnection
-silc_client_add_connection(SilcClient client,
-                          SilcClientConnectionParams *params,
-                          char *hostname, int port, void *context);
+SilcAsyncOperation
+silc_client_connect_to_server(SilcClient client,
+                             SilcClientConnectionParams *params,
+                             SilcPublicKey public_key,
+                             SilcPrivateKey private_key,
+                             char *remote_host, int port,
+                             SilcClientConnectCallback callback,
+                             void *context);
 
-/****f* silcclient/SilcClientAPI/silc_client_del_connection
+/****f* silcclient/SilcClientAPI/silc_client_connect_to_client
  *
  * SYNOPSIS
  *
- *    void silc_client_del_connection(SilcClient client,
- *                                    SilcClientConnection conn);
+ *    SilcAsyncOperation
+ *    silc_client_connect_to_client(SilcClient client,
+ *                                  SilcClientConnectionParams *params,
+ *                                  SilcPublicKey public_key,
+ *                                  char *remote_host, int port,
+ *                                  SilcClientConnectCallback callback,
+ *                                  void *context);
  *
  * DESCRIPTION
  *
- *    Removes connection from client. Frees all memory. The library
- *    call this function automatically for all connection contexts.
- *    The application however may free the connection contexts it has
- *    allocated.
- *
- ***/
-void silc_client_del_connection(SilcClient client, SilcClientConnection conn);
-
-/****f* silcclient/SilcClientAPI/silc_client_add_socket
- *
- * SYNOPSIS
+ *    Connects to remote client `remote_host' at port `port'.  This function
+ *    can be used to create peer-to-peer connection to another SILC client,
+ *    for example, for direct conferencing, or file transfer or for other
+ *    purposes.  The `params' may be provided to provide various connection
+ *    parameters.  The `public_key' and the `private_key' is your identity
+ *    used in this connection.  The `callback' with `context' will be called
+ *    after the connection has been created.  It will also be called later
+ *    when remote host disconnects.
  *
- *    void silc_client_add_socket(SilcClient client,
- *                                SilcSocketConnection sock);
+ *    If application wishes to create the network connection itself, use
+ *    the silc_client_key_exchange after creating the connection to start
+ *    key exchange with the client.
  *
- * DESCRIPTION
- *
- *    Adds listener socket to the listener sockets table. This function is
- *    used to add socket objects that are listeners to the client.  This should
- *    not be used to add other connection objects.
+ *    Returns SilcAsyncOperation which can be used to cancel the connecting,
+ *    or NULL on error.  Note that the returned pointer becomes invalid
+ *    after the `callback' is called.
  *
  ***/
-void silc_client_add_socket(SilcClient client, SilcSocketConnection sock);
+SilcAsyncOperation
+silc_client_connect_to_client(SilcClient client,
+                             SilcClientConnectionParams *params,
+                             SilcPublicKey public_key,
+                             SilcPrivateKey private_key,
+                             char *remote_host, int port,
+                             SilcClientConnectCallback callback,
+                             void *context);
 
-/****f* silcclient/SilcClientAPI/silc_client_del_socket
+/****f* silcclient/SilcClientAPI/silc_client_key_exchange
  *
  * SYNOPSIS
  *
- *    void silc_client_del_socket(SilcClient client,
- *                                SilcSocketConnection sock);
+ *    SilcAsyncOperation
+ *    silc_client_key_exchange(SilcClient client,
+ *                             SilcClientConnectionParams *params,
+ *                             SilcPublicKey public_key,
+ *                             SilcPrivateKey private_key,
+ *                             SilcStream stream,
+ *                             SilcConnectionType conn_type,
+ *                             SilcClientConnectCallback callback,
+ *                             void *context);
  *
  * DESCRIPTION
  *
- *    Deletes listener socket from the listener sockets table.  If the
- *    application has added a socket with silc_client_add_socket it must
- *    also free it using this function.
+ *    Starts key exchange protocol and authentication protocol in the
+ *    connection indicated by `stream'.  This function can be be used to
+ *    start SILC session with remote host (usually server) when the caller
+ *    has itself created the connection, instead of calling the function
+ *    silc_client_connect_to_server or silc_client_connect_to_client.  If
+ *    one of those functions was used this function must not be called as
+ *    in that case the key exchange is performed automatically.
  *
- ***/
-void silc_client_del_socket(SilcClient client, SilcSocketConnection sock);
-
-/****f* silcclient/SilcClientAPI/silc_client_start_key_exchange
+ *    Use this function only if you have created the connection by yourself.
+ *    After creating the connection the socket must be wrapped into a
+ *    socket stream.  See silcsocketstream.h for more information.  Note that
+ *    the `stream' must have valid remote IP address (and optionally also
+ *    hostname) and port set.
  *
- * SYNOPSIS
- *
- *    void silc_client_start_key_exchange(SilcClient client,
- *                                        SilcClientConnection conn,
- *                                        int fd);
+ *    The `params' may be provided to provide various connection parameters.
+ *    The `public_key' and the `private_key' is your identity used in this
+ *    session.  The `callback' with `context' will be called after the session
+ *    has been set up.  It will also be called later when remote host
+ *    disconnects.  The `conn_type' is the type of session this is going to
+ *    be.
  *
- * DESCRIPTION
- *
- *    Start SILC Key Exchange (SKE) protocol to negotiate shared secret
- *    key material between client and server.  This function can be called
- *    directly if application is performing its own connecting and does not
- *    use the connecting provided by this library. This function is normally
- *    used only if the application performed the connecting outside the
- *    library. The library however may use this internally.  After the
- *    key exchange is performed the `connect' client operation is called.
- *
- * NOTES
+ *    Returns SilcAsyncOperation which can be used to cancel the connecting,
+ *    or NULL on error.  Note that the returned pointer becomes invalid
+ *    after the `callback' is called.
  *
- *    The silc_client_add_connection must be called before calling this
- *    function to create the SilcClientConnection context for this
- *    connection.
+ * EXAMPLE
  *
- ***/
-void silc_client_start_key_exchange(SilcClient client,
-                                   SilcClientConnection conn,
-                                   int fd);
+ *    int sock;
+ *
+ *    // Create remote connection stream.  Resolve hostname and IP also.
+ *    sock = create_connection(remote_host, port);
+ *    silc_socket_tcp_stream_create(sock, TRUE, FALSE, schedule,
+ *                                  stream_create_cb, app);
+ *
+ *    // Stream callback delivers our new SilcStream context
+ *    void stream_create_cb(SilcSocketStreamStatus status, SilcStream stream,
+ *                          void *context)
+ *    {
+ *      ...
+ *      if (status != SILC_SOCKET_OK)
+ *        error(status);
+ *
+ *      // Start key exchange
+ *      silc_client_key_exchange(client, NULL, public_key, private_key,
+ *                               stream, SILC_CONN_SERVER, connection_cb, app);
+ *      ...
+ *    }
+ *
+ ***/
+SilcAsyncOperation
+silc_client_key_exchange(SilcClient client,
+                        SilcClientConnectionParams *params,
+                        SilcPublicKey public_key,
+                        SilcPrivateKey private_key,
+                        SilcStream stream,
+                        SilcConnectionType conn_type,
+                        SilcClientConnectCallback callback,
+                        void *context);
 
 /****f* silcclient/SilcClientAPI/silc_client_close_connection
  *
@@ -1147,32 +1119,31 @@ void silc_client_start_key_exchange(SilcClient client,
  *
  * DESCRIPTION
  *
- *    Closes connection to remote end. Free's all allocated data except
- *    for some information such as nickname etc. that are valid at all time.
- *    Usually application does not need to directly call this, except
- *    when explicitly closing the connection, or if an error occurs
- *    during connection to server (see 'connect' client operation for
- *    more information).
+ *    Closes the remote connection `conn'.  The `conn' will become invalid
+ *    after this call.  Usually this function is called only when explicitly
+ *    closing connection for example in case of error, or when the remote
+ *    connection was created by the application or when the remote is client
+ *    connection.  Server connections are usually closed by sending QUIT
+ *    command to the server.  However, this call may also be used.
  *
  ***/
 void silc_client_close_connection(SilcClient client,
                                  SilcClientConnection conn);
 
-
 /* Message sending functions (client_channel.c and client_prvmsg.c) */
 
 /****f* silcclient/SilcClientAPI/silc_client_send_channel_message
  *
  * SYNOPSIS
  *
- *    bool silc_client_send_channel_message(SilcClient client,
- *                                          SilcClientConnection conn,
- *                                          SilcChannelEntry channel,
- *                                          SilcChannelPrivateKey key,
- *                                          SilcMessageFlags flags,
- *                                          unsigned char *data,
- *                                          SilcUInt32 data_len,
- *                                          bool_force_send);
+ *    SilcBool silc_client_send_channel_message(SilcClient client,
+ *                                              SilcClientConnection conn,
+ *                                              SilcChannelEntry channel,
+ *                                              SilcChannelPrivateKey key,
+ *                                              SilcMessageFlags flags,
+ *                                              SilcHash hash,
+ *                                              unsigned char *data,
+ *                                              SilcUInt32 data_len);
  *
  * DESCRIPTION
  *
@@ -1180,8 +1151,7 @@ void silc_client_close_connection(SilcClient client,
  *    differently from "normal" packets. SILC header of the packet is
  *    encrypted with the next receiver's key and the rest of the packet is
  *    encrypted with the channel specific key. Padding and HMAC is computed
- *    with the next receiver's key. The `data' is the channel message. If
- *    the `force_send' is TRUE then the packet is sent immediately.
+ *    with the next receiver's key. The `data' is the channel message.
  *
  *    If `key' is provided then that private key is used to encrypt the
  *    channel message.  If it is not provided, private keys has not been
@@ -1194,527 +1164,62 @@ void silc_client_close_connection(SilcClient client,
  *
  *    Returns TRUE if the message was sent, and FALSE if error occurred or
  *    the sending is not allowed due to channel modes (like sending is
- *    blocked).
+ *    blocked).  This function is thread safe and private messages can be
+ *    sent from multiple threads.
  *
  ***/
-bool silc_client_send_channel_message(SilcClient client,
-                                     SilcClientConnection conn,
-                                     SilcChannelEntry channel,
-                                     SilcChannelPrivateKey key,
-                                     SilcMessageFlags flags,
-                                     unsigned char *data,
-                                     SilcUInt32 data_len,
-                                     bool force_send);
+SilcBool silc_client_send_channel_message(SilcClient client,
+                                         SilcClientConnection conn,
+                                         SilcChannelEntry channel,
+                                         SilcChannelPrivateKey key,
+                                         SilcMessageFlags flags,
+                                         SilcHash hash,
+                                         unsigned char *data,
+                                         SilcUInt32 data_len);
+
+/* Block process until channel message from `channel' is received */
+SilcBool
+silc_client_receive_channel_message(SilcClient client,
+                                   SilcClientConnection conn,
+                                   SilcChannelEntry channel,
+                                   SilcClientEntry *return_sender,
+                                   SilcMessageFlags *return_flags,
+                                   const unsigned char **return_message,
+                                   SilcUInt32 *return_message_len);
 
 /****f* silcclient/SilcClientAPI/silc_client_send_private_message
  *
  * SYNOPSIS
  *
- *    bool silc_client_send_private_message(SilcClient client,
- *                                          SilcClientConnection conn,
- *                                          SilcClientEntry client_entry,
- *                                          SilcMessageFlags flags,
- *                                          unsigned char *data,
- *                                          SilcUInt32 data_len,
- *                                          bool force_send);
+ *    SilcBool silc_client_send_private_message(SilcClient client,
+ *                                              SilcClientConnection conn,
+ *                                              SilcClientEntry client_entry,
+ *                                              SilcMessageFlags flags,
+ *                                              SilcHash hash,
+ *                                              unsigned char *data,
+ *                                              SilcUInt32 data_len);
  *
  * DESCRIPTION
  *
  *    Sends private message to remote client. If private message key has
  *    not been set with this client then the message will be encrypted using
- *    normal session keys. Private messages are special packets in SILC
- *    network hence we need this own function for them. This is similar
- *    to silc_client_packet_send_to_channel except that we send private
- *    message. The `data' is the private message. If the `force_send' is
- *    TRUE the packet is sent immediately.
- *
- *    If the `flags' includes SILC_MESSAGE_FLAG_SIGNED the message will be
- *    digitally signed with the SILC key pair.
+ *    normal session keys.  If the `flags' includes SILC_MESSAGE_FLAG_SIGNED
+ *    the message will be digitally signed with the SILC key pair.  In this
+ *    case the caller must also provide the `hash' pointer.  By default, the
+ *    hash function must be SHA-1.
  *
  *    Returns TRUE if the message was sent, and FALSE if error occurred.
+ *    This function is thread safe and private messages can be sent from
+ *    multiple threads.
  *
  ***/
-bool silc_client_send_private_message(SilcClient client,
-                                     SilcClientConnection conn,
-                                     SilcClientEntry client_entry,
-                                     SilcMessageFlags flags,
-                                     unsigned char *data,
-                                     SilcUInt32 data_len,
-                                     bool force_send);
-
-
-/* Client and Channel entry retrieval (idlist.c) */
-
-/****f* silcclient/SilcClientAPI/SilcGetClientCallback
- *
- * SYNOPSIS
- *
- *    typedef void (*SilcGetClientCallback)(SilcClient client,
- *                                          SilcClientConnection conn,
- *                                          SilcClientEntry *clients,
- *                                          SilcUInt32 clients_count,
- *                                          void *context);
- *
- * DESCRIPTION
- *
- *    Callback function given to the silc_client_get_client function. The
- *    found entries are allocated into the `clients' array. The array must
- *    not be freed by the receiver, the library will free it later. If the
- *    `clients' is NULL, no such clients exist in the SILC Network.
- *
- ***/
-typedef void (*SilcGetClientCallback)(SilcClient client,
-                                     SilcClientConnection conn,
-                                     SilcClientEntry *clients,
-                                     SilcUInt32 clients_count,
-                                     void *context);
-
-/****f* silcclient/SilcClientAPI/silc_client_get_clients
- *
- * SYNOPSIS
- *
- *    void silc_client_get_clients(SilcClient client,
- *                                 SilcClientConnection conn,
- *                                 const char *nickname,
- *                                 const char *server,
- *                                 SilcGetClientCallback completion,
- *                                 void *context);
- *
- * DESCRIPTION
- *
- *    Finds client entry or entries by the `nickname' and `server'. The
- *    completion callback will be called when the client entries has been
- *    found.  After the server returns the client information it is cached
- *    and can be accesses locally at a later time.  The resolving is done
- *    with IDENTIFY command.  The `server' may be NULL.
- *
- * NOTES
- *
- *    NOTE: This function is always asynchronous and resolves the client
- *    information from the server. Thus, if you already know the client
- *    information then use the silc_client_get_client_by_id function to
- *    get the client entry since this function may be very slow and should
- *    be used only to initially get the client entries.
- *
- *    Since this routine resolves with IDENTIFY command only the relevant
- *    information (user's nickname and username) is resolved.  For example,
- *    user's real name, channel list and others are not resolved.  Caller
- *    can/must resolve those separately if they are needed (for example,
- *    with silc_client_get_client_by_id_resolve).
- *
- ***/
-void silc_client_get_clients(SilcClient client,
-                            SilcClientConnection conn,
-                            const char *nickname,
-                            const char *server,
-                            SilcGetClientCallback completion,
-                            void *context);
-
-/****f* silcclient/SilcClientAPI/silc_client_get_clients_whois
- *
- * SYNOPSIS
- *
- *    void silc_client_get_clients_whois(SilcClient client,
- *                                       SilcClientConnection conn,
- *                                       const char *nickname,
- *                                       const char *server,
- *                                       SilcBuffer attributes,
- *                                       SilcGetClientCallback completion,
- *                                       void *context);
- *
- * DESCRIPTION
- *
- *    Finds client entry or entries by the `nickname' and `server'. The
- *    completion callback will be called when the client entries has been
- *    found.  After the server returns the client information it is cached
- *    and can be accesses locally at a later time.  The resolving is done
- *    with WHOIS command.  The `server' may be NULL.
- *
- *    If the `attributes' is non-NULL then the buffer includes Requested
- *    Attributes which can be used to fetch very detailed information
- *    about the user. If it is NULL then only normal WHOIS query is
- *    made (for more information about attributes see SilcAttribute).
- *    Caller may create the `attributes' with silc_client_attributes_request
- *    function.
- *
- * NOTES
- *
- *    The resolving is done with WHOIS command. For this reason this
- *    command may take a long time because it resolves detailed user
- *    information.
- *
- ***/
-void silc_client_get_clients_whois(SilcClient client,
-                                  SilcClientConnection conn,
-                                  const char *nickname,
-                                  const char *server,
-                                  SilcBuffer attributes,
-                                  SilcGetClientCallback completion,
-                                  void *context);
-
-/****f* silcclient/SilcClientAPI/silc_client_get_clients_local
- *
- * SYNOPSIS
- *
- *    SilcClientEntry *silc_client_get_clients_local(SilcClient client,
- *                                                   SilcClientConnection conn,
- *                                                   const char *nickname,
- *                                                   const char *format,
- *                                                   SilcUInt32 *clients_count);
- *
- * DESCRIPTION
- *
- *    Same as silc_client_get_clients function but does not resolve anything
- *    from the server. This checks local cache and returns all matching
- *    clients from the local cache. If none was found this returns NULL.
- *    The `nickname' is the real nickname of the client, and the `format'
- *    is the formatted nickname to find exact match from multiple found
- *    entries. The format must be same as given in the SilcClientParams
- *    structure to the client library. If the `format' is NULL all found
- *    clients by `nickname' are returned. The caller must return the
- *    returned array.
- *
- ***/
-SilcClientEntry *silc_client_get_clients_local(SilcClient client,
-                                              SilcClientConnection conn,
-                                              const char *nickname,
-                                              const char *format,
-                                              SilcUInt32 *clients_count);
-
-/****f* silcclient/SilcClientAPI/silc_client_get_clients_by_channel
- *
- * SYNOPSIS
- *
- *    void silc_client_get_clients_by_channel(SilcClient client,
- *                                            SilcClientConnection conn,
- *                                            SilcChannelEntry channel,
- *                                            SilcGetClientCallback completion,
- *                                            void *context);
- *
- * DESCRIPTION
- *
- *    Gets client entries by the channel indicated by `channel'. Thus,
- *    it resovles the users currently on that channel. If all users are
- *    already resolved this returns the users from the channel. If the
- *    users are resolved only partially this resolves the complete user
- *    information. If no users are resolved on this channel at all, this
- *    calls USERS command to resolve all users on the channel. The `completion'
- *    will be called after the entries are available. When server returns
- *    the client information it will be cached and can be accessed locally
- *    at a later time.
- *
- *    This function can be used for example in SILC_COMMAND_JOIN command
- *    reply handling in application to resolve users on that channel.  It
- *    also can be used after calling silc_client_get_channel_resolve to
- *    resolve users on that channel.
- *
- * NOTES
- *
- *    The resolving is done with WHOIS command. For this reason this
- *    command may take a long time because it resolves detailed user
- *    information.
- *
- ***/
-void silc_client_get_clients_by_channel(SilcClient client,
-                                       SilcClientConnection conn,
-                                       SilcChannelEntry channel,
-                                       SilcGetClientCallback completion,
-                                       void *context);
-
-/****f* silcclient/SilcClientAPI/silc_client_get_clients_by_list
- *
- * SYNOPSIS
- *
- *    void silc_client_get_clients_by_list(SilcClient client,
- *                                         SilcClientConnection conn,
- *                                         SilcUInt32 list_count,
- *                                         SilcBuffer client_id_list,
- *                                         SilcGetClientCallback completion,
- *                                         void *context);
- *
- * DESCRIPTION
- *
- *    Gets client entries by the list of client ID's `client_id_list'. This
- *    always resolves those client ID's it does not know yet from the server
- *    so this function might take a while. The `client_id_list' is a list
- *    of ID Payloads added one after other.  JOIN command reply and USERS
- *    command reply for example returns this sort of list. The `completion'
- *    will be called after the entries are available. When server returns
- *    the client information it will be cached and can be accessed locally
- *    at a later time.
- *
- * NOTES
- *
- *    The resolving is done with IDENTIFY command. This means that only
- *    the relevant information of user (it's nickname and username) is
- *    resolved. For example, user's real name, channel lists and others
- *    are not resolved. Caller can/must resolve those separately if they
- *    are needed (for example, with silc_client_get_client_by_id_resolve).
- *
- ***/
-void silc_client_get_clients_by_list(SilcClient client,
-                                    SilcClientConnection conn,
-                                    SilcUInt32 list_count,
-                                    SilcBuffer client_id_list,
-                                    SilcGetClientCallback completion,
-                                    void *context);
-
-/****f* silcclient/SilcClientAPI/silc_client_get_client_by_id
- *
- * SYNOPSIS
- *
- *    SilcClientEntry silc_client_get_client_by_id(SilcClient client,
- *                                                 SilcClientConnection conn,
- *                                                 SilcClientID *client_id);
- *
- * DESCRIPTION
- *
- *    Find entry for client by the client's ID. Returns the entry or NULL
- *    if the entry was not found.  This checks the local cache and does
- *    not resolve anything from server.
- *
- ***/
-SilcClientEntry silc_client_get_client_by_id(SilcClient client,
-                                            SilcClientConnection conn,
-                                            SilcClientID *client_id);
-
-/****f* silcclient/SilcClientAPI/silc_client_get_client_by_id_resolve
- *
- * SYNOPSIS
- *
- *    void
- *    silc_client_get_client_by_id_resolve(SilcClient client,
- *                                         SilcClientConnection conn,
- *                                         SilcClientID *client_id,
- *                                         SilcBuffer attributes,
- *                                         SilcGetClientCallback completion,
- *                                         void *context);
- *
- * DESCRIPTION
- *
- *    Same as silc_client_get_client_by_id but will always resolve the
- *    information from the server. Use this only if you know that you
- *    do not have the entry and the only thing you know about the client
- *    is its ID. When server returns the client information it will be
- *    cache and can be accessed locally at a later time. The resolving
- *    is done by sending WHOIS command.
- *
- *    If the `attributes' is non-NULL then the buffer includes Requested
- *    Attributes which can be used to fetch very detailed information
- *    about the user. If it is NULL then only normal WHOIS query is
- *    made (for more information about attributes see SilcAttribute).
- *    Caller may create the `attributes' with silc_client_attributes_request
- *    function.
- *
- ***/
-void silc_client_get_client_by_id_resolve(SilcClient client,
+SilcBool silc_client_send_private_message(SilcClient client,
                                          SilcClientConnection conn,
-                                         SilcClientID *client_id,
-                                         SilcBuffer attributes,
-                                         SilcGetClientCallback completion,
-                                         void *context);
-
-/****f* silcclient/SilcClientAPI/silc_client_del_client
- *
- * SYNOPSIS
- *
- *    bool silc_client_del_client(SilcClient client, SilcClientConnection conn,
- *                                SilcClientEntry client_entry)
- *
- * DESCRIPTION
- *
- *    Removes client from local cache by the client entry indicated by
- *    the `client_entry'.  Returns TRUE if the deletion were successful.
- *
- ***/
-bool silc_client_del_client(SilcClient client, SilcClientConnection conn,
-                           SilcClientEntry client_entry);
-
-/****f* silcclient/SilcClientAPI/SilcGetChannelCallback
- *
- * SYNOPSIS
- *
- *    typedef void (*SilcGetChannelCallback)(SilcClient client,
- *                                           SilcClientConnection conn,
- *                                           SilcChannelEntry *channels,
- *                                           SilcUInt32 channels_count,
- *                                           void *context);
- *
- * DESCRIPTION
- *
- *    Callback function given to the silc_client_get_channel_* functions.
- *    The found entries are allocated into the `channels' array. The array
- *    must not be freed by the receiver, the library will free it later.
- *    If the `channel' is NULL, no such channel exist in the SILC Network.
- *
- ***/
-typedef void (*SilcGetChannelCallback)(SilcClient client,
-                                      SilcClientConnection conn,
-                                      SilcChannelEntry *channels,
-                                      SilcUInt32 channels_count,
-                                      void *context);
-
-/****f* silcclient/SilcClientAPI/silc_client_get_channel
- *
- * SYNOPSIS
- *
- *    SilcChannelEntry silc_client_get_channel(SilcClient client,
- *                                             SilcClientConnection conn,
- *                                             char *channel_name);
- *
- * DESCRIPTION
- *
- *    Finds entry for channel by the channel name. Returns the entry or NULL
- *    if the entry was not found. It is found only if the client is joined
- *    to the channel.  Use silc_client_get_channel_resolve or
- *    silc_client_get_channel_by_id_resolve to resolve channel that client
- *    is not joined.
- *
- ***/
-SilcChannelEntry silc_client_get_channel(SilcClient client,
-                                        SilcClientConnection conn,
-                                        char *channel_name);
-
-/****f* silcclient/SilcClientAPI/silc_client_get_channel_resolve
- *
- * SYNOPSIS
- *
- *    void silc_client_get_channel_resolve(SilcClient client,
- *                                         SilcClientConnection conn,
- *                                         char *channel_name,
- *                                         SilcGetChannelCallback completion,
- *                                         void *context);
- *
- * DESCRIPTION
- *
- *    Resolves entry for channel by the channel name from the server.
- *    The resolving is done with IDENTIFY command. Note that users on
- *    the channel are not resolved at the same time. Use for example
- *    silc_client_get_clients_by_channel to resolve all users on a channel.
- *
- ***/
-void silc_client_get_channel_resolve(SilcClient client,
-                                    SilcClientConnection conn,
-                                    char *channel_name,
-                                    SilcGetChannelCallback completion,
-                                    void *context);
-
-/****f* silcclient/SilcClientAPI/silc_client_get_channel_by_id
- *
- * SYNOPSIS
- *
- *    SilcChannelEntry
- *    silc_client_get_channel_by_id(SilcClient client,
- *                                  SilcClientConnection conn,
- *                                  SilcChannelID *channel_id);
- *
- * DESCRIPTION
- *
- *    Finds channel entry by the channel ID. Returns the entry or NULL
- *    if the entry was not found.  This checks the local cache and does
- *    not resolve anything from server.
- *
- ***/
-SilcChannelEntry silc_client_get_channel_by_id(SilcClient client,
-                                              SilcClientConnection conn,
-                                              SilcChannelID *channel_id);
-
-/****f* silcclient/SilcClientAPI/silc_client_get_channel_by_id_resolve
- *
- * SYNOPSIS
- *
- *    void
- *    silc_client_get_channel_by_id_resolve(SilcClient client,
- *                                          SilcClientConnection conn,
- *                                          SilcChannelID *channel_id,
- *                                          SilcGetClientCallback completion,
- *                                          void *context);
- *
- * DESCRIPTION
- *
- *    Resolves the channel information (its name mainly) from the server
- *    by the `channel_id'. Use this only if you know that you do not have
- *    the entry cached locally. The resolving is done with IDENTIFY command.
- *
- *    Note that users on the channel are not resolved at the same time.
- *    Use for example silc_client_get_clients_by_channel to resolve all
- *    users on a channel.
- *
- ***/
-void silc_client_get_channel_by_id_resolve(SilcClient client,
-                                          SilcClientConnection conn,
-                                          SilcChannelID *channel_id,
-                                          SilcGetChannelCallback completion,
-                                          void *context);
-
-/****f* silcclient/SilcClientAPI/silc_client_del_channel
- *
- * SYNOPSIS
- *
- *    bool silc_client_del_channel(SilcClient client,
- *                                 SilcClientConnection conn,
- *                                 SilcChannelEntry channel)
- *
- * DESCRIPTION
- *
- *    Removes channel from local cache by the channel entry indicated by
- *    the `channel'.  Returns TRUE if the deletion were successful.
- *
- ***/
-bool silc_client_del_channel(SilcClient client, SilcClientConnection conn,
-                            SilcChannelEntry channel);
-
-/****f* silcclient/SilcClientAPI/silc_client_get_server
- *
- * SYNOPSIS
- *
- *    SilcServerEntry silc_client_get_server(SilcClient client,
- *                                           SilcClientConnection conn,
- *                                           char *server_name)
- *
- * DESCRIPTION
- *
- *    Finds entry for server by the server name. Returns the entry or NULL
- *    if the entry was not found.
- *
- ***/
-SilcServerEntry silc_client_get_server(SilcClient client,
-                                      SilcClientConnection conn,
-                                      char *server_name);
-
-/****f* silcclient/SilcClientAPI/silc_client_get_server_by_id
- *
- * SYNOPSIS
- *
- *    SilcServerEntry silc_client_get_server_by_id(SilcClient client,
- *                                                 SilcClientConnection conn,
- *                                                 SilcServerID *server_id);
- *
- * DESCRIPTION
- *
- *    Finds entry for server by the server ID. Returns the entry or NULL
- *    if the entry was not found.
- *
- ***/
-SilcServerEntry silc_client_get_server_by_id(SilcClient client,
-                                            SilcClientConnection conn,
-                                            SilcServerID *server_id);
-
-/****f* silcclient/SilcClientAPI/silc_client_del_server
- *
- * SYNOPSIS
- *
- *    bool silc_client_del_server(SilcClient client, SilcClientConnection conn,
- *                                SilcServerEntry server);
- *
- * DESCRIPTION
- *
- *    Removes server from local cache by the server entry indicated by
- *    the `server'.  Returns TRUE if the deletion were successful.
- *
- ***/
-bool silc_client_del_server(SilcClient client, SilcClientConnection conn,
-                           SilcServerEntry server);
+                                         SilcClientEntry client_entry,
+                                         SilcMessageFlags flags,
+                                         SilcHash hash,
+                                         unsigned char *data,
+                                         SilcUInt32 data_len);
 
 /****f* silcclient/SilcClientAPI/silc_client_on_channel
  *
@@ -1733,15 +1238,16 @@ bool silc_client_del_server(SilcClient client, SilcClientConnection conn,
 SilcChannelUser silc_client_on_channel(SilcChannelEntry channel,
                                       SilcClientEntry client_entry);
 
-/* Command management (command.c) */
+
+/* Command management */
 
 /****f* silcclient/SilcClientAPI/silc_client_command_call
  *
  * SYNOPSIS
  *
- *    bool silc_client_command_call(SilcClient client,
- *                                  SilcClientConnection conn,
- *                                  const char *command_line, ...);
+ *    SilcUInt16 silc_client_command_call(SilcClient client,
+ *                                        SilcClientConnection conn,
+ *                                        const char *command_line, ...);
  *
  * DESCRIPTION
  *
@@ -1781,45 +1287,71 @@ SilcChannelUser silc_client_on_channel(SilcChannelEntry channel,
  *    function instead.
  *
  ***/
-bool silc_client_command_call(SilcClient client,
-                             SilcClientConnection conn,
-                             const char *command_line, ...);
+SilcUInt16 silc_client_command_call(SilcClient client,
+                                   SilcClientConnection conn,
+                                   const char *command_line, ...);
+
+/* If FALSE is returned the callback will not be called again, even if there
+   is more data coming in in the command reply.  If there are other pending
+   commands waiting for the reply, they will receive it even if some other
+   command reply has returned FALSE. */
+typedef SilcBool (*SilcClientCommandReply)(SilcClient client,
+                                          SilcClientConnection conn,
+                                          SilcCommand command,
+                                          SilcStatus status,
+                                          SilcStatus error,
+                                          void *context,
+                                          va_list ap);
 
 /****f* silcclient/SilcClientAPI/silc_client_command_send
  *
  * SYNOPSIS
  *
- *    void silc_client_command_send(SilcClient client,
- *                                  SilcClientConnection conn,
- *                                  SilcCommand command, SilcUInt16 ident,
- *                                  SilcUInt32 argc, ...);
+ *    SilcUInt16 silc_client_command_send(SilcClient client,
+ *                                        SilcClientConnection conn,
+ *                                        SilcCommand command,
+ *                                        SilcClientCommandReply reply,
+ *                                        void *reply_context,
+ *                                        SilcUInt32 argc, ...);
  *
  * DESCRIPTION
  *
- *    Generic function to send any command. The arguments must be sent already
- *    encoded into correct form and in correct order. If application wants
- *    to perform the commands by itself, it can do so and send the data
+ *    Generic function to send any command.  The arguments must be given
+ *    already encoded into correct format and in correct order. If application
+ *    wants to perform the commands by itself, it can do so and send the data
  *    directly to the server using this function.  If application is using
  *    the silc_client_command_call, this function is usually not used.
- *    Note that this overriders the Client Librarys commands and sends
- *    the command packet directly to server.
- *
  *    Programmer should get familiar with the SILC protocol commands
  *    specification when using this function, as the arguments needs to
  *    be encoded as specified in the protocol.
  *
- *    The variable arguments are a pair of { type, data, data_length },
- *    and the `argc' is the number of these pairs.
+ *    The variable arguments are a set of { type, data, data_length },
+ *    and the `argc' is the number of these sets.
+ *
+ *    The `reply' callback must be provided, and it is called when the
+ *    command reply is received from the server.  Note that, when using this
+ *    function the default `command_reply' client operation will not be
+ *    called, when reply is received.  Note however that, `reply' is almost
+ *    identical with `command_reply' callback, and application may forward
+ *    the reply from `reply' to `command_reply' callback, if desired.
+ *
+ *    Returns command identifier for this sent command.  It can be used
+ *    to additionally attach to the command reply using the function
+ *    silc_client_command_pending, if needed.  Returns 0 on error,
  *
  * EXAMPLE
  *
- *    silc_client_command_send(client, conn, SILC_COMMAND_WHOIS, 0, 1,
- *                             1, nickname, strlen(nickname));
+ *    silc_client_command_send(client, conn, SILC_COMMAND_WHOIS,
+ *                             my_whois_command_reply, cmd_ctx,
+ *                             1, 1, nickname, strlen(nickname));
  *
  ***/
-void silc_client_command_send(SilcClient client, SilcClientConnection conn,
-                             SilcCommand command, SilcUInt16 ident,
-                             SilcUInt32 argc, ...);
+SilcUInt16 silc_client_command_send(SilcClient client,
+                                   SilcClientConnection conn,
+                                   SilcCommand command,
+                                   SilcClientCommandReply reply,
+                                   void *reply_context,
+                                   SilcUInt32 argc, ...);
 
 /****f* silcclient/SilcClientAPI/silc_client_command_pending
  *
@@ -1827,7 +1359,7 @@ void silc_client_command_send(SilcClient client, SilcClientConnection conn,
  *
  *    void silc_client_command_pending(SilcClientConnection conn,
  *                                     SilcCommand reply_cmd,
- *                                     SilcUInt16 ident,
+ *                                     SilcUInt16 cmd-ident,
  *                                     SilcCommandCb callback,
  *                                     void *context);
  *
@@ -1841,7 +1373,7 @@ void silc_client_command_send(SilcClient client, SilcClientConnection conn,
  *    SilcClientCommandReplyContext which includes the internals of the
  *    command reply.
  *
- *    The `ident' is a command identifier which was set for the earlier
+ *    The `cmd_ident' is a command identifier which was set for the earlier
  *    sent command.  The command reply will include the same identifier
  *    and pending command callback will be called when the reply is
  *    received with the same command identifier.  It is possible to
@@ -1872,11 +1404,11 @@ void silc_client_command_send(SilcClient client, SilcClientConnection conn,
  *                                my_ping_handler, my_ping_context);
  *
  ***/
-void silc_client_command_pending(SilcClientConnection conn,
-                                SilcCommand reply_cmd,
-                                SilcUInt16 ident,
-                                SilcCommandCb callback,
-                                void *context);
+SilcBool silc_client_command_pending(SilcClientConnection conn,
+                                    SilcCommand command,
+                                    SilcUInt16 cmd_ident,
+                                    SilcClientCommandReply reply,
+                                    void *context);
 
 
 /* Private Message key management (client_prvmsg.c) */
@@ -1885,84 +1417,79 @@ void silc_client_command_pending(SilcClientConnection conn,
  *
  * SYNOPSIS
  *
- *    bool silc_client_add_private_message_key(SilcClient client,
- *                                             SilcClientConnection conn,
- *                                             SilcClientEntry client_entry,
- *                                             const char *cipher,
- *                                             const char *hmac,
- *                                             unsigned char *key,
- *                                             SilcUInt32 key_len,
- *                                             bool generate_key,
- *                                             bool responder);
+ *    SilcBool
+ *    silc_client_add_private_message_key(SilcClient client,
+ *                                        SilcClientConnection conn,
+ *                                        SilcClientEntry client_entry,
+ *                                        const char *cipher,
+ *                                        const char *hmac,
+ *                                        unsigned char *key,
+ *                                        SilcUInt32 key_len);
  *
  * DESCRIPTION
  *
- *    Adds private message key to the client library. The key will be used to
- *    encrypt all private message between the client and the remote client
- *    indicated by the `client_entry'. If the `key' is NULL and the boolean
- *    value `generate_key' is TRUE the library will generate random key.
- *    The `key' maybe for example pre-shared-key, passphrase or similar.
- *    The `cipher' and `hmac' MAY be provided but SHOULD be NULL to assure
- *    that the requirements of the SILC protocol are met. The API, however,
- *    allows to allocate any cipher and HMAC.
+ *    Adds a static private message key to the client library.  The key
+ *    will be used to encrypt all private message between the client and
+ *    the remote client indicated by the `client_entry'.  The `key' can
+ *    be for example a pre-shared-key, passphrase or similar shared secret
+ *    string.  The `cipher' and `hmac' MAY be provided but SHOULD be NULL
+ *    to assure that the requirements of the SILC protocol are met. The
+ *    API, however, allows to allocate any cipher and HMAC.
  *
- *    If `responder' is TRUE then the sending and receiving keys will be
- *    set according the client being the receiver of the private key.  If
- *    FALSE the client is being the sender (or negotiator) of the private
- *    key.
+ *    If the private message key is added to client without first receiving
+ *    a request for it from the remote `client_entry' this function will
+ *    send the request to `client_entry'.  Note that, the actual key is
+ *    not sent to the network.
  *
  *    It is not necessary to set key for normal private message usage. If the
  *    key is not set then the private messages are encrypted using normal
- *    session keys. Setting the private key, however, increases the security.
+ *    session keys.  Setting the private key, however, increases the security.
  *
  *    Returns FALSE if the key is already set for the `client_entry', TRUE
  *    otherwise.
  *
  ***/
-bool silc_client_add_private_message_key(SilcClient client,
-                                        SilcClientConnection conn,
-                                        SilcClientEntry client_entry,
-                                        const char *cipher,
-                                        const char *hmac,
-                                        unsigned char *key,
-                                        SilcUInt32 key_len,
-                                        bool generate_key,
-                                        bool responder);
+SilcBool silc_client_add_private_message_key(SilcClient client,
+                                            SilcClientConnection conn,
+                                            SilcClientEntry client_entry,
+                                            const char *cipher,
+                                            const char *hmac,
+                                            unsigned char *key,
+                                            SilcUInt32 key_len);
 
 /****f* silcclient/SilcClientAPI/silc_client_add_private_message_key_ske
  *
  * SYNOPSIS
  *
- *    bool
+ *    SilcBool
  *    silc_client_add_private_message_key_ske(SilcClient client,
  *                                            SilcClientConnection conn,
  *                                            SilcClientEntry client_entry,
  *                                            const char *cipher,
  *                                            const char *hmac,
- *                                            SilcSKEKeyMaterial *key);
+ *                                            SilcSKEKeyMaterial key);
  *
  * DESCRIPTION
  *
  *    Same as silc_client_add_private_message_key but takes the key material
- *    from the SKE key material structure. This structure is received if
+ *    from the SKE key material structure.  This structure is received if
  *    the application uses the silc_client_send_key_agreement to negotiate
- *    the key material. The `cipher' and `hmac' SHOULD be provided as it is
+ *    the key material.  The `cipher' and `hmac' SHOULD be provided as it is
  *    negotiated also in the SKE protocol.
  *
  ***/
-bool silc_client_add_private_message_key_ske(SilcClient client,
-                                            SilcClientConnection conn,
-                                            SilcClientEntry client_entry,
-                                            const char *cipher,
-                                            const char *hmac,
-                                            SilcSKEKeyMaterial *key,
-                                            bool responder);
+SilcBool silc_client_add_private_message_key_ske(SilcClient client,
+                                                SilcClientConnection conn,
+                                                SilcClientEntry client_entry,
+                                                const char *cipher,
+                                                const char *hmac,
+                                                SilcSKEKeyMaterial key);
 
 /****f* silcclient/SilcClientAPI/silc_client_del_private_message_key
  *
  * SYNOPSIS
  *
- *    bool silc_client_del_private_message_key(SilcClient client,
+ *    SilcBool silc_client_del_private_message_key(SilcClient client,
  *                                             SilcClientConnection conn,
  *                                             SilcClientEntry client_entry);
  *
@@ -1973,9 +1500,9 @@ bool silc_client_add_private_message_key_ske(SilcClient client,
  *    client. Returns FALSE on error, TRUE otherwise.
  *
  ***/
-bool silc_client_del_private_message_key(SilcClient client,
-                                        SilcClientConnection conn,
-                                        SilcClientEntry client_entry);
+SilcBool silc_client_del_private_message_key(SilcClient client,
+                                            SilcClientConnection conn,
+                                            SilcClientEntry client_entry);
 
 /****f* silcclient/SilcClientAPI/silc_client_list_private_message_keys
  *
@@ -2002,40 +1529,6 @@ silc_client_list_private_message_keys(SilcClient client,
                                      SilcClientConnection conn,
                                      SilcUInt32 *key_count);
 
-/****f* silcclient/SilcClientAPI/silc_client_send_private_message_key_request
- *
- * SYNOPSIS
- *
- *    bool
- *    silc_client_send_private_message_key_request(SilcClient client,
- *                                               SilcClientConnection conn,
- *                                               SilcClientEntry client_entry);
- *
- * DESCRIPTION
- *
- *    This function can be used to send an private message key indicator
- *    request to the remote client indicated by 'client_entry'.  This can
- *    be used when setting a static or pre-shared private message key.
- *    The sender of this packet is the initiator and must set the 'responder'
- *    argument in silc_client_add_private_message_key function to FALSE.
- *    The receiver of this indicator request must set it to TRUE, if the
- *    receiver decides to set a private message key.  By using this
- *    function applications may automate initiator/responder setting in
- *    private message key functions, without asking from user which one is
- *    the initiator and which one is responder.
- *
- * NOTES
- *
- *    The sender of this packet must set the private message key for
- *    'client_entry' before calling this function.  The 'responder'
- *    argument MUST be set to FALSE when setting the key.
- *
- ***/
-bool
-silc_client_send_private_message_key_request(SilcClient client,
-                                            SilcClientConnection conn,
-                                            SilcClientEntry client_entry);
-
 /****f* silcclient/SilcClientAPI/silc_client_free_private_message_keys
  *
  * SYNOPSIS
@@ -2060,7 +1553,7 @@ void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys,
  *
  * SYNOPSIS
  *
- *    bool silc_client_add_channel_private_key(SilcClient client,
+ *    SilcBool silc_client_add_channel_private_key(SilcClient client,
  *                                             SilcClientConnection conn,
  *                                             SilcChannelEntry channel,
  *                                             const char *name,
@@ -2105,21 +1598,21 @@ void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys,
  *    as channel private key. However, this API allows it.
  *
  ***/
-bool silc_client_add_channel_private_key(SilcClient client,
-                                        SilcClientConnection conn,
-                                        SilcChannelEntry channel,
-                                        const char *name,
-                                        char *cipher,
-                                        char *hmac,
-                                        unsigned char *key,
-                                        SilcUInt32 key_len,
-                                        SilcChannelPrivateKey *ret_key);
+SilcBool silc_client_add_channel_private_key(SilcClient client,
+                                            SilcClientConnection conn,
+                                            SilcChannelEntry channel,
+                                            const char *name,
+                                            char *cipher,
+                                            char *hmac,
+                                            unsigned char *key,
+                                            SilcUInt32 key_len,
+                                            SilcChannelPrivateKey *ret_key);
 
 /****f* silcclient/SilcClientAPI/silc_client_del_channel_private_keys
  *
  * SYNOPSIS
  *
- *    bool silc_client_del_channel_private_keys(SilcClient client,
+ *    SilcBool silc_client_del_channel_private_keys(SilcClient client,
  *                                              SilcClientConnection conn,
  *                                              SilcChannelEntry channel);
  *
@@ -2130,15 +1623,15 @@ bool silc_client_add_channel_private_key(SilcClient client,
  *    on error, TRUE otherwise.
  *
  ***/
-bool silc_client_del_channel_private_keys(SilcClient client,
-                                         SilcClientConnection conn,
-                                         SilcChannelEntry channel);
+SilcBool silc_client_del_channel_private_keys(SilcClient client,
+                                             SilcClientConnection conn,
+                                             SilcChannelEntry channel);
 
 /****f* silcclient/SilcClientAPI/silc_client_del_channel_private_key
  *
  * SYNOPSIS
  *
- *    bool silc_client_del_channel_private_key(SilcClient client,
+ *    SilcBool silc_client_del_channel_private_key(SilcClient client,
  *                                            SilcClientConnection conn,
  *                                            SilcChannelEntry channel,
  *                                            SilcChannelPrivateKey key);
@@ -2153,50 +1646,32 @@ bool silc_client_del_channel_private_keys(SilcClient client,
  *    on error, TRUE otherwise.
  *
  ***/
-bool silc_client_del_channel_private_key(SilcClient client,
-                                        SilcClientConnection conn,
-                                        SilcChannelEntry channel,
-                                        SilcChannelPrivateKey key);
+SilcBool silc_client_del_channel_private_key(SilcClient client,
+                                            SilcClientConnection conn,
+                                            SilcChannelEntry channel,
+                                            SilcChannelPrivateKey key);
 
 /****f* silcclient/SilcClientAPI/silc_client_list_channel_private_keys
  *
  * SYNOPSIS
  *
- *    SilcChannelPrivateKey *
+ *    SilcDList
  *    silc_client_list_channel_private_keys(SilcClient client,
  *                                          SilcClientConnection conn,
- *                                          SilcChannelEntry channel,
- *                                          SilcUInt32 *key_count);
+ *                                          SilcChannelEntry channel);
  *
  * DESCRIPTION
  *
- *    Returns array (pointers) of private keys associated to the `channel'.
- *    The caller must free the array by calling the function
- *    silc_client_free_channel_private_keys. The pointers in the array may be
+ *    Returns list of private keys associated to the `channel'.  The caller
+ *    must free the returned list.  The pointers in the list may be
  *    used to delete the specific key by giving the pointer as argument to the
- *    function silc_client_del_channel_private_key.
- *
- ***/
-SilcChannelPrivateKey *
-silc_client_list_channel_private_keys(SilcClient client,
-                                     SilcClientConnection conn,
-                                     SilcChannelEntry channel,
-                                     SilcUInt32 *key_count);
-
-/****f* silcclient/SilcClientAPI/silc_client_free_channel_private_keys
- *
- * SYNOPSIS
- *
- *    void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
- *                                               SilcUInt32 key_count);
- *
- * DESCRIPTION
- *
- *    Frees the SilcChannelPrivateKey array.
+ *    function silc_client_del_channel_private_key.  Each entry in the list
+ *    is SilcChannelPrivateKey.
  *
  ***/
-void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
-                                          SilcUInt32 key_count);
+SilcDList silc_client_list_channel_private_keys(SilcClient client,
+                                               SilcClientConnection conn,
+                                               SilcChannelEntry channel);
 
 /****f* silcclient/SilcClientAPI/silc_client_current_channel_private_key
  *
@@ -2220,7 +1695,7 @@ void silc_client_current_channel_private_key(SilcClient client,
                                             SilcChannelPrivateKey key);
 
 
-/* Key Agreement routines (client_keyagr.c) */
+/* Key Agreement routines */
 
 /****f* silcclient/SilcClientAPI/silc_client_send_key_agreement
  *
@@ -2229,62 +1704,46 @@ void silc_client_current_channel_private_key(SilcClient client,
  *    void silc_client_send_key_agreement(SilcClient client,
  *                                        SilcClientConnection conn,
  *                                        SilcClientEntry client_entry,
- *                                        char *hostname,
- *                                        int port,
- *                                        SilcUInt32 timeout_secs,
+ *                                        SilcClientConnectionParams *params,
+ *                                        SilcPublicKey public_key,
+ *                                        SilcPrivateKey private_key,
  *                                        SilcKeyAgreementCallback completion,
  *                                        void *context);
  *
  * DESCRIPTION
  *
  *    Sends key agreement request to the remote client indicated by the
- *    `client_entry'. If the caller provides the `hostname' and the `port'
- *    arguments then the library will bind the client to that hostname and
- *    that port for the key agreement protocol. It also sends the `hostname'
- *    and the `port' in the key agreement packet to the remote client. This
- *    would indicate that the remote client may initiate the key agreement
- *    protocol to the `hostname' on the `port'.  If port is zero then the
- *    bound port is undefined (the operating system defines it).
- *
- *    If the `hostname' and `port' is not provided then empty key agreement
- *    packet is sent to the remote client. The remote client may reply with
- *    the same packet including its hostname and port. If the library receives
- *    the reply from the remote client the `key_agreement' client operation
- *    callback will be called to verify whether the user wants to perform the
- *    key agreement or not.
- *
- * NOTES
+ *    `client_entry'.
  *
- *    NOTE: If the application provided the `hostname' and the `port' and the
- *    remote side initiates the key agreement protocol it is not verified
- *    from the user anymore whether the protocol should be executed or not.
- *    By setting the `hostname' and `port' the user gives permission to
- *    perform the protocol (we are responder in this case).
+ *    If `params' is non-NULL and it has the `local_ip' and `local_port' set
+ *    the caller will provide the connection endpoint for the key agreement
+ *    connection.  The `bind_ip' can be used to bind to that IP instead of
+ *    `local_ip'.  If the `udp' is set to TRUE the connection will be UDP
+ *    instead of TCP.  Caller may also set the `repository', `verify_notfound'
+ *    and `timeout_secs' fields in `params'.  Other fields are ignored.
+ *    If `params' is NULL, then the `client_entry' is expected to provide
+ *    the connection endpoint for us.  It is recommended the `timeout_secs'
+ *    is specified in case the remote client does not reply anything to
+ *    the request.
  *
- *    NOTE: If the remote side decides not to initiate the key agreement
- *    or decides not to reply with the key agreement packet then we cannot
- *    perform the key agreement at all. If the key agreement protocol is
- *    performed the `completion' callback with the `context' will be called.
- *    If remote side decides to ignore the request the `completion' will be
- *    called after the specified timeout, `timeout_secs'.
+ *    The `public_key' and `private_key' is our identity in the key agreement.
  *
- *    NOTE: If the `hostname' and the `port' was not provided the `completion'
- *    will not be called at all since this does nothing more than sending
- *    a packet to the remote host.
+ *    In case we do not provide the connection endpoint, we will receive
+ *    the `key_agreement' client operation when the remote send its own
+ *    key agreement request packet.  We may then there start the key
+ *    agreement with silc_client_perform_key_agreement.  If we provided the
+ *    the connection endpoint, the client operation will not be called.
  *
- *    NOTE: There can be only one active key agreement for one client entry.
- *    Before setting new one, the old one must be finished (it is finished
- *    after calling the completion callback) or the function
- *    silc_client_abort_key_agreement must be called.
+ *    There can be only one active key agreement for `client_entry'.  Old
+ *    key agreement may be aborted by calling silc_client_abort_key_agreement.
  *
  ***/
 void silc_client_send_key_agreement(SilcClient client,
                                    SilcClientConnection conn,
                                    SilcClientEntry client_entry,
-                                   const char *hostname,
-                                   const char *bindhost,
-                                   int port,
-                                   SilcUInt32 timeout_secs,
+                                   SilcClientConnectionParams *params,
+                                   SilcPublicKey public_key,
+                                   SilcPrivateKey private_key,
                                    SilcKeyAgreementCallback completion,
                                    void *context);
 
@@ -2296,72 +1755,69 @@ void silc_client_send_key_agreement(SilcClient client,
  *    silc_client_perform_key_agreement(SilcClient client,
  *                                      SilcClientConnection conn,
  *                                      SilcClientEntry client_entry,
- *                                      char *hostname,
- *                                      int port,
+ *                                      SilcClientConnectionParams *params,
+ *                                      SilcPublicKey public_key,
+ *                                      SilcPrivateKey private_key,
+ *                                      char *hostname, int port,
  *                                      SilcKeyAgreementCallback completion,
  *                                      void *context);
  *
  * DESCRIPTION
  *
- *    Performs the actual key agreement protocol. Application may use this
- *    to initiate the key agreement protocol. This can be called for example
- *    after the application has received the `key_agreement' client operation,
- *    and did not return TRUE from it.
+ *    Performs the key agreement protocol.  Application may use this to
+ *    initiate the key agreement protocol.  Usually this is called after
+ *    receiving the `key_agreement' client operation.
  *
  *    The `hostname' is the remote hostname (or IP address) and the `port'
- *    is the remote port. The `completion' callback with the `context' will
+ *    is the remote port.  The `completion' callback with the `context' will
  *    be called after the key agreement protocol.
  *
- * NOTES
- *
- *    NOTE: If the application returns TRUE in the `key_agreement' client
- *    operation the library will automatically start the key agreement. In this
- *    case the application must not call this function. However, application
- *    may choose to just ignore the `key_agreement' client operation (and
- *    merely just print information about it on the screen) and call this
- *    function when the user whishes to do so (by, for example, giving some
- *    specific command). Thus, the API provides both, automatic and manual
- *    initiation of the key agreement. Calling this function is the manual
- *    initiation and returning TRUE in the `key_agreement' client operation
- *    is the automatic initiation.
+ *    The `params' is connection parameters and it may be used to define
+ *    the key agreement connection related parameters.  It may be NULL.
  *
  ***/
 void silc_client_perform_key_agreement(SilcClient client,
                                       SilcClientConnection conn,
                                       SilcClientEntry client_entry,
-                                      char *hostname,
-                                      int port,
+                                      SilcClientConnectionParams *params,
+                                      SilcPublicKey public_key,
+                                      SilcPrivateKey private_key,
+                                      char *hostname, int port,
                                       SilcKeyAgreementCallback completion,
                                       void *context);
 
-/****f* silcclient/SilcClientAPI/silc_client_perform_key_agreement_fd
+/****f* silcclient/SilcClientAPI/silc_client_perform_key_agreement_stream
  *
  * SYNOPSIS
  *
  *    void
- *    silc_client_perform_key_agreement_fd(SilcClient client,
- *                                         SilcClientConnection conn,
- *                                         SilcClientEntry client_entry,
- *                                         int sock,
- *                                         char *hostname,
- *                                         SilcKeyAgreementCallback completion,
- *                                         void *context);
+ *    silc_client_perform_key_agreement_stream(
+ *                                      SilcClient client,
+ *                                      SilcClientConnection conn,
+ *                                      SilcClientEntry client_entry,
+ *                                      SilcClientConnectionParams *params,
+ *                                      SilcPublicKey public_key,
+ *                                      SilcPrivateKey private_key,
+ *                                      SilcStream stream,
+ *                                      SilcKeyAgreementCallback completion,
+ *                                      void *context);
  *
  * DESCRIPTION
  *
- *    Same as above but application has created already the connection to
- *    the remote host. The `sock' is the socket to the remote connection.
- *    Application can use this function if it does not want the client library
- *    to create the connection.
+ *    Same as silc_client_perform_key_agreement but the caller has created
+ *    the connection.  The `stream' is the created connection.
  *
  ***/
-void silc_client_perform_key_agreement_fd(SilcClient client,
-                                         SilcClientConnection conn,
-                                         SilcClientEntry client_entry,
-                                         int sock,
-                                         char *hostname,
-                                         SilcKeyAgreementCallback completion,
-                                         void *context);
+void
+silc_client_perform_key_agreement_stream(SilcClient client,
+                                        SilcClientConnection conn,
+                                        SilcClientEntry client_entry,
+                                        SilcClientConnectionParams *params,
+                                        SilcPublicKey public_key,
+                                        SilcPrivateKey private_key,
+                                        SilcStream stream,
+                                        SilcKeyAgreementCallback completion,
+                                        void *context);
 
 /****f* silcclient/SilcClientAPI/silc_client_abort_key_agreement
  *
@@ -2608,7 +2064,7 @@ typedef void (*SilcClientFileAskName)(SilcClient client,
  *                          void *monitor_context,
  *                          const char *local_ip,
  *                          SilcUInt32 local_port,
- *                          bool do_not_bind,
+ *                          SilcBool do_not_bind,
  *                          SilcClientEntry client_entry,
  *                          const char *filepath);
  *                          SilcUInt32 *session_id);
@@ -2647,7 +2103,7 @@ silc_client_file_send(SilcClient client,
                      void *monitor_context,
                      const char *local_ip,
                      SilcUInt32 local_port,
-                     bool do_not_bind,
+                     SilcBool do_not_bind,
                      SilcClientEntry client_entry,
                      const char *filepath,
                      SilcUInt32 *session_id);
@@ -2760,7 +2216,7 @@ SilcAttributePayload silc_client_attribute_add(SilcClient client,
  *
  * SYNOPSIS
  *
- *    bool silc_client_attribute_del(SilcClient client,
+ *    SilcBool silc_client_attribute_del(SilcClient client,
  *                                   SilcClientConnection conn,
  *                                   SilcAttribute attribute,
  *                                   SilcAttributePayload attr);
@@ -2777,10 +2233,10 @@ SilcAttributePayload silc_client_attribute_add(SilcClient client,
  *    This function Returns TRUE if the attribute was found and deleted.
  *
  ***/
-bool silc_client_attribute_del(SilcClient client,
-                              SilcClientConnection conn,
-                              SilcAttribute attribute,
-                              SilcAttributePayload attr);
+SilcBool silc_client_attribute_del(SilcClient client,
+                                  SilcClientConnection conn,
+                                  SilcAttribute attribute,
+                                  SilcAttributePayload attr);
 
 /****f* silcclient/SilcClientAPI/silc_client_attributes_get
  *
@@ -2800,8 +2256,8 @@ bool silc_client_attribute_del(SilcClient client,
  *    payload while traversing the table.
  *
  ***/
-const SilcHashTable silc_client_attributes_get(SilcClient client,
-                                              SilcClientConnection conn);
+SilcHashTable silc_client_attributes_get(SilcClient client,
+                                        SilcClientConnection conn);
 
 /****f* silcclient/SilcClientAPI/silc_client_attributes_request
  *
@@ -2832,39 +2288,6 @@ const SilcHashTable silc_client_attributes_get(SilcClient client,
  ***/
 SilcBuffer silc_client_attributes_request(SilcAttribute attribute, ...);
 
-/* Low level packet sending functions */
-
-/****f* silcclient/SilcClientAPI/silc_client_send_packet
- *
- * SYNOPSIS
- *
- *     bool silc_client_send_packet(SilcClient client,
- *                                  SilcClientConnection conn,
- *                                  SilcPacketType type,
- *                                  const unsigned char *data,
- *                                  SilcUInt32 data_len);
- *
- * DESCRIPTION
- *
- *    This routine can be used by application to send packets directly
- *    to a connection indicated by `conn'.  Usually application does not
- *    need this routine since the Client Library handles the packet
- *    sending.  The `type' indicates the packet type.  If `data' is
- *    NULL then empty packet is sent.  This returns FALSE if packet cannot
- *    be sent.
- *
- ***/
-bool silc_client_send_packet(SilcClient client,
-                            SilcClientConnection conn,
-                            SilcPacketType type,
-                            const unsigned char *data,
-                            SilcUInt32 data_len);
-
-#include "command.h"
-#include "command_reply.h"
-#include "idlist.h"
-#include "protocol.h"
-
 #ifdef __cplusplus
 }
 #endif