Fixes to connection freeing crashes
[runtime.git] / apps / silcd / packet_send.c
1 /*
2
3   packet_send.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1997 - 2007 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19
20 #include "serverincludes.h"
21 #include "server_internal.h"
22
23 /* Send packet to remote connection */
24
25 SilcBool silc_server_packet_send(SilcServer server,
26                                  SilcPacketStream sock,
27                                  SilcPacketType type,
28                                  SilcPacketFlags flags,
29                                  unsigned char *data,
30                                  SilcUInt32 data_len)
31 {
32   SilcIDListData idata;
33
34   if (!sock)
35     return FALSE;
36
37   idata = silc_packet_get_context(sock);
38
39   /* If entry is disabled do not sent anything.  Allow hearbeat though */
40   if ((idata && idata->status & SILC_IDLIST_STATUS_DISABLED &&
41        type != SILC_PACKET_HEARTBEAT) ||
42       ((SilcServerEntry)idata == server->id_entry)) {
43     SILC_LOG_DEBUG(("Connection is disabled"));
44     return FALSE;
45   }
46
47   SILC_LOG_DEBUG(("Sending %s packet", silc_get_packet_name(type)));
48
49   return silc_packet_send(sock, type, flags, (const unsigned char *)data,
50                           data_len);
51 }
52
53 /* Send packet to remote connection with specific destination ID. */
54
55 SilcBool silc_server_packet_send_dest(SilcServer server,
56                                       SilcPacketStream sock,
57                                       SilcPacketType type,
58                                       SilcPacketFlags flags,
59                                       void *dst_id,
60                                       SilcIdType dst_id_type,
61                                       unsigned char *data,
62                                       SilcUInt32 data_len)
63 {
64   SilcIDListData idata;
65
66   if (!sock)
67     return FALSE;
68
69   idata = silc_packet_get_context(sock);
70
71   /* If entry is disabled do not sent anything.  Allow hearbeat though */
72   if ((idata && idata->status & SILC_IDLIST_STATUS_DISABLED &&
73        type != SILC_PACKET_HEARTBEAT) ||
74       ((SilcServerEntry)idata == server->id_entry)) {
75     SILC_LOG_DEBUG(("Connection is disabled"));
76     return FALSE;
77   }
78
79   SILC_LOG_DEBUG(("Sending %s packet", silc_get_packet_name(type)));
80
81   return silc_packet_send_ext(sock, type, flags, 0, NULL, dst_id_type, dst_id,
82                               (const unsigned char *)data, data_len,
83                               NULL, NULL);
84 }
85
86 /* Send packet to remote connection with specific source and destination
87    IDs. */
88
89 SilcBool silc_server_packet_send_srcdest(SilcServer server,
90                                          SilcPacketStream sock,
91                                          SilcPacketType type,
92                                          SilcPacketFlags flags,
93                                          void *src_id,
94                                          SilcIdType src_id_type,
95                                          void *dst_id,
96                                          SilcIdType dst_id_type,
97                                          unsigned char *data,
98                                          SilcUInt32 data_len)
99 {
100   SilcIDListData idata;
101
102   if (!sock)
103     return FALSE;
104
105   idata = silc_packet_get_context(sock);
106
107   /* If entry is disabled do not sent anything.  Allow hearbeat though */
108   if ((idata && idata->status & SILC_IDLIST_STATUS_DISABLED &&
109        type != SILC_PACKET_HEARTBEAT) ||
110       ((SilcServerEntry)idata == server->id_entry)) {
111     SILC_LOG_DEBUG(("Connection is disabled"));
112     return FALSE;
113   }
114
115   SILC_LOG_DEBUG(("Sending %s packet", silc_get_packet_name(type)));
116
117   return silc_packet_send_ext(sock, type, flags, src_id_type, src_id,
118                               dst_id_type, dst_id,
119                               (const unsigned char *)data, data_len,
120                               NULL, NULL);
121 }
122
123 /* Broadcast received packet to our primary route. This function is used
124    by router to further route received broadcast packet. It is expected
125    that the broadcast flag from the packet is checked before calling this
126    function. This does not test or set the broadcast flag. */
127
128 SilcBool silc_server_packet_broadcast(SilcServer server,
129                                       SilcPacketStream primary_route,
130                                       SilcPacket packet)
131 {
132   SilcServerID src_id, dst_id;
133
134   if (!primary_route)
135     return FALSE;
136
137   SILC_LOG_DEBUG(("Broadcasting received broadcast packet"));
138
139   if (!silc_id_str2id(packet->src_id, packet->src_id_len, packet->src_id_type,
140                       &src_id, sizeof(src_id)))
141     return FALSE;
142   if (!silc_id_str2id(packet->dst_id, packet->dst_id_len, packet->dst_id_type,
143                       &dst_id, sizeof(dst_id)))
144     return FALSE;
145
146   /* If the packet is originated from our primary route we are not allowed
147      to send the packet. */
148   if (SILC_ID_SERVER_COMPARE(&src_id, server->router->id)) {
149     SILC_LOG_DEBUG(("Will not broadcast to primary route since it is the "
150                     "original sender of this packet"));
151     return FALSE;
152   }
153
154   /* Send the packet */
155   return silc_server_packet_send_srcdest(server, primary_route, packet->type,
156                                          packet->flags, &src_id,
157                                          SILC_ID_SERVER, &dst_id,
158                                          SILC_ID_SERVER,
159                                          packet->buffer.data,
160                                          silc_buffer_len(&packet->buffer));
161 }
162
163 /* Routes received packet to `sock'. This is used to route the packets that
164    router receives but are not destined to it. */
165
166 SilcBool silc_server_packet_route(SilcServer server,
167                                   SilcPacketStream sock,
168                                   SilcPacket packet)
169 {
170   SilcID src_id, dst_id;
171
172   if (!silc_id_str2id2(packet->src_id, packet->src_id_len, packet->src_id_type,
173                        &src_id))
174     return FALSE;
175   if (!silc_id_str2id2(packet->dst_id, packet->dst_id_len, packet->dst_id_type,
176                        &dst_id))
177     return FALSE;
178
179   return silc_server_packet_send_srcdest(server, sock, packet->type,
180                                          packet->flags,
181                                          SILC_ID_GET_ID(src_id),
182                                          src_id.type,
183                                          SILC_ID_GET_ID(dst_id),
184                                          dst_id.type,
185                                          packet->buffer.data,
186                                          silc_buffer_len(&packet->buffer));
187 }
188
189 /* This routine can be used to send a packet to table of clients provided
190    in `clients'. If `route' is FALSE the packet is routed only to local
191    clients (for server locally connected, and for router local cell). */
192
193 void silc_server_packet_send_clients(SilcServer server,
194                                      SilcHashTable clients,
195                                      SilcPacketType type,
196                                      SilcPacketFlags flags,
197                                      SilcBool route,
198                                      unsigned char *data,
199                                      SilcUInt32 data_len)
200 {
201   SilcPacketStream sock = NULL;
202   SilcIDListData idata;
203   SilcHashTableList htl;
204   SilcClientEntry client = NULL;
205   SilcServerEntry *routed = NULL;
206   SilcUInt32 routed_count = 0;
207   SilcBool gone = FALSE;
208   int k;
209
210   if (!silc_hash_table_count(clients))
211     return;
212
213   SILC_LOG_DEBUG(("Sending packet to %d clients",
214                   silc_hash_table_count(clients)));
215
216   /* Send to all clients in table */
217   silc_hash_table_list(clients, &htl);
218   while (silc_hash_table_get(&htl, NULL, (void *)&client)) {
219     /* If client has router set it is not locally connected client and
220        we will route the message to the router set in the client. Though,
221        send locally connected server in all cases. */
222     if (server->server_type == SILC_ROUTER && client->router &&
223         ((!route && client->router->router == server->id_entry) || route)) {
224
225       /* Check if we have sent the packet to this route already */
226       for (k = 0; k < routed_count; k++)
227         if (routed[k] == client->router)
228           break;
229       if (k < routed_count)
230         continue;
231
232       /* Route only once to router */
233       sock = client->router->connection;
234       idata = silc_packet_get_context(sock);
235       if (idata->conn_type == SILC_CONN_ROUTER) {
236         if (gone)
237           continue;
238         gone = TRUE;
239       }
240
241       /* Send the packet */
242       silc_server_packet_send_dest(server, sock, type, flags,
243                                    client->router->id, SILC_ID_SERVER,
244                                    data, data_len);
245
246       /* Mark this route routed already */
247       routed = silc_realloc(routed, sizeof(*routed) * (routed_count + 1));
248       routed[routed_count++] = client->router;
249       continue;
250     }
251
252     if (client->router)
253       continue;
254
255     /* Send to locally connected client */
256     sock = client->connection;
257     if (!sock)
258       continue;
259
260     silc_server_packet_send_dest(server, sock, type, flags,
261                                  client->id, SILC_ID_CLIENT,
262                                  data, data_len);
263   }
264   silc_hash_table_list_reset(&htl);
265   silc_free(routed);
266 }
267
268 /* This routine is used by the server to send packets to channel. The
269    packet sent with this function is distributed to all clients on
270    the channel. Usually this is used to send notify messages to the
271    channel, things like notify about new user joining to the channel.
272    If `route' is FALSE then the packet is sent only locally and will not
273    be routed anywhere (for router locally means cell wide). If `sender'
274    is provided then the packet is not sent to that connection since it
275    originally came from it. If `send_to_clients' is FALSE then the
276    packet is not sent clients, only servers. */
277
278 void silc_server_packet_send_to_channel(SilcServer server,
279                                         SilcPacketStream sender,
280                                         SilcChannelEntry channel,
281                                         SilcPacketType type,
282                                         SilcBool route,
283                                         SilcBool send_to_clients,
284                                         unsigned char *data,
285                                         SilcUInt32 data_len)
286 {
287   SilcPacketStream sock = NULL;
288   SilcClientEntry client = NULL;
289   SilcServerEntry *routed = NULL;
290   SilcChannelClientEntry chl;
291   SilcHashTableList htl;
292   SilcIDListData idata;
293   SilcUInt32 routed_count = 0;
294   SilcBool gone = FALSE;
295   int k;
296
297   /* This doesn't send channel message packets */
298   SILC_ASSERT(type != SILC_PACKET_CHANNEL_MESSAGE);
299
300   /* If there are global users in the channel we will send the message
301      first to our router for further routing. */
302   if (route && server->server_type != SILC_ROUTER && !server->standalone &&
303       channel->global_users) {
304     sock = server->router->connection;
305     if (sock != sender) {
306       SILC_LOG_DEBUG(("Sending packet to router for routing"));
307       silc_server_packet_send_dest(server, sock, type, 0, channel->id,
308                                    SILC_ID_CHANNEL, data, data_len);
309     }
310   }
311
312   if (!silc_hash_table_count(channel->user_list)) {
313     SILC_LOG_DEBUG(("Channel %s is empty", channel->channel_name));
314     goto out;
315   }
316
317   SILC_LOG_DEBUG(("Sending %s to channel %s",
318                   silc_get_packet_name(type), channel->channel_name));
319
320   routed = silc_calloc(silc_hash_table_count(channel->user_list),
321                        sizeof(*routed));
322
323   /* Send the message to clients on the channel's client list. */
324   silc_hash_table_list(channel->user_list, &htl);
325   while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
326     client = chl->client;
327     if (!client)
328       continue;
329
330     /* If client has router set it is not locally connected client and
331        we will route the message to the router set in the client. Though,
332        send locally connected server in all cases. */
333     if (server->server_type == SILC_ROUTER && client->router &&
334         ((!route && client->router->router == server->id_entry) || route)) {
335
336       /* Check if we have sent the packet to this route already */
337       for (k = 0; k < routed_count; k++)
338         if (routed[k] == client->router)
339           break;
340       if (k < routed_count)
341         continue;
342
343       /* Get data used in packet header encryption, keys and stuff. */
344       sock = client->router->connection;
345       idata = (SilcIDListData)client->router;
346
347       if (sender && sock == sender)
348         continue;
349
350       /* Route only once to router. Protocol prohibits sending channel
351          messages to more than one router. */
352       if (idata->conn_type == SILC_CONN_ROUTER) {
353         if (gone)
354           continue;
355         gone = TRUE;
356       }
357
358       SILC_LOG_DEBUG(("Sending packet to client %s",
359                       client->nickname ? client->nickname :
360                       (unsigned char *)""));
361
362       /* Send the packet */
363       silc_server_packet_send_dest(server, sock, type, 0, channel->id,
364                                    SILC_ID_CHANNEL, data, data_len);
365
366       /* Mark this route routed already */
367       routed[routed_count++] = client->router;
368       continue;
369     }
370
371     if (client->router || !send_to_clients)
372       continue;
373
374     /* Send to locally connected client */
375
376     /* Get data used in packet header encryption, keys and stuff. */
377     sock = client->connection;
378     if (!sock || (sender && sock == sender))
379       continue;
380
381     SILC_LOG_DEBUG(("Sending packet to client %s",
382                     client->nickname ? client->nickname :
383                     (unsigned char *)""));
384
385     /* Send the packet */
386     silc_server_packet_send_dest(server, sock, type, 0, channel->id,
387                                  SILC_ID_CHANNEL, data, data_len);
388   }
389   silc_hash_table_list_reset(&htl);
390
391  out:
392   silc_free(routed);
393 }
394
395 /* This checks whether the relayed packet came from router. If it did
396    then we'll need to encrypt it with the channel key. This is called
397    from the silc_server_packet_relay_to_channel. */
398
399 static SilcBool
400 silc_server_packet_relay_to_channel_encrypt(SilcServer server,
401                                             SilcPacketStream sender,
402                                             void *sender_id,
403                                             SilcIdType sender_type,
404                                             SilcChannelEntry channel,
405                                             unsigned char *data,
406                                             unsigned int data_len)
407 {
408   SilcIDListData idata;
409   SilcUInt32 mac_len, iv_len;
410   unsigned char iv[SILC_CIPHER_MAX_IV_SIZE];
411   SilcUInt16 totlen, len;
412   SilcID src_id, dst_id;
413
414   idata = silc_packet_get_context(sender);
415
416   /* If we are router and the packet came from router and private key
417      has not been set for the channel then we must encrypt the packet
418      as it was decrypted with the session key shared between us and the
419      router which sent it. This is so, because cells does not share the
420      same channel key. */
421   if (server->server_type == SILC_ROUTER &&
422       idata->conn_type == SILC_CONN_ROUTER &&
423       !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY) && channel->key) {
424
425     /* If we are backup router and remote is our primary router and
426        we are currently doing backup resuming protocol we must not
427        re-encrypt message with session key. */
428     if (server->backup_router && idata->sconn->backup_resuming &&
429         SILC_PRIMARY_ROUTE(server) == sender)
430       return TRUE;
431
432     mac_len = silc_hmac_len(channel->hmac);
433     iv_len = silc_cipher_get_block_len(channel->send_key);
434
435     if (data_len <= mac_len + iv_len) {
436       SILC_LOG_WARNING(("Corrupted channel message, cannot relay it"));
437       return FALSE;
438     }
439
440     totlen = 2;
441     SILC_GET16_MSB(len, data + totlen);
442     totlen += 2 + len;
443     if (totlen + iv_len + mac_len + 2 > data_len) {
444       SILC_LOG_WARNING(("Corrupted channel message, cannot relay it"));
445       return FALSE;
446     }
447     SILC_GET16_MSB(len, data + totlen);
448     totlen += 2 + len;
449     if (totlen + iv_len + mac_len > data_len) {
450       SILC_LOG_WARNING(("Corrupted channel message, cannot relay it"));
451       return FALSE;
452     }
453
454     memcpy(iv, data + (data_len - iv_len - mac_len), iv_len);
455
456     SILC_ASSERT(sender_type == SILC_ID_CLIENT);
457     src_id.type = SILC_ID_CLIENT;
458     src_id.u.client_id = *((SilcClientID *)sender_id);
459     dst_id.type = SILC_ID_CHANNEL;
460     dst_id.u.channel_id = *channel->id;
461
462     return silc_message_payload_encrypt(data, totlen, data_len - mac_len,
463                                         iv, &src_id, &dst_id,
464                                         channel->send_key, channel->hmac);
465   }
466
467   return TRUE;
468 }
469
470 /* This routine is explicitly used to relay messages to some channel.
471    Packets sent with this function we have received earlier and are
472    totally encrypted. This just sends the packet to all clients on
473    the channel. If the sender of the packet is someone on the channel
474    the message will not be sent to that client. The SILC Packet header
475    is encrypted with the session key shared between us and the client.
476    MAC is also computed before encrypting the header. Rest of the
477    packet will be untouched. */
478
479 void silc_server_packet_relay_to_channel(SilcServer server,
480                                          SilcPacketStream sender_sock,
481                                          SilcChannelEntry channel,
482                                          void *sender_id,
483                                          SilcIdType sender_type,
484                                          SilcClientEntry sender_entry,
485                                          unsigned char *data,
486                                          SilcUInt32 data_len)
487 {
488   SilcPacketStream sock = NULL;
489   SilcClientEntry client = NULL;
490   SilcServerEntry *routed = NULL;
491   SilcChannelClientEntry chl, chl_sender;
492   SilcUInt32 routed_count = 0;
493   SilcIDListData idata;
494   SilcHashTableList htl;
495   SilcBool gone = FALSE;
496   int k;
497
498   if (!silc_server_client_on_channel(sender_entry, channel, &chl_sender))
499     return;
500
501   SILC_LOG_DEBUG(("Relaying packet to channel %s", channel->channel_name));
502
503   /* This encrypts the message, if needed. It will be encrypted if
504      it came from the router thus it needs to be encrypted with the
505      channel key. If the channel key does not exist, then we know we
506      don't have a single local user on the channel. */
507   if (!silc_server_packet_relay_to_channel_encrypt(server, sender_sock,
508                                                    sender_id, sender_type,
509                                                    channel, data,
510                                                    data_len))
511     return;
512
513   /* If there are global users in the channel we will send the message
514      first to our router for further routing. */
515   if (server->server_type != SILC_ROUTER && !server->standalone &&
516       channel->global_users) {
517     SilcServerEntry router = server->router;
518
519     /* Check that the sender is not our router. */
520     if (sender_sock != router->connection) {
521       SILC_LOG_DEBUG(("Sending message to router for routing"));
522       sock = router->connection;
523       silc_server_packet_send_srcdest(server, sock,
524                                       SILC_PACKET_CHANNEL_MESSAGE, 0,
525                                       sender_id, sender_type,
526                                       channel->id, SILC_ID_CHANNEL,
527                                       data, data_len);
528     }
529   }
530
531   routed = silc_calloc(silc_hash_table_count(channel->user_list),
532                        sizeof(*routed));
533
534   /* Assure we won't route the message back to the sender's way. */
535   if (sender_entry->router)
536     routed[routed_count++] = sender_entry->router;
537
538   /* Send the message to clients on the channel's client list. */
539   silc_hash_table_list(channel->user_list, &htl);
540   while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
541     client = chl->client;
542     if (!client || client == sender_entry)
543       continue;
544
545     /* Check whether message sending is blocked */
546     if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)
547       continue;
548     if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS &&
549         !(chl_sender->mode & SILC_CHANNEL_UMODE_CHANOP) &&
550         !(chl_sender->mode & SILC_CHANNEL_UMODE_CHANFO))
551       continue;
552     if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS &&
553         sender_entry->mode & SILC_UMODE_ROBOT)
554       continue;
555
556     /* If the client has set router it means that it is not locally
557        connected client and we will route the packet further. */
558     if (server->server_type == SILC_ROUTER && client->router) {
559
560       /* Check if we have sent the packet to this route already */
561       for (k = 0; k < routed_count; k++)
562         if (routed[k] == client->router)
563           break;
564       if (k < routed_count)
565         continue;
566
567       /* Get data used in packet header encryption, keys and stuff. */
568       sock = client->router->connection;
569       idata = (SilcIDListData)client->router;
570
571       /* Check if the sender socket is the same as this client's router
572          socket. */
573       if (sender_sock && sock == sender_sock)
574         continue;
575
576       SILC_LOG_DEBUG(("Relaying packet to client ID(%s)",
577                       silc_id_render(client->id, SILC_ID_CLIENT)));
578
579       /* Mark this route routed already. */
580       routed[routed_count++] = client->router;
581
582       if (idata->conn_type == SILC_CONN_ROUTER) {
583         /* The remote connection is router then we'll decrypt the
584            channel message and re-encrypt it with the session key shared
585            between us and the remote router. This is done because the
586            channel keys are cell specific and we have different channel
587            key than the remote router has. */
588
589         /* Route only once to router. Protocol prohibits sending channel
590            messages to more than one router. */
591         if (gone)
592           continue;
593         gone = TRUE;
594
595         /* If we are backup router and remote is our primary router and
596            we are currently doing backup resuming protocol we must not
597            re-encrypt message with session key. */
598         if (server->backup_router && idata->sconn->backup_resuming &&
599             SILC_PRIMARY_ROUTE(server) == sock) {
600           silc_server_packet_send_srcdest(server, sock,
601                                           SILC_PACKET_CHANNEL_MESSAGE, 0,
602                                           sender_id, sender_type,
603                                           channel->id, SILC_ID_CHANNEL,
604                                           data, data_len);
605           continue;
606         }
607
608         SILC_LOG_DEBUG(("Remote is router, encrypt with session key"));
609
610         /* If private key mode is not set then decrypt the packet
611            and re-encrypt it */
612         if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY) &&
613             channel->receive_key) {
614           unsigned char tmp[SILC_PACKET_MAX_LEN], sid[32], rid[32];
615           SilcUInt32 sid_len, rid_len;
616
617           if (data_len > SILC_PACKET_MAX_LEN)
618             data_len = SILC_PACKET_MAX_LEN;
619           memcpy(tmp, data, data_len);
620
621           /* Decrypt the channel message (we don't check the MAC) */
622           silc_id_id2str(sender_id, sender_type, sid, sizeof(sid), &sid_len);
623           silc_id_id2str(channel->id, SILC_ID_CHANNEL, rid, sizeof(rid),
624                          &rid_len);
625           silc_message_payload_decrypt(tmp, data_len, FALSE, FALSE,
626                                        channel->receive_key,
627                                        channel->hmac, sid, sid_len,
628                                        rid, rid_len, FALSE);
629
630           /* Now re-encrypt and send it to the router */
631           silc_server_packet_send_srcdest(server, sock,
632                                           SILC_PACKET_CHANNEL_MESSAGE, 0,
633                                           sender_id, sender_type,
634                                           channel->id, SILC_ID_CHANNEL,
635                                           tmp, data_len);
636         } else {
637           /* Private key mode is set, we don't have the channel key, so
638              just re-encrypt the entire packet and send it to the router. */
639           silc_server_packet_send_srcdest(server, sock,
640                                           SILC_PACKET_CHANNEL_MESSAGE, 0,
641                                           sender_id, sender_type,
642                                           channel->id, SILC_ID_CHANNEL,
643                                           data, data_len);
644         }
645       } else {
646         /* Send the packet to normal server */
647         silc_server_packet_send_srcdest(server, sock,
648                                         SILC_PACKET_CHANNEL_MESSAGE, 0,
649                                         sender_id, sender_type,
650                                         channel->id, SILC_ID_CHANNEL,
651                                         data, data_len);
652       }
653
654       continue;
655     }
656
657     if (client->router)
658       continue;
659
660     /* Get data used in packet header encryption, keys and stuff. */
661     sock = client->connection;
662     if (!sock || (sender_sock && sock == sender_sock))
663       continue;
664
665     SILC_LOG_DEBUG(("Sending packet to client ID(%s)",
666                     silc_id_render(client->id, SILC_ID_CLIENT)));
667
668     /* Send the packet */
669     silc_server_packet_send_srcdest(server, sock,
670                                     SILC_PACKET_CHANNEL_MESSAGE, 0,
671                                     sender_id, sender_type,
672                                     channel->id, SILC_ID_CHANNEL,
673                                     data, data_len);
674   }
675
676   silc_hash_table_list_reset(&htl);
677   silc_free(routed);
678 }
679
680 /* This function is used to send packets strictly to all local clients
681    on a particular channel.  This is used for example to distribute new
682    channel key to all our locally connected clients on the channel.
683    The packets are always encrypted with the session key shared between
684    the client, this means these are not _to the channel_ but _to the client_
685    on the channel. */
686
687 void silc_server_packet_send_local_channel(SilcServer server,
688                                            SilcChannelEntry channel,
689                                            SilcPacketType type,
690                                            SilcPacketFlags flags,
691                                            unsigned char *data,
692                                            SilcUInt32 data_len)
693 {
694   SilcChannelClientEntry chl;
695   SilcHashTableList htl;
696   SilcPacketStream sock = NULL;
697
698   SILC_LOG_DEBUG(("Send packet to local clients on channel %s",
699                   channel->channel_name));
700
701   /* Send the message to clients on the channel's client list. */
702   silc_hash_table_list(channel->user_list, &htl);
703   while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
704     if (chl->client && SILC_IS_LOCAL(chl->client)) {
705       sock = chl->client->connection;
706
707       /* Send the packet to the client */
708       silc_server_packet_send_dest(server, sock, type, flags, chl->client->id,
709                                    SILC_ID_CLIENT, data, data_len);
710     }
711   }
712   silc_hash_table_list_reset(&htl);
713 }
714
715 /* Sends current motd to client */
716
717 void silc_server_send_motd(SilcServer server,
718                            SilcPacketStream sock)
719 {
720   char *motd, *motd_file = NULL;
721   SilcUInt32 motd_len;
722
723   if (server->config)
724     motd_file = server->config->server_info->motd_file;
725
726   if (motd_file) {
727     motd = silc_file_readfile(motd_file, &motd_len);
728     if (!motd)
729       return;
730
731     motd[motd_len] = 0;
732     silc_server_send_notify(server, sock, FALSE, SILC_NOTIFY_TYPE_MOTD, 1,
733                             motd, motd_len);
734     silc_free(motd);
735   }
736 }
737
738 /* Sends error message. Error messages may or may not have any
739    implications. */
740
741 void silc_server_send_error(SilcServer server,
742                             SilcPacketStream sock,
743                             const char *fmt, ...)
744 {
745   va_list ap;
746   unsigned char buf[4096];
747
748   memset(buf, 0, sizeof(buf));
749   va_start(ap, fmt);
750   vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
751   va_end(ap);
752
753   silc_server_packet_send(server, sock, SILC_PACKET_ERROR, 0,
754                           buf, strlen(buf));
755 }
756
757 /* Sends notify message. If format is TRUE the variable arguments are
758    formatted and the formatted string is sent as argument payload. If it is
759    FALSE then each argument is sent as separate argument and their format
760    in the argument list must be { argument data, argument length }. */
761
762 void silc_server_send_notify(SilcServer server,
763                              SilcPacketStream sock,
764                              SilcBool broadcast,
765                              SilcNotifyType type,
766                              SilcUInt32 argc, ...)
767 {
768   va_list ap;
769   SilcBuffer packet;
770
771   va_start(ap, argc);
772
773   packet = silc_notify_payload_encode(type, argc, ap);
774   silc_server_packet_send(server, sock, SILC_PACKET_NOTIFY,
775                           broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
776                           packet->data, silc_buffer_len(packet));
777
778   /* Send to backup routers if this is being broadcasted to primary
779      router.  The silc_server_backup_send checks further whether to
780      actually send it or not. */
781   if ((broadcast && sock && sock == SILC_PRIMARY_ROUTE(server)) ||
782       (broadcast && !sock && !SILC_PRIMARY_ROUTE(server)))
783     silc_server_backup_send(server, NULL, SILC_PACKET_NOTIFY, 0,
784                             packet->data, silc_buffer_len(packet),
785                             FALSE, TRUE);
786
787   silc_buffer_free(packet);
788   va_end(ap);
789 }
790
791 /* Sends notify message and gets the arguments from the `args' Argument
792    Payloads. */
793
794 void silc_server_send_notify_args(SilcServer server,
795                                   SilcPacketStream sock,
796                                   SilcBool broadcast,
797                                   SilcNotifyType type,
798                                   SilcUInt32 argc,
799                                   SilcBuffer args)
800 {
801   SilcBuffer packet;
802
803   packet = silc_notify_payload_encode_args(type, argc, args);
804   silc_server_packet_send(server, sock, SILC_PACKET_NOTIFY,
805                           broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
806                           packet->data, silc_buffer_len(packet));
807   silc_buffer_free(packet);
808 }
809
810 /* Send CHANNEL_CHANGE notify type. This tells the receiver to replace the
811    `old_id' with the `new_id'. */
812
813 void silc_server_send_notify_channel_change(SilcServer server,
814                                             SilcPacketStream sock,
815                                             SilcBool broadcast,
816                                             SilcChannelID *old_id,
817                                             SilcChannelID *new_id)
818 {
819   SilcBuffer idp1, idp2;
820
821   idp1 = silc_id_payload_encode((void *)old_id, SILC_ID_CHANNEL);
822   idp2 = silc_id_payload_encode((void *)new_id, SILC_ID_CHANNEL);
823
824   silc_server_send_notify(server, sock, broadcast,
825                           SILC_NOTIFY_TYPE_CHANNEL_CHANGE,
826                           2, idp1->data, silc_buffer_len(idp1),
827                           idp2->data, silc_buffer_len(idp2));
828   silc_buffer_free(idp1);
829   silc_buffer_free(idp2);
830 }
831
832 /* Send NICK_CHANGE notify type. This tells the receiver to replace the
833    `old_id' with the `new_id'. */
834
835 void silc_server_send_notify_nick_change(SilcServer server,
836                                          SilcPacketStream sock,
837                                          SilcBool broadcast,
838                                          SilcClientID *old_id,
839                                          SilcClientID *new_id,
840                                          const char *nickname)
841 {
842   SilcBuffer idp1, idp2;
843
844   idp1 = silc_id_payload_encode((void *)old_id, SILC_ID_CLIENT);
845   idp2 = silc_id_payload_encode((void *)new_id, SILC_ID_CLIENT);
846
847   silc_server_send_notify(server, sock, broadcast,
848                           SILC_NOTIFY_TYPE_NICK_CHANGE,
849                           3, idp1->data, silc_buffer_len(idp1),
850                           idp2->data, silc_buffer_len(idp2),
851                           nickname, nickname ? strlen(nickname) : 0);
852   silc_buffer_free(idp1);
853   silc_buffer_free(idp2);
854 }
855
856 /* Sends JOIN notify type. This tells that new client by `client_id' ID
857    has joined to the `channel'. */
858
859 void silc_server_send_notify_join(SilcServer server,
860                                   SilcPacketStream sock,
861                                   SilcBool broadcast,
862                                   SilcChannelEntry channel,
863                                   SilcClientID *client_id)
864 {
865   SilcBuffer idp1, idp2;
866
867   idp1 = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
868   idp2 = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
869   silc_server_send_notify(server, sock, broadcast, SILC_NOTIFY_TYPE_JOIN,
870                           2, idp1->data, silc_buffer_len(idp1),
871                           idp2->data, silc_buffer_len(idp2));
872   silc_buffer_free(idp1);
873   silc_buffer_free(idp2);
874 }
875
876 /* Sends LEAVE notify type. This tells that `client_id' has left the
877    `channel'. The Notify packet is always destined to the channel. */
878
879 void silc_server_send_notify_leave(SilcServer server,
880                                    SilcPacketStream sock,
881                                    SilcBool broadcast,
882                                    SilcChannelEntry channel,
883                                    SilcClientID *client_id)
884 {
885   SilcBuffer idp;
886
887   idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
888   silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
889                                SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_LEAVE,
890                                1, idp->data, silc_buffer_len(idp));
891   silc_buffer_free(idp);
892 }
893
894 /* Sends CMODE_CHANGE notify type. This tells that `client_id' changed the
895    `channel' mode to `mode. The Notify packet is always destined to
896    the channel. */
897
898 void silc_server_send_notify_cmode(SilcServer server,
899                                    SilcPacketStream sock,
900                                    SilcBool broadcast,
901                                    SilcChannelEntry channel,
902                                    SilcUInt32 mode_mask,
903                                    void *id, SilcIdType id_type,
904                                    const char *cipher, const char *hmac,
905                                    const char *passphrase,
906                                    SilcPublicKey founder_key,
907                                    SilcBuffer channel_pubkeys)
908 {
909   SilcBuffer idp, fkey = NULL;
910   unsigned char mode[4], ulimit[4];
911
912   idp = silc_id_payload_encode((void *)id, id_type);
913   SILC_PUT32_MSB(mode_mask, mode);
914   if (founder_key)
915     fkey = silc_public_key_payload_encode(founder_key);
916   if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
917     SILC_PUT32_MSB(channel->user_limit, ulimit);
918
919   silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
920                                SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_CMODE_CHANGE,
921                                8, idp->data, silc_buffer_len(idp),
922                                mode, 4,
923                                cipher, cipher ? strlen(cipher) : 0,
924                                hmac, hmac ? strlen(hmac) : 0,
925                                passphrase, passphrase ?
926                                strlen(passphrase) : 0,
927                                fkey ? fkey->data : NULL,
928                                fkey ? silc_buffer_len(fkey) : 0,
929                                channel_pubkeys ? channel_pubkeys->data : NULL,
930                                channel_pubkeys ?
931                                silc_buffer_len(channel_pubkeys) : 0,
932                                mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
933                                ulimit : NULL,
934                                mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
935                                sizeof(ulimit) : 0);
936   silc_buffer_free(fkey);
937   silc_buffer_free(idp);
938 }
939
940 /* Sends CUMODE_CHANGE notify type. This tells that `id' changed the
941    `target' client's mode on `channel'. The notify packet is always
942    destined to the channel. */
943
944 void silc_server_send_notify_cumode(SilcServer server,
945                                     SilcPacketStream sock,
946                                     SilcBool broadcast,
947                                     SilcChannelEntry channel,
948                                     SilcUInt32 mode_mask,
949                                     void *id, SilcIdType id_type,
950                                     SilcClientID *target,
951                                     SilcPublicKey founder_key)
952 {
953   SilcBuffer idp1, idp2, fkey = NULL;
954   unsigned char mode[4];
955
956   idp1 = silc_id_payload_encode((void *)id, id_type);
957   idp2 = silc_id_payload_encode((void *)target, SILC_ID_CLIENT);
958   SILC_PUT32_MSB(mode_mask, mode);
959   if (founder_key)
960     fkey = silc_public_key_payload_encode(founder_key);
961
962   silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
963                                SILC_ID_CHANNEL,
964                                SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
965                                idp1->data, silc_buffer_len(idp1),
966                                mode, 4,
967                                idp2->data, silc_buffer_len(idp2),
968                                fkey ? fkey->data : NULL,
969                                fkey ? silc_buffer_len(fkey) : 0);
970   silc_buffer_free(fkey);
971   silc_buffer_free(idp1);
972   silc_buffer_free(idp2);
973 }
974
975 /* Sends SIGNOFF notify type. This tells that `client_id' client has
976    left SILC network. This function is used only between server and router
977    traffic. This is not used to send the notify to the channel for
978    client. The `message may be NULL. */
979
980 void silc_server_send_notify_signoff(SilcServer server,
981                                      SilcPacketStream sock,
982                                      SilcBool broadcast,
983                                      SilcClientID *client_id,
984                                      const char *message)
985 {
986   SilcBuffer idp;
987
988   idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
989   silc_server_send_notify(server, sock, broadcast,
990                           SILC_NOTIFY_TYPE_SIGNOFF,
991                           message ? 2 : 1, idp->data, silc_buffer_len(idp),
992                           message, message ? strlen(message): 0);
993   silc_buffer_free(idp);
994 }
995
996 /* Sends TOPIC_SET notify type. This tells that `id' changed
997    the `channel's topic to `topic'. The Notify packet is always destined
998    to the channel. This function is used to send the topic set notifies
999    between routers. */
1000
1001 void silc_server_send_notify_topic_set(SilcServer server,
1002                                        SilcPacketStream sock,
1003                                        SilcBool broadcast,
1004                                        SilcChannelEntry channel,
1005                                        void *id, SilcIdType id_type,
1006                                        char *topic)
1007 {
1008   SilcBuffer idp;
1009
1010   idp = silc_id_payload_encode(id, id_type);
1011   silc_server_send_notify_dest(server, sock, broadcast,
1012                                (void *)channel->id, SILC_ID_CHANNEL,
1013                                SILC_NOTIFY_TYPE_TOPIC_SET,
1014                                topic ? 2 : 1,
1015                                idp->data, silc_buffer_len(idp),
1016                                topic, topic ? strlen(topic) : 0);
1017   silc_buffer_free(idp);
1018 }
1019
1020 /* Send KICKED notify type. This tells that the `client_id' on `channel'
1021    was kicked off the channel.  The `comment' may indicate the reason
1022    for the kicking. This function is used only between server and router
1023    traffic. */
1024
1025 void silc_server_send_notify_kicked(SilcServer server,
1026                                     SilcPacketStream sock,
1027                                     SilcBool broadcast,
1028                                     SilcChannelEntry channel,
1029                                     SilcClientID *client_id,
1030                                     SilcClientID *kicker,
1031                                     char *comment)
1032 {
1033   SilcBuffer idp1;
1034   SilcBuffer idp2;
1035
1036   idp1 = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
1037   idp2 = silc_id_payload_encode((void *)kicker, SILC_ID_CLIENT);
1038   silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
1039                                SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_KICKED, 3,
1040                                idp1->data, silc_buffer_len(idp1),
1041                                comment, comment ? strlen(comment) : 0,
1042                                idp2->data, silc_buffer_len(idp2));
1043   silc_buffer_free(idp1);
1044   silc_buffer_free(idp2);
1045 }
1046
1047 /* Send KILLED notify type. This tells that the `client_id' client was
1048    killed from the network.  The `comment' may indicate the reason
1049    for the killing. */
1050
1051 void silc_server_send_notify_killed(SilcServer server,
1052                                     SilcPacketStream sock,
1053                                     SilcBool broadcast,
1054                                     SilcClientID *client_id,
1055                                     const char *comment,
1056                                     void *killer, SilcIdType killer_type)
1057 {
1058   SilcBuffer idp1;
1059   SilcBuffer idp2;
1060
1061   idp1 = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1062   idp2 = silc_id_payload_encode(killer, killer_type);
1063   silc_server_send_notify_dest(server, sock, broadcast, (void *)client_id,
1064                                SILC_ID_CLIENT, SILC_NOTIFY_TYPE_KILLED,
1065                                3, idp1->data, silc_buffer_len(idp1),
1066                                comment, comment ? strlen(comment) : 0,
1067                                idp2->data, silc_buffer_len(idp2));
1068   silc_buffer_free(idp1);
1069   silc_buffer_free(idp2);
1070 }
1071
1072 /* Sends UMODE_CHANGE notify type. This tells that `client_id' client's
1073    user mode in the SILC Network was changed. This function is used to
1074    send the packet between routers as broadcast packet. */
1075
1076 void silc_server_send_notify_umode(SilcServer server,
1077                                    SilcPacketStream sock,
1078                                    SilcBool broadcast,
1079                                    SilcClientID *client_id,
1080                                    SilcUInt32 mode_mask)
1081 {
1082   SilcBuffer idp;
1083   unsigned char mode[4];
1084
1085   idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
1086   SILC_PUT32_MSB(mode_mask, mode);
1087
1088   silc_server_send_notify(server, sock, broadcast,
1089                           SILC_NOTIFY_TYPE_UMODE_CHANGE, 2,
1090                           idp->data, silc_buffer_len(idp),
1091                           mode, 4);
1092   silc_buffer_free(idp);
1093 }
1094
1095 /* Sends BAN notify type. This tells that ban has been either `add'ed
1096    or `del'eted on the `channel. This function is used to send the packet
1097    between routers as broadcast packet. */
1098
1099 void silc_server_send_notify_ban(SilcServer server,
1100                                  SilcPacketStream sock,
1101                                  SilcBool broadcast,
1102                                  SilcChannelEntry channel,
1103                                  unsigned char *action,
1104                                  SilcBuffer list)
1105 {
1106   SilcBuffer idp;
1107
1108   idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
1109   silc_server_send_notify(server, sock, broadcast,
1110                           SILC_NOTIFY_TYPE_BAN, 3,
1111                           idp->data, silc_buffer_len(idp),
1112                           action ? action : NULL, action ? 1 : 0,
1113                           list ? list->data : NULL,
1114                           list ? silc_buffer_len(list) : 0);
1115   silc_buffer_free(idp);
1116 }
1117
1118 /* Sends INVITE notify type. This tells that invite has been either `add'ed
1119    or `del'eted on the `channel.  The sender of the invite is the `client_id'.
1120    This function is used to send the packet between routers as broadcast
1121    packet. */
1122
1123 void silc_server_send_notify_invite(SilcServer server,
1124                                     SilcPacketStream sock,
1125                                     SilcBool broadcast,
1126                                     SilcChannelEntry channel,
1127                                     SilcClientID *client_id,
1128                                     unsigned char *action,
1129                                     SilcBuffer list)
1130 {
1131   SilcBuffer idp, idp2;
1132
1133   idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
1134   idp2 = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
1135   silc_server_send_notify(server, sock, broadcast,
1136                           SILC_NOTIFY_TYPE_INVITE, 5,
1137                           idp->data, silc_buffer_len(idp),
1138                           channel->channel_name, strlen(channel->channel_name),
1139                           idp2->data, silc_buffer_len(idp2),
1140                           action ? action : NULL, action ? 1 : 0,
1141                           list ? list->data : NULL,
1142                           list ? silc_buffer_len(list) : 0);
1143   silc_buffer_free(idp);
1144   silc_buffer_free(idp2);
1145 }
1146
1147 /* Sends WATCH notify type. This tells that the `client' was watched and
1148    its status in the network has changed. */
1149
1150 void silc_server_send_notify_watch(SilcServer server,
1151                                    SilcPacketStream sock,
1152                                    SilcClientEntry watcher,
1153                                    SilcClientEntry client,
1154                                    const char *nickname,
1155                                    SilcNotifyType type,
1156                                    SilcPublicKey public_key)
1157 {
1158   SilcBuffer idp, pkp = NULL;
1159   unsigned char mode[4], n[2];
1160
1161   idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
1162   SILC_PUT16_MSB(type, n);
1163   SILC_PUT32_MSB(client->mode, mode);
1164   if (public_key)
1165     pkp = silc_public_key_payload_encode(public_key);
1166   silc_server_send_notify_dest(server, sock, FALSE, watcher->id,
1167                                SILC_ID_CLIENT, SILC_NOTIFY_TYPE_WATCH,
1168                                5, idp->data, silc_buffer_len(idp),
1169                                nickname, nickname ? strlen(nickname) : 0,
1170                                mode, sizeof(mode),
1171                                type != SILC_NOTIFY_TYPE_NONE ?
1172                                n : NULL, sizeof(n),
1173                                pkp ? pkp->data : NULL,
1174                                pkp ? silc_buffer_len(pkp) : 0);
1175   silc_buffer_free(idp);
1176   silc_buffer_free(pkp);
1177 }
1178
1179 /* Sends notify message destined to specific entity. */
1180
1181 void silc_server_send_notify_dest(SilcServer server,
1182                                   SilcPacketStream sock,
1183                                   SilcBool broadcast,
1184                                   void *dest_id,
1185                                   SilcIdType dest_id_type,
1186                                   SilcNotifyType type,
1187                                   SilcUInt32 argc, ...)
1188 {
1189   va_list ap;
1190   SilcBuffer packet;
1191
1192   va_start(ap, argc);
1193
1194   packet = silc_notify_payload_encode(type, argc, ap);
1195   silc_server_packet_send_dest(server, sock, SILC_PACKET_NOTIFY,
1196                                broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
1197                                dest_id, dest_id_type,
1198                                packet->data, silc_buffer_len(packet));
1199
1200   /* Send to backup routers if this is being broadcasted to primary
1201      router.  The silc_server_backup_send checks further whether to
1202      actually send it or not. */
1203   if ((broadcast && sock && sock == SILC_PRIMARY_ROUTE(server)) ||
1204       (broadcast && !sock && !SILC_PRIMARY_ROUTE(server)))
1205     silc_server_backup_send_dest(server, NULL, SILC_PACKET_NOTIFY, 0,
1206                                  dest_id, dest_id_type,
1207                                  packet->data, silc_buffer_len(packet),
1208                                  FALSE, TRUE);
1209
1210   silc_buffer_free(packet);
1211   va_end(ap);
1212 }
1213
1214 /* Sends notify message to a channel. The notify message sent is
1215    distributed to all clients on the channel. If `route_notify' is TRUE
1216    then the notify may be routed to primary route or to some other routers.
1217    If FALSE it is assured that the notify is sent only locally. If `sender'
1218    is provided then the packet is not sent to that connection since it
1219    originally came from it. */
1220
1221 void silc_server_send_notify_to_channel(SilcServer server,
1222                                         SilcPacketStream sender,
1223                                         SilcChannelEntry channel,
1224                                         SilcBool route_notify,
1225                                         SilcBool send_to_clients,
1226                                         SilcNotifyType type,
1227                                         SilcUInt32 argc, ...)
1228 {
1229   va_list ap;
1230   SilcBuffer packet;
1231
1232   va_start(ap, argc);
1233
1234   packet = silc_notify_payload_encode(type, argc, ap);
1235   silc_server_packet_send_to_channel(server, sender, channel,
1236                                      SILC_PACKET_NOTIFY, route_notify,
1237                                      send_to_clients,
1238                                      packet->data, silc_buffer_len(packet));
1239   silc_buffer_free(packet);
1240   va_end(ap);
1241 }
1242
1243 /* Send notify message to all channels the client has joined. It is quaranteed
1244    that the message is sent only once to a client (ie. if a client is joined
1245    on two same channel it will receive only one notify message). Also, this
1246    sends only to local clients (locally connected if we are server, and to
1247    local servers if we are router). If `sender' is provided the packet is
1248    not sent to that client at all. */
1249
1250 void silc_server_send_notify_on_channels(SilcServer server,
1251                                          SilcClientEntry sender,
1252                                          SilcClientEntry client,
1253                                          SilcNotifyType type,
1254                                          SilcUInt32 argc, ...)
1255 {
1256   int k;
1257   SilcPacketStream sock = NULL;
1258   SilcClientEntry c;
1259   SilcClientEntry *sent_clients = NULL;
1260   SilcUInt32 sent_clients_count = 0;
1261   SilcServerEntry *routed = NULL;
1262   SilcUInt32 routed_count = 0;
1263   SilcHashTableList htl, htl2;
1264   SilcChannelEntry channel;
1265   SilcChannelClientEntry chl, chl2;
1266   SilcBuffer packet;
1267   unsigned char *data;
1268   SilcUInt32 data_len;
1269   va_list ap;
1270
1271   if (!silc_hash_table_count(client->channels)) {
1272     SILC_LOG_DEBUG(("Client is not joined to any channels"));
1273     return;
1274   }
1275
1276   SILC_LOG_DEBUG(("Sending notify to joined channels"));
1277
1278   va_start(ap, argc);
1279   packet = silc_notify_payload_encode(type, argc, ap);
1280   data = packet->data;
1281   data_len = silc_buffer_len(packet);
1282
1283   silc_hash_table_list(client->channels, &htl);
1284   while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
1285     channel = chl->channel;
1286
1287     /* Send the message to all clients on the channel's client list. */
1288     silc_hash_table_list(channel->user_list, &htl2);
1289     while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) {
1290       c = chl2->client;
1291
1292       if (sender && c == sender)
1293         continue;
1294
1295       /* Check if we have sent the packet to this client already */
1296       for (k = 0; k < sent_clients_count; k++)
1297         if (sent_clients[k] == c)
1298           break;
1299       if (k < sent_clients_count)
1300         continue;
1301
1302       /* If we are router and if this client has router set it is not
1303          locally connected client and we will route the message to the
1304          router set in the client. */
1305       if (c && c->router && server->server_type == SILC_ROUTER) {
1306         /* Check if we have sent the packet to this route already */
1307         for (k = 0; k < routed_count; k++)
1308           if (routed[k] == c->router)
1309             break;
1310         if (k < routed_count)
1311           continue;
1312
1313         sock = c->router->connection;
1314
1315         /* Send the packet */
1316         silc_server_packet_send_dest(server, sock, SILC_PACKET_NOTIFY, 0,
1317                                      c->router->id, SILC_ID_SERVER,
1318                                      data, data_len);
1319
1320         /* We want to make sure that the packet is routed to same router
1321            only once. Mark this route as sent route. */
1322         routed = silc_realloc(routed, sizeof(*routed) * (routed_count + 1));
1323         routed[routed_count++] = c->router;
1324         continue;
1325       }
1326
1327       if (c && c->router)
1328         continue;
1329
1330       /* Send to locally connected client */
1331       if (c) {
1332         sock = c->connection;
1333         if (!sock)
1334           continue;
1335
1336         /* Send the packet */
1337         silc_server_packet_send_dest(server, sock, SILC_PACKET_NOTIFY, 0,
1338                                      c->id, SILC_ID_CLIENT, data, data_len);
1339
1340         /* Make sure that we send the notify only once per client. */
1341         sent_clients = silc_realloc(sent_clients, sizeof(*sent_clients) *
1342                                     (sent_clients_count + 1));
1343         sent_clients[sent_clients_count++] = c;
1344       }
1345     }
1346     silc_hash_table_list_reset(&htl2);
1347   }
1348
1349   silc_hash_table_list_reset(&htl);
1350   silc_free(routed);
1351   silc_free(sent_clients);
1352   silc_buffer_free(packet);
1353   va_end(ap);
1354 }
1355
1356 /* Sends New ID Payload to remote end. The packet is used to distribute
1357    information about new registered clients, servers, channel etc. usually
1358    to routers so that they can keep these information up to date.
1359    If the argument `broadcast' is TRUE then the packet is sent as
1360    broadcast packet. */
1361
1362 void silc_server_send_new_id(SilcServer server,
1363                              SilcPacketStream sock,
1364                              SilcBool broadcast,
1365                              void *id, SilcIdType id_type,
1366                              SilcUInt32 id_len)
1367 {
1368   SilcBuffer idp;
1369
1370   SILC_LOG_DEBUG(("Sending new ID"));
1371
1372   idp = silc_id_payload_encode(id, id_type);
1373   silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID,
1374                           broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
1375                           idp->data, silc_buffer_len(idp));
1376   silc_buffer_free(idp);
1377 }
1378
1379 /* Send New Channel Payload to notify about newly created channel in the
1380    SILC network. Router uses this to notify other routers in the network
1381    about new channel. This packet is broadcasted by router. */
1382
1383 void silc_server_send_new_channel(SilcServer server,
1384                                   SilcPacketStream sock,
1385                                   SilcBool broadcast,
1386                                   char *channel_name,
1387                                   void *channel_id,
1388                                   SilcUInt32 channel_id_len,
1389                                   SilcUInt32 mode)
1390 {
1391   SilcBuffer packet;
1392   unsigned char cid[32];
1393   SilcUInt32 name_len = strlen(channel_name);
1394
1395   SILC_LOG_DEBUG(("Sending new channel"));
1396
1397   if (!silc_id_id2str(channel_id, SILC_ID_CHANNEL, cid, sizeof(cid),
1398                       &channel_id_len))
1399     return;
1400
1401   /* Encode the channel payload */
1402   packet = silc_channel_payload_encode(channel_name, name_len,
1403                                        cid, channel_id_len, mode);
1404
1405   silc_server_packet_send(server, sock, SILC_PACKET_NEW_CHANNEL,
1406                           broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
1407                           packet->data, silc_buffer_len(packet));
1408
1409   silc_buffer_free(packet);
1410 }
1411
1412 /* Send Channel Key payload to distribute the new channel key. Normal server
1413    sends this to router when new client joins to existing channel. Router
1414    sends this to the local server who sent the join command in case where
1415    the channel did not exist yet. Both normal and router servers uses this
1416    also to send this to locally connected clients on the channel. This
1417    must not be broadcasted packet. Routers do not send this to each other.
1418    If `sender is provided then the packet is not sent to that connection since
1419    it originally came from it. */
1420
1421 void silc_server_send_channel_key(SilcServer server,
1422                                   SilcPacketStream sender,
1423                                   SilcChannelEntry channel,
1424                                   unsigned char route)
1425 {
1426   SilcBuffer packet;
1427   unsigned char cid[32];
1428   SilcUInt32 tmp_len, cid_len;
1429   const char *cipher;
1430
1431   SILC_LOG_DEBUG(("Sending key to channel %s", channel->channel_name));
1432
1433   if (!channel->key)
1434     return;
1435
1436   if (!silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid),
1437                       &cid_len))
1438     return;
1439
1440   /* Encode channel key packet */
1441   cipher = silc_cipher_get_name(channel->send_key);
1442   tmp_len = strlen(cipher);
1443   packet = silc_channel_key_payload_encode(cid_len, cid, tmp_len, cipher,
1444                                            channel->key_len / 8, channel->key);
1445   if (packet)
1446     silc_server_packet_send_to_channel(server, sender, channel,
1447                                        SILC_PACKET_CHANNEL_KEY,
1448                                        route, TRUE, packet->data,
1449                                        silc_buffer_len(packet));
1450   silc_buffer_free(packet);
1451 }
1452
1453 /* Generic function to send any command. The arguments must be sent already
1454    encoded into correct form in correct order. */
1455
1456 void silc_server_send_command(SilcServer server,
1457                               SilcPacketStream sock,
1458                               SilcCommand command,
1459                               SilcUInt16 ident,
1460                               SilcUInt32 argc, ...)
1461 {
1462   SilcBuffer packet;
1463   va_list ap;
1464
1465   /* Statistics */
1466   server->stat.commands_sent++;
1467
1468   va_start(ap, argc);
1469
1470   packet = silc_command_payload_encode_vap(command, ident, argc, ap);
1471   silc_server_packet_send(server, sock, SILC_PACKET_COMMAND, 0,
1472                           packet->data, silc_buffer_len(packet));
1473   silc_buffer_free(packet);
1474   va_end(ap);
1475 }
1476
1477 /* Generic function to send any command reply. The arguments must be sent
1478    already encoded into correct form in correct order. */
1479
1480 void silc_server_send_command_reply(SilcServer server,
1481                                     SilcPacketStream sock,
1482                                     SilcCommand command,
1483                                     SilcStatus status,
1484                                     SilcStatus error,
1485                                     SilcUInt16 ident,
1486                                     SilcUInt32 argc, ...)
1487 {
1488   SilcBuffer packet;
1489   va_list ap;
1490
1491   /* Statistics */
1492   server->stat.commands_sent++;
1493
1494   va_start(ap, argc);
1495
1496   packet = silc_command_reply_payload_encode_vap(command, status, error,
1497                                                  ident, argc, ap);
1498   silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0,
1499                           packet->data, silc_buffer_len(packet));
1500   silc_buffer_free(packet);
1501   va_end(ap);
1502 }
1503
1504 /* Generic function to send any command reply. The arguments must be sent
1505    already encoded into correct form in correct order. */
1506
1507 void silc_server_send_dest_command_reply(SilcServer server,
1508                                          SilcPacketStream sock,
1509                                          void *dst_id,
1510                                          SilcIdType dst_id_type,
1511                                          SilcCommand command,
1512                                          SilcStatus status,
1513                                          SilcStatus error,
1514                                          SilcUInt16 ident,
1515                                          SilcUInt32 argc, ...)
1516 {
1517   SilcBuffer packet;
1518   va_list ap;
1519
1520   /* Statistics */
1521   server->stat.commands_sent++;
1522
1523   va_start(ap, argc);
1524
1525   packet = silc_command_reply_payload_encode_vap(command, status, error,
1526                                                  ident, argc, ap);
1527   silc_server_packet_send_dest(server, sock, SILC_PACKET_COMMAND_REPLY, 0,
1528                                dst_id, dst_id_type, packet->data,
1529                                silc_buffer_len(packet));
1530   silc_buffer_free(packet);
1531   va_end(ap);
1532 }
1533
1534 /* Routine used to send the connection authentication packet. */
1535
1536 void silc_server_send_connection_auth_request(SilcServer server,
1537                                               SilcPacketStream sock,
1538                                               SilcUInt16 conn_type,
1539                                               SilcAuthMethod auth_meth)
1540 {
1541   SilcBuffer packet;
1542
1543   packet = silc_buffer_alloc(4);
1544   silc_buffer_pull_tail(packet, silc_buffer_truelen(packet));
1545   silc_buffer_format(packet,
1546                      SILC_STR_UI_SHORT(conn_type),
1547                      SILC_STR_UI_SHORT(auth_meth),
1548                      SILC_STR_END);
1549
1550   silc_server_packet_send(server, sock, SILC_PACKET_CONNECTION_AUTH_REQUEST,
1551                           0, packet->data, silc_buffer_len(packet));
1552   silc_buffer_free(packet);
1553 }
1554
1555 /* Send packet to clients that are known to be operators.  If server
1556    is router and `route' is TRUE then the packet would go to all operators
1557    in the SILC network.  If `route' is FALSE then only local operators
1558    (local for server and cell wide for router).  If `local' is TRUE then
1559    only locally connected operators receive the packet.  If `local' is
1560    TRUE then `route' is ignored.  If server is normal server and `route'
1561    is FALSE it is equivalent to `local' being TRUE. */
1562
1563 void silc_server_send_opers(SilcServer server,
1564                             SilcPacketType type,
1565                             SilcPacketFlags flags,
1566                             SilcBool route, bool local,
1567                             unsigned char *data,
1568                             SilcUInt32 data_len)
1569 {
1570   SilcList list;
1571   SilcIDCacheEntry id_cache = NULL;
1572   SilcClientEntry client = NULL;
1573   SilcIDListData idata;
1574   SilcPacketStream sock;
1575   SilcServerEntry *routed = NULL;
1576   SilcUInt32 routed_count = 0;
1577   SilcBool gone = FALSE;
1578   int k;
1579
1580   SILC_LOG_DEBUG(("Sending %s packet to operators",
1581                   silc_get_packet_name(type)));
1582
1583   /* If local was requested send only locally connected operators. */
1584   if (local || (server->server_type == SILC_SERVER && !route)) {
1585     if (!silc_idcache_get_all(server->local_list->clients, &list))
1586       return;
1587     silc_list_start(list);
1588     while ((id_cache = silc_list_get(list))) {
1589       client = (SilcClientEntry)id_cache->context;
1590       if (!client->router && SILC_IS_LOCAL(client) &&
1591           (client->mode & SILC_UMODE_SERVER_OPERATOR ||
1592            client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1593
1594         /* Send the packet to locally connected operator */
1595         silc_server_packet_send_dest(server, client->connection, type, flags,
1596                                      client->id, SILC_ID_CLIENT,
1597                                      data, data_len);
1598       }
1599     }
1600     return;
1601   }
1602
1603   if (!silc_idcache_get_all(server->local_list->clients, &list))
1604     return;
1605   silc_list_start(list);
1606   while ((id_cache = silc_list_get(list))) {
1607     client = (SilcClientEntry)id_cache->context;
1608     if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
1609         !(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1610       continue;
1611
1612     if (server->server_type != SILC_SERVER && client->router &&
1613         ((!route && client->router->router == server->id_entry) || route)) {
1614
1615       /* Check if we have sent the packet to this route already */
1616       for (k = 0; k < routed_count; k++)
1617         if (routed[k] == client->router)
1618           break;
1619       if (k < routed_count)
1620         continue;
1621
1622       /* Route only once to router */
1623       sock = client->router->connection;
1624       idata = silc_packet_get_context(sock);
1625       if (idata->conn_type == SILC_CONN_ROUTER) {
1626         if (gone)
1627           continue;
1628         gone = TRUE;
1629       }
1630
1631       /* Send the packet */
1632       silc_server_packet_send_dest(server, sock, type, flags,
1633                                    client->id, SILC_ID_CLIENT,
1634                                    data, data_len);
1635
1636       /* Mark this route routed already */
1637       routed = silc_realloc(routed, sizeof(*routed) * (routed_count + 1));
1638       routed[routed_count++] = client->router;
1639       continue;
1640     }
1641
1642     if (client->router || !client->connection)
1643       continue;
1644
1645     /* Send to locally connected client */
1646     sock = client->connection;
1647     silc_server_packet_send_dest(server, sock, type, flags,
1648                                  client->id, SILC_ID_CLIENT,
1649                                  data, data_len);
1650
1651   }
1652
1653   if (!silc_idcache_get_all(server->global_list->clients, &list))
1654     return;
1655   silc_list_start(list);
1656   while ((id_cache = silc_list_get(list))) {
1657     client = (SilcClientEntry)id_cache->context;
1658     if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
1659         !(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1660       continue;
1661
1662     if (server->server_type != SILC_SERVER && client->router &&
1663         ((!route && client->router->router == server->id_entry) || route)) {
1664
1665       /* Check if we have sent the packet to this route already */
1666       for (k = 0; k < routed_count; k++)
1667         if (routed[k] == client->router)
1668           break;
1669       if (k < routed_count)
1670         continue;
1671
1672       /* Route only once to router */
1673       sock = client->router->connection;
1674       idata = silc_packet_get_context(sock);
1675       if (idata->conn_type == SILC_CONN_ROUTER) {
1676         if (gone)
1677           continue;
1678         gone = TRUE;
1679       }
1680
1681       /* Send the packet */
1682       silc_server_packet_send_dest(server, sock, type, flags,
1683                                    client->id, SILC_ID_CLIENT,
1684                                    data, data_len);
1685
1686       /* Mark this route routed already */
1687       routed = silc_realloc(routed, sizeof(*routed) * (routed_count + 1));
1688       routed[routed_count++] = client->router;
1689       continue;
1690     }
1691
1692     if (client->router || !client->connection)
1693       continue;
1694
1695     /* Send to locally connected client */
1696     sock = client->connection;
1697     silc_server_packet_send_dest(server, sock, type, flags,
1698                                  client->id, SILC_ID_CLIENT,
1699                                  data, data_len);
1700   }
1701   silc_free(routed);
1702 }
1703
1704 /* Send a notify packet to operators */
1705
1706 void silc_server_send_opers_notify(SilcServer server,
1707                                    SilcBool route,
1708                                    SilcBool local,
1709                                    SilcNotifyType type,
1710                                    SilcUInt32 argc, ...)
1711 {
1712   va_list ap;
1713   SilcBuffer packet;
1714
1715   va_start(ap, argc);
1716   packet = silc_notify_payload_encode(type, argc, ap);
1717   silc_server_send_opers(server, SILC_PACKET_NOTIFY, 0,
1718                          route, local, packet->data, silc_buffer_len(packet));
1719   silc_buffer_free(packet);
1720   va_end(ap);
1721 }