Backup router related fixes.
authorPekka Riikonen <priikone@silcnet.org>
Mon, 10 Jun 2002 16:16:58 +0000 (16:16 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Mon, 10 Jun 2002 16:16:58 +0000 (16:16 +0000)
CHANGES
apps/silcd/command.c
apps/silcd/packet_receive.c
apps/silcd/packet_send.c
apps/silcd/server.c
apps/silcd/server_internal.h
apps/silcd/serverconfig.c

diff --git a/CHANGES b/CHANGES
index 9cd0e8d6b837f221b774367483ccf9a48f4a9ac2..71472709dc0c199ad999f5dbc9cd7c9012e05215 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,22 @@
+Mon Jun 10 16:29:42 EEST 2002 Pekka Riikonen <priikone@silcnet.org>
+
+       * Added WATCH list sending to backup routers from router.
+         The WATCH command is sent by the router to the backup
+         router.  Affected file silcd/command.c.
+
+       * Mark the backup_router flag for RouterConnection entry
+         if the backup router stuff is defined in the config file.
+         Affected file silcd/serverconfig.c.
+
+       * Fixed some backup data sending around the code to work better
+         if the router is standalone router.  Not all places were fixed.
+         Affected file silcd/packet_receive.c, silcd/packet_send.c,
+         silcd/server.c.
+
+       * Fixed the router connecting when connecting to multiple
+         routers.  It ignored every other router except the first
+         one.  Affected file silcd/server.c.
+
 Mon Jun 10 09:28:21 CEST 2002 Pekka Riikonen <priikone@silcnet.org>
 
        * Made the private key generation after expiration optional.
index 25468230de55357919f6cfb2e8ff46ce6b10b560..2c092734057fe7e0567fae2f80bb2757ae67ceb1 100644 (file)
@@ -5110,6 +5110,17 @@ SILC_SERVER_CMD_FUNC(watch)
       silc_free(tmp);
   }
 
+  /* Distribute the watch list to backup routers too */
+  if (server->backup) {
+    SilcBuffer tmpbuf;
+    silc_command_set_ident(cmd->payload, ++server->cmd_ident);
+    tmpbuf = silc_command_payload_encode_payload(cmd->payload);
+    silc_server_backup_send(server, NULL, SILC_PACKET_COMMAND,
+                           cmd->packet->flags, tmpbuf->data, tmpbuf->len,
+                           FALSE, TRUE);
+    silc_buffer_free(tmpbuf);
+  }
+
   silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
                                        SILC_STATUS_OK, 0);
 
index b20af01c5a9f03dccfc6a9e7e999ce4a5ae769c9..bab1f0e09a0c6b1d154bc03e3aedd7523a27fbdf 100644 (file)
@@ -86,7 +86,7 @@ void silc_server_notify(SilcServer server,
      we will broadcast it. The sending socket really cannot be router or
      the router is buggy. If this packet is coming from router then it must
      have the broadcast flag set already and we won't do anything. */
-  if (!server->standalone && server->server_type == SILC_ROUTER &&
+  if (server->server_type == SILC_ROUTER &&
       sock->type == SILC_SOCKET_TYPE_SERVER &&
       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
     SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
@@ -97,12 +97,13 @@ void silc_server_notify(SilcServer server,
       if (!channel_id)
        goto out;
 
-      silc_server_packet_send_dest(server, server->router->connection, 
-                                  packet->type,
-                                  packet->flags | SILC_PACKET_FLAG_BROADCAST, 
-                                  channel_id, SILC_ID_CHANNEL,
-                                  packet->buffer->data, packet->buffer->len, 
-                                  FALSE);
+      if (!server->standalone)
+       silc_server_packet_send_dest(server, server->router->connection, 
+                                    packet->type, packet->flags | 
+                                    SILC_PACKET_FLAG_BROADCAST, 
+                                    channel_id, SILC_ID_CHANNEL,
+                                    packet->buffer->data, 
+                                    packet->buffer->len, FALSE);
       silc_server_backup_send_dest(server, (SilcServerEntry)sock->user_data, 
                                   packet->type, packet->flags,
                                   channel_id, SILC_ID_CHANNEL,
@@ -110,11 +111,12 @@ void silc_server_notify(SilcServer server,
                                   FALSE, TRUE);
     } else {
       /* Packet is destined to client or server */
-      silc_server_packet_send(server, server->router->connection, 
-                             packet->type,
-                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
-                             packet->buffer->data, packet->buffer->len, 
-                             FALSE);
+      if (!server->standalone)
+       silc_server_packet_send(server, server->router->connection, 
+                               packet->type,
+                               packet->flags | SILC_PACKET_FLAG_BROADCAST, 
+                               packet->buffer->data, packet->buffer->len, 
+                               FALSE);
       silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
                              packet->type, packet->flags,
                              packet->buffer->data, packet->buffer->len, 
@@ -2140,7 +2142,15 @@ SilcClientEntry silc_server_new_client(SilcServer server,
                            server->router->connection, 
                            server->server_type == SILC_ROUTER ? TRUE : FALSE,
                            client->id, SILC_ID_CLIENT, id_len);
-  
+
+  /* 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,
+                           idp->data, idp->len, FALSE, TRUE);
+    silc_buffer_free(idp);
+  }
+
   /* Send the new client ID to the client. */
   silc_server_send_new_id(server, sock, FALSE, client->id, SILC_ID_CLIENT,
                          silc_id_get_len(client->id, SILC_ID_CLIENT));
@@ -2293,8 +2303,16 @@ SilcServerEntry silc_server_new_server(SilcServer server,
                            TRUE, new_server->id, SILC_ID_SERVER, 
                            silc_id_get_len(server_id, SILC_ID_SERVER));
 
-  if (server->server_type == SILC_ROUTER)
+  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,
+                           idp->data, idp->len, FALSE, TRUE);
+    silc_buffer_free(idp);
+
+    /* Statistics */
     server->stat.cell_servers++;
+  }
 
   /* Check whether this router connection has been replaced by an
      backup router. If it has been then we'll disable the server and will
@@ -2513,14 +2531,15 @@ static void silc_server_new_id_real(SilcServer server,
 
   /* If the sender of this packet is server and we are router we need to
      broadcast this packet to other routers in the network. */
-  if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
+  if (broadcast && server->server_type == SILC_ROUTER &&
       sock->type == SILC_SOCKET_TYPE_SERVER &&
       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
-    silc_server_packet_send(server, server->router->connection,
-                           packet->type, 
-                           packet->flags | SILC_PACKET_FLAG_BROADCAST,
-                           buffer->data, buffer->len, FALSE);
+    if (!server->standalone)
+      silc_server_packet_send(server, server->router->connection,
+                             packet->type, 
+                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
+                             buffer->data, buffer->len, FALSE);
     silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
                            packet->type, packet->flags,
                            packet->buffer->data, packet->buffer->len, 
@@ -2560,14 +2579,16 @@ void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
   /* If the sender of this packet is server and we are router we need to
      broadcast this packet to other routers in the network. Broadcast
      this list packet instead of multiple New ID packets. */
-  if (!server->standalone && server->server_type == SILC_ROUTER &&
+  if (server->server_type == SILC_ROUTER &&
       sock->type == SILC_SOCKET_TYPE_SERVER &&
       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
     SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
-    silc_server_packet_send(server, server->router->connection,
-                           packet->type, 
-                           packet->flags | SILC_PACKET_FLAG_BROADCAST,
-                           packet->buffer->data, packet->buffer->len, FALSE);
+    if (!server->standalone)
+      silc_server_packet_send(server, server->router->connection,
+                             packet->type, 
+                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
+                             packet->buffer->data, 
+                             packet->buffer->len, FALSE);
     silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
                            packet->type, packet->flags,
                            packet->buffer->data, packet->buffer->len, 
@@ -2858,14 +2879,16 @@ void silc_server_new_channel_list(SilcServer server,
   /* If the sender of this packet is server and we are router we need to
      broadcast this packet to other routers in the network. Broadcast
      this list packet instead of multiple New Channel packets. */
-  if (!server->standalone && server->server_type == SILC_ROUTER &&
+  if (server->server_type == SILC_ROUTER &&
       sock->type == SILC_SOCKET_TYPE_SERVER &&
       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
     SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
-    silc_server_packet_send(server, server->router->connection,
-                           packet->type, 
-                           packet->flags | SILC_PACKET_FLAG_BROADCAST,
-                           packet->buffer->data, packet->buffer->len, FALSE);
+    if (!server->standalone)
+      silc_server_packet_send(server, server->router->connection,
+                             packet->type, 
+                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
+                             packet->buffer->data, 
+                             packet->buffer->len, FALSE);
     silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
                            packet->type, packet->flags,
                            packet->buffer->data, packet->buffer->len, 
@@ -3565,14 +3588,15 @@ void silc_server_resume_client(SilcServer server,
 
     /* If the sender of this packet is server and we are router we need to
        broadcast this packet to other routers in the network. */
-    if (!server->standalone && server->server_type == SILC_ROUTER &&
+    if (server->server_type == SILC_ROUTER &&
        sock->type == SILC_SOCKET_TYPE_SERVER &&
        !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
       SILC_LOG_DEBUG(("Broadcasting received Resume Client packet"));
-      silc_server_packet_send(server, server->router->connection,
-                             packet->type, 
-                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
-                             buffer->data, buffer->len, FALSE);
+      if (!server->standalone)
+       silc_server_packet_send(server, server->router->connection,
+                               packet->type, 
+                               packet->flags | SILC_PACKET_FLAG_BROADCAST,
+                               buffer->data, buffer->len, FALSE);
       silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
                              packet->type, packet->flags,
                              packet->buffer->data, packet->buffer->len, 
index 93bb71fd0de59e76a27282dcca36c0ccb866978a..40d303e621b84e7c1626a4210268bd0c18a1ce41 100644 (file)
@@ -1656,14 +1656,6 @@ void silc_server_send_new_id(SilcServer server,
   silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 
                          broadcast ? SILC_PACKET_FLAG_BROADCAST : 0, 
                          idp->data, idp->len, FALSE);
-
-  /* Send to backup routers if this is being broadcasted to primary
-     router. */
-  if (server->router && server->router->connection &&
-      sock == server->router->connection && broadcast)
-    silc_server_backup_send(server, NULL, SILC_PACKET_NEW_ID, 0,
-                           idp->data, idp->len, FALSE, TRUE);
-
   silc_buffer_free(idp);
 }
 
@@ -1697,14 +1689,6 @@ void silc_server_send_new_channel(SilcServer server,
                          broadcast ? SILC_PACKET_FLAG_BROADCAST : 0, 
                          packet->data, packet->len, FALSE);
 
-  /* Send to backup routers if this is being broadcasted to primary
-     router. */
-  if (server->server_type == SILC_ROUTER &&
-      server->router && server->router->connection &&
-      sock == server->router->connection && broadcast)
-    silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
-                           packet->data, packet->len, FALSE, TRUE);
-
   silc_free(cid);
   silc_buffer_free(packet);
 }
index 3d7b9686234f1514a10e60c4efc867cbdb61af9a..f26b1091e744c91fc17e8fbe8855c0345f91d40c 100644 (file)
@@ -588,7 +588,7 @@ void silc_server_start_key_exchange(SilcServer server,
 
   /* Cancel any possible retry timeouts */
   silc_schedule_task_del_by_callback(server->schedule,
-                                    silc_server_connect_router);
+                                    silc_server_connect_to_router_retry);
 
   /* Set socket options */
   silc_net_set_socket_nonblock(sock);
@@ -724,10 +724,10 @@ SILC_TASK_CALLBACK(silc_server_connect_router)
   silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
 
   /* Connect to remote host */
-  sock = silc_net_create_connection(server->config->server_info->primary == NULL ? NULL :
-                server->config->server_info->primary->server_ip,
-                sconn->remote_port,
-                sconn->remote_host);
+  sock = silc_net_create_connection(
+                (!server->config->server_info->primary ? NULL :
+                 server->config->server_info->primary->server_ip),
+                sconn->remote_port, sconn->remote_host);
   if (sock < 0) {
     SILC_LOG_ERROR(("Could not connect to router %s:%d",
                    sconn->remote_host, sconn->remote_port));
@@ -1113,6 +1113,13 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
       /* Announce our clients and channels to the router */
       silc_server_announce_clients(server, 0, server->router->connection);
       silc_server_announce_channels(server, 0, server->router->connection);
+
+#ifdef BACKUP_SINGLE_ROUTER
+      /* If we are backup router then this primary router is whom we are
+        backing up. */
+      if (server->server_type == SILC_BACKUP_ROUTER)
+       silc_server_backup_add(server, server->id_entry, sock->ip, 0, TRUE);
+#endif /* BACKUP_SINGLE_ROUTER */
     }
   } else {
     /* Add this server to be our backup router */
@@ -1644,7 +1651,8 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
 
       /* Check whether this connection is to be our primary router connection
         if we do not already have the primary route. */
-      if (server->standalone && ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
+      if (!backup_router &&
+         server->standalone && ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
        if (silc_server_config_is_primary_route(server) && !initiator)
          break;
 
@@ -2702,10 +2710,21 @@ void silc_server_free_sock_user_data(SilcServer server,
                         backup_router->server_name));
          SILC_LOG_DEBUG(("New primary router is backup router %s",
                          backup_router->server_name));
-         server->id_entry->router = backup_router;
-         server->router = backup_router;
-         server->router_connect = time(0);
-         server->backup_primary = TRUE;
+#ifdef BACKUP_SINGLE_ROUTER
+         if (server->id_entry != backup_router) {
+#endif /* BACKUP_SINGLE_ROUTER */
+           server->id_entry->router = backup_router;
+           server->router = backup_router;
+           server->router_connect = time(0);
+           server->backup_primary = TRUE;
+#ifdef BACKUP_SINGLE_ROUTER
+         } else {
+           server->id_entry->router = NULL;
+           server->router = NULL;
+           server->standalone = TRUE;
+         }
+#endif /* BACKUP_SINGLE_ROUTER */
+
          if (server->server_type == SILC_BACKUP_ROUTER) {
            server->server_type = SILC_ROUTER;
 
@@ -3085,6 +3104,22 @@ SilcChannelEntry silc_server_create_new_channel(SilcServer server,
                                 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
                                 entry->mode);
 
+  /* Distribute to backup routers */
+  if (broadcast && server->server_type == SILC_ROUTER) {
+    SilcBuffer packet;
+    unsigned char *cid;
+    SilcUInt32 name_len = strlen(channel_name);
+    SilcUInt32 channel_id_len = silc_id_get_len(entry->id, SILC_ID_CHANNEL);
+    cid = silc_id_id2str(entry->id, SILC_ID_CHANNEL);
+
+    packet = silc_channel_payload_encode(channel_name, name_len,
+                                        cid, channel_id_len, entry->mode);
+    silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
+                           packet->data, packet->len, FALSE, TRUE);
+    silc_free(cid);
+    silc_buffer_free(packet);
+  }
+
   server->stat.my_channels++;
 
   if (server->server_type == SILC_ROUTER)
@@ -3152,6 +3187,22 @@ silc_server_create_new_channel_with_id(SilcServer server,
                                 silc_id_get_len(entry->id, SILC_ID_CHANNEL),
                                 entry->mode);
 
+  /* Distribute to backup routers */
+  if (broadcast && server->server_type == SILC_ROUTER) {
+    SilcBuffer packet;
+    unsigned char *cid;
+    SilcUInt32 name_len = strlen(channel_name);
+    SilcUInt32 channel_id_len = silc_id_get_len(entry->id, SILC_ID_CHANNEL);
+    cid = silc_id_id2str(entry->id, SILC_ID_CHANNEL);
+
+    packet = silc_channel_payload_encode(channel_name, name_len,
+                                        cid, channel_id_len, entry->mode);
+    silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
+                           packet->data, packet->len, FALSE, TRUE);
+    silc_free(cid);
+    silc_buffer_free(packet);
+  }
+
   server->stat.my_channels++;
 
   if (server->server_type == SILC_ROUTER)
index ea703791c46b942b1aa974951c65e563f3c9b57c..56a4a52ae20e83a0207349c5fb29e06923d06807 100644 (file)
@@ -82,8 +82,8 @@ struct SilcServerStruct {
   bool backup_router;               /* TRUE if this is backup router */
   bool backup_primary;              /* TRUE if we've switched our primary
                                        router to a backup router. */
-  SilcServerConnection router_conn; /* non-NULL when connecting to the
-                                      primary router, and NULL otherwise. */
+  SilcServerConnection router_conn;  /* non-NULL when connecting to the
+                                       primary router, and NULL otherwise. */
 
   /* Current command identifier, 0 not used */
   SilcUInt16 cmd_ident;
index 3a8005324a44bce23b9e62630df7343475d0005c..54425dd675d76e9a4b585da89c72a24195803dbf 100644 (file)
@@ -967,6 +967,7 @@ SILC_CONFIG_CALLBACK(fetch_router)
     CONFIG_IS_DOUBLE(tmp->backup_replace_ip);
     tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) :
                              strdup("*"));
+    tmp->backup_router = TRUE;
   }
   else if (!strcmp(name, "backupport")) {
     int port = *(int *)val;