silcd: handle SIGNOFF notify for local clients correctly
[silc.git] / apps / silcd / packet_receive.c
index e776863e6be5a949af821ba2fa2f3a24328f6f28..f2a822124a2560c7dfc39d60e84e122bb083f2c4 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2007 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
@@ -186,6 +186,12 @@ static void silc_server_notify_process(SilcServer server,
        }
 
        client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
+
+       if (idata->conn_type == SILC_CONN_SERVER)
+         server->stat.cell_clients++;
+       SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
+                       server->stat.clients + 1));
+       server->stat.clients++;
       }
     }
 
@@ -326,6 +332,8 @@ static void silc_server_notify_process(SilcServer server,
       tmp_len = 128;
 
     /* 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)
@@ -353,6 +361,20 @@ static void silc_server_notify_process(SilcServer server,
     /* Remove this client from watcher list if it is */
     silc_server_del_from_watcher_list(server, client);
 
+    /* It's possible router doesn't accept our local client in the network
+       and sends SIGNOFF to our local client */
+    if (SILC_IS_LOCAL(client)) {
+      SILC_LOG_DEBUG(("SIGNOFF from router to local client, disconnect"));
+      if (client->data.sconn) {
+       silc_server_connection_free(client->data.sconn);
+       client->data.sconn = NULL;
+      }
+      silc_packet_set_context(client->connection, NULL);
+      silc_server_disconnect_remote(server, client->connection,
+                                   SILC_STATUS_ERR_RESOURCE_LIMIT,
+                                   "Router prevented registration");
+    }
+
     client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
     client->mode = 0;
     client->router = NULL;
@@ -1246,6 +1268,8 @@ static void silc_server_notify_process(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)
@@ -1492,6 +1516,8 @@ static void silc_server_notify_process(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)
@@ -2686,6 +2712,8 @@ static void silc_server_new_id_real(SilcServer server,
 
       if (idata->conn_type == SILC_CONN_SERVER)
        server->stat.cell_clients++;
+      SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
+                     server->stat.clients + 1));
       server->stat.clients++;
 
       /* Check if anyone is watching this nickname */
@@ -3742,6 +3770,8 @@ void silc_server_resume_client(SilcServer server,
        we decremented the count already during detach, thus we'd be undoing
        that operation. */
     detached_client->local_detached = FALSE;
+    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)