Completed the backup router support for standalone routers.
authorPekka Riikonen <priikone@silcnet.org>
Wed, 26 Jun 2002 18:42:27 +0000 (18:42 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Wed, 26 Jun 2002 18:42:27 +0000 (18:42 +0000)
14 files changed:
CHANGES
TODO
apps/silcd/command.c
apps/silcd/command_reply.c
apps/silcd/idlist.c
apps/silcd/idlist.h
apps/silcd/packet_receive.c
apps/silcd/packet_send.c
apps/silcd/server.c
apps/silcd/server_backup.c
apps/silcd/server_util.c
apps/silcd/server_util.h
apps/silcd/silcd.c
lib/silccore/silcnotify.c

diff --git a/CHANGES b/CHANGES
index 6d87f8edc56c3bc03b0e46b95e1be9e61707e732..870d3413443acccf75e2f1cf69e551fc1e732e2f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -8,6 +8,26 @@ Wed Jun 26 15:14:12 EEST 2002 Pekka Riikonen <priikone@silcnet.org>
          clients of those servers can be removed too.  Affected file
          silcd/server_util.[ch].
 
+       * When removing clients after a server has signed of remove
+         also all servers behind that server (unless they are known
+         to be available locally), and send SERVER_SIGNOFF for each
+         of the server separately.  Also the signed off clients are
+         sent now separately per signed off server.  The affected files
+         are silcd/server.c and silcd/server_util.[ch].
+
+       * All servers added with silc_idlist_add_server must always
+         have both "router" and "connection" pointers set.  Otherwise,
+         bad server entries may be left around in the cache.
+         Affected file silcd/command_reply.c.
+
+       * Do not create the channel key in NEW_CHANNEL packet
+         processing if the channel is empty.  Affected file
+         silcd/packet_receive.c.
+
+       * Completed backup router support for standalone routers.
+         Supports also servers in the cell that do not use the backup
+         at all.
+
 Wed Jun 26 10:38:11 EEST 2002 Pekka Riikonen <priikone@silcnet.org>
 
        * Fixed a bug in silc_string_regexify which did not add '^'
@@ -4047,6 +4067,12 @@ Sat Aug 11 00:29:57 EEST 2001  Pekka Riikonen <priikone@silcnet.org>
          set as the new server's context instead of SilcServerEntry.
          This naturally caused some weird bugs.
 
+       * Added "updated" field the SilcChannelEntry which indicates
+         the time since the channel entry was last accessed.  This
+         can be used to determine whether it is necessary to
+         announce the channel after backup resuming protocol.
+         Affected files silcd/idlist.[ch].
+
 Thu Aug  9 18:28:37 EEST 2001  Pekka Riikonen <priikone@silcnet.org>
 
        * Do not delete the channel rekey task when adding it
diff --git a/TODO b/TODO
index 911a25ad0b7d32a8ae54e423204dc1ff6e64c7fa..74d90a129071a327a34818906641a044b15aa609 100644 (file)
--- a/TODO
+++ b/TODO
@@ -11,6 +11,8 @@ TODO/bugs in Irssi SILC client
 TODO/bugs In SILC Client Library
 ================================
 
+ o Still crash with NICK_CHANGE notify.
+
  o The PRIVATE_MESSAGE_KEY packet is not handled (it is implemented 
    though).  This should be added and perhaps new client operation
    should be added to notify application that it was received and
@@ -27,25 +29,10 @@ TODO/bugs In SILC Server
    the core library, client and server.  Maybe implementations of
    RFC 2425 and RFC 2426 to make it complete.
 
- o Add special handling in router and server for "connection timed out"
-   error.  Be optimistic.
-
- o Backup router related issues (Fix this to 0.9.x):
-
-       o Complete backup router support with standalone router
-
-       o Make the backup router work even if not all servers in the
-         cell use it.  When primary goes down, also those that are
-         not using it (are not connected locally) are signoffed.
-
-         o When primary goes down and removing clients of non-backup
-           aware server the SERVER_SIGNOFF includes the router's ID
-           not the server's ID, which it should include.  The notify
-           is sent by backup.
+ o Backup router related issues:
 
-       o When removing clients by server in signoff, EOF etc, find also
-         the client's real server (based on the Client ID's IP), and
-         remove the server too.
+       o Add special handling in router and server for "connection
+         timed out" error.  Be optimistic.
 
        o Testing
 
index f0889aef33e4c049250ea4ce15a181ae122ea7fe..5ed21f8354e710fcb041c29839ede868490f59c5 100644 (file)
@@ -4326,7 +4326,7 @@ SILC_SERVER_CMD_FUNC(cmode)
                                                3, tmp_mask, 4);
   silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0, 
                          packet->data, packet->len, FALSE);
-    
+
   silc_buffer_free(packet);
   silc_buffer_free(cidp);
 
index 63b528fc707597b74692178965e269ab0149ff60..74e3d45e87320f7e8932963e9d474254151131ea 100644 (file)
@@ -566,7 +566,8 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd)
       /* We don't have that server anywhere, add it. */
       server_entry = silc_idlist_add_server(server->global_list, 
                                            strdup(name), 0,
-                                           server_id, NULL, NULL);
+                                           server_id, server->router,
+                                           SILC_PRIMARY_ROUTE(server));
       if (!server_entry) {
        silc_free(server_id);
        goto error;
@@ -693,7 +694,8 @@ SILC_SERVER_CMD_REPLY_FUNC(info)
       /* Add the server to global list */
       server_id = silc_id_dup(server_id, SILC_ID_SERVER);
       entry = silc_idlist_add_server(server->global_list, name, 0,
-                                    server_id, NULL, NULL);
+                                    server_id, cmd->sock->user_data,
+                                    cmd->sock);
       if (!entry) {
        silc_free(server_id);
        goto out;
index 80d1e91e2f959687957de5e885e172153951464b..7ecb033cd298cfe1207579a596cb976a8c18c384 100644 (file)
@@ -92,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, 
@@ -605,7 +605,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);
@@ -635,7 +635,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. */
@@ -648,12 +649,12 @@ static void silc_idlist_del_channel_foreach(void *key, void *context,
 int silc_idlist_del_channel(SilcIDList id_list, SilcChannelEntry entry)
 {
   if (entry) {
-    SILC_LOG_DEBUG(("Deleting channel %s", entry->channel_name));
-
     /* Remove from cache */
     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 
        callback. */
@@ -706,6 +707,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;
 }
 
@@ -734,6 +738,9 @@ silc_idlist_find_channel_by_id(SilcIDList id_list, SilcChannelID *id,
 
   SILC_LOG_DEBUG(("Found"));
 
+  /* Touch channel */
+  channel->updated = time(NULL);
+
   return channel;
 }
 
@@ -770,6 +777,9 @@ silc_idlist_replace_channel_id(SilcIDList id_list, SilcChannelID *old_id,
 
   SILC_LOG_DEBUG(("Replaced"));
 
+  /* Touch channel */
+  channel->updated = time(NULL);
+
   return channel;
 }
 
index d7be279188c14c3195cd86e165c9ab2fbbd1b4ee..ec10bc5921110c382282d1702462185e4192b011 100644 (file)
@@ -485,6 +485,7 @@ struct SilcChannelEntryStruct {
 
   SilcServerChannelRekey rekey;
   unsigned long created;
+  unsigned long updated;
 
   /* Flags */
   unsigned int global_users : 1;
index 4e07b0ce40502355bbca0bb2b7f7580e33ee4c71..33d1bce0a40d521b22fd95580175c5801084ad22 100644 (file)
@@ -100,7 +100,7 @@ void silc_server_notify(SilcServer server,
                                   channel_id, SILC_ID_CHANNEL,
                                   packet->buffer->data, 
                                   packet->buffer->len, FALSE);
-      silc_server_backup_send_dest(server, (SilcServerEntry)sock->user_data, 
+      silc_server_backup_send_dest(server, sock->user_data, 
                                   packet->type, packet->flags,
                                   channel_id, SILC_ID_CHANNEL,
                                   packet->buffer->data, packet->buffer->len, 
@@ -112,7 +112,7 @@ void silc_server_notify(SilcServer server,
                              packet->flags | SILC_PACKET_FLAG_BROADCAST, 
                              packet->buffer->data, packet->buffer->len, 
                              FALSE);
-      silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
+      silc_server_backup_send(server, sock->user_data,
                              packet->type, packet->flags,
                              packet->buffer->data, packet->buffer->len, 
                              FALSE, TRUE);
@@ -196,7 +196,8 @@ void silc_server_notify(SilcServer server,
 
     /* Do not add client to channel if it is there already */
     if (silc_server_client_on_channel(client, channel, NULL)) {
-      SILC_LOG_DEBUG(("Client already on channel"));
+      SILC_LOG_DEBUG(("Client already on channel %s",
+                     channel->channel_name));
       break;
     }
 
@@ -591,7 +592,7 @@ void silc_server_notify(SilcServer server,
       if (server->server_type == SILC_SERVER &&
          sock == SILC_PRIMARY_ROUTE(server) &&
          mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
-       SILC_LOG_DEBUG(("Founder public key received from primary router"));
+       SILC_LOG_DEBUG(("Founder public key received from router"));
        tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
        if (!tmp)
          break;
@@ -982,9 +983,9 @@ void silc_server_notify(SilcServer server,
 
       /* Send the same notify to the channel */
       if (!notify_sent)
-       silc_server_packet_send_to_channel(server, NULL, channel, 
-                                          packet->type, 
-                                          FALSE, packet->buffer->data, 
+       silc_server_packet_send_to_channel(server, NULL, channel,
+                                          packet->type,
+                                          FALSE, packet->buffer->data,
                                           packet->buffer->len, FALSE);
       
       silc_free(channel_id);
@@ -1304,7 +1305,7 @@ void silc_server_notify(SilcServer server,
 
     /* Remove the clients that this server owns as they will become
        invalid now too. */
-    silc_server_remove_clients_by_server(server, server_entry,
+    silc_server_remove_clients_by_server(server, server_entry->router,
                                         server_entry, TRUE);
     silc_server_backup_del(server, server_entry);
 
@@ -2090,7 +2091,7 @@ void silc_server_channel_key(SilcServer server,
   
   if (server->server_type != SILC_BACKUP_ROUTER) {
     /* Distribute to local cell backup routers. */
-    silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
+    silc_server_backup_send(server, sock->user_data, 
                            SILC_PACKET_CHANNEL_KEY, 0,
                            buffer->data, buffer->len, FALSE, TRUE);
   }
@@ -2297,7 +2298,7 @@ SilcClientEntry silc_server_new_client(SilcServer server,
   /* Distribute to backup routers */
   if (server->server_type == SILC_ROUTER) {
     SilcBuffer idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
-    silc_server_backup_send(server, NULL, SILC_PACKET_NEW_ID, 0,
+    silc_server_backup_send(server, sock->user_data, SILC_PACKET_NEW_ID, 0,
                            idp->data, idp->len, FALSE, TRUE);
     silc_buffer_free(idp);
   }
@@ -2457,7 +2458,7 @@ SilcServerEntry silc_server_new_server(SilcServer server,
   if (server->server_type == SILC_ROUTER) {
     /* Distribute to backup routers */
     SilcBuffer idp = silc_id_payload_encode(new_server->id, SILC_ID_SERVER);
-    silc_server_backup_send(server, NULL, SILC_PACKET_NEW_ID, 0,
+    silc_server_backup_send(server, sock->user_data, SILC_PACKET_NEW_ID, 0,
                            idp->data, idp->len, FALSE, TRUE);
     silc_buffer_free(idp);
 
@@ -2696,7 +2697,7 @@ static void silc_server_new_id_real(SilcServer server,
                            packet->type, 
                            packet->flags | SILC_PACKET_FLAG_BROADCAST,
                            buffer->data, buffer->len, FALSE);
-    silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
+    silc_server_backup_send(server, sock->user_data, 
                            packet->type, packet->flags,
                            packet->buffer->data, packet->buffer->len, 
                            FALSE, TRUE);
@@ -2744,7 +2745,7 @@ void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
                            packet->flags | SILC_PACKET_FLAG_BROADCAST,
                            packet->buffer->data, 
                            packet->buffer->len, FALSE);
-    silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
+    silc_server_backup_send(server, sock->user_data, 
                            packet->type, packet->flags,
                            packet->buffer->data, packet->buffer->len, 
                            FALSE, TRUE);
@@ -2903,7 +2904,8 @@ void silc_server_new_channel(SilcServer server,
        return;
       }
       channel->disabled = TRUE;
-      channel->mode = silc_channel_get_mode(payload);
+      if (server_entry->server_type != SILC_BACKUP_ROUTER)
+       channel->mode = silc_channel_get_mode(payload);
 
       /* Send the new channel key to the server */
       id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
@@ -2956,15 +2958,18 @@ void silc_server_new_channel(SilcServer server,
       /* Create new key for the channel and send it to the server and
         everybody else possibly on the channel. */
       if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
-       if (!silc_server_create_channel_key(server, channel, 0))
-         return;
-       
-       /* Send to the channel */
-       silc_server_send_channel_key(server, sock, channel, FALSE);
-       id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
-       id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
+
+       if (silc_hash_table_count(channel->user_list)) {
+         if (!silc_server_create_channel_key(server, channel, 0))
+           return;
+
+         /* Send to the channel */
+         silc_server_send_channel_key(server, sock, channel, FALSE);
+       }
 
        /* Send to the server */
+       id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
+       id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
        chk = silc_channel_key_payload_encode(id_len, id,
                                              strlen(channel->channel_key->
                                                     cipher->name),
@@ -3056,7 +3061,7 @@ void silc_server_new_channel_list(SilcServer server,
                            packet->flags | SILC_PACKET_FLAG_BROADCAST,
                            packet->buffer->data, 
                            packet->buffer->len, FALSE);
-    silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
+    silc_server_backup_send(server, sock->user_data, 
                            packet->type, packet->flags,
                            packet->buffer->data, packet->buffer->len, 
                            FALSE, TRUE);
@@ -3813,7 +3818,7 @@ void silc_server_resume_client(SilcServer server,
                              packet->type, 
                              packet->flags | SILC_PACKET_FLAG_BROADCAST,
                              buffer->data, buffer->len, FALSE);
-      silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
+      silc_server_backup_send(server, sock->user_data, 
                              packet->type, packet->flags,
                              packet->buffer->data, packet->buffer->len, 
                              FALSE, TRUE);
index 7d7e0a5ec2627c27e3837978c96cfb9f57107a64..14895b2ec9e6af20a4b3a7bdc21a9ea92263953b 100644 (file)
@@ -426,7 +426,11 @@ void silc_server_packet_send_clients(SilcServer server,
   bool gone = FALSE;
   int k;
 
-  SILC_LOG_DEBUG(("Sending packet to list of clients"));
+  if (!silc_hash_table_count(clients))
+    return;
+
+  SILC_LOG_DEBUG(("Sending packet to %d clients",
+                 silc_hash_table_count(clients)));
 
   /* Send to all clients in table */
   silc_hash_table_list(clients, &htl);
@@ -609,7 +613,7 @@ void silc_server_packet_send_to_channel(SilcServer server,
     goto out;
   }
 
-  SILC_LOG_DEBUG(("Sending %s packet to channel %s",
+  SILC_LOG_DEBUG(("Sending %s to channel %s",
                  silc_get_packet_name(type), channel->channel_name));
 
   routed = silc_calloc(silc_hash_table_count(channel->user_list), 
@@ -804,7 +808,7 @@ void silc_server_packet_relay_to_channel(SilcServer server,
       sock = (SilcSocketConnection)router->connection;
       idata = (SilcIDListData)router;
 
-      SILC_LOG_DEBUG(("Sending channel message to router for routing"));
+      SILC_LOG_DEBUG(("Sending message to router for routing"));
 
       silc_server_packet_send_to_channel_real(server, sock, &packetdata,
                                              idata->send_key, 
index 75e84719f20557a732c7d2e7d4737b08e27eac27..c568368b56f44dc81e1781cf8b61835b9cbbd104 100644 (file)
@@ -1232,7 +1232,8 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
   SILC_LOG_DEBUG(("New server id(%s)",
                  silc_id_render(ctx->dest_id, SILC_ID_SERVER)));
 
-  /* Add the connected router to global server list */
+  /* Add the connected router to global server list.  Router is sent
+     as NULL since it's local to us. */
   id_entry = silc_idlist_add_server(server->global_list,
                                    strdup(sock->hostname),
                                    SILC_ROUTER, ctx->dest_id, NULL, sock);
@@ -1280,10 +1281,12 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
       server->router = id_entry;
       server->standalone = FALSE;
 
-      /* If we are router then announce our possible servers. */
+      /* If we are router then announce our possible servers.  Backup
+        router announces also global servers. */
       if (server->server_type == SILC_ROUTER)
-       silc_server_announce_servers(server, FALSE, 0,
-                                    SILC_PRIMARY_ROUTE(server));
+       silc_server_announce_servers(server,
+                                    server->backup_router ? TRUE : FALSE,
+                                    0, SILC_PRIMARY_ROUTE(server));
 
       /* Announce our clients and channels to the router */
       silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server));
@@ -3038,6 +3041,13 @@ void silc_server_free_sock_user_data(SilcServer server,
        /* Enable local server connections that may be disabled */
        silc_server_local_servers_toggle_enabled(server, TRUE);
 
+       /* Update the client entries of this server to the new backup
+          router.  If we are the backup router we also resolve the real
+          servers for the clients.  After updating is over this also
+          removes the clients that this server explicitly owns. */
+       silc_server_update_clients_by_server(server, user_data,
+                                            backup_router, TRUE);
+
        /* If we are router and just lost our primary router (now standlaone)
           we remove everything that was behind it, since we don't know
           any better. */
@@ -3046,12 +3056,10 @@ void silc_server_free_sock_user_data(SilcServer server,
             remove the clients of those servers too. */
          silc_server_remove_servers_by_server(server, user_data, TRUE);
 
-       /* Update the client entries of this server to the new backup
-          router.  If we are the backup router we also resolve the real
-          servers for the clients.  After updating is over this also
-          removes the clients that this server explicitly owns. */
-       silc_server_update_clients_by_server(server, user_data,
-                                            backup_router, TRUE, TRUE);
+       /* Finally remove the clients that are explicitly owned by this
+          server.  They go down with the server. */
+       silc_server_remove_clients_by_server(server, user_data,
+                                            user_data, TRUE);
 
        /* Update our server cache to use the new backup router too. */
        silc_server_update_servers_by_server(server, user_data, backup_router);
@@ -3575,13 +3583,13 @@ bool silc_server_create_channel_key(SilcServer server,
   unsigned char channel_key[32], hash[32];
   SilcUInt32 len;
 
-  SILC_LOG_DEBUG(("Generating channel key"));
-
   if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
     SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
     return TRUE;
   }
 
+  SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
+
   if (!channel->channel_key)
     if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->channel_key)) {
       channel->channel_key = NULL;
@@ -3655,8 +3663,6 @@ SilcChannelEntry silc_server_save_channel_key(SilcServer server,
   SilcUInt32 tmp_len;
   char *cipher;
 
-  SILC_LOG_DEBUG(("Saving new channel key"));
-
   /* Decode channel key payload */
   payload = silc_channel_key_payload_parse(key_payload->data,
                                           key_payload->len);
@@ -3688,6 +3694,8 @@ SilcChannelEntry silc_server_save_channel_key(SilcServer server,
     }
   }
 
+  SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
+
   tmp = silc_channel_key_get_key(payload, &tmp_len);
   if (!tmp) {
     channel = NULL;
@@ -4168,31 +4176,38 @@ void silc_server_announce_get_channels(SilcServer server,
          silc_buffer_pull(*channels, len);
        }
 
-       /* Channel user modes */
-       *channel_users_modes = silc_realloc(*channel_users_modes,
-                                           sizeof(**channel_users_modes) *
-                                           (i + 1));
-       (*channel_users_modes)[i] = NULL;
-       *channel_modes = silc_realloc(*channel_modes,
-                                     sizeof(**channel_modes) * (i + 1));
-       (*channel_modes)[i] = NULL;
-       *channel_ids = silc_realloc(*channel_ids,
-                                   sizeof(**channel_ids) * (i + 1));
-       (*channel_ids)[i] = NULL;
-       silc_server_announce_get_channel_users(server, channel,
-                                              &(*channel_modes)[i], 
-                                              channel_users,
-                                              &(*channel_users_modes)[i]);
-       (*channel_ids)[i] = channel->id;
-
-       /* Channel's topic */
-       *channel_topics = silc_realloc(*channel_topics,
-                                      sizeof(**channel_topics) * (i + 1));
-       (*channel_topics)[i] = NULL;
-       silc_server_announce_get_channel_topic(server, channel,
-                                              &(*channel_topics)[i]);
-       (*channel_users_modes_c)++;
-       i++;
+       if (creation_time && channel->updated < creation_time)
+         announce = FALSE;
+       else
+         announce = TRUE;
+
+       if (announce) {
+         /* Channel user modes */
+         *channel_users_modes = silc_realloc(*channel_users_modes,
+                                             sizeof(**channel_users_modes) *
+                                             (i + 1));
+         (*channel_users_modes)[i] = NULL;
+         *channel_modes = silc_realloc(*channel_modes,
+                                       sizeof(**channel_modes) * (i + 1));
+         (*channel_modes)[i] = NULL;
+         *channel_ids = silc_realloc(*channel_ids,
+                                     sizeof(**channel_ids) * (i + 1));
+         (*channel_ids)[i] = NULL;
+         silc_server_announce_get_channel_users(server, channel,
+                                                &(*channel_modes)[i], 
+                                                channel_users,
+                                                &(*channel_users_modes)[i]);
+         (*channel_ids)[i] = channel->id;
+
+         /* Channel's topic */
+         *channel_topics = silc_realloc(*channel_topics,
+                                        sizeof(**channel_topics) * (i + 1));
+         (*channel_topics)[i] = NULL;
+         silc_server_announce_get_channel_topic(server, channel,
+                                                &(*channel_topics)[i]);
+         (*channel_users_modes_c)++;
+         i++;
+       }
 
        if (!silc_idcache_list_next(list, &id_cache))
          break;
index 5ec8945f68cd439d64c0d21e9fc91eb9c1db021e..6c77135d7e02dc3c77ca05c22361867cb9b1ab31 100644 (file)
@@ -339,12 +339,8 @@ void silc_server_backup_send(SilcServer server,
 
   for (i = 0; i < server->backup->servers_count; i++) {
     backup = server->backup->servers[i].server;
-    if (!backup)
+    if (!backup || sender == backup)
       continue;
-
-    if (sender == backup)
-      continue;
-
     if (local && server->backup->servers[i].local == FALSE)
       continue;
     if (server->backup->servers[i].server == server->id_entry)
@@ -385,12 +381,8 @@ void silc_server_backup_send_dest(SilcServer server,
 
   for (i = 0; i < server->backup->servers_count; i++) {
     backup = server->backup->servers[i].server;
-    if (!backup)
+    if (!backup || sender == backup)
       continue;
-
-    if (sender == backup)
-      continue;
-
     if (local && server->backup->servers[i].local == FALSE)
       continue;
     if (server->backup->servers[i].server == server->id_entry)
@@ -838,10 +830,15 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
 
       silc_buffer_free(packet);
 
-      /* Announce all of our information */
-      silc_server_announce_servers(server, TRUE, 0, ctx->sock);
-      silc_server_announce_clients(server, 0, ctx->sock);
-      silc_server_announce_channels(server, 0, ctx->sock);
+      /* If we are not standalone and our primary is not the one we've
+        talking to now, then announce our information to it since we
+        haven't done that yet.  Standalone backup router announces
+        these during connecting to the primary. */
+      if (!server->standalone && SILC_PRIMARY_ROUTE(server) != ctx->sock) {
+       silc_server_announce_servers(server, TRUE, 0, ctx->sock);
+       silc_server_announce_clients(server, 0, ctx->sock);
+       silc_server_announce_channels(server, 0, ctx->sock);
+      }
 
       protocol->state++;
     } else {
@@ -962,7 +959,7 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
       silc_server_update_servers_by_server(server, ctx->sock->user_data, 
                                           server->router);
       silc_server_update_clients_by_server(server, ctx->sock->user_data,
-                                          server->router, TRUE, FALSE);
+                                          server->router, TRUE);
       if (server->server_type == SILC_SERVER)
        silc_server_update_channels_by_server(server, ctx->sock->user_data, 
                                              server->router);
@@ -1083,13 +1080,10 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
          /* We have new primary router now */
          server->id_entry->router = router;
          server->router = router;
-         server->router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
-
          SILC_LOG_INFO(("Switching back to primary router %s",
                         server->router->server_name));
        } else {
          /* We are connected to new primary and now continue using it */
-         router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
          SILC_LOG_INFO(("Resuming the use of primary router %s",
                         router->server_name));
        }
@@ -1097,20 +1091,23 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup)
        /* Update the client entries of the backup router to the new 
           router */
        silc_server_local_servers_toggle_enabled(server, FALSE);
+       router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
        silc_server_update_servers_by_server(server, backup_router, router);
-       silc_server_update_clients_by_server(server, NULL, router, 
-                                            FALSE, FALSE);
+       silc_server_update_clients_by_server(server, NULL, router, FALSE);
        if (server->server_type == SILC_SERVER)
          silc_server_update_channels_by_server(server, backup_router, router);
        silc_server_backup_replaced_del(server, backup_router);
 
        /* Announce all of our information to the router. */
        if (server->server_type == SILC_ROUTER)
-         silc_server_announce_servers(server, FALSE, 0, router->connection);
+         silc_server_announce_servers(server, FALSE, ctx->start,
+                                      router->connection);
 
        /* Announce our clients and channels to the router */
-       silc_server_announce_clients(server, 0, router->connection);
-       silc_server_announce_channels(server, 0, router->connection);
+       silc_server_announce_clients(server, ctx->start,
+                                    router->connection);
+       silc_server_announce_channels(server, ctx->start,
+                                     router->connection);
       }
 
       /* Send notify about primary router going down to local operators */
@@ -1171,14 +1168,6 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup_done)
        server_entry = (SilcServerEntry)id_cache->context;
        sock = (SilcSocketConnection)server_entry->connection;
 
-       /* XXXX */
-       if (!sock) {
-         SILC_LOG_DEBUG(("******** REMOVE THIS TEST, IT ALLOWS A BUG"));
-         if (!silc_idcache_list_next(list, &id_cache))
-           break;
-         continue;
-       }
-
        if (sock->protocol == protocol) {
          sock->protocol = NULL;
 
@@ -1199,14 +1188,6 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup_done)
        server_entry = (SilcServerEntry)id_cache->context;
        sock = (SilcSocketConnection)server_entry->connection;
 
-       /* XXXX */
-       if (!sock) {
-         SILC_LOG_DEBUG(("******** REMOVE THIS TEST, IT ALLOWS A BUG"));
-         if (!silc_idcache_list_next(list, &id_cache))
-           break;
-         continue;
-       }
-
        if (sock->protocol == protocol) {
          sock->protocol = NULL;
 
index 89beb68a2db28d50ef471446d1ad6efb34ccda39..d0157e3a5736740679016c5d45476dcfdb3862bf 100644 (file)
@@ -179,7 +179,8 @@ bool silc_server_remove_clients_by_server(SilcServer server,
           or is not owned by `entry', skip it. */
        if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
            client->router != router ||
-           !SILC_ID_COMPARE(client->id, entry->id, client->id->ip.data_len)) {
+           (router != entry && !SILC_ID_COMPARE(client->id, entry->id,
+                                                client->id->ip.data_len))) {
          if (!silc_idcache_list_next(list, &id_cache))
            break;
          else
@@ -237,7 +238,8 @@ bool silc_server_remove_clients_by_server(SilcServer server,
           or is not owned by `entry', skip it. */
        if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
            client->router != router ||
-           !SILC_ID_COMPARE(client->id, entry->id, client->id->ip.data_len)) {
+           (router != entry && !SILC_ID_COMPARE(client->id, entry->id,
+                                                client->id->ip.data_len))) {
          if (!silc_idcache_list_next(list, &id_cache))
            break;
          else
@@ -461,30 +463,18 @@ silc_server_update_clients_by_real_server(SilcServer server,
    attempt to figure out which clients really are originated from the
    `from' and which are originated from a server that we have connection
    to, when we've acting as backup router. If it is FALSE the `to' will
-   be the new source. This function also removes the clients that are
-   *really* originated from `from' if `remove_from' is TRUE. These are
-   clients that the `from' owns, and not just clients that are behind
-   the `from'. If `from' is NULL then all non-local clients are switched
-   to `to'. */
+   be the new source. */
 
 void silc_server_update_clients_by_server(SilcServer server, 
                                          SilcServerEntry from,
                                          SilcServerEntry to,
-                                         bool resolve_real_server,
-                                         bool remove_from)
+                                         bool resolve_real_server)
 {
   SilcIDCacheList list = NULL;
   SilcIDCacheEntry id_cache = NULL;
   SilcClientEntry client = NULL;
   bool local;
 
-  if (from)
-    SILC_LOG_DEBUG(("Updating %s", silc_id_render(from->id,
-                                                 SILC_ID_SERVER)));
-  if (to)
-    SILC_LOG_DEBUG(("to %s", silc_id_render(to->id,
-                                           SILC_ID_SERVER)));
-
   local = FALSE;
   if (silc_idcache_get_all(server->global_list->clients, &list)) {
     if (silc_idcache_list_first(list, &id_cache)) {
@@ -501,24 +491,14 @@ void silc_server_update_clients_by_server(SilcServer server,
            continue;
        }
 
-       SILC_LOG_DEBUG(("Client (global) %s", 
+       SILC_LOG_DEBUG(("Client %s", 
                        silc_id_render(client->id, SILC_ID_CLIENT)));
        if (client->router)
-         SILC_LOG_DEBUG(("Client->router (global) %s", 
+         SILC_LOG_DEBUG(("Client->router %s", 
                          silc_id_render(client->router->id, SILC_ID_SERVER)));
 
        if (from) {
          if (client->router == from) {
-           /* Skip clients that are *really* owned by the `from' */
-           if (remove_from && SILC_ID_COMPARE(from->id, client->id, 
-                                              client->id->ip.data_len)) {
-             SILC_LOG_DEBUG(("Found really owned client, skip it"));
-             if (!silc_idcache_list_next(list, &id_cache))
-               break;
-             else
-               continue;
-           }
-
            if (resolve_real_server) {
              client->router = 
                silc_server_update_clients_by_real_server(server, from, client,
@@ -565,24 +545,14 @@ void silc_server_update_clients_by_server(SilcServer server,
            continue;
        }
 
-       SILC_LOG_DEBUG(("Client (local) %s", 
+       SILC_LOG_DEBUG(("Client %s", 
                        silc_id_render(client->id, SILC_ID_CLIENT)));
        if (client->router)
-         SILC_LOG_DEBUG(("Client->router (local) %s", 
+         SILC_LOG_DEBUG(("Client->router %s", 
                          silc_id_render(client->router->id, SILC_ID_SERVER)));
 
        if (from) {
          if (client->router == from) {
-           /* Skip clients that are *really* owned by the `from' */
-           if (remove_from && SILC_ID_COMPARE(from->id, client->id, 
-                                              client->id->ip.data_len)) {
-             SILC_LOG_DEBUG(("Found really owned client, skip it"));
-             if (!silc_idcache_list_next(list, &id_cache))
-               break;
-             else
-               continue;
-           }
-
            if (resolve_real_server) {
              client->router = 
                silc_server_update_clients_by_real_server(server, from, client,
@@ -608,12 +578,6 @@ void silc_server_update_clients_by_server(SilcServer server,
     }
     silc_idcache_list_free(list);
   }
-
-  if (remove_from)
-    /* Now remove the clients that are still marked as orignated from the
-       `from'. These are the clients that really was owned by the `from' and
-       not just exist behind the `from'. */
-    silc_server_remove_clients_by_server(server, from, from, TRUE);
 }
 
 /* Updates servers that are from `from' to be originated from `to'.  This
@@ -957,8 +921,6 @@ bool silc_server_channel_delete(SilcServer server,
   bool delchan = !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH);
 
   if (delchan) {
-    SILC_LOG_DEBUG(("Deleting %s channel", channel->channel_name));
-
     /* Update statistics */
     if (server->server_type == SILC_ROUTER)
       server->stat.chanclients -= channel->user_count;
index 6831ce31407caf7340f94beace0c73c721489f35..c18b9c2061c020358a60eb500a4035d7f4e716be 100644 (file)
@@ -34,16 +34,11 @@ bool silc_server_remove_clients_by_server(SilcServer server,
    attempt to figure out which clients really are originated from the
    `from' and which are originated from a server that we have connection
    to, when we've acting as backup router. If it is FALSE the `to' will
-   be the new source. This function also removes the clients that are
-   *really* originated from `from' if `remove_from' is TRUE. These are
-   clients that the `from' owns, and not just clients that are behind
-   the `from'. If `from' is NULL then all non-local clients are switched
-   to `to'. */
+   be the new source. */
 void silc_server_update_clients_by_server(SilcServer server, 
                                          SilcServerEntry from,
                                          SilcServerEntry to,
-                                         bool resolve_real_server,
-                                         bool remove_from);
+                                         bool resolve_real_server);
 
 /* Updates servers that are from `from' to be originated from `to'.  This
    will also update the server's connection to `to's connection. */
index 39c20d82787eab2afc440ffa237c425a59e56ddb..6861727c104d568de119c25b2a7fcfe70d77263d 100644 (file)
@@ -322,7 +322,7 @@ static DebugLevel debug_levels[] = {
   { 3, "silcd\\.c,server\\.c" },
 
   /* More stuff from silcd/ */
-  { 7, "silcd\\.c,server\\.c,command\\.c,server_backup\\.c" },
+  { 7, "silcd\\.c,server\\.c,command\\.c,server_backup\\.c,packet_send\\.c" },
 
   /* All basic stuff from silcd/ */
   { 10, "silc_server_*" },
index 549f7e0a9c3a507dcfbcdda90a614c14c768f438..20a42e9e863c8ac7c8853a57163b346002e7e944 100644 (file)
@@ -65,7 +65,7 @@ SilcNotifyPayload silc_notify_payload_parse(const unsigned char *payload,
   if (newp->argc) {
     silc_buffer_pull(&buffer, 5);
     newp->args = silc_argument_payload_parse(buffer.data, buffer.len, 
-                                           newp->argc);
+                                            newp->argc);
     silc_buffer_push(&buffer, 5);
   }