5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2001 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);
143 /* Prepare outgoing data buffer for packet sending */
144 silc_packet_send_prepare(sock,
145 SILC_PACKET_HEADER_LEN +
146 packetdata.src_id_len +
147 packetdata.dst_id_len,
151 SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len));
153 packetdata.buffer = sock->outbuf;
155 /* Put the data to the buffer */
156 if (data && data_len)
157 silc_buffer_put(sock->outbuf, data, data_len);
159 /* Create the outgoing packet */
160 silc_packet_assemble(&packetdata);
163 cipher = idata->send_key;
167 /* Encrypt the packet */
168 silc_packet_encrypt(cipher, hmac, sock->outbuf, sock->outbuf->len);
170 SILC_LOG_HEXDUMP(("Outgoing packet, len %d", sock->outbuf->len),
171 sock->outbuf->data, sock->outbuf->len);
173 /* Now actually send the packet */
174 silc_server_packet_send_real(server, sock, force_send);
176 if (packetdata.src_id)
177 silc_free(packetdata.src_id);
178 if (packetdata.dst_id)
179 silc_free(packetdata.dst_id);
182 /* Broadcast received packet to our primary route. This function is used
183 by router to further route received broadcast packet. It is expected
184 that the broadcast flag from the packet is checked before calling this
185 function. This does not test or set the broadcast flag. */
187 void silc_server_packet_broadcast(SilcServer server,
188 SilcSocketConnection sock,
189 SilcPacketContext *packet)
191 SilcBuffer buffer = packet->buffer;
192 SilcIDListData idata;
195 SILC_LOG_DEBUG(("Broadcasting received broadcast packet"));
197 /* If the packet is originated from our primary route we are
198 not allowed to send the packet. */
199 id = silc_id_str2id(packet->src_id, packet->src_id_len, packet->src_id_type);
200 if (id && SILC_ID_SERVER_COMPARE(id, server->router->id)) {
201 idata = (SilcIDListData)sock->user_data;
203 silc_buffer_push(buffer, buffer->data - buffer->head);
204 silc_packet_send_prepare(sock, 0, 0, buffer->len);
205 silc_buffer_put(sock->outbuf, buffer->data, buffer->len);
206 silc_packet_encrypt(idata->send_key, idata->hmac,
207 sock->outbuf, sock->outbuf->len);
209 SILC_LOG_HEXDUMP(("Broadcasted packet, len %d", sock->outbuf->len),
210 sock->outbuf->data, sock->outbuf->len);
212 /* Now actually send the packet */
213 silc_server_packet_send_real(server, sock, TRUE);
218 SILC_LOG_DEBUG(("Will not broadcast to primary route since it is the "
219 "original sender of this packet"));
223 /* Routes received packet to `sock'. This is used to route the packets that
224 router receives but are not destined to it. */
226 void silc_server_packet_route(SilcServer server,
227 SilcSocketConnection sock,
228 SilcPacketContext *packet)
230 SilcBuffer buffer = packet->buffer;
231 SilcIDListData idata;
233 SILC_LOG_DEBUG(("Routing received packet"));
235 idata = (SilcIDListData)sock->user_data;
237 silc_buffer_push(buffer, buffer->data - buffer->head);
238 silc_packet_send_prepare(sock, 0, 0, buffer->len);
239 silc_buffer_put(sock->outbuf, buffer->data, buffer->len);
240 silc_packet_encrypt(idata->send_key, idata->hmac,
241 sock->outbuf, sock->outbuf->len);
243 SILC_LOG_HEXDUMP(("Routed packet, len %d", sock->outbuf->len),
244 sock->outbuf->data, sock->outbuf->len);
246 /* Now actually send the packet */
247 silc_server_packet_send_real(server, sock, TRUE);
250 /* Internal routine to actually create the channel packet and send it
251 to network. This is common function in channel message sending. If
252 `channel_message' is TRUE this encrypts the message as it is strictly
253 a channel message. If FALSE normal encryption process is used. */
256 silc_server_packet_send_to_channel_real(SilcServer server,
257 SilcSocketConnection sock,
258 SilcPacketContext *packet,
262 unsigned int data_len,
266 packet->truelen = data_len + SILC_PACKET_HEADER_LEN +
267 packet->src_id_len + packet->dst_id_len;
269 /* Prepare outgoing data buffer for packet sending */
270 silc_packet_send_prepare(sock,
271 SILC_PACKET_HEADER_LEN +
277 packet->buffer = sock->outbuf;
279 /* Put the data to buffer, assemble and encrypt the packet. The packet
280 is encrypted with normal session key shared with the client. */
281 silc_buffer_put(sock->outbuf, data, data_len);
282 silc_packet_assemble(packet);
284 silc_packet_encrypt(cipher, hmac, sock->outbuf, SILC_PACKET_HEADER_LEN +
285 packet->src_id_len + packet->dst_id_len +
288 silc_packet_encrypt(cipher, hmac, sock->outbuf, sock->outbuf->len);
290 SILC_LOG_HEXDUMP(("Channel 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, force_send);
297 /* This routine is used by the server to send packets to channel. The
298 packet sent with this function is distributed to all clients on
299 the channel. Usually this is used to send notify messages to the
300 channel, things like notify about new user joining to the channel.
301 If `route' is FALSE then the packet is sent only locally and will not
302 be routed anywhere (for router locally means cell wide). If `sender'
303 is provided then the packet is not sent to that connection since it
304 originally came from it. */
306 void silc_server_packet_send_to_channel(SilcServer server,
307 SilcSocketConnection sender,
308 SilcChannelEntry channel,
312 unsigned int data_len,
315 SilcSocketConnection sock = NULL;
316 SilcPacketContext packetdata;
317 SilcClientEntry client = NULL;
318 SilcServerEntry *routed = NULL;
319 SilcChannelClientEntry chl;
320 SilcIDListData idata;
321 unsigned int routed_count = 0;
323 /* This doesn't send channel message packets */
324 if (type == SILC_PACKET_CHANNEL_MESSAGE)
327 SILC_LOG_DEBUG(("Sending packet to channel"));
329 /* Set the packet context pointers. */
330 packetdata.flags = 0;
331 packetdata.type = type;
332 packetdata.src_id = silc_id_id2str(server->id, SILC_ID_SERVER);
333 packetdata.src_id_len = SILC_ID_SERVER_LEN;
334 packetdata.src_id_type = SILC_ID_SERVER;
335 packetdata.dst_id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
336 packetdata.dst_id_len = SILC_ID_CHANNEL_LEN;
337 packetdata.dst_id_type = SILC_ID_CHANNEL;
338 packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
339 packetdata.src_id_len + packetdata.dst_id_len;
340 packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
342 /* If there are global users in the channel we will send the message
343 first to our router for further routing. */
344 if (route && server->server_type == SILC_SERVER && !server->standalone &&
345 channel->global_users) {
346 SilcServerEntry router;
348 /* Get data used in packet header encryption, keys and stuff. */
349 router = server->router;
350 sock = (SilcSocketConnection)router->connection;
351 idata = (SilcIDListData)router;
353 if (sock != sender) {
354 SILC_LOG_DEBUG(("Sending channel message to router for routing"));
356 silc_server_packet_send_to_channel_real(server, sock, &packetdata,
357 idata->send_key, idata->hmac,
358 data, data_len, FALSE,
363 /* Send the message to clients on the channel's client list. */
364 silc_list_start(channel->user_list);
365 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
366 client = chl->client;
368 /* If client has router set it is not locally connected client and
369 we will route the message to the router set in the client. Though,
370 send locally connected server in all cases. */
371 if (server->server_type == SILC_ROUTER && client && client->router &&
372 ((!route && client->router->router == server->id_entry) || route)) {
375 /* Check if we have sent the packet to this route already */
376 for (k = 0; k < routed_count; k++)
377 if (routed[k] == client->router)
379 if (k < routed_count)
382 /* Get data used in packet header encryption, keys and stuff. */
383 sock = (SilcSocketConnection)client->router->connection;
384 idata = (SilcIDListData)client->router;
386 if (sender && sock == sender)
389 /* Send the packet */
390 silc_server_packet_send_to_channel_real(server, sock, &packetdata,
391 idata->send_key, idata->hmac,
392 data, data_len, FALSE,
395 /* We want to make sure that the packet is routed to same router
396 only once. Mark this route as sent route. */
398 routed = silc_realloc(routed, sizeof(*routed) * (k + 1));
399 routed[k] = client->router;
405 if (client && client->router)
408 /* Send to locally connected client */
411 /* Get data used in packet header encryption, keys and stuff. */
412 sock = (SilcSocketConnection)client->connection;
413 idata = (SilcIDListData)client;
415 if (sender && sock == sender)
418 /* Send the packet */
419 silc_server_packet_send_to_channel_real(server, sock, &packetdata,
420 idata->send_key, idata->hmac,
421 data, data_len, FALSE,
428 silc_free(packetdata.src_id);
429 silc_free(packetdata.dst_id);
432 /* This routine is explicitly used to relay messages to some channel.
433 Packets sent with this function we have received earlier and are
434 totally encrypted. This just sends the packet to all clients on
435 the channel. If the sender of the packet is someone on the channel
436 the message will not be sent to that client. The SILC Packet header
437 is encrypted with the session key shared between us and the client.
438 MAC is also computed before encrypting the header. Rest of the
439 packet will be untouched. */
441 void silc_server_packet_relay_to_channel(SilcServer server,
442 SilcSocketConnection sender_sock,
443 SilcChannelEntry channel,
445 SilcIdType sender_type,
447 unsigned int data_len,
451 SilcSocketConnection sock = NULL;
452 SilcPacketContext packetdata;
453 SilcClientEntry client = NULL;
454 SilcServerEntry *routed = NULL;
455 SilcChannelClientEntry chl;
456 unsigned int routed_count = 0;
457 SilcIDListData idata;
459 SILC_LOG_DEBUG(("Relaying packet to channel"));
461 /* Set the packet context pointers. */
462 packetdata.flags = 0;
463 packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
464 packetdata.src_id = silc_id_id2str(sender, sender_type);
465 packetdata.src_id_len = silc_id_get_len(sender_type);
466 packetdata.src_id_type = sender_type;
467 packetdata.dst_id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
468 packetdata.dst_id_len = SILC_ID_CHANNEL_LEN;
469 packetdata.dst_id_type = SILC_ID_CHANNEL;
470 packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
471 packetdata.src_id_len +
472 packetdata.dst_id_len));
474 /* If there are global users in the channel we will send the message
475 first to our router for further routing. */
476 if (server->server_type == SILC_SERVER && !server->standalone &&
477 channel->global_users) {
478 SilcServerEntry router;
480 router = server->router;
482 /* Check that the sender is not our router. */
483 if (sender_sock != (SilcSocketConnection)router->connection) {
485 /* Get data used in packet header encryption, keys and stuff. */
486 sock = (SilcSocketConnection)router->connection;
487 idata = (SilcIDListData)router;
489 SILC_LOG_DEBUG(("Sending channel message to router for routing"));
491 silc_server_packet_send_to_channel_real(server, sock, &packetdata,
492 idata->send_key, idata->hmac,
493 data, data_len, TRUE,
498 /* Send the message to clients on the channel's client list. */
499 silc_list_start(channel->user_list);
500 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
501 client = chl->client;
505 /* If sender is one on the channel do not send it the packet. */
506 if (!found && !SILC_ID_CLIENT_COMPARE(client->id, sender)) {
511 /* If the client has set router it means that it is not locally
512 connected client and we will route the packet further. */
513 if (server->server_type == SILC_ROUTER && client->router) {
516 /* Sender maybe server as well so we want to make sure that
517 we won't send the message to the server it came from. */
518 if (!found && !SILC_ID_SERVER_COMPARE(client->router->id, sender)) {
523 /* Check if we have sent the packet to this route already */
524 for (k = 0; k < routed_count; k++)
525 if (routed[k] == client->router)
527 if (k < routed_count)
530 /* Get data used in packet header encryption, keys and stuff. */
531 sock = (SilcSocketConnection)client->router->connection;
532 idata = (SilcIDListData)client->router;
534 if (sender_sock && sock == sender_sock)
537 SILC_LOG_DEBUG(("Relaying packet to client ID(%s) %s (%s)",
538 silc_id_render(client->id, SILC_ID_CLIENT),
539 sock->hostname, sock->ip));
541 /* Send the packet */
542 silc_server_packet_send_to_channel_real(server, sock, &packetdata,
543 idata->send_key, idata->hmac,
544 data, data_len, TRUE,
547 /* We want to make sure that the packet is routed to same router
548 only once. Mark this route as sent route. */
550 routed = silc_realloc(routed, sizeof(*routed) * (k + 1));
551 routed[k] = client->router;
557 if (client && client->router)
560 /* Get data used in packet header encryption, keys and stuff. */
561 sock = (SilcSocketConnection)client->connection;
562 idata = (SilcIDListData)client;
564 if (sender_sock && sock == sender_sock)
567 SILC_LOG_DEBUG(("Sending packet to client ID(%s) %s (%s)",
568 silc_id_render(client->id, SILC_ID_CLIENT),
569 sock->hostname, sock->ip));
571 /* Send the packet */
572 silc_server_packet_send_to_channel_real(server, sock, &packetdata,
573 idata->send_key, idata->hmac,
574 data, data_len, TRUE,
579 silc_free(packetdata.src_id);
580 silc_free(packetdata.dst_id);
583 /* This function is used to send packets strictly to all local clients
584 on a particular channel. This is used for example to distribute new
585 channel key to all our locally connected clients on the channel.
586 The packets are always encrypted with the session key shared between
587 the client, this means these are not _to the channel_ but _to the client_
590 void silc_server_packet_send_local_channel(SilcServer server,
591 SilcChannelEntry channel,
593 SilcPacketFlags flags,
595 unsigned int data_len,
598 SilcChannelClientEntry chl;
599 SilcSocketConnection sock = NULL;
601 SILC_LOG_DEBUG(("Start"));
603 /* Send the message to clients on the channel's client list. */
604 silc_list_start(channel->user_list);
605 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
606 if (chl->client && !chl->client->router) {
607 sock = (SilcSocketConnection)chl->client->connection;
609 /* Send the packet to the client */
610 silc_server_packet_send_dest(server, sock, type, flags, chl->client->id,
611 SILC_ID_CLIENT, data, data_len,
617 /* Routine used to send (relay, route) private messages to some destination.
618 If the private message key does not exist then the message is re-encrypted,
619 otherwise we just pass it along. This really is not used to send new
620 private messages (as server does not send them) but to relay received
623 void silc_server_send_private_message(SilcServer server,
624 SilcSocketConnection dst_sock,
627 SilcPacketContext *packet)
629 SilcBuffer buffer = packet->buffer;
631 /* Send and re-encrypt if private messge key does not exist */
632 if ((packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY) == FALSE) {
634 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
635 + packet->dst_id_len + packet->padlen);
636 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
637 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
639 /* Re-encrypt packet */
640 silc_packet_encrypt(cipher, hmac, dst_sock->outbuf, buffer->len);
642 /* Send the packet */
643 silc_server_packet_send_real(server, dst_sock, FALSE);
646 /* Key exist so just send it */
647 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
648 + packet->dst_id_len + packet->padlen);
649 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
650 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
651 silc_server_packet_send_real(server, dst_sock, FALSE);
655 /* Sends current motd to client */
657 void silc_server_send_motd(SilcServer server,
658 SilcSocketConnection sock)
663 if (server->config && server->config->motd &&
664 server->config->motd->motd_file) {
666 motd = silc_file_read(server->config->motd->motd_file, &motd_len);
670 silc_server_send_notify(server, sock, FALSE, SILC_NOTIFY_TYPE_MOTD, 1,
676 /* Sends error message. Error messages may or may not have any
679 void silc_server_send_error(SilcServer server,
680 SilcSocketConnection sock,
681 const char *fmt, ...)
684 unsigned char buf[4096];
686 memset(buf, 0, sizeof(buf));
688 vsprintf(buf, fmt, ap);
691 silc_server_packet_send(server, sock, SILC_PACKET_ERROR, 0,
692 buf, strlen(buf), FALSE);
695 /* Sends notify message. If format is TRUE the variable arguments are
696 formatted and the formatted string is sent as argument payload. If it is
697 FALSE then each argument is sent as separate argument and their format
698 in the argument list must be { argument data, argument length }. */
700 void silc_server_send_notify(SilcServer server,
701 SilcSocketConnection sock,
704 unsigned int argc, ...)
711 packet = silc_notify_payload_encode(type, argc, ap);
712 silc_server_packet_send(server, sock, SILC_PACKET_NOTIFY, 0,
713 packet->data, packet->len, FALSE);
714 silc_buffer_free(packet);
717 /* Send CHANNEL_CHANGE notify type. This tells the receiver to replace the
718 `old_id' with the `new_id'. */
720 void silc_server_send_notify_channel_change(SilcServer server,
721 SilcSocketConnection sock,
723 SilcChannelID *old_id,
724 SilcChannelID *new_id,
727 SilcBuffer idp1, idp2;
729 idp1 = silc_id_payload_encode((void *)old_id, SILC_ID_CHANNEL);
730 idp2 = silc_id_payload_encode((void *)new_id, SILC_ID_CHANNEL);
732 silc_server_send_notify(server, sock, broadcast,
733 SILC_NOTIFY_TYPE_CHANNEL_CHANGE,
734 2, idp1->data, idp1->len, idp2->data, idp2->len);
735 silc_buffer_free(idp1);
736 silc_buffer_free(idp2);
739 /* Send NICK_CHANGE notify type. This tells the receiver to replace the
740 `old_id' with the `new_id'. */
742 void silc_server_send_notify_nick_change(SilcServer server,
743 SilcSocketConnection sock,
745 SilcClientID *old_id,
746 SilcClientID *new_id,
749 SilcBuffer idp1, idp2;
751 idp1 = silc_id_payload_encode((void *)old_id, SILC_ID_CLIENT);
752 idp2 = silc_id_payload_encode((void *)new_id, SILC_ID_CLIENT);
754 silc_server_send_notify(server, sock, broadcast,
755 SILC_NOTIFY_TYPE_NICK_CHANGE,
756 2, idp1->data, idp1->len, idp2->data, idp2->len);
757 silc_buffer_free(idp1);
758 silc_buffer_free(idp2);
761 /* Sends JOIN notify type. This tells that new client by `client_id' ID
762 has joined to the `channel'. */
764 void silc_server_send_notify_join(SilcServer server,
765 SilcSocketConnection sock,
767 SilcChannelEntry channel,
768 SilcClientID *client_id,
769 unsigned int client_id_len)
771 SilcBuffer idp1, idp2;
773 idp1 = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
774 idp2 = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
775 silc_server_send_notify(server, sock, broadcast, SILC_NOTIFY_TYPE_JOIN,
776 2, idp1->data, idp1->len,
777 idp2->data, idp2->len);
778 silc_buffer_free(idp1);
779 silc_buffer_free(idp2);
782 /* Sends LEAVE notify type. This tells that `client_id' has left the
783 `channel'. The Notify packet is always destined to the channel. */
785 void silc_server_send_notify_leave(SilcServer server,
786 SilcSocketConnection sock,
788 SilcChannelEntry channel,
789 SilcClientID *client_id,
790 unsigned int client_id_len)
794 idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
795 silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
796 SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_LEAVE,
797 1, idp->data, idp->len);
798 silc_buffer_free(idp);
801 /* Sends CMODE_CHANGE notify type. This tells that `client_id' changed the
802 `channel' mode to `mode. The Notify packet is always destined to
805 void silc_server_send_notify_cmode(SilcServer server,
806 SilcSocketConnection sock,
808 SilcChannelEntry channel,
809 unsigned int mode_mask,
810 SilcClientID *client_id,
811 unsigned int client_id_len)
814 unsigned char mode[4];
816 idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
817 SILC_PUT32_MSB(mode_mask, mode);
819 silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
820 SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_CMODE_CHANGE,
821 2, idp->data, idp->len,
823 silc_buffer_free(idp);
826 /* Sends CUMODE_CHANGE notify type. This tells that `client_id' changed the
827 `target' client's mode on `channel'. The Notify packet is always
828 destined to the channel. */
830 void silc_server_send_notify_cumode(SilcServer server,
831 SilcSocketConnection sock,
833 SilcChannelEntry channel,
834 unsigned int mode_mask,
835 SilcClientID *client_id,
836 unsigned int client_id_len,
837 SilcClientID *target,
838 unsigned int target_len)
840 SilcBuffer idp1, idp2;
841 unsigned char mode[4];
843 idp1 = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
844 idp2 = silc_id_payload_encode((void *)target, SILC_ID_CLIENT);
845 SILC_PUT32_MSB(mode_mask, mode);
847 silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
849 SILC_NOTIFY_TYPE_CUMODE_CHANGE, 3,
850 idp1->data, idp1->len,
852 idp2->data, idp2->len);
853 silc_buffer_free(idp1);
854 silc_buffer_free(idp2);
857 /* Sends SIGNOFF notify type. This tells that `client_id' client has
858 left SILC network. This function is used only between server and router
859 traffic. This is not used to send the notify to the channel for
860 client. The `message may be NULL. */
862 void silc_server_send_notify_signoff(SilcServer server,
863 SilcSocketConnection sock,
865 SilcClientID *client_id,
866 unsigned int client_id_len,
871 idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
872 silc_server_send_notify(server, sock, broadcast,
873 SILC_NOTIFY_TYPE_SIGNOFF,
874 message ? 2 : 1, idp->data, idp->len,
875 message, message ? strlen(message): 0);
876 silc_buffer_free(idp);
879 /* Sends SERVER_SIGNOFF notify type. This tells that `server_id' server
880 has quit SILC network. */
882 void silc_server_send_notify_server_signoff(SilcServer server,
883 SilcSocketConnection sock,
885 SilcServerID *server_id,
886 unsigned int server_id_len)
890 idp = silc_id_payload_encode((void *)server_id, SILC_ID_SERVER);
891 silc_server_send_notify(server, sock, broadcast,
892 SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
893 1, idp->data, idp->len);
894 silc_buffer_free(idp);
897 /* Sends TOPIC_SET notify type. This tells that `client_id' changed
898 the `channel's topic to `topic'. The Notify packet is always destined
899 to the channel. This function is used to send the topic set notifies
902 void silc_server_send_notify_topic_set(SilcServer server,
903 SilcSocketConnection sock,
905 SilcChannelEntry channel,
906 SilcClientID *client_id,
907 unsigned int client_id_len,
912 idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
913 silc_server_send_notify(server, sock, broadcast,
914 SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
917 topic, topic ? strlen(topic) : 0);
918 silc_buffer_free(idp);
921 /* Send KICKED notify type. This tells that the `client_id' on `channel'
922 was kicked off the channel. The `comment' may indicate the reason
923 for the kicking. This function is used only between server and router
926 void silc_server_send_notify_kicked(SilcServer server,
927 SilcSocketConnection sock,
929 SilcChannelEntry channel,
930 SilcClientID *client_id,
931 unsigned int client_id_len,
936 idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
937 silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
938 SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_KICKED,
939 comment ? 2 : 1, idp->data, idp->len,
940 comment, comment ? strlen(comment) : 0);
941 silc_buffer_free(idp);
944 /* Sends notify message destined to specific entity. */
946 void silc_server_send_notify_dest(SilcServer server,
947 SilcSocketConnection sock,
950 SilcIdType dest_id_type,
952 unsigned int argc, ...)
959 packet = silc_notify_payload_encode(type, argc, ap);
960 silc_server_packet_send_dest(server, sock, SILC_PACKET_NOTIFY, 0,
961 dest_id, dest_id_type,
962 packet->data, packet->len, FALSE);
963 silc_buffer_free(packet);
966 /* Sends notify message to a channel. The notify message sent is
967 distributed to all clients on the channel. If `route_notify' is TRUE
968 then the notify may be routed to primary route or to some other routers.
969 If FALSE it is assured that the notify is sent only locally. If `sender'
970 is provided then the packet is not sent to that connection since it
971 originally came from it. */
973 void silc_server_send_notify_to_channel(SilcServer server,
974 SilcSocketConnection sender,
975 SilcChannelEntry channel,
976 unsigned char route_notify,
978 unsigned int argc, ...)
985 packet = silc_notify_payload_encode(type, argc, ap);
986 silc_server_packet_send_to_channel(server, sender, channel,
987 SILC_PACKET_NOTIFY, route_notify,
988 packet->data, packet->len, FALSE);
989 silc_buffer_free(packet);
992 /* Send notify message to all clients the client has joined. It is quaranteed
993 that the message is sent only once to a client (ie. if a client is joined
994 on two same channel it will receive only one notify message). Also, this
995 sends only to local clients (locally connected if we are server, and to
996 local servers if we are router). */
998 void silc_server_send_notify_on_channels(SilcServer server,
999 SilcClientEntry client,
1000 SilcNotifyType type,
1001 unsigned int argc, ...)
1004 SilcSocketConnection sock = NULL;
1005 SilcPacketContext packetdata;
1007 SilcClientEntry *sent_clients = NULL;
1008 unsigned int sent_clients_count = 0;
1009 SilcServerEntry *routed = NULL;
1010 unsigned int routed_count = 0;
1011 SilcChannelEntry channel;
1012 SilcChannelClientEntry chl, chl2;
1013 SilcIDListData idata;
1015 unsigned char *data;
1016 unsigned int data_len;
1017 int force_send = FALSE;
1020 SILC_LOG_DEBUG(("Start"));
1022 if (!silc_list_count(client->channels))
1026 packet = silc_notify_payload_encode(type, argc, ap);
1027 data = packet->data;
1028 data_len = packet->len;
1030 /* Set the packet context pointers. */
1031 packetdata.flags = 0;
1032 packetdata.type = SILC_PACKET_NOTIFY;
1033 packetdata.src_id = silc_id_id2str(server->id, SILC_ID_SERVER);
1034 packetdata.src_id_len = SILC_ID_SERVER_LEN;
1035 packetdata.src_id_type = SILC_ID_SERVER;
1037 silc_list_start(client->channels);
1038 while ((chl = silc_list_get(client->channels)) != SILC_LIST_END) {
1039 channel = chl->channel;
1041 /* Send the message to all clients on the channel's client list. */
1042 silc_list_start(channel->user_list);
1043 while ((chl2 = silc_list_get(channel->user_list)) != SILC_LIST_END) {
1046 /* Check if we have sent the packet to this client already */
1047 for (k = 0; k < sent_clients_count; k++)
1048 if (sent_clients[k] == c)
1050 if (k < sent_clients_count)
1053 /* If we are router and if this client has router set it is not
1054 locally connected client and we will route the message to the
1055 router set in the client. */
1056 if (c && c->router && server->server_type == SILC_ROUTER) {
1057 /* Check if we have sent the packet to this route already */
1058 for (k = 0; k < routed_count; k++)
1059 if (routed[k] == c->router)
1061 if (k < routed_count)
1064 /* Get data used in packet header encryption, keys and stuff. */
1065 sock = (SilcSocketConnection)c->router->connection;
1066 idata = (SilcIDListData)c->router;
1068 packetdata.dst_id = silc_id_id2str(c->router->id, SILC_ID_SERVER);
1069 packetdata.dst_id_len = SILC_ID_SERVER_LEN;
1070 packetdata.dst_id_type = SILC_ID_SERVER;
1071 packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
1072 packetdata.src_id_len + packetdata.dst_id_len;
1073 packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
1075 /* Send the packet */
1076 silc_server_packet_send_to_channel_real(server, sock, &packetdata,
1077 idata->send_key, idata->hmac,
1078 data, data_len, FALSE,
1081 silc_free(packetdata.dst_id);
1083 /* We want to make sure that the packet is routed to same router
1084 only once. Mark this route as sent route. */
1086 routed = silc_realloc(routed, sizeof(*routed) * (k + 1));
1087 routed[k] = c->router;
1096 /* Send to locally connected client */
1099 /* Get data used in packet header encryption, keys and stuff. */
1100 sock = (SilcSocketConnection)c->connection;
1101 idata = (SilcIDListData)c;
1103 packetdata.dst_id = silc_id_id2str(c->id, SILC_ID_CLIENT);
1104 packetdata.dst_id_len = SILC_ID_CLIENT_LEN;
1105 packetdata.dst_id_type = SILC_ID_CLIENT;
1106 packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
1107 packetdata.src_id_len + packetdata.dst_id_len;
1108 packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
1110 /* Send the packet */
1111 silc_server_packet_send_to_channel_real(server, sock, &packetdata,
1112 idata->send_key, idata->hmac,
1113 data, data_len, FALSE,
1116 silc_free(packetdata.dst_id);
1118 /* Make sure that we send the notify only once per client. */
1119 sent_clients = silc_realloc(sent_clients, sizeof(*sent_clients) *
1120 (sent_clients_count + 1));
1121 sent_clients[sent_clients_count] = c;
1122 sent_clients_count++;
1129 if (sent_clients_count)
1130 silc_free(sent_clients);
1131 silc_free(packetdata.src_id);
1134 /* Sends New ID Payload to remote end. The packet is used to distribute
1135 information about new registered clients, servers, channel etc. usually
1136 to routers so that they can keep these information up to date.
1137 If the argument `broadcast' is TRUE then the packet is sent as
1138 broadcast packet. */
1140 void silc_server_send_new_id(SilcServer server,
1141 SilcSocketConnection sock,
1143 void *id, SilcIdType id_type,
1144 unsigned int id_len)
1148 SILC_LOG_DEBUG(("Start"));
1150 idp = silc_id_payload_encode(id, id_type);
1151 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID,
1152 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
1153 idp->data, idp->len, FALSE);
1154 silc_buffer_free(idp);
1157 /* Send New Channel Payload to notify about newly created channel in the
1158 SILC network. Normal server nevers sends this packet. Router uses this
1159 to notify other routers in the network about new channel. This packet
1162 void silc_server_send_new_channel(SilcServer server,
1163 SilcSocketConnection sock,
1167 unsigned int channel_id_len)
1171 unsigned int name_len = strlen(channel_name);
1173 SILC_LOG_DEBUG(("Start"));
1175 cid = silc_id_id2str(channel_id, SILC_ID_CHANNEL);
1179 packet = silc_buffer_alloc(2 + 2 + name_len + channel_id_len);
1180 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
1181 silc_buffer_format(packet,
1182 SILC_STR_UI_SHORT(name_len),
1183 SILC_STR_UI_XNSTRING(channel_name, name_len),
1184 SILC_STR_UI_SHORT(channel_id_len),
1185 SILC_STR_UI_XNSTRING(cid, channel_id_len),
1189 silc_server_packet_send(server, sock, SILC_PACKET_NEW_CHANNEL,
1190 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
1191 packet->data, packet->len, FALSE);
1194 silc_buffer_free(packet);
1197 /* Send Channel Key payload to distribute the new channel key. Normal server
1198 sends this to router when new client joins to existing channel. Router
1199 sends this to the local server who sent the join command in case where
1200 the channel did not exist yet. Both normal and router servers uses this
1201 also to send this to locally connected clients on the channel. This
1202 must not be broadcasted packet. Routers do not send this to each other.
1203 If `sender is provided then the packet is not sent to that connection since
1204 it originally came from it. */
1206 void silc_server_send_channel_key(SilcServer server,
1207 SilcSocketConnection sender,
1208 SilcChannelEntry channel,
1209 unsigned char route)
1212 unsigned char *chid;
1213 unsigned int tmp_len;
1215 SILC_LOG_DEBUG(("Start"));
1217 chid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1221 /* Encode channel key packet */
1222 tmp_len = strlen(channel->channel_key->cipher->name);
1223 packet = silc_channel_key_payload_encode(SILC_ID_CHANNEL_LEN, chid, tmp_len,
1224 channel->channel_key->cipher->name,
1225 channel->key_len / 8, channel->key);
1227 silc_server_packet_send_to_channel(server, sender, channel,
1228 SILC_PACKET_CHANNEL_KEY,
1229 route, packet->data, packet->len, FALSE);
1230 silc_buffer_free(packet);
1234 /* Generic function to send any command. The arguments must be sent already
1235 encoded into correct form in correct order. */
1237 void silc_server_send_command(SilcServer server,
1238 SilcSocketConnection sock,
1239 SilcCommand command,
1240 unsigned int argc, ...)
1247 packet = silc_command_payload_encode_vap(command, 0, argc, ap);
1248 silc_server_packet_send(server, sock, SILC_PACKET_COMMAND, 0,
1249 packet->data, packet->len, TRUE);
1250 silc_buffer_free(packet);
1253 /* Send the heartbeat packet. */
1255 void silc_server_send_heartbeat(SilcServer server,
1256 SilcSocketConnection sock)
1258 silc_server_packet_send(server, sock, SILC_PACKET_HEARTBEAT, 0,