Added example files for backup router in doc/examples.
[silc.git] / apps / silcd / packet_send.c
index 5a60a9f9c00d7fb648876c2808f16e84143cf31a..9c721ab01e07f9bc05c20ddb18d06418323b8786 100644 (file)
@@ -1,6 +1,6 @@
 /*
 
-  packet_send.c
+  packet_send.c 
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
@@ -8,9 +8,8 @@
 
   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
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-  
+  the Free Software Foundation; version 2 of the License.
+
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
@@ -96,9 +95,15 @@ void silc_server_packet_send(SilcServer server,
   if (SILC_IS_DISCONNECTING(sock))
     return;
 
-  /* If entry is disabled do not sent anything. */
-  if (idata && idata->status & SILC_IDLIST_STATUS_DISABLED)
+  /* If entry is disabled do not sent anything.  Allow hearbeat and
+     rekeys, though */
+  if ((idata && idata->status & SILC_IDLIST_STATUS_DISABLED &&
+       type != SILC_PACKET_HEARTBEAT && type != SILC_PACKET_REKEY && 
+       type != SILC_PACKET_REKEY_DONE) ||
+      sock->user_data == server->id_entry) {
+    SILC_LOG_DEBUG(("Connection is disabled"));
     return;
+  }
 
   /* Get data used in the packet sending, keys and stuff */
   switch(sock->type) {
@@ -157,8 +162,11 @@ void silc_server_packet_send_dest(SilcServer server,
   idata = (SilcIDListData)sock->user_data;
 
   /* If entry is disabled do not sent anything. */
-  if (idata && idata->status & SILC_IDLIST_STATUS_DISABLED)
+  if ((idata && idata->status & SILC_IDLIST_STATUS_DISABLED) ||
+      sock->user_data == server->id_entry) {
+    SILC_LOG_DEBUG(("Connection is disabled"));
     return;
+  }
 
   SILC_LOG_DEBUG(("Sending %s packet", silc_get_packet_name(type)));
 
@@ -253,6 +261,20 @@ void silc_server_packet_send_srcdest(SilcServer server,
   /* Get data used in the packet sending, keys and stuff */
   idata = (SilcIDListData)sock->user_data;
 
+  /* If entry is disabled do not sent anything. */
+  if ((idata && idata->status & SILC_IDLIST_STATUS_DISABLED) ||
+      sock->user_data == server->id_entry) {
+    SILC_LOG_DEBUG(("Connection is disabled"));
+    return;
+  }
+
+  if (idata) {
+    cipher = idata->send_key;
+    hmac = idata->hmac_send;
+    sequence = idata->psn_send++;
+    block_len = silc_cipher_get_block_len(cipher);
+  }
+
   if (dst_id) {
     dst_id_data = silc_id_id2str(dst_id, dst_id_type);
     dst_id_len = silc_id_get_len(dst_id, dst_id_type);
@@ -263,13 +285,6 @@ void silc_server_packet_send_srcdest(SilcServer server,
     src_id_len = silc_id_get_len(src_id, src_id_type);
   }
 
-  if (idata) {
-    cipher = idata->send_key;
-    hmac = idata->hmac_send;
-    sequence = idata->psn_send++;
-    block_len = silc_cipher_get_block_len(cipher);
-  }
-
   /* Set the packet context pointers */
   packetdata.type = type;
   packetdata.flags = flags;
@@ -413,7 +428,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);
@@ -596,7 +615,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), 
@@ -791,7 +810,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, 
@@ -1477,6 +1496,16 @@ void silc_server_send_notify_dest(SilcServer server,
                               broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
                               dest_id, dest_id_type,
                               packet->data, packet->len, FALSE);
+
+  /* Send to backup routers if this is being broadcasted to primary
+     router.  The silc_server_backup_send checks further whether to
+     actually send it or not. */
+  if ((broadcast && sock && sock == SILC_PRIMARY_ROUTE(server)) ||
+      (broadcast && !sock && !SILC_PRIMARY_ROUTE(server)))
+    silc_server_backup_send_dest(server, NULL, SILC_PACKET_NOTIFY, 0,
+                                dest_id, dest_id_type,
+                                packet->data, packet->len, FALSE, TRUE);
+
   silc_buffer_free(packet);
   va_end(ap);
 }