updates.
[runtime.git] / apps / silcd / packet_send.c
index 1fbb0e59c92215f9f293740310c84677e010908c..4b271c4d9cc5c94e84b04063c3352e3c18cfa342 100644 (file)
@@ -655,9 +655,9 @@ void silc_server_packet_relay_to_channel(SilcServer server,
            memcpy(tmp, data, data_len);
 
            /* Decrypt the channel message (we don't check the MAC) */
-           if (!silc_channel_payload_decrypt(tmp, data_len, 
-                                             channel->channel_key,
-                                             NULL)) {
+           if (!silc_channel_message_payload_decrypt(tmp, data_len, 
+                                                     channel->channel_key,
+                                                     NULL)) {
              memset(tmp, 0, data_len);
              silc_free(tmp);
              continue;
@@ -1101,6 +1101,79 @@ void silc_server_send_notify_killed(SilcServer server,
   silc_buffer_free(idp);
 }
 
+/* Sends UMODE_CHANGE notify type. This tells that `client_id' client's
+   user mode in the SILC Network was changed. This function is used to
+   send the packet between routers as broadcast packet. */
+
+void silc_server_send_notify_umode(SilcServer server,
+                                  SilcSocketConnection sock,
+                                  int broadcast,
+                                  SilcClientID *client_id,
+                                  unsigned int client_id_len,
+                                  unsigned int mode_mask)
+{
+  SilcBuffer idp;
+  unsigned char mode[4];
+
+  idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
+  SILC_PUT32_MSB(mode_mask, mode);
+
+  silc_server_send_notify(server, sock, broadcast,
+                         SILC_NOTIFY_TYPE_UMODE_CHANGE, 2,
+                         idp->data, idp->len, 
+                         mode, 4);
+  silc_buffer_free(idp);
+}
+
+/* Sends BAN notify type. This tells that ban has been either `add'ed
+   or `del'eted on the `channel. This function is used to send the packet
+   between routers as broadcast packet. */
+
+void silc_server_send_notify_ban(SilcServer server,
+                                SilcSocketConnection sock,
+                                int broadcast,
+                                SilcChannelEntry channel,
+                                char *add, char *del)
+{
+  SilcBuffer idp;
+
+  idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
+  silc_server_send_notify(server, sock, broadcast,
+                         SILC_NOTIFY_TYPE_BAN, 3,
+                         idp->data, idp->len,
+                         add, add ? strlen(add) : 0,
+                         del, del ? strlen(del) : 0);
+  silc_buffer_free(idp);
+}
+
+/* Sends INVITE notify type. This tells that invite has been either `add'ed
+   or `del'eted on the `channel.  The sender of the invite is the `client_id'.
+   This function is used to send the packet between routers as broadcast
+   packet. */
+
+void silc_server_send_notify_invite(SilcServer server,
+                                   SilcSocketConnection sock,
+                                   int broadcast,
+                                   SilcChannelEntry channel,
+                                   SilcClientID *client_id,
+                                   unsigned int client_id_len,
+                                   char *add, char *del)
+{
+  SilcBuffer idp, idp2;
+
+  idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
+  idp2 = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
+  silc_server_send_notify(server, sock, broadcast,
+                         SILC_NOTIFY_TYPE_INVITE, 5,
+                         idp->data, idp->len,
+                         channel->channel_name, strlen(channel->channel_name),
+                         idp2->data, idp2->len,
+                         add, add ? strlen(add) : 0,
+                         del, del ? strlen(del) : 0);
+  silc_buffer_free(idp);
+  silc_buffer_free(idp2);
+}
+
 /* Sends notify message destined to specific entity. */
 
 void silc_server_send_notify_dest(SilcServer server,
@@ -1149,14 +1222,15 @@ void silc_server_send_notify_to_channel(SilcServer server,
   silc_buffer_free(packet);
 }
 
-/* Send notify message to all clients the client has joined. It is quaranteed
+/* Send notify message to all channels the client has joined. It is quaranteed
    that the message is sent only once to a client (ie. if a client is joined
    on two same channel it will receive only one notify message). Also, this
    sends only to local clients (locally connected if we are server, and to
-   local servers if we are router). */
+   local servers if we are router). If `sender' is provided the packet is
+   not sent to that client at all. */
 
 void silc_server_send_notify_on_channels(SilcServer server,
-                                        SilcSocketConnection sender,
+                                        SilcClientEntry sender,
                                         SilcClientEntry client,
                                         SilcNotifyType type,
                                         unsigned int argc, ...)
@@ -1204,6 +1278,9 @@ void silc_server_send_notify_on_channels(SilcServer server,
     while ((chl2 = silc_list_get(channel->user_list)) != SILC_LIST_END) {
       c = chl2->client;
       
+      if (sender && c == sender)
+       continue;
+
       /* Check if we have sent the packet to this client already */
       for (k = 0; k < sent_clients_count; k++)
        if (sent_clients[k] == c)
@@ -1226,9 +1303,6 @@ void silc_server_send_notify_on_channels(SilcServer server,
        sock = (SilcSocketConnection)c->router->connection;
        idata = (SilcIDListData)c->router;
        
-       if (sender && sock == sender)
-         continue;
-
        packetdata.dst_id = silc_id_id2str(c->router->id, SILC_ID_SERVER);
        packetdata.dst_id_len = SILC_ID_SERVER_LEN;
        packetdata.dst_id_type = SILC_ID_SERVER;
@@ -1264,9 +1338,6 @@ void silc_server_send_notify_on_channels(SilcServer server,
        sock = (SilcSocketConnection)c->connection;
        idata = (SilcIDListData)c;
        
-       if (sender && sock == sender)
-         continue;
-
        packetdata.dst_id = silc_id_id2str(c->id, SILC_ID_CLIENT);
        packetdata.dst_id_len = SILC_ID_CLIENT_LEN;
        packetdata.dst_id_type = SILC_ID_CLIENT;
@@ -1331,7 +1402,8 @@ void silc_server_send_new_channel(SilcServer server,
                                  int broadcast,
                                  char *channel_name,
                                  void *channel_id, 
-                                 unsigned int channel_id_len)
+                                 unsigned int channel_id_len,
+                                 unsigned int mode)
 {
   SilcBuffer packet;
   unsigned char *cid;
@@ -1343,15 +1415,9 @@ void silc_server_send_new_channel(SilcServer server,
   if (!cid)
     return;
 
-  packet = silc_buffer_alloc(2 + 2 + name_len + channel_id_len);
-  silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
-  silc_buffer_format(packet,
-                    SILC_STR_UI_SHORT(name_len),
-                    SILC_STR_UI_XNSTRING(channel_name, name_len),
-                    SILC_STR_UI_SHORT(channel_id_len),
-                    SILC_STR_UI_XNSTRING(cid, channel_id_len),
-                    SILC_STR_END);
-
+  /* Encode the channel payload */
+  packet = silc_channel_payload_encode(channel_name, name_len,
+                                      cid, channel_id_len, mode);
 
   silc_server_packet_send(server, sock, SILC_PACKET_NEW_CHANNEL, 
                          broadcast ? SILC_PACKET_FLAG_BROADCAST : 0, 
@@ -1426,38 +1492,19 @@ void silc_server_send_heartbeat(SilcServer server,
                          NULL, 0, FALSE);
 }
 
-/* Routine used to send (relay, route) key agreement packets to some 
-   destination. */
+/* Generic function to relay packet we've received. This is used to relay
+   packets to a client but generally can be used to other purposes as well. */
 
-void silc_server_send_key_agreement(SilcServer server,
-                                   SilcSocketConnection dst_sock,
-                                   SilcCipher cipher,
-                                   SilcHmac hmac,
-                                   SilcPacketContext *packet)
+void silc_server_relay_packet(SilcServer server,
+                             SilcSocketConnection dst_sock,
+                             SilcCipher cipher,
+                             SilcHmac hmac,
+                             SilcPacketContext *packet,
+                             int force_send)
 {
   silc_buffer_push(packet->buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len 
                   + packet->dst_id_len + packet->padlen);
-  silc_packet_send_prepare(dst_sock, 0, 0, packet->buffer->len);
-  silc_buffer_put(dst_sock->outbuf, packet->buffer->data, packet->buffer->len);
-  
-  /* Re-encrypt packet */
-  silc_packet_encrypt(cipher, hmac, dst_sock->outbuf, packet->buffer->len);
-  
-  /* Send the packet */
-  silc_server_packet_send_real(server, dst_sock, FALSE);
-}
-
-/* Routine used to send (relay, route) private message key packets to some 
-   destination. */
 
-void silc_server_send_private_message_key(SilcServer server,
-                                         SilcSocketConnection dst_sock,
-                                         SilcCipher cipher,
-                                         SilcHmac hmac,
-                                         SilcPacketContext *packet)
-{
-  silc_buffer_push(packet->buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len 
-                  + packet->dst_id_len + packet->padlen);
   silc_packet_send_prepare(dst_sock, 0, 0, packet->buffer->len);
   silc_buffer_put(dst_sock->outbuf, packet->buffer->data, packet->buffer->len);
   
@@ -1465,27 +1512,8 @@ void silc_server_send_private_message_key(SilcServer server,
   silc_packet_encrypt(cipher, hmac, dst_sock->outbuf, packet->buffer->len);
   
   /* Send the packet */
-  silc_server_packet_send_real(server, dst_sock, FALSE);
-}
+  silc_server_packet_send_real(server, dst_sock, force_send);
 
-/* Routine used to relay notify packets to a client. The notify packets
-   may be destined directly to a client and this routine is used to do
-   that. */
-
-void silc_server_packet_relay_notify(SilcServer server,
-                                    SilcSocketConnection dst_sock,
-                                    SilcCipher cipher,
-                                    SilcHmac hmac,
-                                    SilcPacketContext *packet)
-{
-  silc_buffer_push(packet->buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len 
+  silc_buffer_pull(packet->buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len 
                   + packet->dst_id_len + packet->padlen);
-  silc_packet_send_prepare(dst_sock, 0, 0, packet->buffer->len);
-  silc_buffer_put(dst_sock->outbuf, packet->buffer->data, packet->buffer->len);
-  
-  /* Re-encrypt packet */
-  silc_packet_encrypt(cipher, hmac, dst_sock->outbuf, packet->buffer->len);
-  
-  /* Send the packet */
-  silc_server_packet_send_real(server, dst_sock, FALSE);
 }