Fixed socket connection counting. Added checks for not adding
[silc.git] / apps / silcd / idlist.c
index 9503742f82e7c66fb08d48536047bf608d2ca01e..deae122dbc23af2326be56f64ecc7b7746b220cc 100644 (file)
@@ -76,6 +76,14 @@ void silc_idlist_del_data(void *entry)
     silc_hash_free(idata->hash);
   if (idata->public_key)
     silc_pkcs_public_key_free(idata->public_key);
+
+  idata->send_key = NULL;
+  idata->receive_key = NULL;
+  idata->rekey = NULL;
+  idata->hmac_send = NULL;
+  idata->hmac_receive = NULL;
+  idata->hash = NULL;
+  idata->public_key = NULL;
 }
 
 /* Purges ID cache */
@@ -84,7 +92,7 @@ SILC_TASK_CALLBACK_GLOBAL(silc_idlist_purge)
 {
   SilcIDListPurge i = (SilcIDListPurge)context;
 
-  SILC_LOG_DEBUG(("Start"));
+  SILC_LOG_DEBUG(("Purging cache"));
 
   silc_idcache_purge(i->cache);
   silc_schedule_task_add(i->schedule, 0, 
@@ -282,17 +290,18 @@ silc_idlist_replace_server_id(SilcIDList id_list, SilcServerID *old_id,
 
 int silc_idlist_del_server(SilcIDList id_list, SilcServerEntry entry)
 {
-  SILC_LOG_DEBUG(("Start"));
-
   if (entry) {
     /* Remove from cache */
-    if (entry->id)
-      if (!silc_idcache_del_by_id(id_list->servers, (void *)entry->id))
-       return FALSE;
+    if (!silc_idcache_del_by_context(id_list->servers, entry))
+      return FALSE;
+
+    SILC_LOG_DEBUG(("Deleting server %s", entry->server_name ?
+                   entry->server_name : ""));
 
     /* Free data */
     silc_free(entry->server_name);
     silc_free(entry->id);
+    silc_free(entry->server_info);
 
     memset(entry, 'F', sizeof(*entry));
     silc_free(entry);
@@ -356,12 +365,14 @@ int silc_idlist_del_client(SilcIDList id_list, SilcClientEntry entry)
 
   if (entry) {
     /* Remove from cache */
-    if (entry->id)
-      if (!silc_idcache_del_by_context(id_list->clients, entry))
-       return FALSE;
+    if (!silc_idcache_del_by_context(id_list->clients, entry))
+      return FALSE;
+
+    assert(!silc_hash_table_count(entry->channels));
 
     /* Free data */
     silc_free(entry->nickname);
+    silc_free(entry->servername);
     silc_free(entry->username);
     silc_free(entry->userinfo);
     silc_free(entry->id);
@@ -526,7 +537,7 @@ silc_idlist_replace_client_id(SilcServer server,
   if (!silc_idcache_del_by_context(id_list->clients, client))
     return NULL;
 
-  /* Check if anyone is watching this nickname */
+  /* Check if anyone is watching old nickname */
   if (server->server_type == SILC_ROUTER)
     silc_server_check_watcher_list(server, client, nickname,
                                   SILC_NOTIFY_TYPE_NICK_CHANGE);
@@ -536,6 +547,11 @@ silc_idlist_replace_client_id(SilcServer server,
   client->id = new_id;
   client->nickname = nickname ? strdup(nickname) : NULL;
 
+  /* Check if anyone is watching new nickname */
+  if (server->server_type == SILC_ROUTER)
+    silc_server_check_watcher_list(server, client, nickname,
+                                  SILC_NOTIFY_TYPE_NICK_CHANGE);
+
   if (!silc_idcache_add(id_list->clients, client->nickname, client->id, 
                        client, 0, NULL))
     return NULL;
@@ -560,7 +576,7 @@ void silc_idlist_client_destructor(SilcIDCache cache,
     silc_free(client->id);
     silc_hash_table_free(client->channels);
 
-    memset(client, 'F', sizeof(*client));
+    memset(client, 'A', sizeof(*client));
     silc_free(client);
   }
 }
@@ -582,7 +598,7 @@ silc_idlist_add_channel(SilcIDList id_list, char *channel_name, int mode,
 {
   SilcChannelEntry channel;
 
-  SILC_LOG_DEBUG(("Adding new channel entry"));
+  SILC_LOG_DEBUG(("Adding new channel %s", channel_name));
 
   channel = silc_calloc(1, sizeof(*channel));
   channel->channel_name = channel_name;
@@ -591,7 +607,7 @@ silc_idlist_add_channel(SilcIDList id_list, char *channel_name, int mode,
   channel->router = router;
   channel->channel_key = channel_key;
   channel->hmac = hmac;
-  channel->created = time(0);
+  channel->created = channel->updated = time(0);
   if (!channel->hmac)
     if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
       silc_free(channel);
@@ -621,7 +637,8 @@ static void silc_idlist_del_channel_foreach(void *key, void *context,
   SilcChannelClientEntry chl = (SilcChannelClientEntry)context;
 
   SILC_LOG_DEBUG(("Removing client %s from channel %s",
-                 chl->client->nickname, chl->channel->channel_name));
+                 chl->client->nickname ? chl->client->nickname :
+                 (unsigned char *)"", chl->channel->channel_name));
 
   /* Remove the context from the client's channel hash table as that
      table and channel's user_list hash table share this same context. */
@@ -633,13 +650,12 @@ static void silc_idlist_del_channel_foreach(void *key, void *context,
 
 int silc_idlist_del_channel(SilcIDList id_list, SilcChannelEntry entry)
 {
-  SILC_LOG_DEBUG(("Start"));
-
   if (entry) {
     /* Remove from cache */
-    if (entry->id)
-      if (!silc_idcache_del_by_id(id_list->channels, (void *)entry->id))
-       return FALSE;
+    if (!silc_idcache_del_by_context(id_list->channels, entry))
+      return FALSE;
+
+    SILC_LOG_DEBUG(("Deleting channel %s", entry->channel_name));
 
     /* Free all client entrys from the users list. The silc_hash_table_free
        will free all the entries so they are not freed at the foreach 
@@ -693,6 +709,9 @@ silc_idlist_find_channel_by_name(SilcIDList id_list, char *name,
 
   SILC_LOG_DEBUG(("Found"));
 
+  /* Touch channel */
+  ((SilcChannelEntry)id_cache->context)->updated = time(NULL);
+
   return id_cache->context;
 }
 
@@ -721,6 +740,9 @@ silc_idlist_find_channel_by_id(SilcIDList id_list, SilcChannelID *id,
 
   SILC_LOG_DEBUG(("Found"));
 
+  /* Touch channel */
+  channel->updated = time(NULL);
+
   return channel;
 }
 
@@ -757,6 +779,9 @@ silc_idlist_replace_channel_id(SilcIDList id_list, SilcChannelID *old_id,
 
   SILC_LOG_DEBUG(("Replaced"));
 
+  /* Touch channel */
+  channel->updated = time(NULL);
+
   return channel;
 }