Fixed socket connection counting. Added checks for not adding
[silc.git] / apps / silcd / server.c
index cc772361c46533c3036059ae928ac873495bdbfd..63e3a609231a6dac52298a1cb4620a959b2b04ac 100644 (file)
@@ -923,7 +923,8 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router)
                    ptr->host, ptr->port));
 
     if (server->server_type == SILC_ROUTER && ptr->backup_router &&
-       ptr->initiator == FALSE && !server->backup_router)
+       ptr->initiator == FALSE && !server->backup_router &&
+       !silc_server_config_get_backup_router(server))
       server->wait_backup = TRUE;
 
     if (ptr->initiator) {
@@ -1915,6 +1916,12 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
        if (backup_local)
          ctx->conn_type = SILC_SOCKET_TYPE_SERVER;
        new_server->server_type = SILC_BACKUP_ROUTER;
+
+       /* Remove the backup waiting with timeout */
+       silc_schedule_task_add(server->schedule, 0,
+                              silc_server_backup_router_wait,
+                              (void *)server, 5, 0,
+                              SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
       }
 
       /* Statistics */
@@ -2153,6 +2160,11 @@ SILC_TASK_CALLBACK(silc_server_packet_parse_real)
     SILC_LOG_DEBUG(("Connection is disabled"));
     goto out;
   }
+  if (ret != SILC_PACKET_HEARTBEAT &&
+      idata && idata->status & SILC_IDLIST_STATUS_DISABLED) {
+    SILC_LOG_DEBUG(("Connection is disabled"));
+    goto out;
+  }
 
   if (ret == SILC_PACKET_NONE) {
     SILC_LOG_DEBUG(("Error parsing packet"));
@@ -2860,6 +2872,8 @@ SILC_TASK_CALLBACK(silc_server_free_client_data_timeout)
 {
   FreeClientInternal i = (FreeClientInternal)context;
 
+  assert(!silc_hash_table_count(i->client->channels));
+
   silc_idlist_del_data(i->client);
   silc_idcache_purge_by_context(i->server->local_list->clients, i->client);
   silc_free(i);
@@ -2933,6 +2947,7 @@ void silc_server_free_client_data(SilcServer server,
                         (void *)i, 300, 0,
                         SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
   client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
+  client->data.status &= ~SILC_IDLIST_STATUS_LOCAL;
   client->mode = 0;
   client->router = NULL;
   client->connection = NULL;
@@ -2965,6 +2980,11 @@ void silc_server_free_sock_user_data(SilcServer server,
       if (user_data->id)
        backup_router = silc_server_backup_get(server, user_data->id);
 
+      if (!server->backup_router && server->server_type == SILC_ROUTER &&
+         backup_router == server->id_entry &&
+         sock->type != SILC_SOCKET_TYPE_ROUTER)
+       backup_router = NULL;
+
       /* If this was our primary router connection then we're lost to
         the outside world. */
       if (server->router == user_data) {
@@ -3073,7 +3093,7 @@ void silc_server_free_sock_user_data(SilcServer server,
                                 ("%s switched to backup router %s "
                                  "(we are primary router now)",
                                  server->server_name, server->server_name));
-       else
+       else if (server->router)
          SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
                                 SILC_NOTIFY_TYPE_NONE,
                                 ("%s switched to backup router %s",
@@ -3696,7 +3716,6 @@ SilcChannelEntry silc_server_save_channel_key(SilcServer server,
       if (!channel) {
        SILC_LOG_ERROR(("Received key for non-existent channel %s",
                        silc_id_render(id, SILC_ID_CHANNEL)));
-       assert(FALSE);
        goto out;
       }
     }
@@ -3916,6 +3935,12 @@ static void silc_server_announce_get_clients(SilcServer server,
            break;
          continue;
        }
+       if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) &&
+           !client->connection && !client->router && !SILC_IS_LOCAL(client)) {
+         if (!silc_idcache_list_next(list, &id_cache))
+           break;
+         continue;
+       }
 
        idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
 
@@ -4515,6 +4540,12 @@ void silc_server_save_users_on_channel(SilcServer server,
 
     silc_free(client_id);
 
+    if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
+      SILC_LOG_ERROR(("Attempting to add unregistered client to channel ",
+                     "%s", channel->channel_name));
+      continue;
+    }
+
     if (!silc_server_client_on_channel(client, channel, &chl)) {
       /* Client was not on the channel, add it. */
       chl = silc_calloc(1, sizeof(*chl));
@@ -4552,7 +4583,8 @@ void silc_server_save_user_channels(SilcServer server,
   char *name;
   int i = 0;
 
-  if (!channels ||!channels_user_modes)
+  if (!channels || !channels_user_modes ||
+      !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
     goto out;
   
   ch = silc_channel_payload_parse_list(channels->data, channels->len);