Memory leak fixes.
[silc.git] / apps / silcd / packet_receive.c
index c721c1038cb293d74000dd6d880fc68cacad2f4a..2068c18bdf8219b817f6efa9e57d528f6ba5cc76 100644 (file)
@@ -173,8 +173,10 @@ void silc_server_notify(SilcServer server,
                                             NULL);
       if (!client) {
        /* If router did not find the client the it is bogus */
-       if (server->server_type != SILC_SERVER)
+       if (server->server_type != SILC_SERVER) {
+         silc_free(client_id);
          goto out;
+       }
 
        client = 
          silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
@@ -189,6 +191,7 @@ void silc_server_notify(SilcServer server,
        client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
       }
     }
+    silc_free(client_id);
 
     /* Do not process the notify if the client is not registered */
     if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
@@ -233,7 +236,6 @@ void silc_server_notify(SilcServer server,
 
     silc_hash_table_add(channel->user_list, client, chl);
     silc_hash_table_add(client->channels, channel, chl);
-    silc_free(client_id);
     channel->user_count++;
     channel->disabled = FALSE;
 
@@ -422,6 +424,7 @@ void silc_server_notify(SilcServer server,
        goto out;
       }
     }
+    silc_free(channel_id);
 
     if (channel->topic && !strcmp(channel->topic, tmp)) {
       SILC_LOG_DEBUG(("Topic is already set and same"));
@@ -448,7 +451,6 @@ void silc_server_notify(SilcServer server,
     silc_server_packet_send_to_channel(server, NULL, channel, packet->type, 
                                       FALSE, packet->buffer->data, 
                                       packet->buffer->len, FALSE);
-    silc_free(channel_id);
     break;
 
   case SILC_NOTIFY_TYPE_NICK_CHANGE:
@@ -475,8 +477,10 @@ void silc_server_notify(SilcServer server,
       if (!id2)
        goto out;
       client_id2 = silc_id_payload_parse_id(id2, tmp_len, NULL);
-      if (!client_id2)
+      if (!client_id2) {
+       silc_free(client_id);
        goto out;
+      }
       
       SILC_LOG_DEBUG(("Old Client ID id(%s)", 
                      silc_id_render(client_id, SILC_ID_CLIENT)));
@@ -1284,6 +1288,7 @@ void silc_server_notify(SilcServer server,
              silc_server_del_from_watcher_list(server, client);
 
            /* Remove the client */
+           silc_idlist_del_data(client);
            silc_idlist_del_client(local ? server->local_list :
                                   server->global_list, client);
          }
@@ -1578,6 +1583,8 @@ void silc_server_notify(SilcServer server,
          server->stat.detached--;
       }
     }
+    SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
+    SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
 
     /* Change the mode */
     client->mode = mode;
@@ -1684,6 +1691,7 @@ void silc_server_notify(SilcServer server,
          if (client) {
            silc_server_remove_from_channels(server, NULL, client, TRUE, 
                                             NULL, TRUE);
+           silc_idlist_del_data(client);
            silc_idlist_del_client(server->global_list, client);
          }
          silc_free(client_id);
@@ -2874,7 +2882,7 @@ void silc_server_new_channel(SilcServer server,
                                0, channel_id, sock->user_data, NULL, NULL, 0);
       if (!channel)
        return;
-      channel->disabled = TRUE;
+      channel->disabled = TRUE;    /* Disabled until someone JOINs */
 
       server->stat.channels++;
       if (server->server_type == SILC_ROUTER)
@@ -2929,9 +2937,16 @@ void silc_server_new_channel(SilcServer server,
        silc_free(channel_id);
        return;
       }
-      channel->disabled = TRUE;
+      channel->disabled = TRUE;    /* Disabled until someone JOINs */
+
+#if 0 /* We assume that CMODE_CHANGE notify is sent to us after this. */
+
+      /* XXX Dunno if this is supposed to be set in any server type.  If set
+        here the CMODE_CHANGE that may follow sets mode that we already
+        have, and we may loose data from the CMODE_CHANGE notify. */
       if (server_entry->server_type != SILC_BACKUP_ROUTER)
        channel->mode = silc_channel_get_mode(payload);
+#endif
 
       /* Send the new channel key to the server */
       id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
@@ -3370,6 +3385,7 @@ void silc_server_resume_client(SilcServer server,
 {
   SilcBuffer buffer = packet->buffer, buf;
   SilcIDListData idata;
+  SilcIDCacheEntry id_cache = NULL;
   SilcClientEntry detached_client;
   SilcClientID *client_id = NULL;
   unsigned char *id_string, *auth = NULL;
@@ -3606,7 +3622,8 @@ void silc_server_resume_client(SilcServer server,
       server->stat.cell_clients--;
     silc_server_remove_from_channels(server, NULL, client, FALSE, NULL, FALSE);
     silc_server_del_from_watcher_list(server, client);
-    silc_idlist_del_client(server->local_list, client);
+    if (!silc_idlist_del_client(server->local_list, client))
+      silc_idlist_del_client(server->global_list, client);
     client = detached_client;
 
     /* If the ID is not based in our ID then change it */
@@ -3740,10 +3757,12 @@ void silc_server_resume_client(SilcServer server,
 
     /* Get entry to the client, and resolve it if we don't have it. */
     detached_client = silc_idlist_find_client_by_id(server->local_list, 
-                                                   client_id, TRUE, NULL);
+                                                   client_id, TRUE,
+                                                   &id_cache);
     if (!detached_client) {
       detached_client = silc_idlist_find_client_by_id(server->global_list,
-                                                     client_id, TRUE, NULL);
+                                                     client_id, TRUE,
+                                                     &id_cache);
       if (!detached_client) {
        SILC_LOG_DEBUG(("Resuming client is unknown"));
        silc_free(client_id);
@@ -3796,6 +3815,7 @@ void silc_server_resume_client(SilcServer server,
     detached_client->mode &= ~SILC_UMODE_DETACHED;
     detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
     detached_client->data.status &= ~SILC_IDLIST_STATUS_LOCAL;
+    id_cache->expire = 0;
 
     /* Update channel information regarding global clients on channel. */
     if (server->server_type == SILC_SERVER) {