Added entry locking using read/write locks.
[silc.git] / lib / silcclient / silcclient.h
index 69083194cebaddbe5760cd83e6d10e9208be9d1d..346a166a57ee7214046586ac471ecc78c30e581f 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2000 - 2006 Pekka Riikonen
+  Copyright (C) 2000 - 2007 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
  * DESCRIPTION
  *
  * This interface defines the SILC Client Library API for the application.
- * The client operations are defined first.  These are callback functions that
- * the application MUST implement since the library may call the functions
- * at any time.  At the end of file is the API for the application that
- * it can use from the library.  This is the only file that the application
- * may include from the SIlC Client Library.
- *
- * o SILC Client Operations
- *
- *   These functions must be implemented by the application calling the SILC
- *   client library. The client library can call these functions at any time.
- *
- *   To use this structure: define a static SilcClientOperations variable,
- *   fill it and pass its pointer to silc_client_alloc function.
- *
- * o SILC Client Library API
- *
- *   This is the API that is published by the SILC Client Library for the
- *   applications.  These functions are implemented in the SILC Client Library.
- *   Application may freely call these functions from the library.
+ * The Client Library is a full features SILC client without a user interface.
+ * A simple interface called SILC Client Operations (SilcClientOperations)
+ * is provided for applications to implmeent the necessary functions to use
+ * the client library.  The silcclient.h header file includes client library
+ * API, such as command handling and message sending.  The silcclient_entry.h
+ * header file includes entry handling, such as channel and user entry
+ * handling.
+ *
+ * Practically all functions in the Client Library API accepts SilcClient
+ * and SilcClientConnection as their first two argument.  The first argument
+ * is the actual SilcClient context and the second is the SilcClientConnection
+ * context of the connection in question.  Application may create and handle
+ * multiple connections in one SilcClient.  Connections can be created to
+ * servers and other clients.
+ *
+ * The Client Library support multiple threads and is threads safe is used
+ * correctly.  Messages can be sent from multiple threads without any
+ * locking.  Messages however are always received only in one thread unless
+ * message waiting (see silc_client_private_message_wait as an example) is
+ * used.  The threads can be turned on and off by giving a parameter to the
+ * SilcClient.  When turned on, each new connection to remote host is always
+ * executed in an own thread.  All tasks related to that connection are then
+ * executed in that thread.  This means that client operation callbacks for
+ * that connections may be called from threads and application will need to
+ * employ concurrency control if the callbacks need to access shared data
+ * in the application.  Messages are also received in that thread.
+ *
+ * All entries (SilcClientEntry, SilcChannelEntry and SilcServerEntry) are
+ * reference counted.  If application wishes to save an entry pointer it must
+ * always first acquire a reference.  The reference must be released once the
+ * entry is not needed anymore.  If application wants to read any data from
+ * the entry structure it must first lock the entry.  This protects access to
+ * the entries in multithreaded environment.  If threads are not used, locking
+ * the entries is not needed.  They however still must be referenced even
+ * when threads are not used.
  *
  ***/
 
@@ -135,7 +151,9 @@ typedef void (*SilcClientStopped)(SilcClient client, void *context);
  *    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.
+ *    to the connecting function.  If the `status' is an error the `error'
+ *    may indicate more detailed error.  If `error' is SILC_STATUS_OK no
+ *    detailed error message is available.
  *
  *    When the `status' is SILC_CLIENT_CONN_DISCONNECTED the `error' will
  *    indicate the reason for disconnection.  If the `message' is non-NULL
@@ -427,18 +445,23 @@ typedef void (*SilcVerifyPublicKey)(SilcBool success, void *context);
  *
  * DESCRIPTION
  *
- *    Authentication method resolving callback. This is called by the
- *    application to return the resolved authentication method. The client
+ *    Authentication data resolving callback. This is called by the
+ *    application to return the resolved authentication data. The client
  *    library has called the get_auth_method client operation and given
- *    this function pointer as argument. The `success' will indicate whether
- *    the authentication method could be resolved. The `auth_meth' is the
- *    resolved authentication method. The `auth_data' and the `auth_data_len'
+ *    this function pointer as argument. The `auth_meth' is the selected
+ *    authentication method. The `auth_data' and the `auth_data_len'
  *    are the resolved authentication data. The `context' is the libary's
  *    context sent to the get_auth_method client operation.
  *
+ *    If the `auth_method' is SILC_AUTH_PASSWORD then `auth' and `auth_len'
+ *    is the passphrase and its length.  If it is SILC_AUTH_PUBLIC_KEY the
+ *    `auth' must be NULL.  The library will use the private key given as
+ *    argument to silc_client_connect_to_server, silc_client_connect_to_client
+ *    or silc_client_key_exchange.  If it is SILC_AUTH_NONE, both `auth' and
+ *    `auth_len' are ignored.
+ *
  ***/
-typedef void (*SilcGetAuthMeth)(SilcBool success,
-                               SilcAuthMethod auth_meth,
+typedef void (*SilcGetAuthMeth)(SilcAuthMethod auth_meth,
                                void *auth, SilcUInt32 auth_len,
                                void *context);
 
@@ -561,19 +584,26 @@ typedef struct {
                        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
-     method has been resolved the `completion' callback with the found
-     authentication method and authentication data is called. The `conn'
-     may be NULL. */
+     port. The hostname may be IP address as well. The `auth_method' is
+     the authentication method the remote connection requires.  It is
+     however possible that remote accepts also some other authentication
+     method.  Application should use the method that may have been
+     configured for this connection.  If none has been configured it should
+     use the required `auth_method'.  If the `auth_method' is
+     SILC_AUTH_NONE, server does not require any authentication or the
+     required authentication method is not known.  The `completion'
+     callback must be called to deliver the chosen authentication method
+     and data. The `conn' may be NULL. */
   void (*get_auth_method)(SilcClient client, SilcClientConnection conn,
                          char *hostname, SilcUInt16 port,
+                         SilcAuthMethod auth_method,
                          SilcGetAuthMeth completion, void *context);
 
   /* Verifies received public key. The `conn_type' indicates which entity
-     (server, client etc.) has sent the public key. If user decides to trust
-     the application may save the key as trusted public key for later
-     use. The `completion' must be called after the public key has been
-     verified. */
+     (server or client) has sent the public key. If user decides to trust
+     the key the application may save the key as trusted public key for
+     later use. The `completion' must be called after the public key has
+     been verified. */
   void (*verify_public_key)(SilcClient client, SilcClientConnection conn,
                            SilcConnectionType conn_type,
                            SilcPublicKey public_key,
@@ -632,12 +662,6 @@ typedef struct {
      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
-     in this time interval we'll assume the reply will not come at all.
-     If set to zero, the default value (2 seconds) will be used. */
-  unsigned int connauth_request_secs;
-
   /* Nickname format string. This can be used to order the client library
      to save the nicknames in the library in a certain format. Since
      nicknames are not unique in SILC it is possible to have multiple same
@@ -789,7 +813,6 @@ void silc_client_run(SilcClient client);
  ***/
 void silc_client_run_one(SilcClient client);
 
-
 /****f* silcclient/SilcClientAPI/silc_client_stop
  *
  * SYNOPSIS
@@ -907,7 +930,7 @@ typedef struct {
   /* 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;
+  SilcUInt32 rekey_secs;
 
   /* If this is set to TRUE then the client will ignore all incoming
      Requested Attributes queries and does not reply anything back.  This
@@ -929,6 +952,7 @@ typedef struct {
  *    silc_client_connect_to_server(SilcClient client,
  *                                  SilcClientConnectionParams *params,
  *                                  SilcPublicKey public_key,
+ *                                  SilcPrivateKey private_key,
  *                                  char *remote_host, int port,
  *                                  SilcClientConnectCallback callback,
  *                                  void *context);
@@ -971,6 +995,7 @@ silc_client_connect_to_server(SilcClient client,
  *    silc_client_connect_to_client(SilcClient client,
  *                                  SilcClientConnectionParams *params,
  *                                  SilcPublicKey public_key,
+ *                                  SilcPrivateKey private_key,
  *                                  char *remote_host, int port,
  *                                  SilcClientConnectCallback callback,
  *                                  void *context);
@@ -1099,7 +1124,7 @@ silc_client_key_exchange(SilcClient client,
 void silc_client_close_connection(SilcClient client,
                                  SilcClientConnection conn);
 
-/* Message sending functions (client_channel.c and client_prvmsg.c) */
+/* Message sending functions */
 
 /****f* silcclient/SilcClientAPI/silc_client_send_channel_message
  *
@@ -1129,7 +1154,8 @@ void silc_client_close_connection(SilcClient client,
  *    private key) is used.
  *
  *    If the `flags' includes SILC_MESSAGE_FLAG_SIGNED the message will be
- *    digitally signed with the SILC key pair.
+ *    digitally signed with the SILC key pair.  In this case the `hash'
+ *    pointer must be provided as well.
  *
  *    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
@@ -1146,16 +1172,6 @@ SilcBool silc_client_send_channel_message(SilcClient client,
                                          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
@@ -1174,8 +1190,7 @@ silc_client_receive_channel_message(SilcClient client,
  *    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.  In this
- *    case the caller must also provide the `hash' pointer.  By default, the
- *    hash function must be SHA-1.
+ *    case the caller must also provide the `hash' pointer.
  *
  *    Returns TRUE if the message was sent, and FALSE if error occurred.
  *    This function is thread safe and private messages can be sent from
@@ -1190,6 +1205,83 @@ SilcBool silc_client_send_private_message(SilcClient client,
                                          unsigned char *data,
                                          SilcUInt32 data_len);
 
+/****f* silcclient/SilcClientAPI/silc_client_private_message_wait_init
+ *
+ * SYNOPSIS
+ *
+ *    SilcBool
+ *    silc_client_private_message_wait_init(SilcClient client,
+ *                                          SilcClientConnection conn);
+ *
+ * DESCRIPTION
+ *
+ *    Initializes private message waiting functionality for the connection
+ *    indicated by `conn'.  Once this is called private message from remote
+ *    connection indicated by `conn' for any client entry beloning to that
+ *    connection may be waited for, for example in an thread.  The function
+ *    silc_client_private_message_wait is used to block the current thread
+ *    until a private message is received from a specified client entry.
+ *    Return FALSE on error.
+ *
+ ***/
+SilcBool silc_client_private_message_wait_init(SilcClient client,
+                                              SilcClientConnection conn);
+
+/****f* silcclient/SilcClientAPI/silc_client_private_message_wait_uninit
+ *
+ * SYNOPSIS
+ *
+ *    void
+ *    silc_client_private_message_wait_uninit(SilcClient client,
+ *                                            SilcClientConnection conn);
+ *
+ * DESCRIPTION
+ *
+ *    Unintializes private message waiting for connection indicated by
+ *    `conn'.  After this call private message cannot be waited anymore.
+ *    This call may be called from any thread.  This call will signal all
+ *    private message waiting threads to stop waiting.
+ *
+ ***/
+void silc_client_private_message_wait_uninit(SilcClient client,
+                                            SilcClientConnection conn);
+
+/****f* silcclient/SilcClientAPI/silc_client_private_message_wait
+ *
+ * SYNOPSIS
+ *
+ *    SilcBool
+ *    silc_client_private_message_wait(SilcClient client,
+ *                                     SilcClientConnection conn,
+ *                                     SilcClientEntry client_entry,
+ *                                     SilcMessagePayload *payload);
+ *
+ * DESCRIPTION
+ *
+ *    Blocks current thread or process until a private message has been
+ *    received from the remote client indicated by `client_entry'.  Before
+ *    private messages can be waited the silc_client_private_message_wait_init
+ *    must be called.  This function can be used from a thread to wait for
+ *    private message from the specified client.  Multiple threads can be
+ *    created to wait messages from multiple clients.  Any other private
+ *    message received from the connection indicated by `conn' will be
+ *    forwarded to the normal `private_message' client operation.  The
+ *    private messages from `client_entry' will not be delivered to the
+ *    `private_message' client operation.
+ *
+ *    Returns TRUE and the received private message into `payload'.  The caller
+ *    must free the returned SilcMessagePayload.  If this function returns
+ *    FALSE the private messages cannot be waited anymore.  This happens
+ *    when some other thread calls silc_client_private_message_wait_uninit.
+ *    This returns FALSE also if silc_client_private_message_wait_init has
+ *    not been called.
+ *
+ ***/
+SilcBool silc_client_private_message_wait(SilcClient client,
+                                         SilcClientConnection conn,
+                                         SilcClientEntry client_entry,
+                                         SilcMessagePayload *payload);
+
 /****f* silcclient/SilcClientAPI/silc_client_on_channel
  *
  * SYNOPSIS
@@ -1260,10 +1352,40 @@ 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. */
+/****f* silcclient/SilcClientAPI/SilcClientCommandReply
+ *
+ * SYNOPSIS
+ *
+ *    typedef SilcBool (*SilcClientCommandReply)(SilcClient client,
+ *                                               SilcClientConnection conn,
+ *                                               SilcCommand command,
+ *                                               SilcStatus status,
+ *                                               SilcStatus error,
+ *                                               void *context,
+ *                                               va_list ap);
+ *
+ * DESCRIPTION
+ *
+ *    The command reply callback function given as argument to functions
+ *    silc_client_command_send and silc_client_command_pending.  This is
+ *    called to deliver the command replies to the caller.  Each command
+ *    reply received from the server to the `command' will be delivered
+ *    separately to the caller by calling this callback.  The `status' will
+ *    indicate whether there is only one reply or multiple replies.  The
+ *    `error' will indicate if an error occurred.  The `ap' will include
+ *    command reply arguments.  They are the same arguments as for
+ *    `command_reply' client operation in SilcClientOperations.
+ *
+ *    If `status' is SILC_STATUS_OK only one reply was received and error
+ *    did not occur.  If it is SILC_STATUS_LIST_START, SILC_STATUS_LIST_ITEM
+ *    or SILC_STATUS_LIST_END, there are will be two or more replies.  The
+ *    first reply is SILC_STATUS_LIST_START and last one SILC_STATUS_LIST_END.
+ *
+ *    If FALSE is returned in this function this callback will not be called
+ *    again for `command' even if there are more comand replies.  By returning
+ *    FALSE the caller my stop the command reply handling when needed.
+ *
+ ***/
 typedef SilcBool (*SilcClientCommandReply)(SilcClient client,
                                           SilcClientConnection conn,
                                           SilcCommand command,
@@ -1300,9 +1422,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 almost
- *    identical with `command_reply' callback, and application may forward
- *    the reply from `reply' to `command_reply' callback, if desired.
+ *    called, when reply is received.
  *
  *    Returns command identifier for this sent command.  It can be used
  *    to additionally attach to the command reply using the function
@@ -1380,7 +1500,7 @@ SilcBool silc_client_command_pending(SilcClientConnection conn,
                                     void *context);
 
 
-/* Private Message key management (client_prvmsg.c) */
+/* Private Message key management */
 
 /****f* silcclient/SilcClientAPI/silc_client_add_private_message_key
  *
@@ -1515,8 +1635,7 @@ void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys,
                                           SilcUInt32 key_count);
 
 
-/* Channel private key management (client_channel.c,
-   SilcChannelPrivateKey is defined in idlist.h) */
+/* Channel private key management */
 
 /****f* silcclient/SilcClientAPI/silc_client_add_channel_private_key
  *
@@ -1632,10 +1751,10 @@ SilcBool silc_client_del_channel_private_key(SilcClient client,
  * DESCRIPTION
  *
  *    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.  Each entry in the list
- *    is SilcChannelPrivateKey.
+ *    must free the returned list with silc_dlist_uninit.  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.  Each
+ *    entry in the list is SilcChannelPrivateKey.
  *
  ***/
 SilcDList silc_client_list_channel_private_keys(SilcClient client,
@@ -1835,9 +1954,9 @@ void silc_client_abort_key_agreement(SilcClient client,
  *
  * SYNOPSIS
  *
- *    void silc_client_set_away_message(SilcClient client,
- *                                      SilcClientConnection conn,
- *                                      char *message);
+ *    SilcBool silc_client_set_away_message(SilcClient client,
+ *                                          SilcClientConnection conn,
+ *                                          char *message);
  *
  * DESCRIPTION
  *
@@ -1847,62 +1966,13 @@ void silc_client_abort_key_agreement(SilcClient client,
  *    automatically back to the the client who send private message.  If
  *    away message is already set this replaces the old message with the
  *    new one.  If `message' is NULL the old away message is removed.
- *    The sender may freely free the memory of the `message'.
- *
- ***/
-void silc_client_set_away_message(SilcClient client,
-                                 SilcClientConnection conn,
-                                 char *message);
-
-/****f* silcclient/SilcClientAPI/SilcConnectionAuthRequest
- *
- * SYNOPSIS
- *
- *    typedef void (*SilcConnectionAuthRequest)(SilcClient client,
- *                                              SilcClientConnection conn,
- *                                              SilcAuthMethod auth_meth,
- *                                              void *context);
- *
- * DESCRIPTION
- *
- *    Connection authentication method request callback. This is called
- *    by the client library after it has received the authentication method
- *    that the application requested by calling the function
- *    silc_client_request_authentication_method.
- *
- ***/
-typedef void (*SilcConnectionAuthRequest)(SilcClient client,
-                                         SilcClientConnection conn,
-                                         SilcAuthMethod auth_meth,
-                                         void *context);
-
-/****f* silcclient/SilcClientAPI/silc_client_request_authentication_method
- *
- * SYNOPSIS
- *
- *    void
- *    silc_client_request_authentication_method(SilcClient client,
- *                                              SilcClientConnection conn,
- *                                              SilcConnectionAuthRequest
- *                                                callback,
- *                                              void *context);
- *
- * DESCRIPTION
- *
- *    This function can be used to request the current authentication method
- *    from the server. This may be called when connecting to the server
- *    and the client library requests the authentication data from the
- *    application. If the application does not know the current authentication
- *    method it can request it from the server using this function.
- *    The `callback' with `context' will be called after the server has
- *    replied back with the current authentication method.
+ *    The sender may freely free the memory of the `message'.  Returns
+ *    FALSE on error.
  *
  ***/
-void
-silc_client_request_authentication_method(SilcClient client,
-                                         SilcClientConnection conn,
-                                         SilcConnectionAuthRequest callback,
-                                         void *context);
+SilcBool silc_client_set_away_message(SilcClient client,
+                                     SilcClientConnection conn,
+                                     char *message);
 
 /****d* silcclient/SilcClientAPI/SilcClientMonitorStatus
  *
@@ -2084,13 +2154,12 @@ typedef void (*SilcClientFileAskName)(SilcClient client,
  ***/
 SilcClientFileError
 silc_client_file_send(SilcClient client,
-                     SilcClientConnection conn,
+                     SilcClientEntry client_entry,
+                     SilcClientConnectionParams *params,
+                     SilcPublicKey public_key,
+                     SilcPrivateKey private_key,
                      SilcClientFileMonitor monitor,
                      void *monitor_context,
-                     const char *local_ip,
-                     SilcUInt32 local_port,
-                     SilcBool do_not_bind,
-                     SilcClientEntry client_entry,
                      const char *filepath,
                      SilcUInt32 *session_id);