Added debug logs for updating stat.clients value
[silc.git] / apps / silcd / server_util.c
index 345419a25a9568bf6b77a87f4afdbc1e017ce963..1b8249a561c401a5b36f8f1f19e282b7d8539958 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2008 Pekka Riikonen
+  Copyright (C) 1997 - 2009 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
@@ -119,7 +119,7 @@ silc_server_remove_clients_channels(SilcServer server,
       silc_hash_table_add(channels, channel, channel);
   }
   silc_hash_table_list_reset(&htl);
-  assert(!silc_hash_table_count(client->channels));
+  SILC_VERIFY(!silc_hash_table_count(client->channels));
 }
 
 /* This function removes all client entries that are originated from
@@ -205,6 +205,9 @@ SilcBool silc_server_remove_clients_by_server(SilcServer server,
       }
 
       /* Update statistics */
+      SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
+                     server->stat.clients - 1));
+      SILC_VERIFY(server->stat.clients > 0);
       server->stat.clients--;
       if (server->stat.cell_clients)
        server->stat.cell_clients--;
@@ -228,6 +231,8 @@ SilcBool silc_server_remove_clients_by_server(SilcServer server,
        client->mode = 0;
        client->router = NULL;
        client->connection = NULL;
+       client->data.created = silc_time();
+       silc_dlist_del(server->expired_clients, client);
        silc_dlist_add(server->expired_clients, client);
       } else {
        silc_idlist_del_data(client);
@@ -266,6 +271,9 @@ SilcBool silc_server_remove_clients_by_server(SilcServer server,
       }
 
       /* Update statistics */
+      SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
+                     server->stat.clients - 1));
+      SILC_VERIFY(server->stat.clients > 0);
       server->stat.clients--;
       if (server->stat.cell_clients)
        server->stat.cell_clients--;
@@ -289,6 +297,8 @@ SilcBool silc_server_remove_clients_by_server(SilcServer server,
        client->mode = 0;
        client->router = NULL;
        client->connection = NULL;
+       client->data.created = silc_time();
+       silc_dlist_del(server->expired_clients, client);
        silc_dlist_add(server->expired_clients, client);
       } else {
        silc_idlist_del_data(client);
@@ -1195,6 +1205,7 @@ SilcBool silc_server_connection_allowed(SilcServer server,
       silc_server_disconnect_remote(server, sock,
                                    SILC_STATUS_ERR_BAD_VERSION,
                                    "You support too old protocol version");
+      silc_server_free_sock_user_data(server, sock, NULL);
       return FALSE;
     }
 
@@ -1206,6 +1217,7 @@ SilcBool silc_server_connection_allowed(SilcServer server,
       silc_server_disconnect_remote(server, sock,
                                    SILC_STATUS_ERR_BAD_VERSION,
                                    "You support too old software version");
+      silc_server_free_sock_user_data(server, sock, NULL);
       return FALSE;
     }
 
@@ -1217,6 +1229,7 @@ SilcBool silc_server_connection_allowed(SilcServer server,
       silc_server_disconnect_remote(server, sock,
                                    SILC_STATUS_ERR_BAD_VERSION,
                                    "Your software is not supported");
+      silc_server_free_sock_user_data(server, sock, NULL);
       return FALSE;
     }
   }
@@ -1236,6 +1249,7 @@ SilcBool silc_server_connection_allowed(SilcServer server,
     silc_server_disconnect_remote(server, sock,
                                  SILC_STATUS_ERR_RESOURCE_LIMIT,
                                  "Server is full, try again later");
+    silc_server_free_sock_user_data(server, sock, NULL);
     return FALSE;
   }
 
@@ -1247,6 +1261,7 @@ SilcBool silc_server_connection_allowed(SilcServer server,
     silc_server_disconnect_remote(server, sock,
                                  SILC_STATUS_ERR_RESOURCE_LIMIT,
                                  "Too many connections from your host");
+    silc_server_free_sock_user_data(server, sock, NULL);
     return FALSE;
   }
 
@@ -1538,10 +1553,22 @@ void silc_server_kill_client(SilcServer server,
   if (remote_client->connection) {
     /* Remove locally conneted client */
     SilcPacketStream sock = remote_client->connection;
-    silc_server_free_client_data(server, sock, remote_client, FALSE, NULL);
-    silc_server_close_connection(server, sock);
+
+    if (sock)
+      silc_packet_stream_ref(sock);
+
+    silc_server_free_sock_user_data(server, sock, NULL);
+
+    if (sock) {
+      silc_packet_set_context(sock, NULL);
+      silc_server_close_connection(server, sock);
+      silc_packet_stream_unref(sock);
+    }
   } else {
     /* Update statistics */
+    SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
+                   server->stat.clients - 1));
+    SILC_VERIFY(server->stat.clients > 0);
     server->stat.clients--;
     if (server->stat.cell_clients)
       server->stat.cell_clients--;
@@ -1556,11 +1583,13 @@ void silc_server_kill_client(SilcServer server,
     }
 
     if (SILC_IS_LOCAL(remote_client)) {
-      server->stat.my_clients--;
+      if (!remote_client->local_detached)
+        server->stat.my_clients--;
       silc_schedule_task_del_by_context(server->schedule, remote_client);
     }
 
     /* Remove remote client */
+    silc_dlist_del(server->expired_clients, remote_client);
     silc_idlist_del_data(remote_client);
     if (!silc_idlist_del_client(server->global_list, remote_client)) {
       /* Remove this client from watcher list if it is */
@@ -1753,10 +1782,11 @@ SilcBool silc_server_inviteban_match(SilcServer server, SilcHashTable list,
                                     SilcUInt8 type, void *check)
 {
   unsigned char *tmp = NULL;
-  SilcUInt32 len = 0, t;
+  SilcUInt32 len = 0;
   SilcHashTableList htl;
   SilcBuffer entry, idp = NULL, pkp = NULL;
   SilcBool ret = FALSE;
+  void *t;
 
   SILC_LOG_DEBUG(("Matching invite/ban"));
 
@@ -1786,13 +1816,14 @@ SilcBool silc_server_inviteban_match(SilcServer server, SilcHashTable list,
   /* Compare the list */
   silc_hash_table_list(list, &htl);
   while (silc_hash_table_get(&htl, (void *)&t, (void *)&entry)) {
-    if (type == t) {
+    if (type == SILC_PTR_TO_32(t)) {
       if (type == 1) {
        if (silc_string_match(entry->data, tmp)) {
          ret = TRUE;
          break;
        }
-      } else if (!memcmp(entry->data, tmp, len)) {
+      } else if (silc_buffer_len(entry) == len &&
+                !memcmp(entry->data, tmp, len)) {
        ret = TRUE;
        break;
       }
@@ -1816,6 +1847,7 @@ SilcBool silc_server_inviteban_process(SilcServer server,
 {
   unsigned char *tmp;
   SilcUInt32 type, len;
+  void *ptype;
   SilcBuffer tmp2;
   SilcHashTableList htl;
 
@@ -1842,8 +1874,9 @@ SilcBool silc_server_inviteban_process(SilcServer server,
 
        /* Check if the string is added already */
        silc_hash_table_list(list, &htl);
-       while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
-         if (type == 1 && silc_string_match(tmp2->data, tmp)) {
+       while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
+         if (SILC_PTR_TO_32(ptype) == 1 &&
+             silc_string_match(tmp2->data, tmp)) {
            tmp = NULL;
            break;
          }
@@ -1873,8 +1906,8 @@ SilcBool silc_server_inviteban_process(SilcServer server,
 
        /* Check if the public key is in the list already */
        silc_hash_table_list(list, &htl);
-       while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
-         if (type == 2 && !memcmp(tmp2->data, tmp, len)) {
+       while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
+         if (SILC_PTR_TO_32(ptype) == 2 && !memcmp(tmp2->data, tmp, len)) {
            tmp = NULL;
            break;
          }
@@ -1893,8 +1926,8 @@ SilcBool silc_server_inviteban_process(SilcServer server,
 
        /* Check if the ID is in the list already */
        silc_hash_table_list(list, &htl);
-       while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
-         if (type == 3 && !memcmp(tmp2->data, tmp, len)) {
+       while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
+         if (SILC_PTR_TO_32(ptype) == 3 && !memcmp(tmp2->data, tmp, len)) {
            tmp = NULL;
            break;
          }
@@ -1932,8 +1965,9 @@ SilcBool silc_server_inviteban_process(SilcServer server,
 
        /* Delete from the list */
        silc_hash_table_list(list, &htl);
-       while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
-         if (type == 1 && silc_string_match(tmp2->data, tmp)) {
+       while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
+         if (SILC_PTR_TO_32(ptype) == 1 &&
+             silc_string_match(tmp2->data, tmp)) {
            silc_hash_table_del_by_context(list, (void *)1, tmp2);
            break;
          }
@@ -1953,8 +1987,8 @@ SilcBool silc_server_inviteban_process(SilcServer server,
 
        /* Delete from the invite list */
        silc_hash_table_list(list, &htl);
-       while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
-         if (type == 2 && !memcmp(tmp2->data, tmp, len)) {
+       while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
+         if (SILC_PTR_TO_32(ptype) == 2 && !memcmp(tmp2->data, tmp, len)) {
            silc_hash_table_del_by_context(list, (void *)2, tmp2);
            break;
          }
@@ -1966,8 +2000,8 @@ SilcBool silc_server_inviteban_process(SilcServer server,
 
        /* Delete from the invite list */
        silc_hash_table_list(list, &htl);
-       while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
-         if (type == 3 && !memcmp(tmp2->data, tmp, len)) {
+       while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
+         if (SILC_PTR_TO_32(ptype) == 3 && !memcmp(tmp2->data, tmp, len)) {
            silc_hash_table_del_by_context(list, (void *)3, tmp2);
            break;
          }
@@ -1994,6 +2028,8 @@ void silc_server_inviteban_destruct(void *key, void *context,
 
 void silc_server_create_connections(SilcServer server)
 {
+  silc_schedule_task_del_by_callback(server->schedule,
+                                    silc_server_connect_to_router_retry);
   silc_schedule_task_del_by_callback(server->schedule,
                                     silc_server_connect_to_router);
   silc_schedule_task_add_timeout(server->schedule,
@@ -2097,6 +2133,8 @@ SilcBuffer silc_server_get_channel_pk_list(SilcServer server,
   silc_hash_table_list(channel->channel_pubkeys, &htl);
   while (silc_hash_table_get(&htl, NULL, (void *)&pk)) {
     pkp = silc_public_key_payload_encode(pk);
+    if (!pkp)
+      continue;
     list = silc_argument_payload_encode_one(list, pkp->data,
                                            silc_buffer_len(pkp),
                                            announce ? 0x03 :