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 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,
402 SilcChannelEntry channel,
404 unsigned int data_len)
406 SilcIDListData idata;
407 SilcUInt32 mac_len, iv_len;
408 unsigned char iv[SILC_CIPHER_MAX_IV_SIZE];
409 SilcUInt16 totlen, len;
410 SilcID src_id, dst_id;
412 idata = silc_packet_get_context(sender);
414 /* If we are router and the packet came from router and private key
415 has not been set for the channel then we must encrypt the packet
416 as it was decrypted with the session key shared between us and the
417 router which sent it. This is so, because cells does not share the
419 if (server->server_type == SILC_ROUTER &&
420 idata->conn_type == SILC_CONN_ROUTER &&
421 !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY) && channel->key) {
423 /* If we are backup router and remote is our primary router and
424 we are currently doing backup resuming protocol we must not
425 re-encrypt message with session key. */
426 if (server->backup_router && idata->sconn->backup_resuming &&
427 SILC_PRIMARY_ROUTE(server) == sender)
430 mac_len = silc_hmac_len(channel->hmac);
431 iv_len = silc_cipher_get_block_len(channel->send_key);
433 if (data_len <= mac_len + iv_len) {
434 SILC_LOG_WARNING(("Corrupted channel message, cannot relay it"));
439 SILC_GET16_MSB(len, data + totlen);
441 if (totlen + iv_len + mac_len + 2 > data_len) {
442 SILC_LOG_WARNING(("Corrupted channel message, cannot relay it"));
445 SILC_GET16_MSB(len, data + totlen);
447 if (totlen + iv_len + mac_len > data_len) {
448 SILC_LOG_WARNING(("Corrupted channel message, cannot relay it"));
452 memcpy(iv, data + (data_len - iv_len - mac_len), iv_len);
454 src_id.type = SILC_ID_SERVER;
455 src_id.u.server_id = *((SilcServerEntry)idata)->id;
456 dst_id.type = SILC_ID_CHANNEL;
457 dst_id.u.channel_id = *channel->id;
459 return silc_message_payload_encrypt(data, totlen, data_len - mac_len,
460 iv, &src_id, &dst_id,
461 channel->send_key, channel->hmac);
467 /* This routine is explicitly used to relay messages to some channel.
468 Packets sent with this function we have received earlier and are
469 totally encrypted. This just sends the packet to all clients on
470 the channel. If the sender of the packet is someone on the channel
471 the message will not be sent to that client. The SILC Packet header
472 is encrypted with the session key shared between us and the client.
473 MAC is also computed before encrypting the header. Rest of the
474 packet will be untouched. */
476 void silc_server_packet_relay_to_channel(SilcServer server,
477 SilcPacketStream sender_sock,
478 SilcChannelEntry channel,
480 SilcIdType sender_type,
481 SilcClientEntry sender_entry,
485 SilcPacketStream sock = NULL;
486 SilcClientEntry client = NULL;
487 SilcServerEntry *routed = NULL;
488 SilcChannelClientEntry chl, chl_sender;
489 SilcUInt32 routed_count = 0;
490 SilcIDListData idata;
491 SilcHashTableList htl;
492 SilcBool gone = FALSE;
495 if (!silc_server_client_on_channel(sender_entry, channel, &chl_sender))
498 SILC_LOG_DEBUG(("Relaying packet to channel %s", channel->channel_name));
500 /* This encrypts the message, if needed. It will be encrypted if
501 it came from the router thus it needs to be encrypted with the
502 channel key. If the channel key does not exist, then we know we
503 don't have a single local user on the channel. */
504 if (!silc_server_packet_relay_to_channel_encrypt(server, sender_sock,
509 /* If there are global users in the channel we will send the message
510 first to our router for further routing. */
511 if (server->server_type != SILC_ROUTER && !server->standalone &&
512 channel->global_users) {
513 SilcServerEntry router = server->router;
515 /* Check that the sender is not our router. */
516 if (sender_sock != router->connection) {
517 SILC_LOG_DEBUG(("Sending message to router for routing"));
518 sock = router->connection;
519 silc_server_packet_send_srcdest(server, sock,
520 SILC_PACKET_CHANNEL_MESSAGE, 0,
521 sender_id, sender_type,
522 channel->id, SILC_ID_CHANNEL,
527 routed = silc_calloc(silc_hash_table_count(channel->user_list),
530 /* Assure we won't route the message back to the sender's way. */
531 if (sender_entry->router)
532 routed[routed_count++] = sender_entry->router;
534 /* Send the message to clients on the channel's client list. */
535 silc_hash_table_list(channel->user_list, &htl);
536 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
537 client = chl->client;
538 if (!client || client == sender_entry)
541 /* Check whether message sending is blocked */
542 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)
544 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS &&
545 !(chl_sender->mode & SILC_CHANNEL_UMODE_CHANOP) &&
546 !(chl_sender->mode & SILC_CHANNEL_UMODE_CHANFO))
548 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS &&
549 sender_entry->mode & SILC_UMODE_ROBOT)
552 /* If the client has set router it means that it is not locally
553 connected client and we will route the packet further. */
554 if (server->server_type == SILC_ROUTER && client->router) {
556 /* Check if we have sent the packet to this route already */
557 for (k = 0; k < routed_count; k++)
558 if (routed[k] == client->router)
560 if (k < routed_count)
563 /* Get data used in packet header encryption, keys and stuff. */
564 sock = client->router->connection;
565 idata = (SilcIDListData)client->router;
567 /* Check if the sender socket is the same as this client's router
569 if (sender_sock && sock == sender_sock)
572 SILC_LOG_DEBUG(("Relaying packet to client ID(%s)",
573 silc_id_render(client->id, SILC_ID_CLIENT)));
575 /* Mark this route routed already. */
576 routed[routed_count++] = client->router;
578 if (idata->conn_type == SILC_CONN_ROUTER) {
579 /* The remote connection is router then we'll decrypt the
580 channel message and re-encrypt it with the session key shared
581 between us and the remote router. This is done because the
582 channel keys are cell specific and we have different channel
583 key than the remote router has. */
585 /* Route only once to router. Protocol prohibits sending channel
586 messages to more than one router. */
591 /* If we are backup router and remote is our primary router and
592 we are currently doing backup resuming protocol we must not
593 re-encrypt message with session key. */
594 if (server->backup_router && idata->sconn->backup_resuming &&
595 SILC_PRIMARY_ROUTE(server) == sock) {
596 silc_server_packet_send_srcdest(server, sock,
597 SILC_PACKET_CHANNEL_MESSAGE, 0,
598 sender_id, sender_type,
599 channel->id, SILC_ID_CHANNEL,
604 SILC_LOG_DEBUG(("Remote is router, encrypt with session key"));
606 /* If private key mode is not set then decrypt the packet
608 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY) &&
609 channel->receive_key) {
610 unsigned char tmp[SILC_PACKET_MAX_LEN], sid[32], rid[32];
611 SilcUInt32 sid_len, rid_len;
613 if (data_len > SILC_PACKET_MAX_LEN)
614 data_len = SILC_PACKET_MAX_LEN;
615 memcpy(tmp, data, data_len);
617 /* Decrypt the channel message (we don't check the MAC) */
618 silc_id_id2str(sender_id, sender_type, sid, sizeof(sid), &sid_len);
619 silc_id_id2str(channel->id, SILC_ID_CHANNEL, rid, sizeof(rid),
621 silc_message_payload_decrypt(tmp, data_len, FALSE, FALSE,
622 channel->receive_key,
623 channel->hmac, sid, sid_len,
624 rid, rid_len, FALSE);
626 /* Now re-encrypt and send it to the router */
627 silc_server_packet_send_srcdest(server, sock,
628 SILC_PACKET_CHANNEL_MESSAGE, 0,
629 sender_id, sender_type,
630 channel->id, SILC_ID_CHANNEL,
633 /* Private key mode is set, we don't have the channel key, so
634 just re-encrypt the entire packet and send it to the router. */
635 silc_server_packet_send_srcdest(server, sock,
636 SILC_PACKET_CHANNEL_MESSAGE, 0,
637 sender_id, sender_type,
638 channel->id, SILC_ID_CHANNEL,
642 /* Send the packet to normal server */
643 silc_server_packet_send_srcdest(server, sock,
644 SILC_PACKET_CHANNEL_MESSAGE, 0,
645 sender_id, sender_type,
646 channel->id, SILC_ID_CHANNEL,
656 /* Get data used in packet header encryption, keys and stuff. */
657 sock = client->connection;
658 if (!sock || (sender_sock && sock == sender_sock))
661 SILC_LOG_DEBUG(("Sending packet to client ID(%s)",
662 silc_id_render(client->id, SILC_ID_CLIENT)));
664 /* Send the packet */
665 silc_server_packet_send_srcdest(server, sock,
666 SILC_PACKET_CHANNEL_MESSAGE, 0,
667 sender_id, sender_type,
668 channel->id, SILC_ID_CHANNEL,
672 silc_hash_table_list_reset(&htl);
676 /* This function is used to send packets strictly to all local clients
677 on a particular channel. This is used for example to distribute new
678 channel key to all our locally connected clients on the channel.
679 The packets are always encrypted with the session key shared between
680 the client, this means these are not _to the channel_ but _to the client_
683 void silc_server_packet_send_local_channel(SilcServer server,
684 SilcChannelEntry channel,
686 SilcPacketFlags flags,
690 SilcChannelClientEntry chl;
691 SilcHashTableList htl;
692 SilcPacketStream sock = NULL;
694 SILC_LOG_DEBUG(("Send packet to local clients on channel %s",
695 channel->channel_name));
697 /* Send the message to clients on the channel's client list. */
698 silc_hash_table_list(channel->user_list, &htl);
699 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
700 if (chl->client && SILC_IS_LOCAL(chl->client)) {
701 sock = chl->client->connection;
703 /* Send the packet to the client */
704 silc_server_packet_send_dest(server, sock, type, flags, chl->client->id,
705 SILC_ID_CLIENT, data, data_len);
708 silc_hash_table_list_reset(&htl);
711 /* Sends current motd to client */
713 void silc_server_send_motd(SilcServer server,
714 SilcPacketStream sock)
716 char *motd, *motd_file = NULL;
720 motd_file = server->config->server_info->motd_file;
723 motd = silc_file_readfile(motd_file, &motd_len);
728 silc_server_send_notify(server, sock, FALSE, SILC_NOTIFY_TYPE_MOTD, 1,
734 /* Sends error message. Error messages may or may not have any
737 void silc_server_send_error(SilcServer server,
738 SilcPacketStream sock,
739 const char *fmt, ...)
742 unsigned char buf[4096];
744 memset(buf, 0, sizeof(buf));
746 vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
749 silc_server_packet_send(server, sock, SILC_PACKET_ERROR, 0,
753 /* Sends notify message. If format is TRUE the variable arguments are
754 formatted and the formatted string is sent as argument payload. If it is
755 FALSE then each argument is sent as separate argument and their format
756 in the argument list must be { argument data, argument length }. */
758 void silc_server_send_notify(SilcServer server,
759 SilcPacketStream sock,
762 SilcUInt32 argc, ...)
769 packet = silc_notify_payload_encode(type, argc, ap);
770 silc_server_packet_send(server, sock, SILC_PACKET_NOTIFY,
771 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
772 packet->data, silc_buffer_len(packet));
774 /* Send to backup routers if this is being broadcasted to primary
775 router. The silc_server_backup_send checks further whether to
776 actually send it or not. */
777 if ((broadcast && sock && sock == SILC_PRIMARY_ROUTE(server)) ||
778 (broadcast && !sock && !SILC_PRIMARY_ROUTE(server)))
779 silc_server_backup_send(server, NULL, SILC_PACKET_NOTIFY, 0,
780 packet->data, silc_buffer_len(packet),
783 silc_buffer_free(packet);
787 /* Sends notify message and gets the arguments from the `args' Argument
790 void silc_server_send_notify_args(SilcServer server,
791 SilcPacketStream sock,
799 packet = silc_notify_payload_encode_args(type, argc, args);
800 silc_server_packet_send(server, sock, SILC_PACKET_NOTIFY,
801 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
802 packet->data, silc_buffer_len(packet));
803 silc_buffer_free(packet);
806 /* Send CHANNEL_CHANGE notify type. This tells the receiver to replace the
807 `old_id' with the `new_id'. */
809 void silc_server_send_notify_channel_change(SilcServer server,
810 SilcPacketStream sock,
812 SilcChannelID *old_id,
813 SilcChannelID *new_id)
815 SilcBuffer idp1, idp2;
817 idp1 = silc_id_payload_encode((void *)old_id, SILC_ID_CHANNEL);
818 idp2 = silc_id_payload_encode((void *)new_id, SILC_ID_CHANNEL);
820 silc_server_send_notify(server, sock, broadcast,
821 SILC_NOTIFY_TYPE_CHANNEL_CHANGE,
822 2, idp1->data, silc_buffer_len(idp1),
823 idp2->data, silc_buffer_len(idp2));
824 silc_buffer_free(idp1);
825 silc_buffer_free(idp2);
828 /* Send NICK_CHANGE notify type. This tells the receiver to replace the
829 `old_id' with the `new_id'. */
831 void silc_server_send_notify_nick_change(SilcServer server,
832 SilcPacketStream sock,
834 SilcClientID *old_id,
835 SilcClientID *new_id,
836 const char *nickname)
838 SilcBuffer idp1, idp2;
840 idp1 = silc_id_payload_encode((void *)old_id, SILC_ID_CLIENT);
841 idp2 = silc_id_payload_encode((void *)new_id, SILC_ID_CLIENT);
843 silc_server_send_notify(server, sock, broadcast,
844 SILC_NOTIFY_TYPE_NICK_CHANGE,
845 3, idp1->data, silc_buffer_len(idp1),
846 idp2->data, silc_buffer_len(idp2),
847 nickname, nickname ? strlen(nickname) : 0);
848 silc_buffer_free(idp1);
849 silc_buffer_free(idp2);
852 /* Sends JOIN notify type. This tells that new client by `client_id' ID
853 has joined to the `channel'. */
855 void silc_server_send_notify_join(SilcServer server,
856 SilcPacketStream sock,
858 SilcChannelEntry channel,
859 SilcClientID *client_id)
861 SilcBuffer idp1, idp2;
863 idp1 = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
864 idp2 = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
865 silc_server_send_notify(server, sock, broadcast, SILC_NOTIFY_TYPE_JOIN,
866 2, idp1->data, silc_buffer_len(idp1),
867 idp2->data, silc_buffer_len(idp2));
868 silc_buffer_free(idp1);
869 silc_buffer_free(idp2);
872 /* Sends LEAVE notify type. This tells that `client_id' has left the
873 `channel'. The Notify packet is always destined to the channel. */
875 void silc_server_send_notify_leave(SilcServer server,
876 SilcPacketStream sock,
878 SilcChannelEntry channel,
879 SilcClientID *client_id)
883 idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
884 silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
885 SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_LEAVE,
886 1, idp->data, silc_buffer_len(idp));
887 silc_buffer_free(idp);
890 /* Sends CMODE_CHANGE notify type. This tells that `client_id' changed the
891 `channel' mode to `mode. The Notify packet is always destined to
894 void silc_server_send_notify_cmode(SilcServer server,
895 SilcPacketStream sock,
897 SilcChannelEntry channel,
898 SilcUInt32 mode_mask,
899 void *id, SilcIdType id_type,
900 const char *cipher, const char *hmac,
901 const char *passphrase,
902 SilcPublicKey founder_key,
903 SilcBuffer channel_pubkeys)
905 SilcBuffer idp, fkey = NULL;
906 unsigned char mode[4], ulimit[4];
908 idp = silc_id_payload_encode((void *)id, id_type);
909 SILC_PUT32_MSB(mode_mask, mode);
911 fkey = silc_public_key_payload_encode(founder_key);
912 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
913 SILC_PUT32_MSB(channel->user_limit, ulimit);
915 silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
916 SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_CMODE_CHANGE,
917 8, idp->data, silc_buffer_len(idp),
919 cipher, cipher ? strlen(cipher) : 0,
920 hmac, hmac ? strlen(hmac) : 0,
921 passphrase, passphrase ?
922 strlen(passphrase) : 0,
923 fkey ? fkey->data : NULL,
924 fkey ? silc_buffer_len(fkey) : 0,
925 channel_pubkeys ? channel_pubkeys->data : NULL,
927 silc_buffer_len(channel_pubkeys) : 0,
928 mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
930 mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
932 silc_buffer_free(fkey);
933 silc_buffer_free(idp);
936 /* Sends CUMODE_CHANGE notify type. This tells that `id' changed the
937 `target' client's mode on `channel'. The notify packet is always
938 destined to the channel. */
940 void silc_server_send_notify_cumode(SilcServer server,
941 SilcPacketStream sock,
943 SilcChannelEntry channel,
944 SilcUInt32 mode_mask,
945 void *id, SilcIdType id_type,
946 SilcClientID *target,
947 SilcPublicKey founder_key)
949 SilcBuffer idp1, idp2, fkey = NULL;
950 unsigned char mode[4];
952 idp1 = silc_id_payload_encode((void *)id, id_type);
953 idp2 = silc_id_payload_encode((void *)target, SILC_ID_CLIENT);
954 SILC_PUT32_MSB(mode_mask, mode);
956 fkey = silc_public_key_payload_encode(founder_key);
958 silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
960 SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
961 idp1->data, silc_buffer_len(idp1),
963 idp2->data, silc_buffer_len(idp2),
964 fkey ? fkey->data : NULL,
965 fkey ? silc_buffer_len(fkey) : 0);
966 silc_buffer_free(fkey);
967 silc_buffer_free(idp1);
968 silc_buffer_free(idp2);
971 /* Sends SIGNOFF notify type. This tells that `client_id' client has
972 left SILC network. This function is used only between server and router
973 traffic. This is not used to send the notify to the channel for
974 client. The `message may be NULL. */
976 void silc_server_send_notify_signoff(SilcServer server,
977 SilcPacketStream sock,
979 SilcClientID *client_id,
984 idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
985 silc_server_send_notify(server, sock, broadcast,
986 SILC_NOTIFY_TYPE_SIGNOFF,
987 message ? 2 : 1, idp->data, silc_buffer_len(idp),
988 message, message ? strlen(message): 0);
989 silc_buffer_free(idp);
992 /* Sends TOPIC_SET notify type. This tells that `id' changed
993 the `channel's topic to `topic'. The Notify packet is always destined
994 to the channel. This function is used to send the topic set notifies
997 void silc_server_send_notify_topic_set(SilcServer server,
998 SilcPacketStream sock,
1000 SilcChannelEntry channel,
1001 void *id, SilcIdType id_type,
1006 idp = silc_id_payload_encode(id, id_type);
1007 silc_server_send_notify_dest(server, sock, broadcast,
1008 (void *)channel->id, SILC_ID_CHANNEL,
1009 SILC_NOTIFY_TYPE_TOPIC_SET,
1011 idp->data, silc_buffer_len(idp),
1012 topic, topic ? strlen(topic) : 0);
1013 silc_buffer_free(idp);
1016 /* Send KICKED notify type. This tells that the `client_id' on `channel'
1017 was kicked off the channel. The `comment' may indicate the reason
1018 for the kicking. This function is used only between server and router
1021 void silc_server_send_notify_kicked(SilcServer server,
1022 SilcPacketStream sock,
1024 SilcChannelEntry channel,
1025 SilcClientID *client_id,
1026 SilcClientID *kicker,
1032 idp1 = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
1033 idp2 = silc_id_payload_encode((void *)kicker, SILC_ID_CLIENT);
1034 silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
1035 SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_KICKED, 3,
1036 idp1->data, silc_buffer_len(idp1),
1037 comment, comment ? strlen(comment) : 0,
1038 idp2->data, silc_buffer_len(idp2));
1039 silc_buffer_free(idp1);
1040 silc_buffer_free(idp2);
1043 /* Send KILLED notify type. This tells that the `client_id' client was
1044 killed from the network. The `comment' may indicate the reason
1047 void silc_server_send_notify_killed(SilcServer server,
1048 SilcPacketStream sock,
1050 SilcClientID *client_id,
1051 const char *comment,
1052 void *killer, SilcIdType killer_type)
1057 idp1 = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1058 idp2 = silc_id_payload_encode(killer, killer_type);
1059 silc_server_send_notify_dest(server, sock, broadcast, (void *)client_id,
1060 SILC_ID_CLIENT, SILC_NOTIFY_TYPE_KILLED,
1061 3, idp1->data, silc_buffer_len(idp1),
1062 comment, comment ? strlen(comment) : 0,
1063 idp2->data, silc_buffer_len(idp2));
1064 silc_buffer_free(idp1);
1065 silc_buffer_free(idp2);
1068 /* Sends UMODE_CHANGE notify type. This tells that `client_id' client's
1069 user mode in the SILC Network was changed. This function is used to
1070 send the packet between routers as broadcast packet. */
1072 void silc_server_send_notify_umode(SilcServer server,
1073 SilcPacketStream sock,
1075 SilcClientID *client_id,
1076 SilcUInt32 mode_mask)
1079 unsigned char mode[4];
1081 idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
1082 SILC_PUT32_MSB(mode_mask, mode);
1084 silc_server_send_notify(server, sock, broadcast,
1085 SILC_NOTIFY_TYPE_UMODE_CHANGE, 2,
1086 idp->data, silc_buffer_len(idp),
1088 silc_buffer_free(idp);
1091 /* Sends BAN notify type. This tells that ban has been either `add'ed
1092 or `del'eted on the `channel. This function is used to send the packet
1093 between routers as broadcast packet. */
1095 void silc_server_send_notify_ban(SilcServer server,
1096 SilcPacketStream sock,
1098 SilcChannelEntry channel,
1099 unsigned char *action,
1104 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
1105 silc_server_send_notify(server, sock, broadcast,
1106 SILC_NOTIFY_TYPE_BAN, 3,
1107 idp->data, silc_buffer_len(idp),
1108 action ? action : NULL, action ? 1 : 0,
1109 list ? list->data : NULL,
1110 list ? silc_buffer_len(list) : 0);
1111 silc_buffer_free(idp);
1114 /* Sends INVITE notify type. This tells that invite has been either `add'ed
1115 or `del'eted on the `channel. The sender of the invite is the `client_id'.
1116 This function is used to send the packet between routers as broadcast
1119 void silc_server_send_notify_invite(SilcServer server,
1120 SilcPacketStream sock,
1122 SilcChannelEntry channel,
1123 SilcClientID *client_id,
1124 unsigned char *action,
1127 SilcBuffer idp, idp2;
1129 idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
1130 idp2 = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
1131 silc_server_send_notify(server, sock, broadcast,
1132 SILC_NOTIFY_TYPE_INVITE, 5,
1133 idp->data, silc_buffer_len(idp),
1134 channel->channel_name, strlen(channel->channel_name),
1135 idp2->data, silc_buffer_len(idp2),
1136 action ? action : NULL, action ? 1 : 0,
1137 list ? list->data : NULL,
1138 list ? silc_buffer_len(list) : 0);
1139 silc_buffer_free(idp);
1140 silc_buffer_free(idp2);
1143 /* Sends WATCH notify type. This tells that the `client' was watched and
1144 its status in the network has changed. */
1146 void silc_server_send_notify_watch(SilcServer server,
1147 SilcPacketStream sock,
1148 SilcClientEntry watcher,
1149 SilcClientEntry client,
1150 const char *nickname,
1151 SilcNotifyType type,
1152 SilcPublicKey public_key)
1154 SilcBuffer idp, pkp = NULL;
1155 unsigned char mode[4], n[2];
1157 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
1158 SILC_PUT16_MSB(type, n);
1159 SILC_PUT32_MSB(client->mode, mode);
1161 pkp = silc_public_key_payload_encode(public_key);
1162 silc_server_send_notify_dest(server, sock, FALSE, watcher->id,
1163 SILC_ID_CLIENT, SILC_NOTIFY_TYPE_WATCH,
1164 5, idp->data, silc_buffer_len(idp),
1165 nickname, nickname ? strlen(nickname) : 0,
1167 type != SILC_NOTIFY_TYPE_NONE ?
1168 n : NULL, sizeof(n),
1169 pkp ? pkp->data : NULL,
1170 pkp ? silc_buffer_len(pkp) : 0);
1171 silc_buffer_free(idp);
1172 silc_buffer_free(pkp);
1175 /* Sends notify message destined to specific entity. */
1177 void silc_server_send_notify_dest(SilcServer server,
1178 SilcPacketStream sock,
1181 SilcIdType dest_id_type,
1182 SilcNotifyType type,
1183 SilcUInt32 argc, ...)
1190 packet = silc_notify_payload_encode(type, argc, ap);
1191 silc_server_packet_send_dest(server, sock, SILC_PACKET_NOTIFY,
1192 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
1193 dest_id, dest_id_type,
1194 packet->data, silc_buffer_len(packet));
1196 /* Send to backup routers if this is being broadcasted to primary
1197 router. The silc_server_backup_send checks further whether to
1198 actually send it or not. */
1199 if ((broadcast && sock && sock == SILC_PRIMARY_ROUTE(server)) ||
1200 (broadcast && !sock && !SILC_PRIMARY_ROUTE(server)))
1201 silc_server_backup_send_dest(server, NULL, SILC_PACKET_NOTIFY, 0,
1202 dest_id, dest_id_type,
1203 packet->data, silc_buffer_len(packet),
1206 silc_buffer_free(packet);
1210 /* Sends notify message to a channel. The notify message sent is
1211 distributed to all clients on the channel. If `route_notify' is TRUE
1212 then the notify may be routed to primary route or to some other routers.
1213 If FALSE it is assured that the notify is sent only locally. If `sender'
1214 is provided then the packet is not sent to that connection since it
1215 originally came from it. */
1217 void silc_server_send_notify_to_channel(SilcServer server,
1218 SilcPacketStream sender,
1219 SilcChannelEntry channel,
1220 SilcBool route_notify,
1221 SilcBool send_to_clients,
1222 SilcNotifyType type,
1223 SilcUInt32 argc, ...)
1230 packet = silc_notify_payload_encode(type, argc, ap);
1231 silc_server_packet_send_to_channel(server, sender, channel,
1232 SILC_PACKET_NOTIFY, route_notify,
1234 packet->data, silc_buffer_len(packet));
1235 silc_buffer_free(packet);
1239 /* Send notify message to all channels the client has joined. It is quaranteed
1240 that the message is sent only once to a client (ie. if a client is joined
1241 on two same channel it will receive only one notify message). Also, this
1242 sends only to local clients (locally connected if we are server, and to
1243 local servers if we are router). If `sender' is provided the packet is
1244 not sent to that client at all. */
1246 void silc_server_send_notify_on_channels(SilcServer server,
1247 SilcClientEntry sender,
1248 SilcClientEntry client,
1249 SilcNotifyType type,
1250 SilcUInt32 argc, ...)
1253 SilcPacketStream sock = NULL;
1255 SilcClientEntry *sent_clients = NULL;
1256 SilcUInt32 sent_clients_count = 0;
1257 SilcServerEntry *routed = NULL;
1258 SilcUInt32 routed_count = 0;
1259 SilcHashTableList htl, htl2;
1260 SilcChannelEntry channel;
1261 SilcChannelClientEntry chl, chl2;
1263 unsigned char *data;
1264 SilcUInt32 data_len;
1267 if (!silc_hash_table_count(client->channels)) {
1268 SILC_LOG_DEBUG(("Client is not joined to any channels"));
1272 SILC_LOG_DEBUG(("Sending notify to joined channels"));
1275 packet = silc_notify_payload_encode(type, argc, ap);
1276 data = packet->data;
1277 data_len = silc_buffer_len(packet);
1279 silc_hash_table_list(client->channels, &htl);
1280 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
1281 channel = chl->channel;
1283 /* Send the message to all clients on the channel's client list. */
1284 silc_hash_table_list(channel->user_list, &htl2);
1285 while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) {
1288 if (sender && c == sender)
1291 /* Check if we have sent the packet to this client already */
1292 for (k = 0; k < sent_clients_count; k++)
1293 if (sent_clients[k] == c)
1295 if (k < sent_clients_count)
1298 /* If we are router and if this client has router set it is not
1299 locally connected client and we will route the message to the
1300 router set in the client. */
1301 if (c && c->router && server->server_type == SILC_ROUTER) {
1302 /* Check if we have sent the packet to this route already */
1303 for (k = 0; k < routed_count; k++)
1304 if (routed[k] == c->router)
1306 if (k < routed_count)
1309 sock = c->router->connection;
1311 /* Send the packet */
1312 silc_server_packet_send_dest(server, sock, SILC_PACKET_NOTIFY, 0,
1313 c->router->id, SILC_ID_SERVER,
1316 /* We want to make sure that the packet is routed to same router
1317 only once. Mark this route as sent route. */
1318 routed = silc_realloc(routed, sizeof(*routed) * (routed_count + 1));
1319 routed[routed_count++] = c->router;
1326 /* Send to locally connected client */
1328 sock = c->connection;
1332 /* Send the packet */
1333 silc_server_packet_send_dest(server, sock, SILC_PACKET_NOTIFY, 0,
1334 c->id, SILC_ID_CLIENT, data, data_len);
1336 /* Make sure that we send the notify only once per client. */
1337 sent_clients = silc_realloc(sent_clients, sizeof(*sent_clients) *
1338 (sent_clients_count + 1));
1339 sent_clients[sent_clients_count++] = c;
1342 silc_hash_table_list_reset(&htl2);
1345 silc_hash_table_list_reset(&htl);
1347 silc_free(sent_clients);
1348 silc_buffer_free(packet);
1352 /* Sends New ID Payload to remote end. The packet is used to distribute
1353 information about new registered clients, servers, channel etc. usually
1354 to routers so that they can keep these information up to date.
1355 If the argument `broadcast' is TRUE then the packet is sent as
1356 broadcast packet. */
1358 void silc_server_send_new_id(SilcServer server,
1359 SilcPacketStream sock,
1361 void *id, SilcIdType id_type,
1366 SILC_LOG_DEBUG(("Sending new ID"));
1368 idp = silc_id_payload_encode(id, id_type);
1369 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID,
1370 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
1371 idp->data, silc_buffer_len(idp));
1372 silc_buffer_free(idp);
1375 /* Send New Channel Payload to notify about newly created channel in the
1376 SILC network. Router uses this to notify other routers in the network
1377 about new channel. This packet is broadcasted by router. */
1379 void silc_server_send_new_channel(SilcServer server,
1380 SilcPacketStream sock,
1384 SilcUInt32 channel_id_len,
1388 unsigned char cid[32];
1389 SilcUInt32 name_len = strlen(channel_name);
1391 SILC_LOG_DEBUG(("Sending new channel"));
1393 if (!silc_id_id2str(channel_id, SILC_ID_CHANNEL, cid, sizeof(cid),
1397 /* Encode the channel payload */
1398 packet = silc_channel_payload_encode(channel_name, name_len,
1399 cid, channel_id_len, mode);
1401 silc_server_packet_send(server, sock, SILC_PACKET_NEW_CHANNEL,
1402 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
1403 packet->data, silc_buffer_len(packet));
1405 silc_buffer_free(packet);
1408 /* Send Channel Key payload to distribute the new channel key. Normal server
1409 sends this to router when new client joins to existing channel. Router
1410 sends this to the local server who sent the join command in case where
1411 the channel did not exist yet. Both normal and router servers uses this
1412 also to send this to locally connected clients on the channel. This
1413 must not be broadcasted packet. Routers do not send this to each other.
1414 If `sender is provided then the packet is not sent to that connection since
1415 it originally came from it. */
1417 void silc_server_send_channel_key(SilcServer server,
1418 SilcPacketStream sender,
1419 SilcChannelEntry channel,
1420 unsigned char route)
1423 unsigned char cid[32];
1424 SilcUInt32 tmp_len, cid_len;
1427 SILC_LOG_DEBUG(("Sending key to channel %s", channel->channel_name));
1432 if (!silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid),
1436 /* Encode channel key packet */
1437 cipher = silc_cipher_get_name(channel->send_key);
1438 tmp_len = strlen(cipher);
1439 packet = silc_channel_key_payload_encode(cid_len, cid, tmp_len, cipher,
1440 channel->key_len / 8, channel->key);
1441 silc_server_packet_send_to_channel(server, sender, channel,
1442 SILC_PACKET_CHANNEL_KEY,
1443 route, TRUE, packet->data,
1444 silc_buffer_len(packet));
1445 silc_buffer_free(packet);
1448 /* Generic function to send any command. The arguments must be sent already
1449 encoded into correct form in correct order. */
1451 void silc_server_send_command(SilcServer server,
1452 SilcPacketStream sock,
1453 SilcCommand command,
1455 SilcUInt32 argc, ...)
1461 server->stat.commands_sent++;
1465 packet = silc_command_payload_encode_vap(command, ident, argc, ap);
1466 silc_server_packet_send(server, sock, SILC_PACKET_COMMAND, 0,
1467 packet->data, silc_buffer_len(packet));
1468 silc_buffer_free(packet);
1472 /* Generic function to send any command reply. The arguments must be sent
1473 already encoded into correct form in correct order. */
1475 void silc_server_send_command_reply(SilcServer server,
1476 SilcPacketStream sock,
1477 SilcCommand command,
1481 SilcUInt32 argc, ...)
1487 server->stat.commands_sent++;
1491 packet = silc_command_reply_payload_encode_vap(command, status, error,
1493 silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0,
1494 packet->data, silc_buffer_len(packet));
1495 silc_buffer_free(packet);
1499 /* Generic function to send any command reply. The arguments must be sent
1500 already encoded into correct form in correct order. */
1502 void silc_server_send_dest_command_reply(SilcServer server,
1503 SilcPacketStream sock,
1505 SilcIdType dst_id_type,
1506 SilcCommand command,
1510 SilcUInt32 argc, ...)
1516 server->stat.commands_sent++;
1520 packet = silc_command_reply_payload_encode_vap(command, status, error,
1522 silc_server_packet_send_dest(server, sock, SILC_PACKET_COMMAND_REPLY, 0,
1523 dst_id, dst_id_type, packet->data,
1524 silc_buffer_len(packet));
1525 silc_buffer_free(packet);
1529 /* Routine used to send the connection authentication packet. */
1531 void silc_server_send_connection_auth_request(SilcServer server,
1532 SilcPacketStream sock,
1533 SilcUInt16 conn_type,
1534 SilcAuthMethod auth_meth)
1538 packet = silc_buffer_alloc(4);
1539 silc_buffer_pull_tail(packet, silc_buffer_truelen(packet));
1540 silc_buffer_format(packet,
1541 SILC_STR_UI_SHORT(conn_type),
1542 SILC_STR_UI_SHORT(auth_meth),
1545 silc_server_packet_send(server, sock, SILC_PACKET_CONNECTION_AUTH_REQUEST,
1546 0, packet->data, silc_buffer_len(packet));
1547 silc_buffer_free(packet);
1550 /* Send packet to clients that are known to be operators. If server
1551 is router and `route' is TRUE then the packet would go to all operators
1552 in the SILC network. If `route' is FALSE then only local operators
1553 (local for server and cell wide for router). If `local' is TRUE then
1554 only locally connected operators receive the packet. If `local' is
1555 TRUE then `route' is ignored. If server is normal server and `route'
1556 is FALSE it is equivalent to `local' being TRUE. */
1558 void silc_server_send_opers(SilcServer server,
1559 SilcPacketType type,
1560 SilcPacketFlags flags,
1561 SilcBool route, bool local,
1562 unsigned char *data,
1563 SilcUInt32 data_len)
1566 SilcIDCacheEntry id_cache = NULL;
1567 SilcClientEntry client = NULL;
1568 SilcIDListData idata;
1569 SilcPacketStream sock;
1570 SilcServerEntry *routed = NULL;
1571 SilcUInt32 routed_count = 0;
1572 SilcBool gone = FALSE;
1575 SILC_LOG_DEBUG(("Sending %s packet to operators",
1576 silc_get_packet_name(type)));
1578 /* If local was requested send only locally connected operators. */
1579 if (local || (server->server_type == SILC_SERVER && !route)) {
1580 if (!silc_idcache_get_all(server->local_list->clients, &list))
1582 silc_list_start(list);
1583 while ((id_cache = silc_list_get(list))) {
1584 client = (SilcClientEntry)id_cache->context;
1585 if (!client->router && SILC_IS_LOCAL(client) &&
1586 (client->mode & SILC_UMODE_SERVER_OPERATOR ||
1587 client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1589 /* Send the packet to locally connected operator */
1590 silc_server_packet_send_dest(server, client->connection, type, flags,
1591 client->id, SILC_ID_CLIENT,
1598 if (!silc_idcache_get_all(server->local_list->clients, &list))
1600 silc_list_start(list);
1601 while ((id_cache = silc_list_get(list))) {
1602 client = (SilcClientEntry)id_cache->context;
1603 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
1604 !(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1607 if (server->server_type != SILC_SERVER && client->router &&
1608 ((!route && client->router->router == server->id_entry) || route)) {
1610 /* Check if we have sent the packet to this route already */
1611 for (k = 0; k < routed_count; k++)
1612 if (routed[k] == client->router)
1614 if (k < routed_count)
1617 /* Route only once to router */
1618 sock = client->router->connection;
1619 idata = silc_packet_get_context(sock);
1620 if (idata->conn_type == SILC_CONN_ROUTER) {
1626 /* Send the packet */
1627 silc_server_packet_send_dest(server, sock, type, flags,
1628 client->id, SILC_ID_CLIENT,
1631 /* Mark this route routed already */
1632 routed = silc_realloc(routed, sizeof(*routed) * (routed_count + 1));
1633 routed[routed_count++] = client->router;
1637 if (client->router || !client->connection)
1640 /* Send to locally connected client */
1641 sock = client->connection;
1642 silc_server_packet_send_dest(server, sock, type, flags,
1643 client->id, SILC_ID_CLIENT,
1648 if (!silc_idcache_get_all(server->global_list->clients, &list))
1650 silc_list_start(list);
1651 while ((id_cache = silc_list_get(list))) {
1652 client = (SilcClientEntry)id_cache->context;
1653 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
1654 !(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1657 if (server->server_type != SILC_SERVER && client->router &&
1658 ((!route && client->router->router == server->id_entry) || route)) {
1660 /* Check if we have sent the packet to this route already */
1661 for (k = 0; k < routed_count; k++)
1662 if (routed[k] == client->router)
1664 if (k < routed_count)
1667 /* Route only once to router */
1668 sock = client->router->connection;
1669 idata = silc_packet_get_context(sock);
1670 if (idata->conn_type == SILC_CONN_ROUTER) {
1676 /* Send the packet */
1677 silc_server_packet_send_dest(server, sock, type, flags,
1678 client->id, SILC_ID_CLIENT,
1681 /* Mark this route routed already */
1682 routed = silc_realloc(routed, sizeof(*routed) * (routed_count + 1));
1683 routed[routed_count++] = client->router;
1687 if (client->router || !client->connection)
1690 /* Send to locally connected client */
1691 sock = client->connection;
1692 silc_server_packet_send_dest(server, sock, type, flags,
1693 client->id, SILC_ID_CLIENT,
1699 /* Send a notify packet to operators */
1701 void silc_server_send_opers_notify(SilcServer server,
1704 SilcNotifyType type,
1705 SilcUInt32 argc, ...)
1711 packet = silc_notify_payload_encode(type, argc, ap);
1712 silc_server_send_opers(server, SILC_PACKET_NOTIFY, 0,
1713 route, local, packet->data, silc_buffer_len(packet));
1714 silc_buffer_free(packet);