5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2000 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; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
21 * Server packet routines to send packets.
25 #include "serverincludes.h"
26 #include "server_internal.h"
28 /* Routine that sends packet or marks packet to be sent. This is used
29 directly only in special cases. Normal cases should use
30 silc_server_packet_send. Returns < 0 error. */
32 int silc_server_packet_send_real(SilcServer server,
33 SilcSocketConnection sock,
39 ret = silc_packet_send(sock, force_send);
43 /* Mark that there is some outgoing data available for this connection.
44 This call sets the connection both for input and output (the input
45 is set always and this call keeps the input setting, actually).
46 Actual data sending is performed by silc_server_packet_process. */
47 SILC_SET_CONNECTION_FOR_OUTPUT(sock->sock);
49 /* Mark to socket that data is pending in outgoing buffer. This flag
50 is needed if new data is added to the buffer before the earlier
51 put data is sent to the network. */
52 SILC_SET_OUTBUF_PENDING(sock);
57 /* Assembles a new packet to be sent out to network. This doesn't actually
58 send the packet but creates the packet and fills the outgoing data
59 buffer and marks the packet ready to be sent to network. However, If
60 argument force_send is TRUE the packet is sent immediately and not put
61 to queue. Normal case is that the packet is not sent immediately. */
63 void silc_server_packet_send(SilcServer server,
64 SilcSocketConnection sock,
66 SilcPacketFlags flags,
68 unsigned int data_len,
72 SilcIdType dst_id_type = SILC_ID_NONE;
77 /* Get data used in the packet sending, keys and stuff */
79 case SILC_SOCKET_TYPE_CLIENT:
80 dst_id = ((SilcClientEntry)sock->user_data)->id;
81 dst_id_type = SILC_ID_CLIENT;
83 case SILC_SOCKET_TYPE_SERVER:
84 case SILC_SOCKET_TYPE_ROUTER:
85 dst_id = ((SilcServerEntry)sock->user_data)->id;
86 dst_id_type = SILC_ID_SERVER;
92 silc_server_packet_send_dest(server, sock, type, flags, dst_id,
93 dst_id_type, data, data_len, force_send);
96 /* Assembles a new packet to be sent out to network. This doesn't actually
97 send the packet but creates the packet and fills the outgoing data
98 buffer and marks the packet ready to be sent to network. However, If
99 argument force_send is TRUE the packet is sent immediately and not put
100 to queue. Normal case is that the packet is not sent immediately.
101 Destination information is sent as argument for this function. */
103 void silc_server_packet_send_dest(SilcServer server,
104 SilcSocketConnection sock,
106 SilcPacketFlags flags,
108 SilcIdType dst_id_type,
110 unsigned int data_len,
113 SilcPacketContext packetdata;
114 SilcIDListData idata;
115 SilcCipher cipher = NULL;
116 SilcHmac hmac = NULL;
117 unsigned char *dst_id_data = NULL;
118 unsigned int dst_id_len = 0;
120 SILC_LOG_DEBUG(("Sending packet, type %d", type));
122 /* Get data used in the packet sending, keys and stuff */
123 idata = (SilcIDListData)sock->user_data;
126 dst_id_data = silc_id_id2str(dst_id, dst_id_type);
127 dst_id_len = silc_id_get_len(dst_id_type);
130 /* Set the packet context pointers */
131 packetdata.type = type;
132 packetdata.flags = flags;
133 packetdata.src_id = silc_id_id2str(server->id, server->id_type);
134 packetdata.src_id_len = SILC_ID_SERVER_LEN;
135 packetdata.src_id_type = server->id_type;
136 packetdata.dst_id = dst_id_data;
137 packetdata.dst_id_len = dst_id_len;
138 packetdata.dst_id_type = dst_id_type;
139 packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
140 packetdata.src_id_len + dst_id_len;
141 packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
142 packetdata.rng = server->rng;
144 /* Prepare outgoing data buffer for packet sending */
145 silc_packet_send_prepare(sock,
146 SILC_PACKET_HEADER_LEN +
147 packetdata.src_id_len +
148 packetdata.dst_id_len,
152 SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len));
154 packetdata.buffer = sock->outbuf;
156 /* Put the data to the buffer */
157 if (data && data_len)
158 silc_buffer_put(sock->outbuf, data, data_len);
160 /* Create the outgoing packet */
161 silc_packet_assemble(&packetdata);
164 cipher = idata->send_key;
168 /* Encrypt the packet */
169 silc_packet_encrypt(cipher, hmac, sock->outbuf, sock->outbuf->len);
171 SILC_LOG_HEXDUMP(("Outgoing packet, len %d", sock->outbuf->len),
172 sock->outbuf->data, sock->outbuf->len);
174 /* Now actually send the packet */
175 silc_server_packet_send_real(server, sock, force_send);
177 if (packetdata.src_id)
178 silc_free(packetdata.src_id);
179 if (packetdata.dst_id)
180 silc_free(packetdata.dst_id);
183 /* Forwards packet. Packets sent with this function will be marked as
184 forwarded (in the SILC header flags) so that the receiver knows that
185 we have forwarded the packet to it. Forwarded packets are handled
186 specially by the receiver as they are not destined to the receiver
187 originally. However, the receiver knows this because the forwarded
188 flag has been set (and the flag is authenticated). */
190 void silc_server_packet_forward(SilcServer server,
191 SilcSocketConnection sock,
192 unsigned char *data, unsigned int data_len,
195 SilcIDListData idata;
196 SilcCipher cipher = NULL;
197 SilcHmac hmac = NULL;
199 SILC_LOG_DEBUG(("Forwarding packet"));
201 /* Get data used in the packet sending, keys and stuff */
202 idata = (SilcIDListData)sock->user_data;
204 /* Prepare outgoing data buffer for packet sending */
205 silc_packet_send_prepare(sock, 0, 0, data_len);
207 /* Put the data to the buffer */
208 if (data && data_len)
209 silc_buffer_put(sock->outbuf, data, data_len);
211 /* Add the FORWARDED flag to packet flags */
212 sock->outbuf->data[2] |= (unsigned char)SILC_PACKET_FLAG_FORWARDED;
215 cipher = idata->send_key;
219 /* Encrypt the packet */
220 silc_packet_encrypt(cipher, hmac, sock->outbuf, sock->outbuf->len);
222 SILC_LOG_HEXDUMP(("Forwarded packet, len %d", sock->outbuf->len),
223 sock->outbuf->data, sock->outbuf->len);
225 /* Now actually send the packet */
226 silc_server_packet_send_real(server, sock, force_send);
229 /* Broadcast received packet to our primary route. This function is used
230 by router to further route received broadcast packet. It is expected
231 that the broadcast flag from the packet is checked before calling this
232 function. This does not test or set the broadcast flag. */
234 void silc_server_packet_broadcast(SilcServer server,
235 SilcSocketConnection sock,
236 SilcPacketContext *packet)
238 SilcBuffer buffer = packet->buffer;
239 SilcIDListData idata;
242 SILC_LOG_DEBUG(("Broadcasting received broadcast packet"));
244 /* If the packet is originated from our primary route we are
245 not allowed to send the packet. */
246 id = silc_id_str2id(packet->src_id, packet->src_id_type);
247 if (id && SILC_ID_SERVER_COMPARE(id, server->router->id)) {
248 idata = (SilcIDListData)sock->user_data;
250 silc_buffer_push(buffer, buffer->data - buffer->head);
251 silc_packet_send_prepare(sock, 0, 0, buffer->len);
252 silc_buffer_put(sock->outbuf, buffer->data, buffer->len);
253 silc_packet_encrypt(idata->send_key, idata->hmac,
254 sock->outbuf, sock->outbuf->len);
256 SILC_LOG_HEXDUMP(("Broadcasted packet, len %d", sock->outbuf->len),
257 sock->outbuf->data, sock->outbuf->len);
259 /* Now actually send the packet */
260 silc_server_packet_send_real(server, sock, TRUE);
265 SILC_LOG_DEBUG(("Will not broadcast to primary route since it is the "
266 "original sender of this packet"));
270 /* Routes received packet to `sock'. This is used to route the packets that
271 router receives but are not destined to it. */
273 void silc_server_packet_route(SilcServer server,
274 SilcSocketConnection sock,
275 SilcPacketContext *packet)
277 SilcBuffer buffer = packet->buffer;
278 SilcIDListData idata;
280 SILC_LOG_DEBUG(("Routing received packet"));
282 idata = (SilcIDListData)sock->user_data;
284 silc_buffer_push(buffer, buffer->data - buffer->head);
285 silc_packet_send_prepare(sock, 0, 0, buffer->len);
286 silc_buffer_put(sock->outbuf, buffer->data, buffer->len);
287 silc_packet_encrypt(idata->send_key, idata->hmac,
288 sock->outbuf, sock->outbuf->len);
290 SILC_LOG_HEXDUMP(("Routed packet, len %d", sock->outbuf->len),
291 sock->outbuf->data, sock->outbuf->len);
293 /* Now actually send the packet */
294 silc_server_packet_send_real(server, sock, TRUE);
297 /* Internal routine to actually create the channel packet and send it
298 to network. This is common function in channel message sending. If
299 `channel_message' is TRUE this encrypts the message as it is strictly
300 a channel message. If FALSE normal encryption process is used. */
303 silc_server_packet_send_to_channel_real(SilcServer server,
304 SilcSocketConnection sock,
305 SilcPacketContext *packet,
309 unsigned int data_len,
313 packet->truelen = data_len + SILC_PACKET_HEADER_LEN +
314 packet->src_id_len + packet->dst_id_len;
316 /* Prepare outgoing data buffer for packet sending */
317 silc_packet_send_prepare(sock,
318 SILC_PACKET_HEADER_LEN +
324 packet->buffer = sock->outbuf;
326 /* Put the data to buffer, assemble and encrypt the packet. The packet
327 is encrypted with normal session key shared with the client. */
328 silc_buffer_put(sock->outbuf, data, data_len);
329 silc_packet_assemble(packet);
331 silc_packet_encrypt(cipher, hmac, sock->outbuf, SILC_PACKET_HEADER_LEN +
332 packet->src_id_len + packet->dst_id_len +
335 silc_packet_encrypt(cipher, hmac, sock->outbuf, sock->outbuf->len);
337 SILC_LOG_HEXDUMP(("Channel packet, len %d", sock->outbuf->len),
338 sock->outbuf->data, sock->outbuf->len);
340 /* Now actually send the packet */
341 silc_server_packet_send_real(server, sock, force_send);
344 /* This routine is used by the server to send packets to channel. The
345 packet sent with this function is distributed to all clients on
346 the channel. Usually this is used to send notify messages to the
347 channel, things like notify about new user joining to the channel.
348 If `route' is FALSE then the packet is sent only locally and will not
349 be routed anywhere (for router locally means cell wide). */
351 void silc_server_packet_send_to_channel(SilcServer server,
352 SilcChannelEntry channel,
356 unsigned int data_len,
359 SilcSocketConnection sock = NULL;
360 SilcPacketContext packetdata;
361 SilcClientEntry client = NULL;
362 SilcServerEntry *routed = NULL;
363 SilcChannelClientEntry chl;
364 SilcIDListData idata;
365 unsigned int routed_count = 0;
367 /* This doesn't send channel message packets */
368 if (type == SILC_PACKET_CHANNEL_MESSAGE)
371 SILC_LOG_DEBUG(("Sending packet to channel"));
373 /* Set the packet context pointers. */
374 packetdata.flags = 0;
375 packetdata.type = type;
376 packetdata.src_id = silc_id_id2str(server->id, SILC_ID_SERVER);
377 packetdata.src_id_len = SILC_ID_SERVER_LEN;
378 packetdata.src_id_type = SILC_ID_SERVER;
379 packetdata.dst_id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
380 packetdata.dst_id_len = SILC_ID_CHANNEL_LEN;
381 packetdata.dst_id_type = SILC_ID_CHANNEL;
382 packetdata.rng = server->rng;
383 packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
384 packetdata.src_id_len + packetdata.dst_id_len;
385 packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
387 /* If there are global users in the channel we will send the message
388 first to our router for further routing. */
389 if (route && server->server_type == SILC_SERVER && !server->standalone &&
390 channel->global_users) {
391 SilcServerEntry router;
393 /* Get data used in packet header encryption, keys and stuff. */
394 router = server->router;
395 sock = (SilcSocketConnection)router->connection;
396 idata = (SilcIDListData)router;
398 SILC_LOG_DEBUG(("Sending channel message to router for routing"));
400 silc_server_packet_send_to_channel_real(server, sock, &packetdata,
401 idata->send_key, idata->hmac,
402 data, data_len, FALSE, force_send);
405 /* Send the message to clients on the channel's client list. */
406 silc_list_start(channel->user_list);
407 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
408 client = chl->client;
410 /* If client has router set it is not locally connected client and
411 we will route the message to the router set in the client. Though,
412 send locally connected server in all cases. */
413 if (server->server_type == SILC_ROUTER && client && client->router &&
414 ((!route && client->router->router == server->id_entry) || route)) {
417 /* Check if we have sent the packet to this route already */
418 for (k = 0; k < routed_count; k++)
419 if (routed[k] == client->router)
421 if (k < routed_count)
424 /* Get data used in packet header encryption, keys and stuff. */
425 sock = (SilcSocketConnection)client->router->connection;
426 idata = (SilcIDListData)client->router;
428 /* Send the packet */
429 silc_server_packet_send_to_channel_real(server, sock, &packetdata,
430 idata->send_key, idata->hmac,
431 data, data_len, FALSE,
434 /* We want to make sure that the packet is routed to same router
435 only once. Mark this route as sent route. */
437 routed = silc_realloc(routed, sizeof(*routed) * (k + 1));
438 routed[k] = client->router;
444 if (server->server_type == SILC_ROUTER && !route)
447 if (server->server_type == SILC_SERVER && client->router)
450 /* Send to locally connected client */
453 /* Get data used in packet header encryption, keys and stuff. */
454 sock = (SilcSocketConnection)client->connection;
455 idata = (SilcIDListData)client;
457 /* Send the packet */
458 silc_server_packet_send_to_channel_real(server, sock, &packetdata,
459 idata->send_key, idata->hmac,
460 data, data_len, FALSE,
467 silc_free(packetdata.src_id);
468 silc_free(packetdata.dst_id);
471 /* This routine is explicitly used to relay messages to some channel.
472 Packets sent with this function we have received earlier and are
473 totally encrypted. This just sends the packet to all clients on
474 the channel. If the sender of the packet is someone on the channel
475 the message will not be sent to that client. The SILC Packet header
476 is encrypted with the session key shared between us and the client.
477 MAC is also computed before encrypting the header. Rest of the
478 packet will be untouched. */
480 void silc_server_packet_relay_to_channel(SilcServer server,
481 SilcSocketConnection sender_sock,
482 SilcChannelEntry channel,
484 SilcIdType sender_type,
486 unsigned int data_len,
490 SilcSocketConnection sock = NULL;
491 SilcPacketContext packetdata;
492 SilcClientEntry client = NULL;
493 SilcServerEntry *routed = NULL;
494 SilcChannelClientEntry chl;
495 unsigned int routed_count = 0;
496 SilcIDListData idata;
498 SILC_LOG_DEBUG(("Relaying packet to channel"));
500 /* Set the packet context pointers. */
501 packetdata.flags = 0;
502 packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
503 packetdata.src_id = silc_id_id2str(sender, sender_type);
504 packetdata.src_id_len = silc_id_get_len(sender_type);
505 packetdata.src_id_type = sender_type;
506 packetdata.dst_id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
507 packetdata.dst_id_len = SILC_ID_CHANNEL_LEN;
508 packetdata.dst_id_type = SILC_ID_CHANNEL;
509 packetdata.rng = server->rng;
510 packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
511 packetdata.src_id_len +
512 packetdata.dst_id_len));
514 /* If there are global users in the channel we will send the message
515 first to our router for further routing. */
516 if (server->server_type == SILC_SERVER && !server->standalone &&
517 channel->global_users) {
518 SilcServerEntry router;
520 router = server->router;
522 /* Check that the sender is not our router. */
523 if (sender_sock != (SilcSocketConnection)router->connection) {
525 /* Get data used in packet header encryption, keys and stuff. */
526 sock = (SilcSocketConnection)router->connection;
527 idata = (SilcIDListData)router;
529 SILC_LOG_DEBUG(("Sending channel message to router for routing"));
531 silc_server_packet_send_to_channel_real(server, sock, &packetdata,
532 idata->send_key, idata->hmac,
533 data, data_len, TRUE,
538 /* Send the message to clients on the channel's client list. */
539 silc_list_start(channel->user_list);
540 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
541 client = chl->client;
545 /* If sender is one on the channel do not send it the packet. */
546 if (!found && !SILC_ID_CLIENT_COMPARE(client->id, sender)) {
551 /* If the client has set router it means that it is not locally
552 connected client and we will route the packet further. */
553 if (server->server_type == SILC_ROUTER && client->router) {
556 /* Sender maybe server as well so we want to make sure that
557 we won't send the message to the server it came from. */
558 if (!found && !SILC_ID_SERVER_COMPARE(client->router->id, sender)) {
563 /* Check if we have sent the packet to this route already */
564 for (k = 0; k < routed_count; k++)
565 if (routed[k] == client->router)
567 if (k < routed_count)
570 /* Get data used in packet header encryption, keys and stuff. */
571 sock = (SilcSocketConnection)client->router->connection;
572 idata = (SilcIDListData)client->router;
574 /* Send the packet */
575 silc_server_packet_send_to_channel_real(server, sock, &packetdata,
576 idata->send_key, idata->hmac,
577 data, data_len, TRUE,
580 /* We want to make sure that the packet is routed to same router
581 only once. Mark this route as sent route. */
583 routed = silc_realloc(routed, sizeof(*routed) * (k + 1));
584 routed[k] = client->router;
590 if (server->server_type == SILC_SERVER && client->router)
593 /* Get data used in packet header encryption, keys and stuff. */
594 sock = (SilcSocketConnection)client->connection;
595 idata = (SilcIDListData)client;
597 SILC_LOG_DEBUG(("Sending packet to client %s (%s)",
598 sock->hostname, sock->ip));
600 /* Send the packet */
601 silc_server_packet_send_to_channel_real(server, sock, &packetdata,
602 idata->send_key, idata->hmac,
603 data, data_len, TRUE,
608 silc_free(packetdata.src_id);
609 silc_free(packetdata.dst_id);
612 /* This function is used to send packets strictly to all local clients
613 on a particular channel. This is used for example to distribute new
614 channel key to all our locally connected clients on the channel.
615 The packets are always encrypted with the session key shared between
616 the client, this means these are not _to the channel_ but _to the client_
619 void silc_server_packet_send_local_channel(SilcServer server,
620 SilcChannelEntry channel,
622 SilcPacketFlags flags,
624 unsigned int data_len,
627 SilcChannelClientEntry chl;
628 SilcSocketConnection sock = NULL;
630 SILC_LOG_DEBUG(("Start"));
632 /* Send the message to clients on the channel's client list. */
633 silc_list_start(channel->user_list);
634 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
636 sock = (SilcSocketConnection)chl->client->connection;
638 /* Send the packet to the client */
639 silc_server_packet_send_dest(server, sock, type, flags, chl->client->id,
640 SILC_ID_CLIENT, data, data_len,
646 /* Routine used to send (relay, route) private messages to some destination.
647 If the private message key does not exist then the message is re-encrypted,
648 otherwise we just pass it along. This really is not used to send new
649 private messages (as server does not send them) but to relay received
652 void silc_server_send_private_message(SilcServer server,
653 SilcSocketConnection dst_sock,
656 SilcPacketContext *packet)
658 SilcBuffer buffer = packet->buffer;
660 /* Send and re-encrypt if private messge key does not exist */
661 if ((packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY) == FALSE) {
663 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
664 + packet->dst_id_len + packet->padlen);
665 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
666 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
668 /* Re-encrypt packet */
669 silc_packet_encrypt(cipher, hmac, dst_sock->outbuf, buffer->len);
671 /* Send the packet */
672 silc_server_packet_send_real(server, dst_sock, FALSE);
675 /* Key exist so just send it */
676 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
677 + packet->dst_id_len + packet->padlen);
678 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
679 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
680 silc_server_packet_send_real(server, dst_sock, FALSE);
684 /* Sends current motd to client */
686 void silc_server_send_motd(SilcServer server,
687 SilcSocketConnection sock)
692 if (server->config && server->config->motd &&
693 server->config->motd->motd_file) {
695 motd = silc_file_read(server->config->motd->motd_file, &motd_len);
699 silc_server_send_notify(server, sock, SILC_NOTIFY_TYPE_MOTD, 1,
705 /* Sends error message. Error messages may or may not have any
708 void silc_server_send_error(SilcServer server,
709 SilcSocketConnection sock,
710 const char *fmt, ...)
713 unsigned char buf[4096];
715 memset(buf, 0, sizeof(buf));
717 vsprintf(buf, fmt, ap);
720 silc_server_packet_send(server, sock, SILC_PACKET_ERROR, 0,
721 buf, strlen(buf), FALSE);
724 /* Sends notify message. If format is TRUE the variable arguments are
725 formatted and the formatted string is sent as argument payload. If it is
726 FALSE then each argument is sent as separate argument and their format
727 in the argument list must be { argument data, argument length }. */
729 void silc_server_send_notify(SilcServer server,
730 SilcSocketConnection sock,
732 unsigned int argc, ...)
739 packet = silc_notify_payload_encode(type, argc, ap);
740 silc_server_packet_send(server, sock, SILC_PACKET_NOTIFY, 0,
741 packet->data, packet->len, FALSE);
742 silc_buffer_free(packet);
745 /* Sends notify message destined to specific entity. */
747 void silc_server_send_notify_dest(SilcServer server,
748 SilcSocketConnection sock,
750 SilcIdType dest_id_type,
752 unsigned int argc, ...)
759 packet = silc_notify_payload_encode(type, argc, ap);
760 silc_server_packet_send_dest(server, sock, SILC_PACKET_NOTIFY, 0,
761 dest_id, dest_id_type,
762 packet->data, packet->len, FALSE);
763 silc_buffer_free(packet);
766 /* Sends notify message to a channel. The notify message sent is
767 distributed to all clients on the channel. If `router_notify' is TRUE
768 then the notify may be routed to primary route or to some other routers.
769 If FALSE it is assured that the notify is sent only locally. */
771 void silc_server_send_notify_to_channel(SilcServer server,
772 SilcChannelEntry channel,
773 unsigned char route_notify,
775 unsigned int argc, ...)
782 packet = silc_notify_payload_encode(type, argc, ap);
783 silc_server_packet_send_to_channel(server, channel,
784 SILC_PACKET_NOTIFY, route_notify,
785 packet->data, packet->len, FALSE);
786 silc_buffer_free(packet);
789 /* Send notify message to all clients the client has joined. It is quaranteed
790 that the message is sent only once to a client (ie. if a client is joined
791 on two same channel it will receive only one notify message). Also, this
792 sends only to local clients (locally connected if we are server, and to
793 local servers if we are router). */
795 void silc_server_send_notify_on_channels(SilcServer server,
796 SilcClientEntry client,
798 unsigned int argc, ...)
801 SilcSocketConnection sock = NULL;
802 SilcPacketContext packetdata;
804 SilcClientEntry *sent_clients = NULL;
805 unsigned int sent_clients_count = 0;
806 SilcServerEntry *routed = NULL;
807 unsigned int routed_count = 0;
808 SilcChannelEntry channel;
809 SilcChannelClientEntry chl, chl2;
810 SilcIDListData idata;
813 unsigned int data_len;
814 int force_send = FALSE;
817 SILC_LOG_DEBUG(("Start"));
819 if (!silc_list_count(client->channels))
823 packet = silc_notify_payload_encode(type, argc, ap);
825 data_len = packet->len;
827 /* Set the packet context pointers. */
828 packetdata.flags = 0;
829 packetdata.type = SILC_PACKET_NOTIFY;
830 packetdata.src_id = silc_id_id2str(server->id, SILC_ID_SERVER);
831 packetdata.src_id_len = SILC_ID_SERVER_LEN;
832 packetdata.src_id_type = SILC_ID_SERVER;
833 packetdata.rng = server->rng;
835 silc_list_start(client->channels);
836 while ((chl = silc_list_get(client->channels)) != SILC_LIST_END) {
837 channel = chl->channel;
839 /* Send the message to all clients on the channel's client list. */
840 silc_list_start(channel->user_list);
841 while ((chl2 = silc_list_get(channel->user_list)) != SILC_LIST_END) {
844 /* Check if we have sent the packet to this client already */
845 for (k = 0; k < sent_clients_count; k++)
846 if (sent_clients[k] == c)
848 if (k < sent_clients_count)
851 /* If we are router and if this client has router set it is not
852 locally connected client and we will route the message to the
853 router set in the client. */
854 if (c && c->router && server->server_type == SILC_ROUTER) {
855 /* Check if we have sent the packet to this route already */
856 for (k = 0; k < routed_count; k++)
857 if (routed[k] == c->router)
859 if (k < routed_count)
862 /* Get data used in packet header encryption, keys and stuff. */
863 sock = (SilcSocketConnection)c->router->connection;
864 idata = (SilcIDListData)c->router;
866 packetdata.dst_id = silc_id_id2str(c->router->id, SILC_ID_SERVER);
867 packetdata.dst_id_len = SILC_ID_SERVER_LEN;
868 packetdata.dst_id_type = SILC_ID_SERVER;
869 packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
870 packetdata.src_id_len + packetdata.dst_id_len;
871 packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
873 /* Send the packet */
874 silc_server_packet_send_to_channel_real(server, sock, &packetdata,
875 idata->send_key, idata->hmac,
876 data, data_len, FALSE,
879 silc_free(packetdata.dst_id);
881 /* We want to make sure that the packet is routed to same router
882 only once. Mark this route as sent route. */
884 routed = silc_realloc(routed, sizeof(*routed) * (k + 1));
885 routed[k] = c->router;
891 if (server->server_type == SILC_SERVER && client->router)
894 /* Send to locally connected client */
897 /* Get data used in packet header encryption, keys and stuff. */
898 sock = (SilcSocketConnection)c->connection;
899 idata = (SilcIDListData)c;
901 packetdata.dst_id = silc_id_id2str(c->id, SILC_ID_CLIENT);
902 packetdata.dst_id_len = SILC_ID_CLIENT_LEN;
903 packetdata.dst_id_type = SILC_ID_CLIENT;
904 packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
905 packetdata.src_id_len + packetdata.dst_id_len;
906 packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
908 /* Send the packet */
909 silc_server_packet_send_to_channel_real(server, sock, &packetdata,
910 idata->send_key, idata->hmac,
911 data, data_len, FALSE,
914 silc_free(packetdata.dst_id);
916 /* Make sure that we send the notify only once per client. */
917 sent_clients = silc_realloc(sent_clients, sizeof(*sent_clients) *
918 (sent_clients_count + 1));
919 sent_clients[sent_clients_count] = c;
920 sent_clients_count++;
927 if (sent_clients_count)
928 silc_free(sent_clients);
929 silc_free(packetdata.src_id);
932 /* Sends New ID Payload to remote end. The packet is used to distribute
933 information about new registered clients, servers, channel etc. usually
934 to routers so that they can keep these information up to date.
935 If the argument `broadcast' is TRUE then the packet is sent as
938 void silc_server_send_new_id(SilcServer server,
939 SilcSocketConnection sock,
941 void *id, SilcIdType id_type,
946 SILC_LOG_DEBUG(("Start"));
948 idp = silc_id_payload_encode(id, id_type);
949 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID,
950 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
951 idp->data, idp->len, FALSE);
952 silc_buffer_free(idp);
955 /* Sends Replace ID payload to remote end. This is used to replace old
956 ID with new ID sent in the packet. This is called for example when
957 user changes nickname and we create new ID for the user. If the
958 argument `broadcast' is TRUE then the packet is sent as
960 /* XXX It would be expected that the new id is same type as the old
963 void silc_server_send_replace_id(SilcServer server,
964 SilcSocketConnection sock,
966 void *old_id, SilcIdType old_id_type,
967 unsigned int old_id_len,
968 void *new_id, SilcIdType new_id_type,
969 unsigned int new_id_len)
975 SILC_LOG_DEBUG(("Start"));
977 oid = silc_id_id2str(old_id, old_id_type);
981 nid = silc_id_id2str(new_id, new_id_type);
985 packet = silc_buffer_alloc(2 + 2 + 2 + 2 + old_id_len + new_id_len);
986 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
987 silc_buffer_format(packet,
988 SILC_STR_UI_SHORT(old_id_type),
989 SILC_STR_UI_SHORT(old_id_len),
990 SILC_STR_UI_XNSTRING(oid, old_id_len),
991 SILC_STR_UI_SHORT(new_id_type),
992 SILC_STR_UI_SHORT(new_id_len),
993 SILC_STR_UI_XNSTRING(nid, new_id_len),
996 silc_server_packet_send(server, sock, SILC_PACKET_REPLACE_ID,
997 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
998 packet->data, packet->len, FALSE);
1001 silc_buffer_free(packet);
1004 /* This function is used to send Remove Channel User payload. This may sent
1005 by server but is usually used only by router to notify other routers that
1006 user has left a channel. Normal server sends this packet to its router
1007 to notify that the router should not hold a record about this client
1008 on a channel anymore. Router distributes it further to other routers. */
1010 void silc_server_send_remove_channel_user(SilcServer server,
1011 SilcSocketConnection sock,
1013 void *client_id, void *channel_id)
1016 unsigned char *clid, *chid;
1018 SILC_LOG_DEBUG(("Start"));
1020 clid = silc_id_id2str(client_id, SILC_ID_CLIENT);
1024 chid = silc_id_id2str(channel_id, SILC_ID_CHANNEL);
1028 packet = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN + SILC_ID_CHANNEL_LEN);
1029 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
1030 silc_buffer_format(packet,
1031 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
1032 SILC_STR_UI_XNSTRING(clid, SILC_ID_CLIENT_LEN),
1033 SILC_STR_UI_SHORT(SILC_ID_CHANNEL_LEN),
1034 SILC_STR_UI_XNSTRING(chid, SILC_ID_CHANNEL_LEN),
1037 silc_server_packet_send(server, sock, SILC_PACKET_REMOVE_CHANNEL_USER,
1038 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
1039 packet->data, packet->len, FALSE);
1042 silc_buffer_free(packet);
1045 /* Send New Channel Payload to notify about newly created channel in the
1046 SILC network. Normal server nevers sends this packet. Router uses this
1047 to notify other routers in the network about new channel. This packet
1050 void silc_server_send_new_channel(SilcServer server,
1051 SilcSocketConnection sock,
1055 unsigned int channel_id_len)
1059 unsigned int name_len = strlen(channel_name);
1061 SILC_LOG_DEBUG(("Start"));
1063 cid = silc_id_id2str(channel_id, SILC_ID_CHANNEL);
1067 packet = silc_buffer_alloc(2 + 2 + name_len + channel_id_len);
1068 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
1069 silc_buffer_format(packet,
1070 SILC_STR_UI_SHORT(name_len),
1071 SILC_STR_UI_XNSTRING(channel_name, name_len),
1072 SILC_STR_UI_SHORT(channel_id_len),
1073 SILC_STR_UI_XNSTRING(cid, channel_id_len),
1076 silc_server_packet_send(server, sock, SILC_PACKET_NEW_CHANNEL,
1077 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
1078 packet->data, packet->len, FALSE);
1081 silc_buffer_free(packet);
1084 /* Send New Channel User payload to notify routers in the network about new
1085 user on the channel. The packet is may be broadcasted. Normal server
1086 can send this but must not receive. Router can send and receive it. */
1088 void silc_server_send_new_channel_user(SilcServer server,
1089 SilcSocketConnection sock,
1092 unsigned int channel_id_len,
1094 unsigned int client_id_len)
1097 unsigned char *clid, *chid;
1099 SILC_LOG_DEBUG(("Start"));
1101 chid = silc_id_id2str(channel_id, SILC_ID_CHANNEL);
1105 clid = silc_id_id2str(client_id, SILC_ID_CLIENT);
1109 packet = silc_buffer_alloc(2 + 2 + channel_id_len + client_id_len);
1110 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
1111 silc_buffer_format(packet,
1112 SILC_STR_UI_SHORT(channel_id_len),
1113 SILC_STR_UI_XNSTRING(chid, channel_id_len),
1114 SILC_STR_UI_SHORT(client_id_len),
1115 SILC_STR_UI_XNSTRING(clid, client_id_len),
1118 silc_server_packet_send(server, sock, SILC_PACKET_NEW_CHANNEL_USER,
1119 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
1120 packet->data, packet->len, FALSE);
1123 silc_buffer_free(packet);
1126 /* Send Channel Key payload to distribute the new channel key. Normal server
1127 sends this to router when new client joins to existing channel. Router
1128 sends this to the local server who sent the join command in case where
1129 the channel did not exist yet. Both normal and router servers uses this
1130 also to send this to locally connected clients on the channel. This
1131 must not be broadcasted packet. Routers do not send this to each other. */
1133 void silc_server_send_channel_key(SilcServer server,
1134 SilcChannelEntry channel,
1135 unsigned char route)
1138 unsigned char *chid;
1139 unsigned int tmp_len;
1141 SILC_LOG_DEBUG(("Start"));
1143 chid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1147 /* Encode channel key packet */
1148 tmp_len = strlen(channel->channel_key->cipher->name);
1149 packet = silc_channel_key_payload_encode(SILC_ID_CHANNEL_LEN, chid, tmp_len,
1150 channel->channel_key->cipher->name,
1151 channel->key_len / 8, channel->key);
1153 silc_server_packet_send_to_channel(server, channel, SILC_PACKET_CHANNEL_KEY,
1154 route, packet->data, packet->len, FALSE);
1155 silc_buffer_free(packet);
1159 /* Generic function to send any command. The arguments must be sent already
1160 encoded into correct form in correct order. */
1162 void silc_server_send_command(SilcServer server,
1163 SilcSocketConnection sock,
1164 SilcCommand command,
1165 unsigned int argc, ...)
1172 packet = silc_command_payload_encode_vap(command, 0, argc, ap);
1173 silc_server_packet_send(server, sock, SILC_PACKET_COMMAND, 0,
1174 packet->data, packet->len, TRUE);
1175 silc_buffer_free(packet);
1178 /* Function used to send REMOVE_ID packet. The packet is used to notify
1179 routers that certain ID should be removed. After that the ID will become
1180 invalid. If the argument `broadcast' is TRUE then the packet is sent as
1181 broadcast packet. */
1183 void silc_server_send_remove_id(SilcServer server,
1184 SilcSocketConnection sock,
1186 void *id, unsigned int id_len,
1191 SILC_LOG_DEBUG(("Start"));
1193 idp = silc_id_payload_encode(id, id_type);
1194 silc_server_packet_send(server, sock, SILC_PACKET_REMOVE_ID,
1195 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
1196 idp->data, idp->len, FALSE);
1197 silc_buffer_free(idp);