5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2007 Pekka Riikonen
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.
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.
20 #include "serverincludes.h"
21 #include "server_internal.h"
23 /* Send packet to remote connection */
25 SilcBool silc_server_packet_send(SilcServer server,
26 SilcPacketStream sock,
28 SilcPacketFlags flags,
37 idata = silc_packet_get_context(sock);
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"));
47 SILC_LOG_DEBUG(("Sending %s packet", silc_get_packet_name(type)));
49 return silc_packet_send(sock, type, flags, (const unsigned char *)data,
53 /* Send packet to remote connection with specific destination ID. */
55 SilcBool silc_server_packet_send_dest(SilcServer server,
56 SilcPacketStream sock,
58 SilcPacketFlags flags,
60 SilcIdType dst_id_type,
69 idata = silc_packet_get_context(sock);
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"));
79 SILC_LOG_DEBUG(("Sending %s packet", silc_get_packet_name(type)));
81 return silc_packet_send_ext(sock, type, flags, 0, NULL, dst_id_type, dst_id,
82 (const unsigned char *)data, data_len,
86 /* Send packet to remote connection with specific source and destination
89 SilcBool silc_server_packet_send_srcdest(SilcServer server,
90 SilcPacketStream sock,
92 SilcPacketFlags flags,
94 SilcIdType src_id_type,
96 SilcIdType dst_id_type,
100 SilcIDListData idata;
105 idata = silc_packet_get_context(sock);
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"));
115 SILC_LOG_DEBUG(("Sending %s packet", silc_get_packet_name(type)));
117 return silc_packet_send_ext(sock, type, flags, src_id_type, src_id,
119 (const unsigned char *)data, data_len,
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. */
128 SilcBool silc_server_packet_broadcast(SilcServer server,
129 SilcPacketStream primary_route,
132 SilcServerID src_id, dst_id;
137 SILC_LOG_DEBUG(("Broadcasting received broadcast packet"));
139 if (!silc_id_str2id(packet->src_id, packet->src_id_len, packet->src_id_type,
140 &src_id, sizeof(src_id)))
142 if (!silc_id_str2id(packet->dst_id, packet->dst_id_len, packet->dst_id_type,
143 &dst_id, sizeof(dst_id)))
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"));
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,
160 silc_buffer_len(&packet->buffer));
163 /* Routes received packet to `sock'. This is used to route the packets that
164 router receives but are not destined to it. */
166 SilcBool silc_server_packet_route(SilcServer server,
167 SilcPacketStream sock,
170 SilcID src_id, dst_id;
172 if (!silc_id_str2id2(packet->src_id, packet->src_id_len, packet->src_id_type,
175 if (!silc_id_str2id2(packet->dst_id, packet->dst_id_len, packet->dst_id_type,
179 return silc_server_packet_send_srcdest(server, sock, packet->type,
181 SILC_ID_GET_ID(src_id),
183 SILC_ID_GET_ID(dst_id),
186 silc_buffer_len(&packet->buffer));
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). */
193 void silc_server_packet_send_clients(SilcServer server,
194 SilcHashTable clients,
196 SilcPacketFlags flags,
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;
210 if (!silc_hash_table_count(clients))
213 SILC_LOG_DEBUG(("Sending packet to %d clients",
214 silc_hash_table_count(clients)));
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)) {
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)
229 if (k < routed_count)
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) {
241 /* Send the packet */
242 silc_server_packet_send_dest(server, sock, type, flags,
243 client->router->id, SILC_ID_SERVER,
246 /* Mark this route routed already */
247 routed = silc_realloc(routed, sizeof(*routed) * (routed_count + 1));
248 routed[routed_count++] = client->router;
255 /* Send to locally connected client */
256 sock = client->connection;
260 silc_server_packet_send_dest(server, sock, type, flags,
261 client->id, SILC_ID_CLIENT,
264 silc_hash_table_list_reset(&htl);
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. */
278 void silc_server_packet_send_to_channel(SilcServer server,
279 SilcPacketStream sender,
280 SilcChannelEntry channel,
283 SilcBool send_to_clients,
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;
297 /* This doesn't send channel message packets */
298 SILC_ASSERT(type != SILC_PACKET_CHANNEL_MESSAGE);
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);
312 if (!silc_hash_table_count(channel->user_list)) {
313 SILC_LOG_DEBUG(("Channel %s is empty", channel->channel_name));
317 SILC_LOG_DEBUG(("Sending %s to channel %s",
318 silc_get_packet_name(type), channel->channel_name));
320 routed = silc_calloc(silc_hash_table_count(channel->user_list),
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;
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)) {
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)
340 if (k < routed_count)
343 /* Get data used in packet header encryption, keys and stuff. */
344 sock = client->router->connection;
345 idata = (SilcIDListData)client->router;
347 if (sender && sock == sender)
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) {
358 SILC_LOG_DEBUG(("Sending packet to client %s",
359 client->nickname ? client->nickname :
360 (unsigned char *)""));
362 /* Send the packet */
363 silc_server_packet_send_dest(server, sock, type, 0, channel->id,
364 SILC_ID_CHANNEL, data, data_len);
366 /* Mark this route routed already */
367 routed[routed_count++] = client->router;
371 if (client->router || !send_to_clients)
374 /* Send to locally connected client */
376 /* Get data used in packet header encryption, keys and stuff. */
377 sock = client->connection;
378 if (!sock || (sender && sock == sender))
381 SILC_LOG_DEBUG(("Sending packet to client %s",
382 client->nickname ? client->nickname :
383 (unsigned char *)""));
385 /* Send the packet */
386 silc_server_packet_send_dest(server, sock, type, 0, channel->id,
387 SILC_ID_CHANNEL, data, data_len);
389 silc_hash_table_list_reset(&htl);
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. */
400 silc_server_packet_relay_to_channel_encrypt(SilcServer server,
401 SilcPacketStream sender,
403 SilcIdType sender_type,
404 SilcChannelEntry channel,
406 unsigned int data_len)
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;
414 idata = silc_packet_get_context(sender);
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
421 if (server->server_type == SILC_ROUTER &&
422 idata->conn_type == SILC_CONN_ROUTER &&
423 !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY) && channel->key) {
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)
432 mac_len = silc_hmac_len(channel->hmac);
433 iv_len = silc_cipher_get_block_len(channel->send_key);
435 if (data_len <= mac_len + iv_len) {
436 SILC_LOG_WARNING(("Corrupted channel message, cannot relay it"));
441 SILC_GET16_MSB(len, data + totlen);
443 if (totlen + iv_len + mac_len + 2 > data_len) {
444 SILC_LOG_WARNING(("Corrupted channel message, cannot relay it"));
447 SILC_GET16_MSB(len, data + totlen);
449 if (totlen + iv_len + mac_len > data_len) {
450 SILC_LOG_WARNING(("Corrupted channel message, cannot relay it"));
454 memcpy(iv, data + (data_len - iv_len - mac_len), iv_len);
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;
462 return silc_message_payload_encrypt(data, totlen, data_len - mac_len,
463 iv, &src_id, &dst_id,
464 channel->send_key, channel->hmac);
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. */
479 void silc_server_packet_relay_to_channel(SilcServer server,
480 SilcPacketStream sender_sock,
481 SilcChannelEntry channel,
483 SilcIdType sender_type,
484 SilcClientEntry sender_entry,
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;
498 if (!silc_server_client_on_channel(sender_entry, channel, &chl_sender))
501 SILC_LOG_DEBUG(("Relaying packet to channel %s", channel->channel_name));
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,
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;
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,
531 routed = silc_calloc(silc_hash_table_count(channel->user_list),
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;
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)
545 /* Check whether message sending is blocked */
546 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)
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))
552 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS &&
553 sender_entry->mode & SILC_UMODE_ROBOT)
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) {
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)
564 if (k < routed_count)
567 /* Get data used in packet header encryption, keys and stuff. */
568 sock = client->router->connection;
569 idata = (SilcIDListData)client->router;
571 /* Check if the sender socket is the same as this client's router
573 if (sender_sock && sock == sender_sock)
576 SILC_LOG_DEBUG(("Relaying packet to client ID(%s)",
577 silc_id_render(client->id, SILC_ID_CLIENT)));
579 /* Mark this route routed already. */
580 routed[routed_count++] = client->router;
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. */
589 /* Route only once to router. Protocol prohibits sending channel
590 messages to more than one router. */
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,
608 SILC_LOG_DEBUG(("Remote is router, encrypt with session key"));
610 /* If private key mode is not set then decrypt the packet
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;
617 if (data_len > SILC_PACKET_MAX_LEN)
618 data_len = SILC_PACKET_MAX_LEN;
619 memcpy(tmp, data, data_len);
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),
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);
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,
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,
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,
660 /* Get data used in packet header encryption, keys and stuff. */
661 sock = client->connection;
662 if (!sock || (sender_sock && sock == sender_sock))
665 SILC_LOG_DEBUG(("Sending packet to client ID(%s)",
666 silc_id_render(client->id, SILC_ID_CLIENT)));
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,
676 silc_hash_table_list_reset(&htl);
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_
687 void silc_server_packet_send_local_channel(SilcServer server,
688 SilcChannelEntry channel,
690 SilcPacketFlags flags,
694 SilcChannelClientEntry chl;
695 SilcHashTableList htl;
696 SilcPacketStream sock = NULL;
698 SILC_LOG_DEBUG(("Send packet to local clients on channel %s",
699 channel->channel_name));
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;
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);
712 silc_hash_table_list_reset(&htl);
715 /* Sends current motd to client */
717 void silc_server_send_motd(SilcServer server,
718 SilcPacketStream sock)
720 char *motd, *motd_file = NULL;
724 motd_file = server->config->server_info->motd_file;
727 motd = silc_file_readfile(motd_file, &motd_len);
732 silc_server_send_notify(server, sock, FALSE, SILC_NOTIFY_TYPE_MOTD, 1,
738 /* Sends error message. Error messages may or may not have any
741 void silc_server_send_error(SilcServer server,
742 SilcPacketStream sock,
743 const char *fmt, ...)
746 unsigned char buf[4096];
748 memset(buf, 0, sizeof(buf));
750 vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
753 silc_server_packet_send(server, sock, SILC_PACKET_ERROR, 0,
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 }. */
762 void silc_server_send_notify(SilcServer server,
763 SilcPacketStream sock,
766 SilcUInt32 argc, ...)
773 packet = silc_notify_payload_encode(type, argc, ap);
778 silc_server_packet_send(server, sock, SILC_PACKET_NOTIFY,
779 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
780 packet->data, silc_buffer_len(packet));
782 /* Send to backup routers if this is being broadcasted to primary
783 router. The silc_server_backup_send checks further whether to
784 actually send it or not. */
785 if ((broadcast && sock && sock == SILC_PRIMARY_ROUTE(server)) ||
786 (broadcast && !sock && !SILC_PRIMARY_ROUTE(server)))
787 silc_server_backup_send(server, NULL, SILC_PACKET_NOTIFY, 0,
788 packet->data, silc_buffer_len(packet),
791 silc_buffer_free(packet);
795 /* Sends notify message and gets the arguments from the `args' Argument
798 void silc_server_send_notify_args(SilcServer server,
799 SilcPacketStream sock,
807 packet = silc_notify_payload_encode_args(type, argc, args);
809 silc_server_packet_send(server, sock, SILC_PACKET_NOTIFY,
810 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
811 packet->data, silc_buffer_len(packet));
812 silc_buffer_free(packet);
815 /* Send CHANNEL_CHANGE notify type. This tells the receiver to replace the
816 `old_id' with the `new_id'. */
818 void silc_server_send_notify_channel_change(SilcServer server,
819 SilcPacketStream sock,
821 SilcChannelID *old_id,
822 SilcChannelID *new_id)
824 SilcBuffer idp1, idp2;
826 idp1 = silc_id_payload_encode((void *)old_id, SILC_ID_CHANNEL);
827 idp2 = silc_id_payload_encode((void *)new_id, SILC_ID_CHANNEL);
830 silc_server_send_notify(server, sock, broadcast,
831 SILC_NOTIFY_TYPE_CHANNEL_CHANGE,
832 2, idp1->data, silc_buffer_len(idp1),
833 idp2->data, silc_buffer_len(idp2));
834 silc_buffer_free(idp1);
835 silc_buffer_free(idp2);
838 /* Send NICK_CHANGE notify type. This tells the receiver to replace the
839 `old_id' with the `new_id'. */
841 void silc_server_send_notify_nick_change(SilcServer server,
842 SilcPacketStream sock,
844 SilcClientID *old_id,
845 SilcClientID *new_id,
846 const char *nickname)
848 SilcBuffer idp1, idp2;
850 idp1 = silc_id_payload_encode((void *)old_id, SILC_ID_CLIENT);
851 idp2 = silc_id_payload_encode((void *)new_id, SILC_ID_CLIENT);
854 silc_server_send_notify(server, sock, broadcast,
855 SILC_NOTIFY_TYPE_NICK_CHANGE,
856 3, idp1->data, silc_buffer_len(idp1),
857 idp2->data, silc_buffer_len(idp2),
858 nickname, nickname ? strlen(nickname) : 0);
859 silc_buffer_free(idp1);
860 silc_buffer_free(idp2);
863 /* Sends JOIN notify type. This tells that new client by `client_id' ID
864 has joined to the `channel'. */
866 void silc_server_send_notify_join(SilcServer server,
867 SilcPacketStream sock,
869 SilcChannelEntry channel,
870 SilcClientID *client_id)
872 SilcBuffer idp1, idp2;
874 idp1 = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
875 idp2 = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
878 silc_server_send_notify(server, sock, broadcast, SILC_NOTIFY_TYPE_JOIN,
879 2, idp1->data, silc_buffer_len(idp1),
880 idp2->data, silc_buffer_len(idp2));
881 silc_buffer_free(idp1);
882 silc_buffer_free(idp2);
885 /* Sends LEAVE notify type. This tells that `client_id' has left the
886 `channel'. The Notify packet is always destined to the channel. */
888 void silc_server_send_notify_leave(SilcServer server,
889 SilcPacketStream sock,
891 SilcChannelEntry channel,
892 SilcClientID *client_id)
896 idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
898 silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
899 SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_LEAVE,
900 1, idp->data, silc_buffer_len(idp));
901 silc_buffer_free(idp);
904 /* Sends CMODE_CHANGE notify type. This tells that `client_id' changed the
905 `channel' mode to `mode. The Notify packet is always destined to
908 void silc_server_send_notify_cmode(SilcServer server,
909 SilcPacketStream sock,
911 SilcChannelEntry channel,
912 SilcUInt32 mode_mask,
913 void *id, SilcIdType id_type,
914 const char *cipher, const char *hmac,
915 const char *passphrase,
916 SilcPublicKey founder_key,
917 SilcBuffer channel_pubkeys)
919 SilcBuffer idp, fkey = NULL;
920 unsigned char mode[4], ulimit[4];
922 idp = silc_id_payload_encode((void *)id, id_type);
925 SILC_PUT32_MSB(mode_mask, mode);
927 fkey = silc_public_key_payload_encode(founder_key);
928 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
929 SILC_PUT32_MSB(channel->user_limit, ulimit);
931 silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
932 SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_CMODE_CHANGE,
933 8, idp->data, silc_buffer_len(idp),
935 cipher, cipher ? strlen(cipher) : 0,
936 hmac, hmac ? strlen(hmac) : 0,
937 passphrase, passphrase ?
938 strlen(passphrase) : 0,
939 fkey ? fkey->data : NULL,
940 fkey ? silc_buffer_len(fkey) : 0,
941 channel_pubkeys ? channel_pubkeys->data : NULL,
943 silc_buffer_len(channel_pubkeys) : 0,
944 mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
946 mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
948 silc_buffer_free(fkey);
949 silc_buffer_free(idp);
952 /* Sends CUMODE_CHANGE notify type. This tells that `id' changed the
953 `target' client's mode on `channel'. The notify packet is always
954 destined to the channel. */
956 void silc_server_send_notify_cumode(SilcServer server,
957 SilcPacketStream sock,
959 SilcChannelEntry channel,
960 SilcUInt32 mode_mask,
961 void *id, SilcIdType id_type,
962 SilcClientID *target,
963 SilcPublicKey founder_key)
965 SilcBuffer idp1, idp2, fkey = NULL;
966 unsigned char mode[4];
968 idp1 = silc_id_payload_encode((void *)id, id_type);
969 idp2 = silc_id_payload_encode((void *)target, SILC_ID_CLIENT);
972 SILC_PUT32_MSB(mode_mask, mode);
974 fkey = silc_public_key_payload_encode(founder_key);
976 silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
978 SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
979 idp1->data, silc_buffer_len(idp1),
981 idp2->data, silc_buffer_len(idp2),
982 fkey ? fkey->data : NULL,
983 fkey ? silc_buffer_len(fkey) : 0);
984 silc_buffer_free(fkey);
985 silc_buffer_free(idp1);
986 silc_buffer_free(idp2);
989 /* Sends SIGNOFF notify type. This tells that `client_id' client has
990 left SILC network. This function is used only between server and router
991 traffic. This is not used to send the notify to the channel for
992 client. The `message may be NULL. */
994 void silc_server_send_notify_signoff(SilcServer server,
995 SilcPacketStream sock,
997 SilcClientID *client_id,
1002 idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
1004 silc_server_send_notify(server, sock, broadcast,
1005 SILC_NOTIFY_TYPE_SIGNOFF,
1006 message ? 2 : 1, idp->data, silc_buffer_len(idp),
1007 message, message ? strlen(message): 0);
1008 silc_buffer_free(idp);
1011 /* Sends TOPIC_SET notify type. This tells that `id' changed
1012 the `channel's topic to `topic'. The Notify packet is always destined
1013 to the channel. This function is used to send the topic set notifies
1016 void silc_server_send_notify_topic_set(SilcServer server,
1017 SilcPacketStream sock,
1019 SilcChannelEntry channel,
1020 void *id, SilcIdType id_type,
1025 idp = silc_id_payload_encode(id, id_type);
1027 silc_server_send_notify_dest(server, sock, broadcast,
1028 (void *)channel->id, SILC_ID_CHANNEL,
1029 SILC_NOTIFY_TYPE_TOPIC_SET,
1031 idp->data, silc_buffer_len(idp),
1032 topic, topic ? strlen(topic) : 0);
1033 silc_buffer_free(idp);
1036 /* Send KICKED notify type. This tells that the `client_id' on `channel'
1037 was kicked off the channel. The `comment' may indicate the reason
1038 for the kicking. This function is used only between server and router
1041 void silc_server_send_notify_kicked(SilcServer server,
1042 SilcPacketStream sock,
1044 SilcChannelEntry channel,
1045 SilcClientID *client_id,
1046 SilcClientID *kicker,
1052 idp1 = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
1053 idp2 = silc_id_payload_encode((void *)kicker, SILC_ID_CLIENT);
1056 silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
1057 SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_KICKED, 3,
1058 idp1->data, silc_buffer_len(idp1),
1059 comment, comment ? strlen(comment) : 0,
1060 idp2->data, silc_buffer_len(idp2));
1061 silc_buffer_free(idp1);
1062 silc_buffer_free(idp2);
1065 /* Send KILLED notify type. This tells that the `client_id' client was
1066 killed from the network. The `comment' may indicate the reason
1069 void silc_server_send_notify_killed(SilcServer server,
1070 SilcPacketStream sock,
1072 SilcClientID *client_id,
1073 const char *comment,
1074 void *killer, SilcIdType killer_type)
1079 idp1 = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1080 idp2 = silc_id_payload_encode(killer, killer_type);
1083 silc_server_send_notify_dest(server, sock, broadcast, (void *)client_id,
1084 SILC_ID_CLIENT, SILC_NOTIFY_TYPE_KILLED,
1085 3, idp1->data, silc_buffer_len(idp1),
1086 comment, comment ? strlen(comment) : 0,
1087 idp2->data, silc_buffer_len(idp2));
1088 silc_buffer_free(idp1);
1089 silc_buffer_free(idp2);
1092 /* Sends UMODE_CHANGE notify type. This tells that `client_id' client's
1093 user mode in the SILC Network was changed. This function is used to
1094 send the packet between routers as broadcast packet. */
1096 void silc_server_send_notify_umode(SilcServer server,
1097 SilcPacketStream sock,
1099 SilcClientID *client_id,
1100 SilcUInt32 mode_mask)
1103 unsigned char mode[4];
1105 idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
1106 SILC_PUT32_MSB(mode_mask, mode);
1109 silc_server_send_notify(server, sock, broadcast,
1110 SILC_NOTIFY_TYPE_UMODE_CHANGE, 2,
1111 idp->data, silc_buffer_len(idp),
1113 silc_buffer_free(idp);
1116 /* Sends BAN notify type. This tells that ban has been either `add'ed
1117 or `del'eted on the `channel. This function is used to send the packet
1118 between routers as broadcast packet. */
1120 void silc_server_send_notify_ban(SilcServer server,
1121 SilcPacketStream sock,
1123 SilcChannelEntry channel,
1124 unsigned char *action,
1129 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
1132 silc_server_send_notify(server, sock, broadcast,
1133 SILC_NOTIFY_TYPE_BAN, 3,
1134 idp->data, silc_buffer_len(idp),
1135 action ? action : NULL, action ? 1 : 0,
1136 list ? list->data : NULL,
1137 list ? silc_buffer_len(list) : 0);
1138 silc_buffer_free(idp);
1141 /* Sends INVITE notify type. This tells that invite has been either `add'ed
1142 or `del'eted on the `channel. The sender of the invite is the `client_id'.
1143 This function is used to send the packet between routers as broadcast
1146 void silc_server_send_notify_invite(SilcServer server,
1147 SilcPacketStream sock,
1149 SilcChannelEntry channel,
1150 SilcClientID *client_id,
1151 unsigned char *action,
1154 SilcBuffer idp, idp2;
1156 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
1157 idp2 = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
1160 silc_server_send_notify(server, sock, broadcast,
1161 SILC_NOTIFY_TYPE_INVITE, 5,
1162 idp->data, silc_buffer_len(idp),
1163 channel->channel_name,
1164 strlen(channel->channel_name),
1165 idp2->data, silc_buffer_len(idp2),
1166 action ? action : NULL, action ? 1 : 0,
1167 list ? list->data : NULL,
1168 list ? silc_buffer_len(list) : 0);
1169 silc_buffer_free(idp);
1170 silc_buffer_free(idp2);
1173 /* Sends WATCH notify type. This tells that the `client' was watched and
1174 its status in the network has changed. */
1176 void silc_server_send_notify_watch(SilcServer server,
1177 SilcPacketStream sock,
1178 SilcClientEntry watcher,
1179 SilcClientEntry client,
1180 const char *nickname,
1181 SilcNotifyType type,
1182 SilcPublicKey public_key)
1184 SilcBuffer idp, pkp = NULL;
1185 unsigned char mode[4], n[2];
1187 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
1190 SILC_PUT16_MSB(type, n);
1191 SILC_PUT32_MSB(client->mode, mode);
1193 pkp = silc_public_key_payload_encode(public_key);
1194 silc_server_send_notify_dest(server, sock, FALSE, watcher->id,
1195 SILC_ID_CLIENT, SILC_NOTIFY_TYPE_WATCH,
1196 5, idp->data, silc_buffer_len(idp),
1197 nickname, nickname ? strlen(nickname) : 0,
1199 type != SILC_NOTIFY_TYPE_NONE ?
1200 n : NULL, sizeof(n),
1201 pkp ? pkp->data : NULL,
1202 pkp ? silc_buffer_len(pkp) : 0);
1203 silc_buffer_free(idp);
1204 silc_buffer_free(pkp);
1207 /* Sends notify message destined to specific entity. */
1209 void silc_server_send_notify_dest(SilcServer server,
1210 SilcPacketStream sock,
1213 SilcIdType dest_id_type,
1214 SilcNotifyType type,
1215 SilcUInt32 argc, ...)
1222 packet = silc_notify_payload_encode(type, argc, ap);
1227 silc_server_packet_send_dest(server, sock, SILC_PACKET_NOTIFY,
1228 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
1229 dest_id, dest_id_type,
1230 packet->data, silc_buffer_len(packet));
1232 /* Send to backup routers if this is being broadcasted to primary
1233 router. The silc_server_backup_send checks further whether to
1234 actually send it or not. */
1235 if ((broadcast && sock && sock == SILC_PRIMARY_ROUTE(server)) ||
1236 (broadcast && !sock && !SILC_PRIMARY_ROUTE(server)))
1237 silc_server_backup_send_dest(server, NULL, SILC_PACKET_NOTIFY, 0,
1238 dest_id, dest_id_type,
1239 packet->data, silc_buffer_len(packet),
1242 silc_buffer_free(packet);
1246 /* Sends notify message to a channel. The notify message sent is
1247 distributed to all clients on the channel. If `route_notify' is TRUE
1248 then the notify may be routed to primary route or to some other routers.
1249 If FALSE it is assured that the notify is sent only locally. If `sender'
1250 is provided then the packet is not sent to that connection since it
1251 originally came from it. */
1253 void silc_server_send_notify_to_channel(SilcServer server,
1254 SilcPacketStream sender,
1255 SilcChannelEntry channel,
1256 SilcBool route_notify,
1257 SilcBool send_to_clients,
1258 SilcNotifyType type,
1259 SilcUInt32 argc, ...)
1266 packet = silc_notify_payload_encode(type, argc, ap);
1268 silc_server_packet_send_to_channel(server, sender, channel,
1269 SILC_PACKET_NOTIFY, route_notify,
1271 packet->data, silc_buffer_len(packet));
1272 silc_buffer_free(packet);
1276 /* Send notify message to all channels the client has joined. It is quaranteed
1277 that the message is sent only once to a client (ie. if a client is joined
1278 on two same channel it will receive only one notify message). Also, this
1279 sends only to local clients (locally connected if we are server, and to
1280 local servers if we are router). If `sender' is provided the packet is
1281 not sent to that client at all. */
1283 void silc_server_send_notify_on_channels(SilcServer server,
1284 SilcClientEntry sender,
1285 SilcClientEntry client,
1286 SilcNotifyType type,
1287 SilcUInt32 argc, ...)
1290 SilcPacketStream sock = NULL;
1292 SilcClientEntry *sent_clients = NULL;
1293 SilcUInt32 sent_clients_count = 0;
1294 SilcServerEntry *routed = NULL;
1295 SilcUInt32 routed_count = 0;
1296 SilcHashTableList htl, htl2;
1297 SilcChannelEntry channel;
1298 SilcChannelClientEntry chl, chl2;
1300 unsigned char *data;
1301 SilcUInt32 data_len;
1304 if (!silc_hash_table_count(client->channels)) {
1305 SILC_LOG_DEBUG(("Client is not joined to any channels"));
1309 SILC_LOG_DEBUG(("Sending notify to joined channels"));
1312 packet = silc_notify_payload_encode(type, argc, ap);
1317 data = packet->data;
1318 data_len = silc_buffer_len(packet);
1320 silc_hash_table_list(client->channels, &htl);
1321 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
1322 channel = chl->channel;
1324 /* Send the message to all clients on the channel's client list. */
1325 silc_hash_table_list(channel->user_list, &htl2);
1326 while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) {
1329 if (sender && c == sender)
1332 /* Check if we have sent the packet to this client already */
1333 for (k = 0; k < sent_clients_count; k++)
1334 if (sent_clients[k] == c)
1336 if (k < sent_clients_count)
1339 /* If we are router and if this client has router set it is not
1340 locally connected client and we will route the message to the
1341 router set in the client. */
1342 if (c && c->router && server->server_type == SILC_ROUTER) {
1343 /* Check if we have sent the packet to this route already */
1344 for (k = 0; k < routed_count; k++)
1345 if (routed[k] == c->router)
1347 if (k < routed_count)
1350 sock = c->router->connection;
1352 /* Send the packet */
1353 silc_server_packet_send_dest(server, sock, SILC_PACKET_NOTIFY, 0,
1354 c->router->id, SILC_ID_SERVER,
1357 /* We want to make sure that the packet is routed to same router
1358 only once. Mark this route as sent route. */
1359 routed = silc_realloc(routed, sizeof(*routed) * (routed_count + 1));
1360 routed[routed_count++] = c->router;
1367 /* Send to locally connected client */
1369 sock = c->connection;
1373 /* Send the packet */
1374 silc_server_packet_send_dest(server, sock, SILC_PACKET_NOTIFY, 0,
1375 c->id, SILC_ID_CLIENT, data, data_len);
1377 /* Make sure that we send the notify only once per client. */
1378 sent_clients = silc_realloc(sent_clients, sizeof(*sent_clients) *
1379 (sent_clients_count + 1));
1380 sent_clients[sent_clients_count++] = c;
1383 silc_hash_table_list_reset(&htl2);
1386 silc_hash_table_list_reset(&htl);
1388 silc_free(sent_clients);
1389 silc_buffer_free(packet);
1393 /* Sends New ID Payload to remote end. The packet is used to distribute
1394 information about new registered clients, servers, channel etc. usually
1395 to routers so that they can keep these information up to date.
1396 If the argument `broadcast' is TRUE then the packet is sent as
1397 broadcast packet. */
1399 void silc_server_send_new_id(SilcServer server,
1400 SilcPacketStream sock,
1402 void *id, SilcIdType id_type,
1407 SILC_LOG_DEBUG(("Sending new ID"));
1409 idp = silc_id_payload_encode(id, id_type);
1411 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID,
1412 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
1413 idp->data, silc_buffer_len(idp));
1414 silc_buffer_free(idp);
1417 /* Send New Channel Payload to notify about newly created channel in the
1418 SILC network. Router uses this to notify other routers in the network
1419 about new channel. This packet is broadcasted by router. */
1421 void silc_server_send_new_channel(SilcServer server,
1422 SilcPacketStream sock,
1426 SilcUInt32 channel_id_len,
1430 unsigned char cid[32];
1431 SilcUInt32 name_len = strlen(channel_name);
1433 SILC_LOG_DEBUG(("Sending new channel"));
1435 if (!silc_id_id2str(channel_id, SILC_ID_CHANNEL, cid, sizeof(cid),
1439 /* Encode the channel payload */
1440 packet = silc_channel_payload_encode(channel_name, name_len,
1441 cid, channel_id_len, mode);
1443 silc_server_packet_send(server, sock, SILC_PACKET_NEW_CHANNEL,
1444 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
1445 packet->data, silc_buffer_len(packet));
1447 silc_buffer_free(packet);
1450 /* Send Channel Key payload to distribute the new channel key. Normal server
1451 sends this to router when new client joins to existing channel. Router
1452 sends this to the local server who sent the join command in case where
1453 the channel did not exist yet. Both normal and router servers uses this
1454 also to send this to locally connected clients on the channel. This
1455 must not be broadcasted packet. Routers do not send this to each other.
1456 If `sender is provided then the packet is not sent to that connection since
1457 it originally came from it. */
1459 void silc_server_send_channel_key(SilcServer server,
1460 SilcPacketStream sender,
1461 SilcChannelEntry channel,
1462 unsigned char route)
1465 unsigned char cid[32];
1466 SilcUInt32 tmp_len, cid_len;
1469 SILC_LOG_DEBUG(("Sending key to channel %s", channel->channel_name));
1474 if (!silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid),
1478 /* Encode channel key packet */
1479 cipher = silc_cipher_get_name(channel->send_key);
1480 tmp_len = strlen(cipher);
1481 packet = silc_channel_key_payload_encode(cid_len, cid, tmp_len, cipher,
1482 channel->key_len / 8, channel->key);
1484 silc_server_packet_send_to_channel(server, sender, channel,
1485 SILC_PACKET_CHANNEL_KEY,
1486 route, TRUE, packet->data,
1487 silc_buffer_len(packet));
1488 silc_buffer_free(packet);
1491 /* Generic function to send any command. The arguments must be sent already
1492 encoded into correct form in correct order. */
1494 void silc_server_send_command(SilcServer server,
1495 SilcPacketStream sock,
1496 SilcCommand command,
1498 SilcUInt32 argc, ...)
1504 server->stat.commands_sent++;
1508 packet = silc_command_payload_encode_vap(command, ident, argc, ap);
1510 silc_server_packet_send(server, sock, SILC_PACKET_COMMAND, 0,
1511 packet->data, silc_buffer_len(packet));
1512 silc_buffer_free(packet);
1516 /* Generic function to send any command reply. The arguments must be sent
1517 already encoded into correct form in correct order. */
1519 void silc_server_send_command_reply(SilcServer server,
1520 SilcPacketStream sock,
1521 SilcCommand command,
1525 SilcUInt32 argc, ...)
1531 server->stat.commands_sent++;
1535 packet = silc_command_reply_payload_encode_vap(command, status, error,
1538 silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0,
1539 packet->data, silc_buffer_len(packet));
1540 silc_buffer_free(packet);
1544 /* Generic function to send any command reply. The arguments must be sent
1545 already encoded into correct form in correct order. */
1547 void silc_server_send_dest_command_reply(SilcServer server,
1548 SilcPacketStream sock,
1550 SilcIdType dst_id_type,
1551 SilcCommand command,
1555 SilcUInt32 argc, ...)
1561 server->stat.commands_sent++;
1565 packet = silc_command_reply_payload_encode_vap(command, status, error,
1568 silc_server_packet_send_dest(server, sock, SILC_PACKET_COMMAND_REPLY, 0,
1569 dst_id, dst_id_type, packet->data,
1570 silc_buffer_len(packet));
1571 silc_buffer_free(packet);
1575 /* Routine used to send the connection authentication packet. */
1577 void silc_server_send_connection_auth_request(SilcServer server,
1578 SilcPacketStream sock,
1579 SilcUInt16 conn_type,
1580 SilcAuthMethod auth_meth)
1584 packet = silc_buffer_alloc(4);
1588 silc_buffer_pull_tail(packet, silc_buffer_truelen(packet));
1589 silc_buffer_format(packet,
1590 SILC_STR_UI_SHORT(conn_type),
1591 SILC_STR_UI_SHORT(auth_meth),
1594 silc_server_packet_send(server, sock, SILC_PACKET_CONNECTION_AUTH_REQUEST,
1595 0, packet->data, silc_buffer_len(packet));
1596 silc_buffer_free(packet);
1599 /* Send packet to clients that are known to be operators. If server
1600 is router and `route' is TRUE then the packet would go to all operators
1601 in the SILC network. If `route' is FALSE then only local operators
1602 (local for server and cell wide for router). If `local' is TRUE then
1603 only locally connected operators receive the packet. If `local' is
1604 TRUE then `route' is ignored. If server is normal server and `route'
1605 is FALSE it is equivalent to `local' being TRUE. */
1607 void silc_server_send_opers(SilcServer server,
1608 SilcPacketType type,
1609 SilcPacketFlags flags,
1610 SilcBool route, bool local,
1611 unsigned char *data,
1612 SilcUInt32 data_len)
1615 SilcIDCacheEntry id_cache = NULL;
1616 SilcClientEntry client = NULL;
1617 SilcIDListData idata;
1618 SilcPacketStream sock;
1619 SilcServerEntry *routed = NULL;
1620 SilcUInt32 routed_count = 0;
1621 SilcBool gone = FALSE;
1624 SILC_LOG_DEBUG(("Sending %s packet to operators",
1625 silc_get_packet_name(type)));
1627 /* If local was requested send only locally connected operators. */
1628 if (local || (server->server_type == SILC_SERVER && !route)) {
1629 if (!silc_idcache_get_all(server->local_list->clients, &list))
1631 silc_list_start(list);
1632 while ((id_cache = silc_list_get(list))) {
1633 client = (SilcClientEntry)id_cache->context;
1634 if (!client->router && SILC_IS_LOCAL(client) &&
1635 (client->mode & SILC_UMODE_SERVER_OPERATOR ||
1636 client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1638 /* Send the packet to locally connected operator */
1639 silc_server_packet_send_dest(server, client->connection, type, flags,
1640 client->id, SILC_ID_CLIENT,
1647 if (!silc_idcache_get_all(server->local_list->clients, &list))
1649 silc_list_start(list);
1650 while ((id_cache = silc_list_get(list))) {
1651 client = (SilcClientEntry)id_cache->context;
1652 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
1653 !(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1656 if (server->server_type != SILC_SERVER && client->router &&
1657 ((!route && client->router->router == server->id_entry) || route)) {
1659 /* Check if we have sent the packet to this route already */
1660 for (k = 0; k < routed_count; k++)
1661 if (routed[k] == client->router)
1663 if (k < routed_count)
1666 /* Route only once to router */
1667 sock = client->router->connection;
1668 idata = silc_packet_get_context(sock);
1669 if (idata->conn_type == SILC_CONN_ROUTER) {
1675 /* Send the packet */
1676 silc_server_packet_send_dest(server, sock, type, flags,
1677 client->id, SILC_ID_CLIENT,
1680 /* Mark this route routed already */
1681 routed = silc_realloc(routed, sizeof(*routed) * (routed_count + 1));
1682 routed[routed_count++] = client->router;
1686 if (client->router || !client->connection)
1689 /* Send to locally connected client */
1690 sock = client->connection;
1691 silc_server_packet_send_dest(server, sock, type, flags,
1692 client->id, SILC_ID_CLIENT,
1697 if (!silc_idcache_get_all(server->global_list->clients, &list))
1699 silc_list_start(list);
1700 while ((id_cache = silc_list_get(list))) {
1701 client = (SilcClientEntry)id_cache->context;
1702 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
1703 !(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1706 if (server->server_type != SILC_SERVER && client->router &&
1707 ((!route && client->router->router == server->id_entry) || route)) {
1709 /* Check if we have sent the packet to this route already */
1710 for (k = 0; k < routed_count; k++)
1711 if (routed[k] == client->router)
1713 if (k < routed_count)
1716 /* Route only once to router */
1717 sock = client->router->connection;
1718 idata = silc_packet_get_context(sock);
1719 if (idata->conn_type == SILC_CONN_ROUTER) {
1725 /* Send the packet */
1726 silc_server_packet_send_dest(server, sock, type, flags,
1727 client->id, SILC_ID_CLIENT,
1730 /* Mark this route routed already */
1731 routed = silc_realloc(routed, sizeof(*routed) * (routed_count + 1));
1732 routed[routed_count++] = client->router;
1736 if (client->router || !client->connection)
1739 /* Send to locally connected client */
1740 sock = client->connection;
1741 silc_server_packet_send_dest(server, sock, type, flags,
1742 client->id, SILC_ID_CLIENT,
1748 /* Send a notify packet to operators */
1750 void silc_server_send_opers_notify(SilcServer server,
1753 SilcNotifyType type,
1754 SilcUInt32 argc, ...)
1760 packet = silc_notify_payload_encode(type, argc, ap);
1762 silc_server_send_opers(server, SILC_PACKET_NOTIFY, 0,
1763 route, local, packet->data, silc_buffer_len(packet));
1764 silc_buffer_free(packet);