updates.
[silc.git] / apps / silcd / idlist.h
index c958e26ab82fd8ca124ee87b0f0a5c7ef9409fb7..bd526b9368ba5732f09953162312f6e7ad15724a 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
 
-  Copyright (C) 1997 - 2000 Pekka Riikonen
+  Copyright (C) 1997 - 2001 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
 #define IDLIST_H
 
 /* Forward declarations */
-typedef struct SilcServerListStruct SilcServerList;
-typedef struct SilcClientListStruct SilcClientList;
-typedef struct SilcChannelListStruct SilcChannelList;
+typedef struct SilcServerEntryStruct *SilcServerEntry;
+typedef struct SilcClientEntryStruct *SilcClientEntry;
+typedef struct SilcChannelEntryStruct *SilcChannelEntry;
+
+/* Context for holding cache information to periodically purge
+   the cache. */
+typedef struct {
+  SilcIDCache cache;
+  SilcSchedule schedule;
+} *SilcIDListPurge;
+
+/* Channel key re-key context. */
+typedef struct {
+  void *context;
+  SilcChannelEntry channel;
+  uint32 key_len;
+  SilcTask task;
+} *SilcServerChannelRekey;
+
+/* 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;
+} *SilcServerRekey;
+
+/* ID List Entry status type and all the types. */
+typedef uint8 SilcIDListStatus;
+#define SILC_IDLIST_STATUS_NONE         0x00    /* No status */
+#define SILC_IDLIST_STATUS_REGISTERED   0x01    /* Entry is registered */
+#define SILC_IDLIST_STATUS_RESOLVED     0x02    /* Entry info is resolved */
+#define SILC_IDLIST_STATUS_RESOLVING    0x04    /* Entry is being resolved
+                                                  with WHOIS or IDENTIFY */
+#define SILC_IDLIST_STATUS_DISABLED     0x08    /* Entry is disabled */
+
+/*
+   Generic ID list data structure.
+
+   This structure is included in all ID list entries and it includes data
+   pointers that are common to all ID entries.  This structure is always
+   defined to the first field in the ID entries and is used to explicitly
+   type cast to this type without first explicitly casting to correct ID
+   entry type.  Hence, the ID list entry is type casted to this type to
+   get this data from the ID entry (which is usually opaque pointer).
+
+   Note that some of the fields may be NULL.
+
+*/
+typedef struct {
+  /* Send and receive symmetric keys */
+  SilcCipher send_key;
+  SilcCipher receive_key;
+
+  /* Re-key context */
+  SilcServerRekey rekey;
+
+  /* Hash selected in the SKE protocol, NULL if not needed at all */
+  SilcHash hash;
+
+  /* HMAC */
+  SilcHmac hmac_send;
+  SilcHmac hmac_receive;
+
+  /* Public key */
+  SilcPublicKey public_key;
+
+  long last_receive;           /* Time last received data */
+  long last_sent;              /* Time last sent data */
+
+  unsigned long created;       /* Time when entry was created */
+
+  SilcIDListStatus status;     /* Status mask of the entry */
+} *SilcIDListData, SilcIDListDataStruct;
 
 /* 
-   SILC Server list object.
+   SILC Server entry object.
 
-   This list holds information about servers in SILC network. However, 
-   contents of this list is highly dependent of what kind of server we are 
-   (normal server or router server) and whether the list is used as a local 
-   list or a global list. These factors dictates the contents of this list.
+   This entry holds information about servers in SILC network. However, 
+   contents of this entry is highly dependent of what kind of server we are 
+   (normal server or router server) and whether the entry is used as a local 
+   list or a global list. These factors dictates the contents of this entry.
 
-   This list is defined as follows:
+   This entry is defined as follows:
 
    Server type   List type      Contents
    =======================================================================
@@ -45,12 +120,16 @@ typedef struct SilcChannelListStruct SilcChannelList;
 
    Following short description of the fields:
 
+   SilcIDListDataStruct data
+
+       Generic data structure to hold data common to all ID entries.
+
    char *server_name
 
        Logical name of the server. There is no limit of the length of the
        server name. This is usually the same name as defined in DNS.
 
-   int server_type
+   uint8 server_type
 
        Type of the server. SILC_SERVER or SILC_ROUTER are the possible
        choices for this.
@@ -61,16 +140,23 @@ typedef struct SilcChannelListStruct SilcChannelList;
        the server SILC will ever need. These are also the informations
        that is broadcasted between servers and routers in the SILC network.
 
-   struct SilcServerListStruct *router
+   char *server_info
+   char *motd
+
+       Server info (from INFO command) saved temporarily and motd (from
+       MOTD command) saved temporarily.
+
+   SilcServerEntry router
 
        This is a pointer back to the server list. This is the router server 
        where this server is connected to. If this is the router itself and 
        it doesn't have a route this is NULL.
 
    SilcCipher send_key
-   
    SilcCipher receive_key
 
+       Data sending and receiving keys.
+
    void *connection
 
        A pointer, usually, to the socket list for fast referencing to
@@ -79,41 +165,59 @@ typedef struct SilcChannelListStruct SilcChannelList;
        list.
    
 */
-struct SilcServerListStruct {
+struct SilcServerEntryStruct {
+  /* Generic data structure. DO NOT add anything before this! */
+  SilcIDListDataStruct data;
+
   char *server_name;
-  int server_type;
+  uint8 server_type;
   SilcServerID *id;
-
-  /* TRUE when server is registered to server */
-  int registered;
+  char *server_info;
+  char *motd;
 
   /* Pointer to the router */
-  struct SilcServerListStruct *router;
-
-  /* Keys */
-  SilcCipher send_key;
-  SilcCipher receive_key;
-  SilcPKCS pkcs;
-  SilcPublicKey public_key;
-  SilcHmac hmac;
-  unsigned char *hmac_key;
-  unsigned int hmac_key_len;
+  SilcServerEntry router;
 
   /* Connection data */
   void *connection;
-
-  struct SilcServerListStruct *next;
-  struct SilcServerListStruct *prev;
 };
 
 /* 
-   SILC Client list object.
+   SILC Channel Client entry structure.
+
+   This entry used only by the SilcChannelEntry object and it holds
+   information about current clients (ie. users) on channel. Following
+   short description of the fields:
+
+   SilcClientEntry client
+
+       Pointer to the client list. This is the client currently on channel.
+
+   uint32 mode
+
+       Client's current mode on the channel.
+
+   SilcChannelEntry channel
+
+       Back pointer back to channel. As this structure is also used by
+       SilcClientEntry we have this here for fast access to the channel when
+       used by SilcClientEntry.
+
+*/
+typedef struct SilcChannelClientEntryStruct {
+  SilcClientEntry client;
+  uint32 mode;
+  SilcChannelEntry channel;
+} *SilcChannelClientEntry;
+
+/* 
+   SILC Client entry object.
 
-   This list holds information about connected clients ie. users in the SILC
-   network. The contents of this list is depended on whether we are normal 
+   This entry holds information about connected clients ie. users in the SILC
+   network. The contents of this entrt is depended on whether we are normal 
    server or router server and whether the list is a local or global list.
 
-   This list is defined as follows:
+   This entry is defined as follows:
 
    Server type   List type      Contents
    =======================================================================
@@ -124,10 +228,21 @@ struct SilcServerListStruct {
 
    Following short description of the fields:
 
+   SilcIDListDataStruct data
+
+       Generic data structure to hold data common to all ID entries.
+
+   unsigned char *nickname
+
+       The nickname of the client.
+
+   char *servername
+
+       The name of the server where the client is from. MAy be NULL.
+
    char username
 
-       Client's (meaning user's) real name. This is defined in following 
-       manner:
+       Client's usename. This is defined in the following manner:
 
        Server type   List type      Contents
        ====================================================
@@ -163,31 +278,34 @@ struct SilcServerListStruct {
        nickname. Nickname is not relevant information that would need to be 
        saved as plain.
 
-   int mode
+   uint32 mode
 
        Client's mode.  Client maybe for example server operator or
        router operator (SILC operator).
 
-   SilcServerList *router
+   long last_command
 
-       This is a pointer to the server list. This is the router server whose 
-       cell this client is coming from. This is used to route messages to 
-       this client.
+       Time of last time client executed command. We are strict and will
+       not allow any command to be exeucted more than once in about
+       2 seconds. This is result of normal time().
 
-   SilcCipher session_key
+   uint8 fast_command
 
-       The actual session key established by key exchange protcol between
-       connecting parties. This is used for both encryption and decryption.
+       Counter to check command bursts.  By default, up to 5 commands
+       are allowed before limiting the execution.  See command flags
+       for more detail.
 
-   SilcPKCS pkcs
+   SilcServerEntry router
 
-       PKCS of the client. This maybe NULL.
+       This is a pointer to the server list. This is the router server whose 
+       cell this client is coming from. This is used to route messages to 
+       this client.
 
-   SilcHmac hmac
-   unsigned char *hmac_key
-   unsigned int hmac_key_len
+   SilcHashTable channels;
 
-       MAC key used to compute MAC's for packets. 
+       All the channels this client has joined.  The context saved in the
+       hash table shares memory with the channel entrys `user_list' hash
+       table.
 
    void *connection
 
@@ -196,68 +314,51 @@ struct SilcServerListStruct {
        but as just said, this is usually pointer to the socket connection
        list.
 
+   uint16 resolve_cmd_ident
+
+       Command identifier for the entry when the entry's data.status
+       is SILC_IDLIST_STATUS_RESOLVING.  If this entry is asked to be
+       resolved when the status is set then the resolver may attach to
+       this command identifier and handle the process after the resolving
+       is over.
+
 */
-struct SilcClientListStruct {
-  char *nickname;
+struct SilcClientEntryStruct {
+  /* Generic data structure. DO NOT add anything before this! */
+  SilcIDListDataStruct data;
+
+  unsigned char *nickname;
+  char *servername;
   char *username;
   char *userinfo;
   SilcClientID *id;
-  int mode;
+  uint32 mode;
 
-  /* TRUE when client is registered to server */
-  int registered;
+  long last_command;
+  uint8 fast_command;
 
   /* Pointer to the router */
-  SilcServerList *router;
+  SilcServerEntry router;
 
-  /* Pointers to channels this client has joined */
-  SilcChannelList **channel;
-  unsigned int channel_count;
-
-  /* Keys */
-  SilcCipher send_key;
-  SilcCipher receive_key;
-  SilcPKCS pkcs;
-  SilcHmac hmac;
-  unsigned char *hmac_key;
-  unsigned int hmac_key_len;
+  /* All channels this client has joined */
+  SilcHashTable channels;
 
   /* Connection data */
   void *connection;
 
-  struct SilcClientListStruct *next;
-  struct SilcClientListStruct *prev;
+  /* data.status is RESOLVING and this includes the resolving command 
+     reply identifier. */
+  uint16 resolve_cmd_ident;
 };
 
 /* 
-   SILC Channel Client list structure.
-
-   This list used only by the SilcChannelList object and it holds information 
-   about current clients (ie. users) on channel. Following short description 
-   of the fields:
-
-   SilcClientList client
-
-       Pointer to the client list. This is the client currently on channel.
-
-   int mode
-
-       Client's current mode on the channel.
-
-*/
-typedef struct SilcChannelClientListStruct {
-  SilcClientList *client;
-  int mode;
-} SilcChannelClientList;
-
-/* 
-   SILC Channel list object.
+   SILC Channel entry object.
 
-   This list holds information about channels in SILC network. The contents 
-   of this list is depended on whether we are normal server or router server 
+   This entry holds information about channels in SILC network. The contents 
+   of this entry is depended on whether we are normal server or router server 
    and whether the list is a local or global list.
 
-   This list is defined as follows:
+   This entry is defined as follows:
 
    Server type   List type      Contents
    =======================================================================
@@ -272,16 +373,17 @@ typedef struct SilcChannelClientListStruct {
 
        Logical name of the channel.
 
-   int mode
+   uint32 mode
 
-       Current mode of the channel.
+       Current mode of the channel.  See lib/silccore/silcchannel.h for
+       all modes.
 
    SilcChannelID *id
 
        ID of the channel. This includes all the information SILC will ever
        need.
 
-   int global_users
+   bool global_users
  
        Boolean value to tell whether there are users outside this server
        on this channel. This is set to TRUE if router sends message to
@@ -295,40 +397,96 @@ typedef struct SilcChannelClientListStruct {
 
        Current topic of the channel.
 
-   SilcServerList *router
+   char *cipher
+
+       Default cipher of the channel. If this is NULL then server picks
+       the cipher to be used. This can be set at SILC_COMMAND_JOIN.
+
+   char *hmac_name
+
+       Default hmac of the channel. If this is NULL then server picks
+       the cipher to be used. This can be set at SILC_COMMAND_JOIN.
+
+   SilcPublicKey founder_key
+   SilcAuthMethod founder_method
+   unsigned char *founder_passwd
+   uint32 founder_passwd_len
+
+       If the SILC_CMODE_FOUNDER_AUTH has been set then these will include
+       the founder's public key, authentication method and the password
+       if the method is SILC_AUTH_PASSWORD.  If it is SILC_AUTH_PUBLIC_KEY
+       then the `founder_passwd' is NULL.
+
+   SilcHashTable user_list
+
+       All users joined on this channel.  Note that the context saved to
+       this entry shares memory with the client entrys `channels' hash
+       table.
+
+   SilcServerEntry router
 
        This is a pointer to the server list. This is the router server 
        whose cell this channel belongs to. This is used to route messages 
        to this channel.
 
-   SilcCipher send_key
+   SilcCipher channel_key
 
+       The key of the channel (the cipher actually).
 
-   SilcCipher receive_key
+   unsigned char *key
+   uint32 key_len
+
+       Raw key data of the channel key.
+
+   unsigned char iv[SILC_CIPHER_MAX_IV_SIZE]
+
+       Current initial vector. Initial vector is received always along
+       with the channel packet. By default this is filled with NULL.
+
+   SilcHmac hmac;
+
+       HMAC of the channel.
+
+   SilcServerChannelRekey rekey
+
+       Channel key re-key context.
 
 */
-struct SilcChannelListStruct {
+struct SilcChannelEntryStruct {
   char *channel_name;
-  int mode;
+  uint32 mode;
   SilcChannelID *id;
-  int global_users;
+  bool global_users;
   char *topic;
+  char *cipher;
+  char *hmac_name;
+
+  SilcPublicKey founder_key;
+  SilcAuthMethod founder_method;
+  unsigned char *founder_passwd;
+  uint32 founder_passwd_len;
 
-  /* List of users on channel */
-  SilcChannelClientList *user_list;
-  unsigned int user_list_count;
+  uint32 user_limit;
+  unsigned char *passphrase;
+  char *invite_list;
+  char *ban_list;
+
+  /* All users on this channel */
+  SilcHashTable user_list;
 
   /* Pointer to the router */
-  SilcServerList *router;
+  SilcServerEntry router;
 
   /* Channel keys */
   SilcCipher channel_key;
   unsigned char *key;
-  unsigned int key_len;
+  uint32 key_len;
   unsigned char iv[SILC_CIPHER_MAX_IV_SIZE];
+  SilcHmac hmac;
 
-  struct SilcChannelListStruct *next;
-  struct SilcChannelListStruct *prev;
+  SilcServerChannelRekey rekey;
+
+  unsigned long created;
 };
 
 /* 
@@ -336,22 +494,22 @@ struct SilcChannelListStruct {
 
    As for remainder these lists are defined as follows:
 
-   List        Server type   List type      Contents
+   Entry list (cache)  Server type   List type      Contents
    =======================================================================
-   servers     server        local list     Server itself
-   servers     server        global list    NULL
-   servers     router        local list     All servers in cell
-   servers     router        global list    All servers in SILC
+   servers             server        local list     Server itself
+   servers             server        global list    NULL
+   servers             router        local list     All servers in cell
+   servers             router        global list    All servers in SILC
 
-   clients     server        local list     All clients in server
-   clients     server        global list    NULL
-   clients     router        local list     All clients in cell
-   clients     router        global list    All clients in SILC
+   clients             server        local list     All clients in server
+   clients             server        global list    NULL
+   clients             router        local list     All clients in cell
+   clients             router        global list    All clients in SILC
 
-   channels    server        local list     All channels in server
-   channels    server        global list    NULL
-   channels    router        local list     All channels in cell
-   channels    router        global list    All channels in SILC
+   channels            server        local list     All channels in server
+   channels            server        global list    NULL
+   channels            router        local list     All channels in cell
+   channels            router        global list    All channels in SILC
 
    As seen on the list normal server never defines a global list. This is
    because of normal server don't know anything about anything global data,
@@ -359,78 +517,96 @@ struct SilcChannelListStruct {
    other hand, always define local and global lists because routers really
    know all the relevant data in the SILC network.
 
-*/
-typedef struct SilcIDListStruct {
-  SilcServerList *servers;
-  SilcClientList *clients;
-  SilcChannelList *channels;
+   This object is used as local and global list by the server/router.
+   Above table shows how this is defined on different conditions.
 
-  /* ID Caches. Caches are used to perform fast search on the ID's. */
-  SilcIDCache *server_cache[96];
-  unsigned int server_cache_count[96];
-  SilcIDCache *client_cache[96];
-  unsigned int client_cache_count[96];
-  SilcIDCache *channel_cache[96];
-  unsigned int channel_cache_count[96];
-} SilcIDListObject;
+   This object holds pointers to the ID cache system. Every ID cache entry
+   has a specific context pointer to allocated entry (server, client or
+   channel entry).
 
-typedef SilcIDListObject *SilcIDList;
+*/
+typedef struct SilcIDListStruct {
+  SilcIDCache servers;
+  SilcIDCache clients;
+  SilcIDCache channels;
+} *SilcIDList;
 
 /*
-   Temporary ID List object.
+   ID Entry for Unknown connections.
 
-   This is used during authentication phases where we still don't
-   know what kind of connection remote connection is, hence, we
-   will use this structure instead until we know what type of
-   connection remote end is.
+   This is used during authentication phases where we still don't know 
+   what kind of connection remote connection is, hence, we will use this
+   structure instead until we know what type of connection remote end is.
 
-   This is not in any list. This is always individually allocated
-   and used as such.
+   This is not in any list. This is always individually allocated and
+   used as such.
 
 */
 typedef struct {
-  SilcCipher send_key;
-  SilcCipher receive_key;
-  SilcPKCS pkcs;
-  SilcPublicKey public_key;
-
-  SilcHmac hmac;
-  unsigned char *hmac_key;
-  unsigned int hmac_key_len;
-
-  /* SilcComp comp */
-} SilcIDListUnknown;
+  /* Generic data structure. DO NOT add anything before this! */
+  SilcIDListDataStruct data;
+} *SilcUnknownEntry;
 
 /* Prototypes */
-void silc_idlist_add_server(SilcServerList **list, 
-                           char *server_name, int server_type,
-                           SilcServerID *id, SilcServerList *router,
-                           SilcCipher send_key, SilcCipher receive_key,
-                           SilcPKCS public_key, SilcHmac hmac, 
-                           SilcServerList **new_idlist);
-void silc_idlist_add_client(SilcClientList **list, char *nickname,
-                           char *username, char *userinfo,
-                           SilcClientID *id, SilcServerList *router,
-                           SilcCipher send_key, SilcCipher receive_key,
-                           SilcPKCS public_key, SilcHmac hmac, 
-                           SilcClientList **new_idlist);
-void silc_idlist_del_client(SilcClientList **list, SilcClientList *entry);
-SilcClientList *
-silc_idlist_find_client_by_nickname(SilcClientList *list,
-                                   char *nickname,
-                                   char *server);
-SilcClientList *
-silc_idlist_find_client_by_hash(SilcClientList *list,
-                               char *nickname, SilcHash hash);
-SilcClientList *
-silc_idlist_find_client_by_id(SilcClientList *list, SilcClientID *id);
-void silc_idlist_add_channel(SilcChannelList **list, 
-                            char *channel_name, int mode,
-                            SilcChannelID *id, SilcServerList *router,
-                            SilcCipher channel_key,
-                            SilcChannelList **new_idlist);
-SilcChannelList *
-silc_idlist_find_channel_by_id(SilcChannelList *list, SilcChannelID *id);
-void silc_idlist_del_channel(SilcChannelList **list, SilcChannelList *entry);
+void silc_idlist_add_data(void *entry, SilcIDListData idata);
+void silc_idlist_del_data(void *entry);
+SILC_TASK_CALLBACK_GLOBAL(silc_idlist_purge);
+SilcServerEntry 
+silc_idlist_add_server(SilcIDList id_list, 
+                      char *server_name, int server_type,
+                      SilcServerID *id, SilcServerEntry router,
+                      void *connection);
+SilcServerEntry
+silc_idlist_find_server_by_id(SilcIDList id_list, SilcServerID *id,
+                             bool registered, SilcIDCacheEntry *ret_entry);
+SilcServerEntry
+silc_idlist_find_server_by_name(SilcIDList id_list, char *name,
+                               bool registered, SilcIDCacheEntry *ret_entry);
+SilcServerEntry
+silc_idlist_find_server_by_conn(SilcIDList id_list, char *hostname,
+                               int port, bool registered,
+                               SilcIDCacheEntry *ret_entry);
+SilcServerEntry
+silc_idlist_replace_server_id(SilcIDList id_list, SilcServerID *old_id,
+                             SilcServerID *new_id);
+int silc_idlist_del_server(SilcIDList id_list, SilcServerEntry entry);
+SilcClientEntry
+silc_idlist_add_client(SilcIDList id_list, char *nickname, char *username, 
+                      char *userinfo, SilcClientID *id, 
+                      SilcServerEntry router, void *connection);
+int silc_idlist_del_client(SilcIDList id_list, SilcClientEntry entry);
+int silc_idlist_get_clients_by_nickname(SilcIDList id_list, char *nickname,
+                                       char *server, 
+                                       SilcClientEntry **clients,
+                                       uint32 *clients_count);
+int silc_idlist_get_clients_by_hash(SilcIDList id_list, char *nickname,
+                                   SilcHash md5hash,
+                                   SilcClientEntry **clients,
+                                   uint32 *clients_count);
+SilcClientEntry
+silc_idlist_find_client_by_id(SilcIDList id_list, SilcClientID *id,
+                             bool registered, SilcIDCacheEntry *ret_entry);
+SilcClientEntry
+silc_idlist_replace_client_id(SilcIDList id_list, SilcClientID *old_id,
+                             SilcClientID *new_id);
+void silc_idlist_client_destructor(SilcIDCache cache,
+                                  SilcIDCacheEntry entry);
+SilcChannelEntry
+silc_idlist_add_channel(SilcIDList id_list, char *channel_name, int mode,
+                       SilcChannelID *id, SilcServerEntry router,
+                       SilcCipher channel_key, SilcHmac hmac);
+int silc_idlist_del_channel(SilcIDList id_list, SilcChannelEntry entry);
+SilcChannelEntry
+silc_idlist_find_channel_by_name(SilcIDList id_list, char *name,
+                                SilcIDCacheEntry *ret_entry);
+SilcChannelEntry
+silc_idlist_find_channel_by_id(SilcIDList id_list, SilcChannelID *id,
+                              SilcIDCacheEntry *ret_entry);
+SilcChannelEntry
+silc_idlist_replace_channel_id(SilcIDList id_list, SilcChannelID *old_id,
+                              SilcChannelID *new_id);
+SilcChannelEntry *
+silc_idlist_get_channels(SilcIDList id_list, SilcChannelID *channel_id,
+                        uint32 *channels_count);
 
 #endif