The silc_client_connect_to_[server|client] and
[silc.git] / lib / silcclient / silcclient.h
index 56852d83361230f5ed4a41f356571701dab44da5..ee1e0edd039bd308d52cdac1854d0826233010bf 100644 (file)
@@ -83,6 +83,39 @@ typedef enum {
 } SilcClientConnectionStatus;
 /***/
 
+/****f* silcclient/SilcClientAPI/SilcClientRunning
+ *
+ * SYNOPSIS
+ *
+ *    typedef void (*SilcClientRunning)(SilcClient client, void *context);
+ *
+ * DESCRIPTION
+ *
+ *    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.
+ *
+ ***/
+typedef void (*SilcClientRunning)(SilcClient client, void *context);
+
+/****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);
+
 /****f* silcclient/SilcClientAPI/SilcClientConnectCallback
  *
  * SYNOPSIS
@@ -90,22 +123,30 @@ typedef enum {
  *    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_add_connection functions.
+ *    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/SilcClient
@@ -122,41 +163,21 @@ typedef void (*SilcClientConnectCallback)(SilcClient client,
  *    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 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 */
-
-  /*
-   * 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 */
-  /* XXX remove these; not thread safe */
-  SilcHash md5hash;
-  SilcHash sha1hash;
-
-  /* Internal data for client library. Application cannot access this
-     data at all. */
+  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;
 };
 /***/
@@ -170,33 +191,21 @@ struct SilcClientStruct {
  *
  * 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.
+ *    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 SilcClientConnectionStruct {
-  /*
-   * Local data
-   */
-  SilcClientEntry local_entry;        /* Own Client Entry */
-  SilcClientID *local_id;             /* Current Client ID */
-  SilcBuffer local_idp;                       /* Current Client ID Payload */
-
-  /*
-   * Remote data
-   */
-  char *remote_host;                  /* Remote host name, UTF-8 encoded */
+  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 */
-  SilcBuffer remote_idp;              /* Remote ID Payload */
-
-  /*
-   * Common data
-   */
 
   SilcChannelEntry current_channel;    /* Current joined channel */
   SilcPublicKey public_key;           /* Public key used in this connection */
@@ -204,9 +213,12 @@ struct SilcClientConnectionStruct {
   SilcPacketStream stream;            /* Connection to remote host */
   SilcConnectionType type;            /* Connection type */
   SilcClientConnectCallback callback;  /* Connection callback */
-  void *context;                      /* Connection context */
+  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;
 };
@@ -290,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;
 /***/
 
@@ -319,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
@@ -330,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
@@ -340,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;
@@ -365,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 */
 };
 /***/
 
@@ -497,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
@@ -577,18 +586,17 @@ typedef struct {
   void (*ask_passphrase)(SilcClient client, SilcClientConnection conn,
                         SilcAskPassphrase completion, void *context);
 
-  /* 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. */
-  SilcBool (*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
@@ -608,21 +616,17 @@ typedef struct {
      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. */
+     silc_client_connect_to_server or silc_client_key_exchange when creating
+     connection to remote host, 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);
-
-  /* Called when the client library is up and running.  After this callback
-     is called the application may start using the client library APIs. */
-  void (*running)(SilcClient client, void *application);
 } SilcClientOperations;
 /***/
 
@@ -667,16 +671,6 @@ typedef struct {
      in the callbacks to protect application specific data. */
   SilcBool threads;
 
-  /* 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;
-
   /* Connection authentication method request timeout. If server does not
      reply back the current authentication method when we've requested it
      in this time interval we'll assume the reply will not come at all.
@@ -796,7 +790,9 @@ void silc_client_free(SilcClient client);
  *
  * SYNOPSIS
  *
- *    SilcBool 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
  *
@@ -804,8 +800,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.
+ *
  ***/
-SilcBool 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
  *
@@ -815,7 +823,7 @@ SilcBool silc_client_init(SilcClient client);
  *
  * DESCRIPTION
  *
- *    Runs the client. This starts the scheduler from the utility library.
+ *    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.
  *
@@ -841,21 +849,30 @@ 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 */
 
@@ -868,18 +885,28 @@ 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 {
+  /* 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'. */
+     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;
 
@@ -897,14 +924,19 @@ typedef struct {
   void *auth;
   SilcUInt32 auth_len;
 
-  /* If this boolean is set to TRUE then the client's connection to the
-     remote host will use UDP instead of TCP.  The `local_ip' specifies
-     the local IP address used with the UDP connection, and it must be
-     non-NULL.  If the `local_port' is non-zero it will be used as local
-     port with the UDP connection.  The remote host will also send packets
-     to the specified address and port. */
+  /* 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
@@ -931,6 +963,15 @@ typedef struct {
   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;
 /***/
 
@@ -938,7 +979,7 @@ typedef struct {
  *
  * SYNOPSIS
  *
- *    void
+ *    SilcAsyncOperation
  *    silc_client_connect_to_server(SilcClient client,
  *                                  SilcClientConnectionParams *params,
  *                                  SilcPublicKey public_key,
@@ -959,23 +1000,28 @@ typedef struct {
  *    host disconnects.
  *
  *    If application wishes to create the network connection itself, use
- *    the silc_client_add_connection after creating the connection, instead
- *    of using this function.
+ *    the silc_client_key_exchange after creating the connection to start
+ *    key exchange and authentication with the server.
+ *
+ *    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_connect_to_server(SilcClient client,
-                                  SilcClientConnectionParams *params,
-                                  SilcPublicKey public_key,
-                                  SilcPrivateKey private_key,
-                                  char *remote_host, int port,
-                                  SilcClientConnectCallback callback,
-                                  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_connect_to_client
  *
  * SYNOPSIS
  *
- *    void
+ *    SilcAsyncOperation
  *    silc_client_connect_to_client(SilcClient client,
  *                                  SilcClientConnectionParams *params,
  *                                  SilcPublicKey public_key,
@@ -995,100 +1041,97 @@ void silc_client_connect_to_server(SilcClient client,
  *    when remote host disconnects.
  *
  *    If application wishes to create the network connection itself, use
- *    the silc_client_add_connection after creating the connection, instead
- *    of using this function.
+ *    the silc_client_key_exchange after creating the connection to start
+ *    key exchange with the client.
  *
- ***/
-void 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_add_connection
- *
- * SYNOPSIS
- *
- *
- *    SilcClientConnection
- *    silc_client_add_connection(SilcClient client,
- *                               SilcConnectionType conn_type,
- *                               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 hosts. 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.
+ *    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,
-                          SilcConnectionType conn_type,
-                          SilcClientConnectionParams *params,
-                          SilcPublicKey public_key,
-                          SilcPrivateKey private_key,
-                          char *remote_host, int port,
-                          SilcClientConnectCallback callback,
-                          void *context);
-
-/****f* silcclient/SilcClientAPI/silc_client_del_connection
- *
- * SYNOPSIS
- *
- *    void silc_client_del_connection(SilcClient client,
- *                                    SilcClientConnection conn);
- *
- * 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);
+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_start_key_exchange
+/****f* silcclient/SilcClientAPI/silc_client_key_exchange
  *
  * SYNOPSIS
  *
- *    void silc_client_start_key_exchange(SilcClient client,
- *                                        SilcClientConnection conn,
- *                                        SilcStream stream);
+ *    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
+ *
+ *    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.
+ *
+ *    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.
+ *
+ *    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.
+ *
+ *    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.
  *
- * DESCRIPTION
+ * EXAMPLE
  *
- *    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.
+ *    int sock;
  *
- * NOTES
+ *    // 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);
  *
- *    The silc_client_add_connection must be called before calling this
- *    function to create the SilcClientConnection context for this
- *    connection.
+ *      // Start key exchange
+ *      silc_client_key_exchange(client, NULL, public_key, private_key,
+ *                               stream, SILC_CONN_SERVER, connection_cb, app);
+ *      ...
+ *    }
  *
  ***/
-void silc_client_start_key_exchange(SilcClient client,
-                                   SilcClientConnection conn,
-                                   SilcStream stream);
+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
  *
@@ -1099,18 +1142,17 @@ 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
@@ -1122,6 +1164,7 @@ void silc_client_close_connection(SilcClient client,
  *                                              SilcChannelEntry channel,
  *                                              SilcChannelPrivateKey key,
  *                                              SilcMessageFlags flags,
+ *                                              SilcHash hash,
  *                                              unsigned char *data,
  *                                              SilcUInt32 data_len);
  *
@@ -1153,6 +1196,7 @@ SilcBool silc_client_send_channel_message(SilcClient client,
                                          SilcChannelEntry channel,
                                          SilcChannelPrivateKey key,
                                          SilcMessageFlags flags,
+                                         SilcHash hash,
                                          unsigned char *data,
                                          SilcUInt32 data_len);
 
@@ -1174,6 +1218,7 @@ silc_client_receive_channel_message(SilcClient client,
  *                                              SilcClientConnection conn,
  *                                              SilcClientEntry client_entry,
  *                                              SilcMessageFlags flags,
+ *                                              SilcHash hash,
  *                                              unsigned char *data,
  *                                              SilcUInt32 data_len);
  *
@@ -1182,7 +1227,9 @@ silc_client_receive_channel_message(SilcClient client,
  *    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.  If the `flags' includes SILC_MESSAGE_FLAG_SIGNED
- *    the message will be digitally signed with the SILC key pair.
+ *    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
@@ -1193,195 +1240,10 @@ SilcBool silc_client_send_private_message(SilcClient client,
                                          SilcClientConnection conn,
                                          SilcClientEntry client_entry,
                                          SilcMessageFlags flags,
+                                         SilcHash hash,
                                          unsigned char *data,
                                          SilcUInt32 data_len);
 
-/****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
- *
- *    SilcBool 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.
- *
- ***/
-SilcBool 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
- *
- *    SilcBool 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.
- *
- ***/
-SilcBool silc_client_del_server(SilcClient client, SilcClientConnection conn,
-                               SilcServerEntry server);
-
 /****f* silcclient/SilcClientAPI/silc_client_on_channel
  *
  * SYNOPSIS
@@ -1453,7 +1315,9 @@ SilcUInt16 silc_client_command_call(SilcClient client,
                                    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. */
+   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,
@@ -1490,7 +1354,7 @@ typedef SilcBool (*SilcClientCommandReply)(SilcClient client,
  *    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
+ *    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.
  *
@@ -1583,29 +1447,26 @@ SilcBool silc_client_command_pending(SilcClientConnection conn,
  *                                        const char *cipher,
  *                                        const char *hmac,
  *                                        unsigned char *key,
- *                                        SilcUInt32 key_len,
- *                                        SilcBool generate_key,
- *                                        SilcBool responder);
+ *                                        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.
@@ -1617,9 +1478,7 @@ SilcBool silc_client_add_private_message_key(SilcClient client,
                                             const char *cipher,
                                             const char *hmac,
                                             unsigned char *key,
-                                            SilcUInt32 key_len,
-                                            SilcBool generate_key,
-                                            SilcBool responder);
+                                            SilcUInt32 key_len);
 
 /****f* silcclient/SilcClientAPI/silc_client_add_private_message_key_ske
  *
@@ -1636,9 +1495,9 @@ SilcBool silc_client_add_private_message_key(SilcClient client,
  * 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.
  *
  ***/
@@ -1647,8 +1506,7 @@ SilcBool silc_client_add_private_message_key_ske(SilcClient client,
                                                 SilcClientEntry client_entry,
                                                 const char *cipher,
                                                 const char *hmac,
-                                                SilcSKEKeyMaterial key,
-                                                SilcBool responder);
+                                                SilcSKEKeyMaterial key);
 
 /****f* silcclient/SilcClientAPI/silc_client_del_private_message_key
  *
@@ -1694,40 +1552,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
- *
- *    SilcBool
- *    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.
- *
- ***/
-SilcBool
-silc_client_send_private_message_key_request(SilcClient client,
-                                            SilcClientConnection conn,
-                                            SilcClientEntry client_entry);
-
 /****f* silcclient/SilcClientAPI/silc_client_free_private_message_keys
  *
  * SYNOPSIS
@@ -1854,41 +1678,23 @@ SilcBool silc_client_del_channel_private_key(SilcClient client,
  *
  * 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.
+ *    function silc_client_del_channel_private_key.  Each entry in the list
+ *    is SilcChannelPrivateKey.
  *
  ***/
-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.
- *
- ***/
-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
  *
@@ -1912,7 +1718,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
  *
@@ -1921,62 +1727,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
- *
- *    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).
- *
- *    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'.
- *
- *    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.
- *
- *    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.
+ *    `client_entry'.
+ *
+ *    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.
+ *
+ *    The `public_key' and `private_key' is our identity in the key agreement.
+ *
+ *    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.
+ *
+ *    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);
 
@@ -1988,72 +1778,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
  *