updates.
[silc.git] / lib / silcclient / client.h
index 10fc21396b92a91c42758a51afa4f294cd4f1143..dd27a1467a6af1b94e66463fbc2ad92f17452fe7 100644 (file)
 #ifndef CLIENT_H
 #define CLIENT_H
 
-/* Forward declaration for client */
-typedef struct SilcClientObject *SilcClient;
-
-/* Forward declaration for client connection */
-typedef struct SilcClientConnectionObject *SilcClientConnection;
+/* Forward declarations */
+typedef struct SilcClientStruct *SilcClient;
+typedef struct SilcClientConnectionStruct *SilcClientConnection;
+typedef struct SilcClientPingStruct SilcClientPing;
+typedef struct SilcClientAwayStruct SilcClientAway;
+typedef struct SilcClientKeyAgreementStruct *SilcClientKeyAgreement;
 
 #include "idlist.h"
 #include "command.h"
 #include "silcapi.h"
 
-/* Structure to hold ping time information. Every PING command will 
-   add entry of this structure and is removed after reply to the ping
-   as been received. */
-typedef struct SilcClientPingStruct {
-  time_t start_time;
-  void *dest_id;
-  char *dest_name;
-} SilcClientPing;
-
-/* Structure to hold away messages set by user. This is mainly created
-   for future extensions where away messages could be set according filters
-   such as nickname and hostname. For now only one away message can 
-   be set in one connection. */
-typedef struct SilcClientAwayStruct {
-  char *away;
-  struct SilcClientAwayStruct *next;
-} SilcClientAway;
+/* Generic rekey context for connections */
+typedef struct {
+  /* Current sending encryption key, provided for re-key. The `pfs'
+     is TRUE if the Perfect Forward Secrecy is performed in re-key. */
+  unsigned char *send_enc_key;
+  uint32 enc_key_len;
+  int ske_group;
+  bool pfs;
+  uint32 timeout;
+  void *context;
+} *SilcClientRekey;
 
 /* Connection structure used in client to associate all the important
    connection specific data to this structure. */
-struct SilcClientConnectionObject {
+struct SilcClientConnectionStruct {
   /*
    * Local data 
    */
@@ -63,7 +58,7 @@ struct SilcClientConnectionObject {
   /* Decoded local ID so that the above defined ID would not have
      to be decoded for every packet. */
   unsigned char *local_id_data;
-  unsigned int local_id_data_len;
+  uint32 local_id_data_len;
 
   /* Own client entry. */
   SilcClientEntry local_entry;
@@ -82,17 +77,17 @@ struct SilcClientConnectionObject {
   /* Decoded remote ID so that the above defined ID would not have
      to be decoded for every packet. */
   unsigned char *remote_id_data;
-  unsigned int remote_id_data_len;
+  uint32 remote_id_data_len;
 
   /*
    * Common data 
    */
-  /* Keys */
+  /* Keys and stuff negotiated in the SKE protocol */
   SilcCipher send_key;
   SilcCipher receive_key;
-  SilcHmac hmac;
-  unsigned char *hmac_key;
-  unsigned int hmac_key_len;
+  SilcHmac hmac_send;
+  SilcHmac hmac_receive;
+  SilcHash hash;
 
   /* Client ID and Channel ID cache. Messages transmitted in SILC network
      are done using different unique ID's. These are the cache for
@@ -114,15 +109,18 @@ struct SilcClientConnectionObject {
   SilcDList pending_commands;
 
   /* Current command identifier, 0 not used */
-  unsigned short cmd_ident;
+  uint16 cmd_ident;
 
   /* Requested pings. */
   SilcClientPing *ping;
-  unsigned int ping_count;
+  uint32 ping_count;
 
   /* Set away message */
   SilcClientAway *away;
 
+  /* Re-key context */
+  SilcClientRekey rekey;
+
   /* Pointer back to the SilcClient. This object is passed to the application
      and the actual client object is accesible through this pointer. */
   SilcClient client;
@@ -132,7 +130,7 @@ struct SilcClientConnectionObject {
 };
 
 /* Main client structure. */
-struct SilcClientObject {
+struct SilcClientStruct {
   /*
    * Public data. All the following pointers must be set by the allocator
    * of this structure.
@@ -160,14 +158,22 @@ struct SilcClientObject {
   /* All client operations that are implemented in the application. */
   SilcClientOperations *ops;
 
-  /* SILC client task queues */
+  /* SILC client scheduler and task queues */
+  SilcSchedule schedule;
   SilcTaskQueue io_queue;
   SilcTaskQueue timeout_queue;
   SilcTaskQueue generic_queue;
 
   /* Table of connections in client. All the connection data is saved here. */
   SilcClientConnection *conns;
-  unsigned int conns_count;
+  uint32 conns_count;
+
+  /* Table of listenning sockets in client.  Client can have listeners
+     (like key agreement protocol server) and those sockets are saved here.
+     This table is checked always if the connection object cannot be found
+     from the `conns' table. */
+  SilcSocketConnection *sockets;
+  uint32 sockets_count;
 
   /* Generic cipher and hash objects. These can be used and referenced
      by the application as well. */
@@ -197,15 +203,15 @@ do {                                                                      \
   silc_task_set_iotype(tmptask, SILC_TASK_WRITE);                      \
 } while(0)
 
-#define SILC_CLIENT_SET_CONNECTION_FOR_INPUT(fd)               \
-do {                                                           \
-  silc_schedule_set_listen_fd((fd), (1L << SILC_TASK_READ));   \
-} while(0)                                                     \
+#define SILC_CLIENT_SET_CONNECTION_FOR_INPUT(s, fd)                    \
+do {                                                                   \
+  silc_schedule_set_listen_fd((s), (fd), (1L << SILC_TASK_READ));      \
+} while(0)
      
-#define SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(fd)              \
-do {                                                           \
-  silc_schedule_set_listen_fd((fd), ((1L << SILC_TASK_READ) |  \
-                                    (1L << SILC_TASK_WRITE))); \
+#define SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(s, fd)                   \
+do {                                                                   \
+  silc_schedule_set_listen_fd((s), (fd), ((1L << SILC_TASK_READ) |     \
+                                    (1L << SILC_TASK_WRITE)));         \
 } while(0)
 
 /* Finds socket connection object by file descriptor */
@@ -214,14 +220,25 @@ do {                                                      \
   int __i;                                             \
                                                        \
   for (__i = 0; __i < (__x)->conns_count; __i++)       \
-    if ((__x)->conns[__i]->sock->sock == (__fd))       \
+    if ((__x)->conns[__i] &&                           \
+       (__x)->conns[__i]->sock->sock == (__fd))        \
       break;                                           \
                                                        \
-  if (__i >= (__x)->conns_count)                       \
+  if (__i >= (__x)->conns_count) {                     \
     (__sock) = NULL;                                   \
- (__sock) = (__x)->conns[__i]->sock;                   \
+    for (__i = 0; __i < (__x)->sockets_count; __i++)   \
+      if ((__x)->sockets[__i] &&                       \
+         (__x)->sockets[__i]->sock == (__fd))          \
+        (__sock) = (__x)->sockets[__i];                        \
+  } else                                               \
+    (__sock) = (__x)->conns[__i]->sock;                        \
 } while(0)
 
+/* Check whether rekey protocol is active */
+#define SILC_CLIENT_IS_REKEY(sock)                                     \
+  (sock->protocol && sock->protocol->protocol &&                       \
+   sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)
+
 /* Prototypes (some of the prototypes are defined in the silcapi.h) */
 
 void silc_client_packet_send(SilcClient client, 
@@ -232,7 +249,7 @@ void silc_client_packet_send(SilcClient client,
                             SilcCipher cipher,
                             SilcHmac hmac,
                             unsigned char *data, 
-                            unsigned int data_len, 
+                            uint32 data_len, 
                             int force_send);
 void silc_client_disconnected_by_server(SilcClient client,
                                        SilcSocketConnection sock,
@@ -240,16 +257,14 @@ void silc_client_disconnected_by_server(SilcClient client,
 void silc_client_error_by_server(SilcClient client,
                                 SilcSocketConnection sock,
                                 SilcBuffer message);
-void silc_client_notify_by_server(SilcClient client,
-                                 SilcSocketConnection sock,
-                                 SilcPacketContext *packet);
 void silc_client_receive_new_id(SilcClient client,
                                SilcSocketConnection sock,
                                SilcIDPayload idp);
-void silc_client_new_channel_id(SilcClient client,
-                               SilcSocketConnection sock,
-                               char *channel_name,
-                               unsigned int mode, SilcIDPayload idp);
+SilcChannelEntry silc_client_new_channel_id(SilcClient client,
+                                           SilcSocketConnection sock,
+                                           char *channel_name,
+                                           uint32 mode, 
+                                           SilcIDPayload idp);
 void silc_client_save_channel_key(SilcClientConnection conn,
                                  SilcBuffer key_payload, 
                                  SilcChannelEntry channel);
@@ -259,9 +274,6 @@ void silc_client_receive_channel_key(SilcClient client,
 void silc_client_channel_message(SilcClient client, 
                                 SilcSocketConnection sock, 
                                 SilcPacketContext *packet);
-void silc_client_private_message(SilcClient client, 
-                                SilcSocketConnection sock, 
-                                SilcPacketContext *packet);
 void silc_client_remove_from_channels(SilcClient client,
                                      SilcClientConnection conn,
                                      SilcClientEntry client_entry);
@@ -269,8 +281,17 @@ void silc_client_replace_from_channels(SilcClient client,
                                       SilcClientConnection conn,
                                       SilcClientEntry old,
                                       SilcClientEntry new);
-char *silc_client_chmode(unsigned int mode);
-char *silc_client_chumode(unsigned int mode);
-char *silc_client_chumode_char(unsigned int mode);
+void silc_client_process_failure(SilcClient client,
+                                SilcSocketConnection sock,
+                                SilcPacketContext *packet);
+void silc_client_key_agreement(SilcClient client,
+                              SilcSocketConnection sock,
+                              SilcPacketContext *packet);
+void silc_client_notify_by_server(SilcClient client,
+                                 SilcSocketConnection sock,
+                                 SilcPacketContext *packet);
+void silc_client_private_message(SilcClient client, 
+                                SilcSocketConnection sock, 
+                                SilcPacketContext *packet);
 
 #endif