5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2009 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),
325 /* Send the message to clients on the channel's client list. */
326 silc_hash_table_list(channel->user_list, &htl);
327 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
328 client = chl->client;
332 /* If client has router set it is not locally connected client and
333 we will route the message to the router set in the client. Though,
334 send locally connected server in all cases. */
335 if (server->server_type == SILC_ROUTER && client->router &&
336 ((!route && client->router->router == server->id_entry) || route)) {
338 /* Check if we have sent the packet to this route already */
339 for (k = 0; k < routed_count; k++)
340 if (routed[k] == client->router)
342 if (k < routed_count)
345 /* Get data used in packet header encryption, keys and stuff. */
346 sock = client->router->connection;
347 idata = (SilcIDListData)client->router;
349 if (sender && sock == sender)
352 /* Route only once to router. Protocol prohibits sending channel
353 messages to more than one router. */
354 if (idata->conn_type == SILC_CONN_ROUTER) {
360 SILC_LOG_DEBUG(("Sending packet to client %s",
361 client->nickname ? client->nickname :
362 (unsigned char *)""));
364 /* Send the packet */
365 silc_server_packet_send_dest(server, sock, type, 0, channel->id,
366 SILC_ID_CHANNEL, data, data_len);
368 /* Mark this route routed already */
369 routed[routed_count++] = client->router;
373 if (client->router || !send_to_clients)
376 /* Send to locally connected client */
378 /* Get data used in packet header encryption, keys and stuff. */
379 sock = client->connection;
380 if (!sock || (sender && sock == sender))
383 SILC_LOG_DEBUG(("Sending packet to client %s",
384 client->nickname ? client->nickname :
385 (unsigned char *)""));
387 /* Send the packet */
388 silc_server_packet_send_dest(server, sock, type, 0, channel->id,
389 SILC_ID_CHANNEL, data, data_len);
391 silc_hash_table_list_reset(&htl);
397 /* This checks whether the relayed packet came from router. If it did
398 then we'll need to encrypt it with the channel key. This is called
399 from the silc_server_packet_relay_to_channel. */
402 silc_server_packet_relay_to_channel_encrypt(SilcServer server,
403 SilcPacketStream sender,
405 SilcIdType sender_type,
406 SilcChannelEntry channel,
408 unsigned int data_len)
410 SilcIDListData idata;
411 SilcUInt32 mac_len, iv_len;
412 unsigned char iv[SILC_CIPHER_MAX_IV_SIZE];
413 SilcUInt16 totlen, len;
414 SilcID src_id, dst_id;
416 idata = silc_packet_get_context(sender);
418 /* If we are router and the packet came from router and private key
419 has not been set for the channel then we must encrypt the packet
420 as it was decrypted with the session key shared between us and the
421 router which sent it. This is so, because cells does not share the
423 if (server->server_type == SILC_ROUTER &&
424 idata->conn_type == SILC_CONN_ROUTER &&
425 !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY) && channel->key) {
427 /* If we are backup router and remote is our primary router and
428 we are currently doing backup resuming protocol we must not
429 re-encrypt message with session key. */
430 if (server->backup_router && idata->sconn->backup_resuming &&
431 SILC_PRIMARY_ROUTE(server) == sender)
434 mac_len = silc_hmac_len(channel->hmac);
435 iv_len = silc_cipher_get_block_len(channel->send_key);
437 if (data_len <= mac_len + iv_len) {
438 SILC_LOG_WARNING(("Corrupted channel message, cannot relay it"));
443 SILC_GET16_MSB(len, data + totlen);
445 if (totlen + iv_len + mac_len + 2 > data_len) {
446 SILC_LOG_WARNING(("Corrupted channel message, cannot relay it"));
449 SILC_GET16_MSB(len, data + totlen);
451 if (totlen + iv_len + mac_len > data_len) {
452 SILC_LOG_WARNING(("Corrupted channel message, cannot relay it"));
456 memcpy(iv, data + (data_len - iv_len - mac_len), iv_len);
458 SILC_ASSERT(sender_type == SILC_ID_CLIENT);
459 src_id.type = SILC_ID_CLIENT;
460 src_id.u.client_id = *((SilcClientID *)sender_id);
461 dst_id.type = SILC_ID_CHANNEL;
462 dst_id.u.channel_id = *channel->id;
464 return silc_message_payload_encrypt(data, totlen, data_len - mac_len,
465 iv, &src_id, &dst_id,
466 channel->send_key, channel->hmac);
472 /* This routine is explicitly used to relay messages to some channel.
473 Packets sent with this function we have received earlier and are
474 totally encrypted. This just sends the packet to all clients on
475 the channel. If the sender of the packet is someone on the channel
476 the message will not be sent to that client. The SILC Packet header
477 is encrypted with the session key shared between us and the client.
478 MAC is also computed before encrypting the header. Rest of the
479 packet will be untouched. */
481 void silc_server_packet_relay_to_channel(SilcServer server,
482 SilcPacketStream sender_sock,
483 SilcChannelEntry channel,
485 SilcIdType sender_type,
486 SilcClientEntry sender_entry,
490 SilcPacketStream sock = NULL;
491 SilcClientEntry client = NULL;
492 SilcServerEntry *routed = NULL;
493 SilcChannelClientEntry chl, chl_sender;
494 SilcUInt32 routed_count = 0;
495 SilcIDListData idata;
496 SilcHashTableList htl;
497 SilcBool gone = FALSE;
500 if (!silc_server_client_on_channel(sender_entry, channel, &chl_sender))
503 SILC_LOG_DEBUG(("Relaying packet to channel %s", channel->channel_name));
505 /* This encrypts the message, if needed. It will be encrypted if
506 it came from the router thus it needs to be encrypted with the
507 channel key. If the channel key does not exist, then we know we
508 don't have a single local user on the channel. */
509 if (!silc_server_packet_relay_to_channel_encrypt(server, sender_sock,
510 sender_id, sender_type,
515 /* If there are global users in the channel we will send the message
516 first to our router for further routing. */
517 if (server->server_type != SILC_ROUTER && !server->standalone &&
518 channel->global_users) {
519 SilcServerEntry router = server->router;
521 /* Check that the sender is not our router. */
522 if (sender_sock != router->connection) {
523 SILC_LOG_DEBUG(("Sending message to router for routing"));
524 sock = router->connection;
525 silc_server_packet_send_srcdest(server, sock,
526 SILC_PACKET_CHANNEL_MESSAGE, 0,
527 sender_id, sender_type,
528 channel->id, SILC_ID_CHANNEL,
533 if (!silc_hash_table_count(channel->user_list)) {
534 SILC_LOG_DEBUG(("Channel %s is empty", channel->channel_name));
538 routed = silc_calloc(silc_hash_table_count(channel->user_list),
543 /* Assure we won't route the message back to the sender's way. */
544 if (sender_entry->router)
545 routed[routed_count++] = sender_entry->router;
547 /* Send the message to clients on the channel's client list. */
548 silc_hash_table_list(channel->user_list, &htl);
549 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
550 client = chl->client;
551 if (!client || client == sender_entry)
554 /* Check whether message sending is blocked */
555 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)
557 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS &&
558 !(chl_sender->mode & SILC_CHANNEL_UMODE_CHANOP) &&
559 !(chl_sender->mode & SILC_CHANNEL_UMODE_CHANFO))
561 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS &&
562 sender_entry->mode & SILC_UMODE_ROBOT)
565 /* If the client has set router it means that it is not locally
566 connected client and we will route the packet further. */
567 if (server->server_type == SILC_ROUTER && client->router) {
569 /* Check if we have sent the packet to this route already */
570 for (k = 0; k < routed_count; k++)
571 if (routed[k] == client->router)
573 if (k < routed_count)
576 /* Get data used in packet header encryption, keys and stuff. */
577 sock = client->router->connection;
578 idata = (SilcIDListData)client->router;
580 /* Check if the sender socket is the same as this client's router
582 if (sender_sock && sock == sender_sock)
585 SILC_LOG_DEBUG(("Relaying packet to client ID(%s)",
586 silc_id_render(client->id, SILC_ID_CLIENT)));
588 /* Mark this route routed already. */
589 routed[routed_count++] = client->router;
591 if (idata->conn_type == SILC_CONN_ROUTER) {
592 /* The remote connection is router then we'll decrypt the
593 channel message and re-encrypt it with the session key shared
594 between us and the remote router. This is done because the
595 channel keys are cell specific and we have different channel
596 key than the remote router has. */
598 /* Route only once to router. Protocol prohibits sending channel
599 messages to more than one router. */
604 /* If we are backup router and remote is our primary router and
605 we are currently doing backup resuming protocol we must not
606 re-encrypt message with session key. */
607 if (server->backup_router && idata->sconn->backup_resuming &&
608 SILC_PRIMARY_ROUTE(server) == sock) {
609 silc_server_packet_send_srcdest(server, sock,
610 SILC_PACKET_CHANNEL_MESSAGE, 0,
611 sender_id, sender_type,
612 channel->id, SILC_ID_CHANNEL,
617 SILC_LOG_DEBUG(("Remote is router, encrypt with session key"));
619 /* If private key mode is not set then decrypt the packet
621 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY) &&
622 channel->receive_key) {
623 unsigned char tmp[SILC_PACKET_MAX_LEN], sid[32], rid[32];
624 SilcUInt32 sid_len, rid_len;
626 if (data_len > SILC_PACKET_MAX_LEN)
627 data_len = SILC_PACKET_MAX_LEN;
628 memcpy(tmp, data, data_len);
630 /* Decrypt the channel message (we don't check the MAC) */
631 silc_id_id2str(sender_id, sender_type, sid, sizeof(sid), &sid_len);
632 silc_id_id2str(channel->id, SILC_ID_CHANNEL, rid, sizeof(rid),
634 silc_message_payload_decrypt(tmp, data_len, FALSE, FALSE,
635 channel->receive_key,
636 channel->hmac, sid, sid_len,
637 rid, rid_len, FALSE);
639 /* Now re-encrypt and send it to the router */
640 silc_server_packet_send_srcdest(server, sock,
641 SILC_PACKET_CHANNEL_MESSAGE, 0,
642 sender_id, sender_type,
643 channel->id, SILC_ID_CHANNEL,
646 /* Private key mode is set, we don't have the channel key, so
647 just re-encrypt the entire packet and send it to the router. */
648 silc_server_packet_send_srcdest(server, sock,
649 SILC_PACKET_CHANNEL_MESSAGE, 0,
650 sender_id, sender_type,
651 channel->id, SILC_ID_CHANNEL,
655 /* Send the packet to normal server */
656 silc_server_packet_send_srcdest(server, sock,
657 SILC_PACKET_CHANNEL_MESSAGE, 0,
658 sender_id, sender_type,
659 channel->id, SILC_ID_CHANNEL,
669 /* Get data used in packet header encryption, keys and stuff. */
670 sock = client->connection;
671 if (!sock || (sender_sock && sock == sender_sock))
674 SILC_LOG_DEBUG(("Sending packet to client ID(%s)",
675 silc_id_render(client->id, SILC_ID_CLIENT)));
677 /* Send the packet */
678 silc_server_packet_send_srcdest(server, sock,
679 SILC_PACKET_CHANNEL_MESSAGE, 0,
680 sender_id, sender_type,
681 channel->id, SILC_ID_CHANNEL,
685 silc_hash_table_list_reset(&htl);
689 /* This function is used to send packets strictly to all local clients
690 on a particular channel. This is used for example to distribute new
691 channel key to all our locally connected clients on the channel.
692 The packets are always encrypted with the session key shared between
693 the client, this means these are not _to the channel_ but _to the client_
696 void silc_server_packet_send_local_channel(SilcServer server,
697 SilcChannelEntry channel,
699 SilcPacketFlags flags,
703 SilcChannelClientEntry chl;
704 SilcHashTableList htl;
705 SilcPacketStream sock = NULL;
707 SILC_LOG_DEBUG(("Send packet to local clients on channel %s",
708 channel->channel_name));
710 /* Send the message to clients on the channel's client list. */
711 silc_hash_table_list(channel->user_list, &htl);
712 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
713 if (chl->client && SILC_IS_LOCAL(chl->client)) {
714 sock = chl->client->connection;
716 /* Send the packet to the client */
717 silc_server_packet_send_dest(server, sock, type, flags, chl->client->id,
718 SILC_ID_CLIENT, data, data_len);
721 silc_hash_table_list_reset(&htl);
724 /* Sends current motd to client */
726 void silc_server_send_motd(SilcServer server,
727 SilcPacketStream sock)
729 char *motd, *motd_file = NULL;
733 motd_file = server->config->server_info->motd_file;
736 motd = silc_file_readfile(motd_file, &motd_len);
741 silc_server_send_notify(server, sock, FALSE, SILC_NOTIFY_TYPE_MOTD, 1,
747 /* Sends error message. Error messages may or may not have any
750 void silc_server_send_error(SilcServer server,
751 SilcPacketStream sock,
752 const char *fmt, ...)
755 unsigned char buf[4096];
757 memset(buf, 0, sizeof(buf));
759 vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
762 silc_server_packet_send(server, sock, SILC_PACKET_ERROR, 0,
766 /* Sends notify message. If format is TRUE the variable arguments are
767 formatted and the formatted string is sent as argument payload. If it is
768 FALSE then each argument is sent as separate argument and their format
769 in the argument list must be { argument data, argument length }. */
771 void silc_server_send_notify(SilcServer server,
772 SilcPacketStream sock,
775 SilcUInt32 argc, ...)
782 packet = silc_notify_payload_encode(type, argc, ap);
787 silc_server_packet_send(server, sock, SILC_PACKET_NOTIFY,
788 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
789 packet->data, silc_buffer_len(packet));
791 /* Send to backup routers if this is being broadcasted to primary
792 router. The silc_server_backup_send checks further whether to
793 actually send it or not. */
794 if ((broadcast && sock && sock == SILC_PRIMARY_ROUTE(server)) ||
795 (broadcast && !sock && !SILC_PRIMARY_ROUTE(server)))
796 silc_server_backup_send(server, NULL, SILC_PACKET_NOTIFY, 0,
797 packet->data, silc_buffer_len(packet),
800 silc_buffer_free(packet);
804 /* Sends notify message and gets the arguments from the `args' Argument
807 void silc_server_send_notify_args(SilcServer server,
808 SilcPacketStream sock,
816 packet = silc_notify_payload_encode_args(type, argc, args);
818 silc_server_packet_send(server, sock, SILC_PACKET_NOTIFY,
819 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
820 packet->data, silc_buffer_len(packet));
821 silc_buffer_free(packet);
824 /* Send CHANNEL_CHANGE notify type. This tells the receiver to replace the
825 `old_id' with the `new_id'. */
827 void silc_server_send_notify_channel_change(SilcServer server,
828 SilcPacketStream sock,
830 SilcChannelID *old_id,
831 SilcChannelID *new_id)
833 SilcBuffer idp1, idp2;
835 idp1 = silc_id_payload_encode((void *)old_id, SILC_ID_CHANNEL);
836 idp2 = silc_id_payload_encode((void *)new_id, SILC_ID_CHANNEL);
839 silc_server_send_notify(server, sock, broadcast,
840 SILC_NOTIFY_TYPE_CHANNEL_CHANGE,
841 2, idp1->data, silc_buffer_len(idp1),
842 idp2->data, silc_buffer_len(idp2));
843 silc_buffer_free(idp1);
844 silc_buffer_free(idp2);
847 /* Send NICK_CHANGE notify type. This tells the receiver to replace the
848 `old_id' with the `new_id'. */
850 void silc_server_send_notify_nick_change(SilcServer server,
851 SilcPacketStream sock,
853 SilcClientID *old_id,
854 SilcClientID *new_id,
855 const char *nickname)
857 SilcBuffer idp1, idp2;
859 idp1 = silc_id_payload_encode((void *)old_id, SILC_ID_CLIENT);
860 idp2 = silc_id_payload_encode((void *)new_id, SILC_ID_CLIENT);
863 silc_server_send_notify(server, sock, broadcast,
864 SILC_NOTIFY_TYPE_NICK_CHANGE,
865 3, idp1->data, silc_buffer_len(idp1),
866 idp2->data, silc_buffer_len(idp2),
867 nickname, nickname ? strlen(nickname) : 0);
868 silc_buffer_free(idp1);
869 silc_buffer_free(idp2);
872 /* Sends JOIN notify type. This tells that new client by `client_id' ID
873 has joined to the `channel'. */
875 void silc_server_send_notify_join(SilcServer server,
876 SilcPacketStream sock,
878 SilcChannelEntry channel,
879 SilcClientID *client_id)
881 SilcBuffer idp1, idp2;
883 idp1 = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
884 idp2 = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
887 silc_server_send_notify(server, sock, broadcast, SILC_NOTIFY_TYPE_JOIN,
888 2, idp1->data, silc_buffer_len(idp1),
889 idp2->data, silc_buffer_len(idp2));
890 silc_buffer_free(idp1);
891 silc_buffer_free(idp2);
894 /* Sends LEAVE notify type. This tells that `client_id' has left the
895 `channel'. The Notify packet is always destined to the channel. */
897 void silc_server_send_notify_leave(SilcServer server,
898 SilcPacketStream sock,
900 SilcChannelEntry channel,
901 SilcClientID *client_id)
905 idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
907 silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
908 SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_LEAVE,
909 1, idp->data, silc_buffer_len(idp));
910 silc_buffer_free(idp);
913 /* Sends CMODE_CHANGE notify type. This tells that `client_id' changed the
914 `channel' mode to `mode. The Notify packet is always destined to
917 void silc_server_send_notify_cmode(SilcServer server,
918 SilcPacketStream sock,
920 SilcChannelEntry channel,
921 SilcUInt32 mode_mask,
922 void *id, SilcIdType id_type,
923 const char *cipher, const char *hmac,
924 const char *passphrase,
925 SilcPublicKey founder_key,
926 SilcBuffer channel_pubkeys)
928 SilcBuffer idp, fkey = NULL;
929 unsigned char mode[4], ulimit[4];
931 idp = silc_id_payload_encode((void *)id, id_type);
934 SILC_PUT32_MSB(mode_mask, mode);
936 fkey = silc_public_key_payload_encode(founder_key);
937 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
938 SILC_PUT32_MSB(channel->user_limit, ulimit);
940 silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
941 SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_CMODE_CHANGE,
942 8, idp->data, silc_buffer_len(idp),
944 cipher, cipher ? strlen(cipher) : 0,
945 hmac, hmac ? strlen(hmac) : 0,
946 passphrase, passphrase ?
947 strlen(passphrase) : 0,
948 fkey ? fkey->data : NULL,
949 fkey ? silc_buffer_len(fkey) : 0,
950 channel_pubkeys ? channel_pubkeys->data : NULL,
952 silc_buffer_len(channel_pubkeys) : 0,
953 mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
955 mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
957 silc_buffer_free(fkey);
958 silc_buffer_free(idp);
961 /* Sends CUMODE_CHANGE notify type. This tells that `id' changed the
962 `target' client's mode on `channel'. The notify packet is always
963 destined to the channel. */
965 void silc_server_send_notify_cumode(SilcServer server,
966 SilcPacketStream sock,
968 SilcChannelEntry channel,
969 SilcUInt32 mode_mask,
970 void *id, SilcIdType id_type,
971 SilcClientID *target,
972 SilcPublicKey founder_key)
974 SilcBuffer idp1, idp2, fkey = NULL;
975 unsigned char mode[4];
977 idp1 = silc_id_payload_encode((void *)id, id_type);
978 idp2 = silc_id_payload_encode((void *)target, SILC_ID_CLIENT);
981 SILC_PUT32_MSB(mode_mask, mode);
983 fkey = silc_public_key_payload_encode(founder_key);
985 silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
987 SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
988 idp1->data, silc_buffer_len(idp1),
990 idp2->data, silc_buffer_len(idp2),
991 fkey ? fkey->data : NULL,
992 fkey ? silc_buffer_len(fkey) : 0);
993 silc_buffer_free(fkey);
994 silc_buffer_free(idp1);
995 silc_buffer_free(idp2);
998 /* Sends SIGNOFF notify type. This tells that `client_id' client has
999 left SILC network. This function is used only between server and router
1000 traffic. This is not used to send the notify to the channel for
1001 client. The `message may be NULL. */
1003 void silc_server_send_notify_signoff(SilcServer server,
1004 SilcPacketStream sock,
1006 SilcClientID *client_id,
1007 const char *message)
1011 idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
1013 silc_server_send_notify(server, sock, broadcast,
1014 SILC_NOTIFY_TYPE_SIGNOFF,
1015 message ? 2 : 1, idp->data, silc_buffer_len(idp),
1016 message, message ? strlen(message): 0);
1017 silc_buffer_free(idp);
1020 /* Sends TOPIC_SET notify type. This tells that `id' changed
1021 the `channel's topic to `topic'. The Notify packet is always destined
1022 to the channel. This function is used to send the topic set notifies
1025 void silc_server_send_notify_topic_set(SilcServer server,
1026 SilcPacketStream sock,
1028 SilcChannelEntry channel,
1029 void *id, SilcIdType id_type,
1034 idp = silc_id_payload_encode(id, id_type);
1036 silc_server_send_notify_dest(server, sock, broadcast,
1037 (void *)channel->id, SILC_ID_CHANNEL,
1038 SILC_NOTIFY_TYPE_TOPIC_SET,
1040 idp->data, silc_buffer_len(idp),
1041 topic, topic ? strlen(topic) : 0);
1042 silc_buffer_free(idp);
1045 /* Send KICKED notify type. This tells that the `client_id' on `channel'
1046 was kicked off the channel. The `comment' may indicate the reason
1047 for the kicking. This function is used only between server and router
1050 void silc_server_send_notify_kicked(SilcServer server,
1051 SilcPacketStream sock,
1053 SilcChannelEntry channel,
1054 SilcClientID *client_id,
1055 SilcClientID *kicker,
1061 idp1 = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
1062 idp2 = silc_id_payload_encode((void *)kicker, SILC_ID_CLIENT);
1065 silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
1066 SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_KICKED, 3,
1067 idp1->data, silc_buffer_len(idp1),
1068 comment, comment ? strlen(comment) : 0,
1069 idp2->data, silc_buffer_len(idp2));
1070 silc_buffer_free(idp1);
1071 silc_buffer_free(idp2);
1074 /* Send KILLED notify type. This tells that the `client_id' client was
1075 killed from the network. The `comment' may indicate the reason
1078 void silc_server_send_notify_killed(SilcServer server,
1079 SilcPacketStream sock,
1081 SilcClientID *client_id,
1082 const char *comment,
1083 void *killer, SilcIdType killer_type)
1088 idp1 = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1089 idp2 = silc_id_payload_encode(killer, killer_type);
1092 silc_server_send_notify_dest(server, sock, broadcast, (void *)client_id,
1093 SILC_ID_CLIENT, SILC_NOTIFY_TYPE_KILLED,
1094 3, idp1->data, silc_buffer_len(idp1),
1095 comment, comment ? strlen(comment) : 0,
1096 idp2->data, silc_buffer_len(idp2));
1097 silc_buffer_free(idp1);
1098 silc_buffer_free(idp2);
1101 /* Sends UMODE_CHANGE notify type. This tells that `client_id' client's
1102 user mode in the SILC Network was changed. This function is used to
1103 send the packet between routers as broadcast packet. */
1105 void silc_server_send_notify_umode(SilcServer server,
1106 SilcPacketStream sock,
1108 SilcClientID *client_id,
1109 SilcUInt32 mode_mask)
1112 unsigned char mode[4];
1114 idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
1115 SILC_PUT32_MSB(mode_mask, mode);
1118 silc_server_send_notify(server, sock, broadcast,
1119 SILC_NOTIFY_TYPE_UMODE_CHANGE, 2,
1120 idp->data, silc_buffer_len(idp),
1122 silc_buffer_free(idp);
1125 /* Sends BAN notify type. This tells that ban has been either `add'ed
1126 or `del'eted on the `channel. This function is used to send the packet
1127 between routers as broadcast packet. */
1129 void silc_server_send_notify_ban(SilcServer server,
1130 SilcPacketStream sock,
1132 SilcChannelEntry channel,
1133 unsigned char *action,
1138 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
1141 silc_server_send_notify(server, sock, broadcast,
1142 SILC_NOTIFY_TYPE_BAN, 3,
1143 idp->data, silc_buffer_len(idp),
1144 action ? action : NULL, action ? 1 : 0,
1145 list ? list->data : NULL,
1146 list ? silc_buffer_len(list) : 0);
1147 silc_buffer_free(idp);
1150 /* Sends INVITE notify type. This tells that invite has been either `add'ed
1151 or `del'eted on the `channel. The sender of the invite is the `client_id'.
1152 This function is used to send the packet between routers as broadcast
1155 void silc_server_send_notify_invite(SilcServer server,
1156 SilcPacketStream sock,
1158 SilcChannelEntry channel,
1159 SilcClientID *client_id,
1160 unsigned char *action,
1163 SilcBuffer idp, idp2;
1165 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
1166 idp2 = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
1169 silc_server_send_notify(server, sock, broadcast,
1170 SILC_NOTIFY_TYPE_INVITE, 5,
1171 idp->data, silc_buffer_len(idp),
1172 channel->channel_name,
1173 strlen(channel->channel_name),
1174 idp2->data, silc_buffer_len(idp2),
1175 action ? action : NULL, action ? 1 : 0,
1176 list ? list->data : NULL,
1177 list ? silc_buffer_len(list) : 0);
1178 silc_buffer_free(idp);
1179 silc_buffer_free(idp2);
1182 /* Sends WATCH notify type. This tells that the `client' was watched and
1183 its status in the network has changed. */
1185 void silc_server_send_notify_watch(SilcServer server,
1186 SilcPacketStream sock,
1187 SilcClientEntry watcher,
1188 SilcClientEntry client,
1189 const char *nickname,
1190 SilcNotifyType type,
1191 SilcPublicKey public_key)
1193 SilcBuffer idp, pkp = NULL;
1194 unsigned char mode[4], n[2];
1196 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
1199 SILC_PUT16_MSB(type, n);
1200 SILC_PUT32_MSB(client->mode, mode);
1202 pkp = silc_public_key_payload_encode(public_key);
1203 silc_server_send_notify_dest(server, sock, FALSE, watcher->id,
1204 SILC_ID_CLIENT, SILC_NOTIFY_TYPE_WATCH,
1205 5, idp->data, silc_buffer_len(idp),
1206 nickname, nickname ? strlen(nickname) : 0,
1208 type != SILC_NOTIFY_TYPE_NONE ?
1209 n : NULL, sizeof(n),
1210 pkp ? pkp->data : NULL,
1211 pkp ? silc_buffer_len(pkp) : 0);
1212 silc_buffer_free(idp);
1213 silc_buffer_free(pkp);
1216 /* Sends notify message destined to specific entity. */
1218 void silc_server_send_notify_dest(SilcServer server,
1219 SilcPacketStream sock,
1222 SilcIdType dest_id_type,
1223 SilcNotifyType type,
1224 SilcUInt32 argc, ...)
1231 packet = silc_notify_payload_encode(type, argc, ap);
1236 silc_server_packet_send_dest(server, sock, SILC_PACKET_NOTIFY,
1237 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
1238 dest_id, dest_id_type,
1239 packet->data, silc_buffer_len(packet));
1241 /* Send to backup routers if this is being broadcasted to primary
1242 router. The silc_server_backup_send checks further whether to
1243 actually send it or not. */
1244 if ((broadcast && sock && sock == SILC_PRIMARY_ROUTE(server)) ||
1245 (broadcast && !sock && !SILC_PRIMARY_ROUTE(server)))
1246 silc_server_backup_send_dest(server, NULL, SILC_PACKET_NOTIFY, 0,
1247 dest_id, dest_id_type,
1248 packet->data, silc_buffer_len(packet),
1251 silc_buffer_free(packet);
1255 /* Sends notify message to a channel. The notify message sent is
1256 distributed to all clients on the channel. If `route_notify' is TRUE
1257 then the notify may be routed to primary route or to some other routers.
1258 If FALSE it is assured that the notify is sent only locally. If `sender'
1259 is provided then the packet is not sent to that connection since it
1260 originally came from it. */
1262 void silc_server_send_notify_to_channel(SilcServer server,
1263 SilcPacketStream sender,
1264 SilcChannelEntry channel,
1265 SilcBool route_notify,
1266 SilcBool send_to_clients,
1267 SilcNotifyType type,
1268 SilcUInt32 argc, ...)
1275 packet = silc_notify_payload_encode(type, argc, ap);
1277 silc_server_packet_send_to_channel(server, sender, channel,
1278 SILC_PACKET_NOTIFY, route_notify,
1280 packet->data, silc_buffer_len(packet));
1281 silc_buffer_free(packet);
1285 /* Send notify message to all channels the client has joined. It is quaranteed
1286 that the message is sent only once to a client (ie. if a client is joined
1287 on two same channel it will receive only one notify message). Also, this
1288 sends only to local clients (locally connected if we are server, and to
1289 local servers if we are router). If `sender' is provided the packet is
1290 not sent to that client at all. */
1292 void silc_server_send_notify_on_channels(SilcServer server,
1293 SilcClientEntry sender,
1294 SilcClientEntry client,
1295 SilcNotifyType type,
1296 SilcUInt32 argc, ...)
1299 SilcPacketStream sock = NULL;
1301 SilcClientEntry *sent_clients = NULL;
1302 SilcUInt32 sent_clients_count = 0;
1303 SilcServerEntry *routed = NULL;
1304 SilcUInt32 routed_count = 0;
1305 SilcHashTableList htl, htl2;
1306 SilcChannelEntry channel;
1307 SilcChannelClientEntry chl, chl2;
1309 unsigned char *data;
1310 SilcUInt32 data_len;
1313 if (!silc_hash_table_count(client->channels)) {
1314 SILC_LOG_DEBUG(("Client is not joined to any channels"));
1318 SILC_LOG_DEBUG(("Sending notify to joined channels"));
1321 packet = silc_notify_payload_encode(type, argc, ap);
1326 data = packet->data;
1327 data_len = silc_buffer_len(packet);
1329 silc_hash_table_list(client->channels, &htl);
1330 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
1331 channel = chl->channel;
1333 /* Send the message to all clients on the channel's client list. */
1334 silc_hash_table_list(channel->user_list, &htl2);
1335 while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) {
1338 if (sender && c == sender)
1341 /* Check if we have sent the packet to this client already */
1342 for (k = 0; k < sent_clients_count; k++)
1343 if (sent_clients[k] == c)
1345 if (k < sent_clients_count)
1348 /* If we are router and if this client has router set it is not
1349 locally connected client and we will route the message to the
1350 router set in the client. */
1351 if (c && c->router && server->server_type == SILC_ROUTER) {
1352 /* Check if we have sent the packet to this route already */
1353 for (k = 0; k < routed_count; k++)
1354 if (routed[k] == c->router)
1356 if (k < routed_count)
1359 sock = c->router->connection;
1361 /* Send the packet */
1362 silc_server_packet_send_dest(server, sock, SILC_PACKET_NOTIFY, 0,
1363 c->router->id, SILC_ID_SERVER,
1366 /* We want to make sure that the packet is routed to same router
1367 only once. Mark this route as sent route. */
1368 routed = silc_realloc(routed, sizeof(*routed) * (routed_count + 1));
1369 routed[routed_count++] = c->router;
1376 /* Send to locally connected client */
1378 sock = c->connection;
1382 /* Send the packet */
1383 silc_server_packet_send_dest(server, sock, SILC_PACKET_NOTIFY, 0,
1384 c->id, SILC_ID_CLIENT, data, data_len);
1386 /* Make sure that we send the notify only once per client. */
1387 sent_clients = silc_realloc(sent_clients, sizeof(*sent_clients) *
1388 (sent_clients_count + 1));
1389 sent_clients[sent_clients_count++] = c;
1392 silc_hash_table_list_reset(&htl2);
1395 silc_hash_table_list_reset(&htl);
1397 silc_free(sent_clients);
1398 silc_buffer_free(packet);
1402 /* Sends New ID Payload to remote end. The packet is used to distribute
1403 information about new registered clients, servers, channel etc. usually
1404 to routers so that they can keep these information up to date.
1405 If the argument `broadcast' is TRUE then the packet is sent as
1406 broadcast packet. */
1408 void silc_server_send_new_id(SilcServer server,
1409 SilcPacketStream sock,
1411 void *id, SilcIdType id_type,
1416 SILC_LOG_DEBUG(("Sending new ID"));
1418 idp = silc_id_payload_encode(id, id_type);
1420 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID,
1421 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
1422 idp->data, silc_buffer_len(idp));
1423 silc_buffer_free(idp);
1426 /* Send New Channel Payload to notify about newly created channel in the
1427 SILC network. Router uses this to notify other routers in the network
1428 about new channel. This packet is broadcasted by router. */
1430 void silc_server_send_new_channel(SilcServer server,
1431 SilcPacketStream sock,
1435 SilcUInt32 channel_id_len,
1439 unsigned char cid[32];
1440 SilcUInt32 name_len = strlen(channel_name);
1442 SILC_LOG_DEBUG(("Sending new channel"));
1444 if (!silc_id_id2str(channel_id, SILC_ID_CHANNEL, cid, sizeof(cid),
1448 /* Encode the channel payload */
1449 packet = silc_channel_payload_encode(channel_name, name_len,
1450 cid, channel_id_len, mode);
1452 silc_server_packet_send(server, sock, SILC_PACKET_NEW_CHANNEL,
1453 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
1454 packet->data, silc_buffer_len(packet));
1456 silc_buffer_free(packet);
1459 /* Send Channel Key payload to distribute the new channel key. Normal server
1460 sends this to router when new client joins to existing channel. Router
1461 sends this to the local server who sent the join command in case where
1462 the channel did not exist yet. Both normal and router servers uses this
1463 also to send this to locally connected clients on the channel. This
1464 must not be broadcasted packet. Routers do not send this to each other.
1465 If `sender is provided then the packet is not sent to that connection since
1466 it originally came from it. */
1468 void silc_server_send_channel_key(SilcServer server,
1469 SilcPacketStream sender,
1470 SilcChannelEntry channel,
1471 unsigned char route)
1474 unsigned char cid[32];
1475 SilcUInt32 tmp_len, cid_len;
1478 SILC_LOG_DEBUG(("Sending key to channel %s", channel->channel_name));
1483 if (!silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid),
1487 /* Encode channel key packet */
1488 cipher = silc_cipher_get_name(channel->send_key);
1489 tmp_len = strlen(cipher);
1490 packet = silc_channel_key_payload_encode(cid_len, cid, tmp_len, cipher,
1491 channel->key_len / 8, channel->key);
1493 silc_server_packet_send_to_channel(server, sender, channel,
1494 SILC_PACKET_CHANNEL_KEY,
1495 route, TRUE, packet->data,
1496 silc_buffer_len(packet));
1497 silc_buffer_free(packet);
1500 /* Generic function to send any command. The arguments must be sent already
1501 encoded into correct form in correct order. */
1503 void silc_server_send_command(SilcServer server,
1504 SilcPacketStream sock,
1505 SilcCommand command,
1507 SilcUInt32 argc, ...)
1513 server->stat.commands_sent++;
1517 packet = silc_command_payload_encode_vap(command, ident, argc, ap);
1519 silc_server_packet_send(server, sock, SILC_PACKET_COMMAND, 0,
1520 packet->data, silc_buffer_len(packet));
1521 silc_buffer_free(packet);
1525 /* Generic function to send any command reply. The arguments must be sent
1526 already encoded into correct form in correct order. */
1528 void silc_server_send_command_reply(SilcServer server,
1529 SilcPacketStream sock,
1530 SilcCommand command,
1534 SilcUInt32 argc, ...)
1540 server->stat.commands_sent++;
1544 packet = silc_command_reply_payload_encode_vap(command, status, error,
1547 silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0,
1548 packet->data, silc_buffer_len(packet));
1549 silc_buffer_free(packet);
1553 /* Generic function to send any command reply. The arguments must be sent
1554 already encoded into correct form in correct order. */
1556 void silc_server_send_dest_command_reply(SilcServer server,
1557 SilcPacketStream sock,
1559 SilcIdType dst_id_type,
1560 SilcCommand command,
1564 SilcUInt32 argc, ...)
1570 server->stat.commands_sent++;
1574 packet = silc_command_reply_payload_encode_vap(command, status, error,
1577 silc_server_packet_send_dest(server, sock, SILC_PACKET_COMMAND_REPLY, 0,
1578 dst_id, dst_id_type, packet->data,
1579 silc_buffer_len(packet));
1580 silc_buffer_free(packet);
1584 /* Send the heartbeat packet. */
1586 void silc_server_send_heartbeat(SilcServer server,
1587 SilcPacketStream sock)
1589 silc_server_packet_send(server, sock, SILC_PACKET_HEARTBEAT, 0,
1593 /* Routine used to send the connection authentication packet. */
1595 void silc_server_send_connection_auth_request(SilcServer server,
1596 SilcPacketStream sock,
1597 SilcUInt16 conn_type,
1598 SilcAuthMethod auth_meth)
1602 packet = silc_buffer_alloc(4);
1606 silc_buffer_pull_tail(packet, silc_buffer_truelen(packet));
1607 silc_buffer_format(packet,
1608 SILC_STR_UI_SHORT(conn_type),
1609 SILC_STR_UI_SHORT(auth_meth),
1612 silc_server_packet_send(server, sock, SILC_PACKET_CONNECTION_AUTH_REQUEST,
1613 0, packet->data, silc_buffer_len(packet));
1614 silc_buffer_free(packet);
1617 /* Send packet to clients that are known to be operators. If server
1618 is router and `route' is TRUE then the packet would go to all operators
1619 in the SILC network. If `route' is FALSE then only local operators
1620 (local for server and cell wide for router). If `local' is TRUE then
1621 only locally connected operators receive the packet. If `local' is
1622 TRUE then `route' is ignored. If server is normal server and `route'
1623 is FALSE it is equivalent to `local' being TRUE. */
1625 void silc_server_send_opers(SilcServer server,
1626 SilcPacketType type,
1627 SilcPacketFlags flags,
1628 SilcBool route, bool local,
1629 unsigned char *data,
1630 SilcUInt32 data_len)
1633 SilcIDCacheEntry id_cache = NULL;
1634 SilcClientEntry client = NULL;
1635 SilcIDListData idata;
1636 SilcPacketStream sock;
1637 SilcServerEntry *routed = NULL;
1638 SilcUInt32 routed_count = 0;
1639 SilcBool gone = FALSE;
1642 SILC_LOG_DEBUG(("Sending %s packet to operators",
1643 silc_get_packet_name(type)));
1645 /* If local was requested send only locally connected operators. */
1646 if (local || (server->server_type == SILC_SERVER && !route)) {
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->router && SILC_IS_LOCAL(client) &&
1653 (client->mode & SILC_UMODE_SERVER_OPERATOR ||
1654 client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1656 /* Send the packet to locally connected operator */
1657 silc_server_packet_send_dest(server, client->connection, type, flags,
1658 client->id, SILC_ID_CLIENT,
1665 if (!silc_idcache_get_all(server->local_list->clients, &list))
1667 silc_list_start(list);
1668 while ((id_cache = silc_list_get(list))) {
1669 client = (SilcClientEntry)id_cache->context;
1670 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
1671 !(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1674 if (server->server_type != SILC_SERVER && client->router &&
1675 ((!route && client->router->router == server->id_entry) || route)) {
1677 /* Check if we have sent the packet to this route already */
1678 for (k = 0; k < routed_count; k++)
1679 if (routed[k] == client->router)
1681 if (k < routed_count)
1684 /* Route only once to router */
1685 sock = client->router->connection;
1686 idata = silc_packet_get_context(sock);
1687 if (idata->conn_type == SILC_CONN_ROUTER) {
1693 /* Send the packet */
1694 silc_server_packet_send_dest(server, sock, type, flags,
1695 client->id, SILC_ID_CLIENT,
1698 /* Mark this route routed already */
1699 routed = silc_realloc(routed, sizeof(*routed) * (routed_count + 1));
1700 routed[routed_count++] = client->router;
1704 if (client->router || !client->connection)
1707 /* Send to locally connected client */
1708 sock = client->connection;
1709 silc_server_packet_send_dest(server, sock, type, flags,
1710 client->id, SILC_ID_CLIENT,
1715 if (!silc_idcache_get_all(server->global_list->clients, &list))
1717 silc_list_start(list);
1718 while ((id_cache = silc_list_get(list))) {
1719 client = (SilcClientEntry)id_cache->context;
1720 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
1721 !(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1724 if (server->server_type != SILC_SERVER && client->router &&
1725 ((!route && client->router->router == server->id_entry) || route)) {
1727 /* Check if we have sent the packet to this route already */
1728 for (k = 0; k < routed_count; k++)
1729 if (routed[k] == client->router)
1731 if (k < routed_count)
1734 /* Route only once to router */
1735 sock = client->router->connection;
1736 idata = silc_packet_get_context(sock);
1737 if (idata->conn_type == SILC_CONN_ROUTER) {
1743 /* Send the packet */
1744 silc_server_packet_send_dest(server, sock, type, flags,
1745 client->id, SILC_ID_CLIENT,
1748 /* Mark this route routed already */
1749 routed = silc_realloc(routed, sizeof(*routed) * (routed_count + 1));
1750 routed[routed_count++] = client->router;
1754 if (client->router || !client->connection)
1757 /* Send to locally connected client */
1758 sock = client->connection;
1759 silc_server_packet_send_dest(server, sock, type, flags,
1760 client->id, SILC_ID_CLIENT,
1766 /* Send a notify packet to operators */
1768 void silc_server_send_opers_notify(SilcServer server,
1771 SilcNotifyType type,
1772 SilcUInt32 argc, ...)
1778 packet = silc_notify_payload_encode(type, argc, ap);
1780 silc_server_send_opers(server, SILC_PACKET_NOTIFY, 0,
1781 route, local, packet->data, silc_buffer_len(packet));
1782 silc_buffer_free(packet);