Send CMODE_CHANGE and CUMODE_CHANGE notifys to the original
[silc.git] / apps / silcd / packet_send.c
index 93bb71fd0de59e76a27282dcca36c0ccb866978a..ed048624a40663f49f5c771971ebdbe7c821e24c 100644 (file)
@@ -50,8 +50,10 @@ int silc_server_packet_send_real(SilcServer server,
 
   /* Send the packet */
   ret = silc_packet_send(sock, force_send);
-  if (ret != -2)
+  if (ret != -2) {
+    server->stat.packets_sent++;
     return ret;
+  }
 
   /* Mark that there is some outgoing data available for this connection. 
      This call sets the connection both for input and output (the input
@@ -83,11 +85,13 @@ void silc_server_packet_send(SilcServer server,
 {
   void *dst_id = NULL;
   SilcIdType dst_id_type = SILC_ID_NONE;
-  SilcIDListData idata = (SilcIDListData)sock->user_data;
+  SilcIDListData idata;
 
   if (!sock)
     return;
 
+  idata = (SilcIDListData)sock->user_data;
+
   /* If disconnecting, ignore the data */
   if (SILC_IS_DISCONNECTING(sock))
     return;
@@ -138,7 +142,7 @@ void silc_server_packet_send_dest(SilcServer server,
 {
   SilcPacketContext packetdata;
   const SilcBufferStruct packet;
-  SilcIDListData idata = (SilcIDListData)sock->user_data;
+  SilcIDListData idata;
   SilcCipher cipher = NULL;
   SilcHmac hmac = NULL;
   SilcUInt32 sequence = 0;
@@ -147,14 +151,16 @@ void silc_server_packet_send_dest(SilcServer server,
   int block_len = 0;
 
   /* If disconnecting, ignore the data */
-  if (SILC_IS_DISCONNECTING(sock))
+  if (!sock || SILC_IS_DISCONNECTING(sock))
     return;
 
+  idata = (SilcIDListData)sock->user_data;
+
   /* If entry is disabled do not sent anything. */
   if (idata && idata->status & SILC_IDLIST_STATUS_DISABLED)
     return;
 
-  SILC_LOG_DEBUG(("Sending packet, type %d", type));
+  SILC_LOG_DEBUG(("Sending %s packet", silc_get_packet_name(type)));
 
   if (dst_id) {
     dst_id_data = silc_id_id2str(dst_id, dst_id_type);
@@ -171,9 +177,9 @@ void silc_server_packet_send_dest(SilcServer server,
   /* Set the packet context pointers */
   packetdata.type = type;
   packetdata.flags = flags;
-  packetdata.src_id = silc_id_id2str(server->id, server->id_type);
-  packetdata.src_id_len = silc_id_get_len(server->id, server->id_type);
-  packetdata.src_id_type = server->id_type;
+  packetdata.src_id = silc_id_id2str(server->id, SILC_ID_SERVER);
+  packetdata.src_id_len = silc_id_get_len(server->id, SILC_ID_SERVER);
+  packetdata.src_id_type = SILC_ID_SERVER;
   packetdata.dst_id = dst_id_data;
   packetdata.dst_id_len = dst_id_len;
   packetdata.dst_id_type = dst_id_type;
@@ -239,7 +245,10 @@ void silc_server_packet_send_srcdest(SilcServer server,
   SilcUInt32 src_id_len = 0;
   int block_len = 0;
 
-  SILC_LOG_DEBUG(("Sending packet, type %d", type));
+  SILC_LOG_DEBUG(("Sending %s packet", silc_get_packet_name(type)));
+
+  if (!sock)
+    return;
 
   /* Get data used in the packet sending, keys and stuff */
   idata = (SilcIDListData)sock->user_data;
@@ -313,6 +322,9 @@ void silc_server_packet_broadcast(SilcServer server,
   SilcIDListData idata;
   void *id;
 
+  if (!sock)
+    return;
+
   SILC_LOG_DEBUG(("Broadcasting received broadcast packet"));
 
   /* If the packet is originated from our primary route we are
@@ -385,8 +397,7 @@ void silc_server_packet_route(SilcServer server,
    clients (for server locally connected, and for router local cell). */
 
 void silc_server_packet_send_clients(SilcServer server,
-                                    SilcClientEntry *clients,
-                                    SilcUInt32 clients_count,
+                                    SilcHashTable clients,
                                     SilcPacketType type, 
                                     SilcPacketFlags flags,
                                     bool route,
@@ -395,18 +406,18 @@ void silc_server_packet_send_clients(SilcServer server,
                                     bool force_send)
 {
   SilcSocketConnection sock = NULL;
+  SilcHashTableList htl;
   SilcClientEntry client = NULL;
   SilcServerEntry *routed = NULL;
   SilcUInt32 routed_count = 0;
   bool gone = FALSE;
-  int i, k;
+  int k;
 
   SILC_LOG_DEBUG(("Sending packet to list of clients"));
 
   /* Send to all clients in table */
-  for (i = 0; i < clients_count; i++) {
-    client = clients[i];
-
+  silc_hash_table_list(clients, &htl);
+  while (silc_hash_table_get(&htl, NULL, (void **)&client)) {
     /* If client has router set it is not locally connected client and
        we will route the message to the router set in the client. Though,
        send locally connected server in all cases. */
@@ -451,7 +462,7 @@ void silc_server_packet_send_clients(SilcServer server,
                                 client->id, SILC_ID_CLIENT,
                                 data, data_len, force_send);
   }
-
+  silc_hash_table_list_reset(&htl);
   silc_free(routed);
 }
 
@@ -548,8 +559,6 @@ void silc_server_packet_send_to_channel(SilcServer server,
   /* This doesn't send channel message packets */
   assert(type != SILC_PACKET_CHANNEL_MESSAGE);
   
-  SILC_LOG_DEBUG(("Sending packet to channel"));
-
   /* Set the packet context pointers. */
   packetdata.flags = 0;
   packetdata.type = type;
@@ -573,7 +582,6 @@ void silc_server_packet_send_to_channel(SilcServer server,
     
     if (sock != sender) {
       SILC_LOG_DEBUG(("Sending packet to router for routing"));
-      
       silc_server_packet_send_to_channel_real(server, sock, &packetdata,
                                              idata->send_key, 
                                              idata->hmac_send, 
@@ -583,12 +591,19 @@ void silc_server_packet_send_to_channel(SilcServer server,
     }
   }
 
+  if (!silc_hash_table_count(channel->user_list)) {
+    SILC_LOG_DEBUG(("Channel %s is empty", channel->channel_name));
+    goto out;
+  }
+
+  SILC_LOG_DEBUG(("Sending packet to channel %s", channel->channel_name));
+
   routed = silc_calloc(silc_hash_table_count(channel->user_list), 
                       sizeof(*routed));
 
   /* Send the message to clients on the channel's client list. */
   silc_hash_table_list(channel->user_list, &htl);
-  while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
+  while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
     client = chl->client;
     if (!client)
       continue;
@@ -654,8 +669,9 @@ void silc_server_packet_send_to_channel(SilcServer server,
                                            data, data_len, FALSE, 
                                            force_send);
   }
-
   silc_hash_table_list_reset(&htl);
+
+ out:
   silc_free(routed);
   silc_free(packetdata.src_id);
   silc_free(packetdata.dst_id);
@@ -786,7 +802,7 @@ void silc_server_packet_relay_to_channel(SilcServer server,
 
   /* Send the message to clients on the channel's client list. */
   silc_hash_table_list(channel->user_list, &htl);
-  while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
+  while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
     client = chl->client;
     if (!client || client == sender_entry)
       continue;
@@ -938,7 +954,7 @@ void silc_server_packet_send_local_channel(SilcServer server,
 
   /* Send the message to clients on the channel's client list. */
   silc_hash_table_list(channel->user_list, &htl);
-  while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
+  while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
     if (chl->client && !chl->client->router) {
       sock = (SilcSocketConnection)chl->client->connection;
 
@@ -1054,9 +1070,10 @@ void silc_server_send_notify(SilcServer server,
                          packet->data, packet->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)
+     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(server, NULL, SILC_PACKET_NOTIFY, 0,
                            packet->data, packet->len, FALSE, TRUE);
 
@@ -1512,10 +1529,12 @@ void silc_server_send_notify_on_channels(SilcServer server,
   bool force_send = FALSE;
   va_list ap;
 
-  SILC_LOG_DEBUG(("Start"));
-
-  if (!silc_hash_table_count(client->channels))
+  if (!silc_hash_table_count(client->channels)) {
+    SILC_LOG_DEBUG(("Client is not joined to any channels"));
     return;
+  }
+
+  SILC_LOG_DEBUG(("Sending notify to joined channels"));
 
   va_start(ap, argc);
   packet = silc_notify_payload_encode(type, argc, ap);
@@ -1530,12 +1549,12 @@ void silc_server_send_notify_on_channels(SilcServer server,
   packetdata.src_id_type = SILC_ID_SERVER;
 
   silc_hash_table_list(client->channels, &htl);
-  while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
+  while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
     channel = chl->channel;
 
     /* Send the message to all clients on the channel's client list. */
     silc_hash_table_list(channel->user_list, &htl2);
-    while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) {
+    while (silc_hash_table_get(&htl2, NULL, (void **)&chl2)) {
       c = chl2->client;
       
       if (sender && c == sender)
@@ -1650,20 +1669,12 @@ void silc_server_send_new_id(SilcServer server,
 {
   SilcBuffer idp;
 
-  SILC_LOG_DEBUG(("Start"));
+  SILC_LOG_DEBUG(("Sending new ID"));
 
   idp = silc_id_payload_encode(id, id_type);
   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);
 }
 
@@ -1683,7 +1694,7 @@ void silc_server_send_new_channel(SilcServer server,
   unsigned char *cid;
   SilcUInt32 name_len = strlen(channel_name);
 
-  SILC_LOG_DEBUG(("Start"));
+  SILC_LOG_DEBUG(("Sending new channel"));
 
   cid = silc_id_id2str(channel_id, SILC_ID_CHANNEL);
   if (!cid)
@@ -1697,14 +1708,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);
 }