updates.
[silc.git] / apps / silcd / packet_receive.c
1 /*
2
3   packet_receive.c
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 1997 - 2001 Pekka Riikonen
8
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.
13   
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.
18
19 */
20 /*
21  * Server packet routines to handle received packets.
22  */
23 /* $Id$ */
24
25 #include "serverincludes.h"
26 #include "server_internal.h"
27
28 extern char *server_version;
29
30 /* Received notify packet. Server can receive notify packets from router. 
31    Server then relays the notify messages to clients if needed. */
32
33 void silc_server_notify(SilcServer server,
34                         SilcSocketConnection sock,
35                         SilcPacketContext *packet)
36 {
37   SilcNotifyPayload payload;
38   SilcNotifyType type;
39   SilcArgumentPayload args;
40   SilcChannelID *channel_id;
41   SilcClientID *client_id, *client_id2;
42   SilcChannelEntry channel;
43   SilcClientEntry client;
44   SilcChannelClientEntry chl;
45   unsigned int mode;
46   unsigned char *tmp;
47   unsigned int tmp_len;
48
49   SILC_LOG_DEBUG(("Start"));
50
51   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
52       packet->src_id_type != SILC_ID_SERVER)
53     return;
54
55   /* If we are router and this packet is not already broadcast packet
56      we will broadcast it. The sending socket really cannot be router or
57      the router is buggy. If this packet is coming from router then it must
58      have the broadcast flag set already and we won't do anything. */
59   if (!server->standalone && server->server_type == SILC_ROUTER &&
60       sock->type == SILC_SOCKET_TYPE_SERVER &&
61       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
62     SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
63     silc_server_packet_send(server, server->router->connection, packet->type,
64                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
65                             packet->buffer->data, packet->buffer->len, FALSE);
66   }
67
68   payload = silc_notify_payload_parse(packet->buffer);
69   if (!payload)
70     return;
71
72   type = silc_notify_get_type(payload);
73   args = silc_notify_get_args(payload);
74   if (!args)
75     goto out;
76
77   switch(type) {
78   case SILC_NOTIFY_TYPE_JOIN:
79     /* 
80      * Distribute the notify to local clients on the channel
81      */
82     SILC_LOG_DEBUG(("JOIN notify"));
83
84     /* Get Channel ID */
85     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
86     if (!tmp)
87       goto out;
88     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
89     if (!channel_id)
90       goto out;
91
92     /* Get channel entry */
93     channel = silc_idlist_find_channel_by_id(server->local_list, 
94                                              channel_id, NULL);
95     if (!channel) {
96       channel = silc_idlist_find_channel_by_id(server->global_list, 
97                                                channel_id, NULL);
98       if (!channel) {
99         silc_free(channel_id);
100         goto out;
101       }
102     }
103     silc_free(channel_id);
104
105     /* Get client ID */
106     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
107     if (!tmp)
108       goto out;
109     client_id = silc_id_payload_parse_id(tmp, tmp_len);
110     if (!client_id)
111       goto out;
112
113     /* Send to channel */
114     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
115                                        FALSE, packet->buffer->data, 
116                                        packet->buffer->len, FALSE);
117
118     /* If the the client is not in local list we check global list (ie. the
119        channel will be global channel) and if it does not exist then create
120        entry for the client. */
121     client = silc_idlist_find_client_by_id(server->local_list, 
122                                            client_id, NULL);
123     if (!client) {
124       client = silc_idlist_find_client_by_id(server->global_list, 
125                                              client_id, NULL);
126       if (!client) {
127         /* If router did not find the client the it is bogus */
128         if (server->server_type == SILC_ROUTER)
129           goto out;
130
131         client = 
132           silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
133                                  silc_id_dup(client_id, SILC_ID_CLIENT), 
134                                  sock->user_data, NULL);
135         if (!client) {
136           silc_free(client_id);
137           goto out;
138         }
139       }
140     }
141
142     /* Do not add client to channel if it is there already */
143     if (silc_server_client_on_channel(client, channel))
144       break;
145
146     if (server->server_type == SILC_SERVER && 
147         sock->type == SILC_SOCKET_TYPE_ROUTER)
148       /* The channel is global now */
149       channel->global_users = TRUE;
150
151     /* JOIN the global client to the channel (local clients (if router 
152        created the channel) is joined in the pending JOIN command). */
153     chl = silc_calloc(1, sizeof(*chl));
154     chl->client = client;
155     chl->channel = channel;
156     silc_list_add(channel->user_list, chl);
157     silc_list_add(client->channels, chl);
158     silc_free(client_id);
159
160     break;
161
162   case SILC_NOTIFY_TYPE_LEAVE:
163     /* 
164      * Distribute the notify to local clients on the channel
165      */
166     SILC_LOG_DEBUG(("LEAVE notify"));
167
168     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
169                                 packet->dst_id_type);
170     if (!channel_id)
171       goto out;
172
173     /* Get channel entry */
174     channel = silc_idlist_find_channel_by_id(server->local_list, 
175                                              channel_id, NULL);
176     if (!channel) { 
177       silc_free(channel_id);
178       goto out;
179     }
180
181     /* Get client ID */
182     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
183     if (!tmp) {
184       silc_free(channel_id);
185       goto out;
186     }
187     client_id = silc_id_payload_parse_id(tmp, tmp_len);
188     if (!client_id) {
189       silc_free(channel_id);
190       goto out;
191     }
192
193     /* Send to channel */
194     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
195                                        FALSE, packet->buffer->data, 
196                                        packet->buffer->len, FALSE);
197
198     /* Get client entry */
199     client = silc_idlist_find_client_by_id(server->global_list, 
200                                            client_id, NULL);
201     if (!client) {
202       client = silc_idlist_find_client_by_id(server->local_list, 
203                                              client_id, NULL);
204       if (!client) {
205         silc_free(client_id);
206         silc_free(channel_id);
207         goto out;
208       }
209     }
210     silc_free(client_id);
211
212     /* Remove the user from channel */
213     silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
214     break;
215
216   case SILC_NOTIFY_TYPE_SIGNOFF:
217     /* 
218      * Distribute the notify to local clients on the channel
219      */
220     SILC_LOG_DEBUG(("SIGNOFF notify"));
221
222     /* Get client ID */
223     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
224     if (!tmp)
225       goto out;
226     client_id = silc_id_payload_parse_id(tmp, tmp_len);
227     if (!client_id)
228       goto out;
229
230     /* Get client entry */
231     client = silc_idlist_find_client_by_id(server->global_list, 
232                                            client_id, NULL);
233     if (!client) {
234       client = silc_idlist_find_client_by_id(server->local_list, 
235                                              client_id, NULL);
236       if (!client) {
237         silc_free(client_id);
238         goto out;
239       }
240     }
241     silc_free(client_id);
242
243     /* Get signoff message */
244     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
245     if (tmp_len > 128)
246       tmp = NULL;
247
248     /* Remove the client from all channels */
249     silc_server_remove_from_channels(server, NULL, client, tmp);
250
251     /* Remove the client entry */
252     if (!silc_idlist_del_client(server->global_list, client))
253       silc_idlist_del_client(server->local_list, client);
254     break;
255
256   case SILC_NOTIFY_TYPE_TOPIC_SET:
257     /* 
258      * Distribute the notify to local clients on the channel
259      */
260
261     SILC_LOG_DEBUG(("TOPIC SET notify"));
262
263     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
264                                 packet->dst_id_type);
265     if (!channel_id)
266       goto out;
267
268     /* Get channel entry */
269     channel = silc_idlist_find_channel_by_id(server->local_list, 
270                                              channel_id, NULL);
271     if (!channel) {
272       channel = silc_idlist_find_channel_by_id(server->global_list, 
273                                                channel_id, NULL);
274       if (!channel) {
275         silc_free(channel_id);
276         goto out;
277       }
278     }
279
280     /* Get the topic */
281     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
282     if (!tmp) {
283       silc_free(channel_id);
284       goto out;
285     }
286
287     if (channel->topic)
288       silc_free(channel->topic);
289     channel->topic = silc_calloc(tmp_len, sizeof(*channel->topic));
290     memcpy(channel->topic, tmp, tmp_len);
291
292     /* Send the same notify to the channel */
293     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
294                                        FALSE, packet->buffer->data, 
295                                        packet->buffer->len, FALSE);
296     silc_free(channel_id);
297     break;
298
299   case SILC_NOTIFY_TYPE_NICK_CHANGE:
300     {
301       /* 
302        * Distribute the notify to local clients on the channel
303        */
304       unsigned char *id, *id2;
305
306       SILC_LOG_DEBUG(("NICK CHANGE notify"));
307       
308       /* Get old client ID */
309       id = silc_argument_get_arg_type(args, 1, &tmp_len);
310       if (!id)
311         goto out;
312       client_id = silc_id_payload_parse_id(id, tmp_len);
313       if (!client_id)
314         goto out;
315       
316       /* Get new client ID */
317       id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
318       if (!id2)
319         goto out;
320       client_id2 = silc_id_payload_parse_id(id2, tmp_len);
321       if (!client_id2)
322         goto out;
323       
324       SILC_LOG_DEBUG(("Old Client ID id(%s)", 
325                       silc_id_render(client_id, SILC_ID_CLIENT)));
326       SILC_LOG_DEBUG(("New Client ID id(%s)", 
327                       silc_id_render(client_id2, SILC_ID_CLIENT)));
328
329       /* Replace the Client ID */
330       client = silc_idlist_replace_client_id(server->global_list, client_id,
331                                              client_id2);
332       if (!client)
333         client = silc_idlist_replace_client_id(server->local_list, client_id, 
334                                                client_id2);
335
336       if (client) {
337         /* The nickname is not valid anymore, set it NULL. This causes that
338            the nickname will be queried if someone wants to know it. */
339         if (client->nickname)
340           silc_free(client->nickname);
341         client->nickname = NULL;
342
343         /* Send the NICK_CHANGE notify type to local clients on the channels
344            this client is joined to. */
345         silc_server_send_notify_on_channels(server, client, 
346                                             SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
347                                             id, tmp_len, 
348                                             id2, tmp_len);
349       }
350
351       silc_free(client_id);
352       if (!client)
353         silc_free(client_id2);
354       break;
355     }
356
357   case SILC_NOTIFY_TYPE_CMODE_CHANGE:
358     /* 
359      * Distribute the notify to local clients on the channel
360      */
361     
362     SILC_LOG_DEBUG(("CMODE CHANGE notify"));
363       
364     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
365                                 packet->dst_id_type);
366     if (!channel_id)
367       goto out;
368
369     /* Get channel entry */
370     channel = silc_idlist_find_channel_by_id(server->local_list, 
371                                              channel_id, NULL);
372     if (!channel) {
373       channel = silc_idlist_find_channel_by_id(server->global_list, 
374                                                channel_id, NULL);
375       if (!channel) {
376         silc_free(channel_id);
377         goto out;
378       }
379     }
380
381     /* Send the same notify to the channel */
382     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
383                                        FALSE, packet->buffer->data, 
384                                        packet->buffer->len, FALSE);
385
386     /* Get the mode */
387     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
388     if (!tmp) {
389       silc_free(channel_id);
390       goto out;
391     }
392
393     SILC_GET32_MSB(mode, tmp);
394
395     /* Change mode */
396     channel->mode = mode;
397     silc_free(channel_id);
398     break;
399
400   case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
401     /* 
402      * Distribute the notify to local clients on the channel
403      */
404
405     SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
406
407     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
408                                 packet->dst_id_type);
409     if (!channel_id)
410       goto out;
411
412     /* Get channel entry */
413     channel = silc_idlist_find_channel_by_id(server->local_list, 
414                                              channel_id, NULL);
415     if (!channel) {
416       channel = silc_idlist_find_channel_by_id(server->global_list, 
417                                                channel_id, NULL);
418       if (!channel) {
419         silc_free(channel_id);
420         goto out;
421       }
422     }
423
424     /* Get the mode */
425     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
426     if (!tmp) {
427       silc_free(channel_id);
428       goto out;
429     }
430       
431     SILC_GET32_MSB(mode, tmp);
432
433     /* Get target client */
434     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
435     if (!tmp)
436       goto out;
437     client_id = silc_id_payload_parse_id(tmp, tmp_len);
438     if (!client_id)
439       goto out;
440     
441     /* Get client entry */
442     client = silc_idlist_find_client_by_id(server->global_list, 
443                                            client_id, NULL);
444     if (!client) {
445       client = silc_idlist_find_client_by_id(server->local_list, 
446                                              client_id, NULL);
447       if (!client) {
448         silc_free(client_id);
449         goto out;
450       }
451     }
452     silc_free(client_id);
453
454     /* Get entry to the channel user list */
455     silc_list_start(channel->user_list);
456     while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
457       if (chl->client == client) {
458         /* Change the mode */
459         chl->mode = mode;
460         break;
461       }
462
463     /* Send the same notify to the channel */
464     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
465                                        FALSE, packet->buffer->data, 
466                                        packet->buffer->len, FALSE);
467     silc_free(channel_id);
468     break;
469
470   case SILC_NOTIFY_TYPE_INVITE:
471     SILC_LOG_DEBUG(("INVITE notify (not-impl XXX)"));
472     break;
473
474   case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
475     SILC_LOG_DEBUG(("CHANNEL CHANGE notify (not-impl XXX)"));
476     break;
477
478   case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
479     SILC_LOG_DEBUG(("SERVER SIGNOFF notify (not-impl XXX)"));
480     break;
481
482     /* Ignore rest of the notify types for now */
483   case SILC_NOTIFY_TYPE_NONE:
484   case SILC_NOTIFY_TYPE_MOTD:
485     break;
486   default:
487     break;
488   }
489
490  out:
491   silc_notify_payload_free(payload);
492 }
493
494 void silc_server_notify_list(SilcServer server,
495                              SilcSocketConnection sock,
496                              SilcPacketContext *packet)
497 {
498   SilcPacketContext *new;
499   SilcBuffer buffer;
500   unsigned short len;
501
502   SILC_LOG_DEBUG(("Processing New Notify List"));
503
504   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
505       packet->src_id_type != SILC_ID_SERVER)
506     return;
507
508   /* Make copy of the original packet context, except for the actual
509      data buffer, which we will here now fetch from the original buffer. */
510   new = silc_packet_context_alloc();
511   new->type = SILC_PACKET_NOTIFY;
512   new->flags = packet->flags;
513   new->src_id = packet->src_id;
514   new->src_id_len = packet->src_id_len;
515   new->src_id_type = packet->src_id_type;
516   new->dst_id = packet->dst_id;
517   new->dst_id_len = packet->dst_id_len;
518   new->dst_id_type = packet->dst_id_type;
519
520   buffer = silc_buffer_alloc(1024);
521   new->buffer = buffer;
522
523   while (packet->buffer->len) {
524     SILC_GET16_MSB(len, packet->buffer->data + 2);
525     if (len > packet->buffer->len)
526       break;
527
528     if (len > buffer->truelen) {
529       silc_buffer_free(buffer);
530       buffer = silc_buffer_alloc(1024 + len);
531     }
532
533     silc_buffer_pull_tail(buffer, len);
534     silc_buffer_put(buffer, packet->buffer->data, len);
535
536     /* Process the Notify */
537     silc_server_notify(server, sock, new);
538
539     silc_buffer_push_tail(buffer, len);
540     silc_buffer_pull(packet->buffer, len);
541   }
542
543   silc_buffer_free(buffer);
544   silc_free(new);
545 }
546
547 /* Received private message. This resolves the destination of the message 
548    and sends the packet. This is used by both server and router.  If the
549    destination is our locally connected client this sends the packet to
550    the client. This may also send the message for further routing if
551    the destination is not in our server (or router). */
552
553 void silc_server_private_message(SilcServer server,
554                                  SilcSocketConnection sock,
555                                  SilcPacketContext *packet)
556 {
557   SilcClientID *id;
558   SilcServerEntry router;
559   SilcSocketConnection dst_sock;
560   SilcClientEntry client;
561   SilcIDListData idata;
562
563   SILC_LOG_DEBUG(("Start"));
564
565   if (!packet->dst_id)
566     goto err;
567
568   /* Decode destination Client ID */
569   id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
570   if (!id) {
571     SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
572     goto err;
573   }
574
575   /* If the destination belongs to our server we don't have to route
576      the message anywhere but to send it to the local destination. */
577   client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
578   if (client) {
579     /* It exists, now deliver the message to the destination */
580     dst_sock = (SilcSocketConnection)client->connection;
581
582     /* If we are router and the client has router then the client is in
583        our cell but not directly connected to us. */
584     if (server->server_type == SILC_ROUTER && client->router) {
585       /* We are of course in this case the client's router thus the real
586          "router" of the client is the server who owns the client. Thus
587          we will send the packet to that server. */
588       router = (SilcServerEntry)client->router;
589       idata = (SilcIDListData)router;
590
591       silc_server_send_private_message(server, router->connection,
592                                        idata->send_key,
593                                        idata->hmac,
594                                        packet);
595       return;
596     }
597
598     /* Seems that client really is directly connected to us */
599     idata = (SilcIDListData)client;
600     silc_server_send_private_message(server, dst_sock, 
601                                      idata->send_key,
602                                      idata->hmac, packet);
603     return;
604   }
605
606   /* Destination belongs to someone not in this server. If we are normal
607      server our action is to send the packet to our router. */
608   if (server->server_type == SILC_SERVER && !server->standalone) {
609     router = server->router;
610
611     /* Send to primary route */
612     if (router) {
613       dst_sock = (SilcSocketConnection)router->connection;
614       idata = (SilcIDListData)router;
615       silc_server_send_private_message(server, dst_sock, 
616                                        idata->send_key,
617                                        idata->hmac, packet);
618     }
619     return;
620   }
621
622   /* We are router and we will perform route lookup for the destination 
623      and send the message to fastest route. */
624   if (server->server_type == SILC_ROUTER && !server->standalone) {
625     /* Check first that the ID is valid */
626     client = silc_idlist_find_client_by_id(server->global_list, id, NULL);
627     if (client) {
628       dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
629       router = (SilcServerEntry)dst_sock->user_data;
630       idata = (SilcIDListData)router;
631
632       /* Get fastest route and send packet. */
633       if (router)
634         silc_server_send_private_message(server, dst_sock, 
635                                          idata->send_key,
636                                          idata->hmac, packet);
637       return;
638     }
639   }
640
641  err:
642   silc_server_send_error(server, sock, 
643                          "No such nickname: Private message not sent");
644 }
645
646 /* Processes incoming command reply packet. The command reply packet may
647    be destined to one of our clients or it may directly for us. We will 
648    call the command reply routine after processing the packet. */
649
650 void silc_server_command_reply(SilcServer server,
651                                SilcSocketConnection sock,
652                                SilcPacketContext *packet)
653 {
654   SilcBuffer buffer = packet->buffer;
655   SilcClientEntry client = NULL;
656   SilcSocketConnection dst_sock;
657   SilcIDListData idata;
658   SilcClientID *id = NULL;
659
660   SILC_LOG_DEBUG(("Start"));
661
662   /* Source must be server or router */
663   if (packet->src_id_type != SILC_ID_SERVER &&
664       sock->type != SILC_SOCKET_TYPE_ROUTER)
665     return;
666
667   if (packet->dst_id_type == SILC_ID_CHANNEL)
668     return;
669
670   if (packet->dst_id_type == SILC_ID_CLIENT) {
671     /* Destination must be one of ours */
672     id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
673     if (!id)
674       return;
675     client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
676     if (!client) {
677       SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
678       silc_free(id);
679       return;
680     }
681   }
682
683   if (packet->dst_id_type == SILC_ID_SERVER) {
684     /* For now this must be for us */
685     if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
686       SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
687       return;
688     }
689   }
690
691   /* Execute command reply locally for the command */
692   silc_server_command_reply_process(server, sock, buffer);
693
694   if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
695     /* Relay the packet to the client */
696     
697     dst_sock = (SilcSocketConnection)client->connection;
698     silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len 
699                      + packet->dst_id_len + packet->padlen);
700     
701     silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
702     silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
703     
704     idata = (SilcIDListData)client;
705     
706     /* Encrypt packet */
707     silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf, 
708                         buffer->len);
709     
710     /* Send the packet */
711     silc_server_packet_send_real(server, dst_sock, TRUE);
712
713     silc_free(id);
714   }
715 }
716
717 /* Process received channel message. The message can be originated from
718    client or server. */
719
720 void silc_server_channel_message(SilcServer server,
721                                  SilcSocketConnection sock,
722                                  SilcPacketContext *packet)
723 {
724   SilcChannelEntry channel = NULL;
725   SilcChannelClientEntry chl;
726   SilcChannelID *id = NULL;
727   void *sender = NULL;
728
729   SILC_LOG_DEBUG(("Processing channel message"));
730
731   /* Sanity checks */
732   if (packet->dst_id_type != SILC_ID_CHANNEL) {
733     SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
734     goto out;
735   }
736
737   /* Find channel entry */
738   id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
739   if (!id)
740     goto out;
741   channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
742   if (!channel) {
743     channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
744     if (!channel) {
745       SILC_LOG_DEBUG(("Could not find channel"));
746       goto out;
747     }
748   }
749
750   /* See that this client is on the channel. If the message is coming
751      from router we won't do the check as the message is from client that
752      we don't know about. Also, if the original sender is not client
753      (as it can be server as well) we don't do the check. */
754   sender = silc_id_str2id(packet->src_id, packet->src_id_len, 
755                           packet->src_id_type);
756   if (!sender)
757     goto out;
758   if (sock->type != SILC_SOCKET_TYPE_ROUTER && 
759       packet->src_id_type == SILC_ID_CLIENT) {
760     silc_list_start(channel->user_list);
761     while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
762       if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
763         break;
764     }
765     if (chl == SILC_LIST_END) {
766       SILC_LOG_DEBUG(("Client not on channel"));
767       goto out;
768     }
769   }
770
771   /* Distribute the packet to our local clients. This will send the
772      packet for further routing as well, if needed. */
773   silc_server_packet_relay_to_channel(server, sock, channel, sender,
774                                       packet->src_id_type,
775                                       packet->buffer->data,
776                                       packet->buffer->len, FALSE);
777
778  out:
779   if (sender)
780     silc_free(sender);
781   if (id)
782     silc_free(id);
783 }
784
785 /* Received channel key packet. We distribute the key to all of our locally
786    connected clients on the channel. */
787
788 void silc_server_channel_key(SilcServer server,
789                              SilcSocketConnection sock,
790                              SilcPacketContext *packet)
791 {
792   SilcBuffer buffer = packet->buffer;
793   SilcChannelEntry channel;
794
795   if (packet->src_id_type != SILC_ID_SERVER)
796     return;
797
798   /* Save the channel key */
799   channel = silc_server_save_channel_key(server, buffer, NULL);
800   if (!channel)
801     return;
802
803   /* Distribute the key to everybody who is on the channel. If we are router
804      we will also send it to locally connected servers. */
805   silc_server_send_channel_key(server, sock, channel, FALSE);
806 }
807
808 /* Received New Client packet and processes it.  Creates Client ID for the
809    client. Client becomes registered after calling this functions. */
810
811 SilcClientEntry silc_server_new_client(SilcServer server,
812                                        SilcSocketConnection sock,
813                                        SilcPacketContext *packet)
814 {
815   SilcBuffer buffer = packet->buffer;
816   SilcClientEntry client;
817   SilcIDCacheEntry cache;
818   SilcClientID *client_id;
819   SilcBuffer reply;
820   SilcIDListData idata;
821   char *username = NULL, *realname = NULL, *id_string;
822   int ret;
823
824   SILC_LOG_DEBUG(("Creating new client"));
825
826   if (sock->type != SILC_SOCKET_TYPE_CLIENT)
827     return NULL;
828
829   /* Take client entry */
830   client = (SilcClientEntry)sock->user_data;
831   idata = (SilcIDListData)client;
832
833   /* Fetch the old client cache entry so that we can update it. */
834   if (!silc_idcache_find_by_context(server->local_list->clients,
835                                     sock->user_data, &cache)) {
836     SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
837     return NULL;
838   }
839
840   /* Parse incoming packet */
841   ret = silc_buffer_unformat(buffer,
842                              SILC_STR_UI16_STRING_ALLOC(&username),
843                              SILC_STR_UI16_STRING_ALLOC(&realname),
844                              SILC_STR_END);
845   if (ret == -1) {
846     if (username)
847       silc_free(username);
848     if (realname)
849       silc_free(realname);
850     return NULL;
851   }
852
853   if (!username) {
854     silc_free(username);
855     if (realname)
856       silc_free(realname);
857     silc_server_disconnect_remote(server, sock, "Server closed connection: "
858                                   "Incomplete client information");
859     return NULL;
860   }
861
862   /* Create Client ID */
863   silc_id_create_client_id(server->id, server->rng, server->md5hash,
864                            username, &client_id);
865
866   /* Update client entry */
867   idata->registered = TRUE;
868   client->nickname = strdup(username);
869   client->username = username;
870   client->userinfo = realname ? realname : strdup("");
871   client->id = client_id;
872
873   /* Update the cache entry */
874   cache->id = (void *)client_id;
875   cache->type = SILC_ID_CLIENT;
876   cache->data = username;
877   silc_idcache_sort_by_data(server->local_list->clients);
878
879   /* Notify our router about new client on the SILC network */
880   if (!server->standalone)
881     silc_server_send_new_id(server, (SilcSocketConnection) 
882                             server->router->connection, 
883                             server->server_type == SILC_ROUTER ? TRUE : FALSE,
884                             client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
885   
886   /* Send the new client ID to the client. */
887   id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
888   reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
889   silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
890   silc_buffer_format(reply,
891                      SILC_STR_UI_SHORT(SILC_ID_CLIENT),
892                      SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
893                      SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
894                      SILC_STR_END);
895   silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0, 
896                           reply->data, reply->len, FALSE);
897   silc_free(id_string);
898   silc_buffer_free(reply);
899
900   /* Send some nice info to the client */
901   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
902                           ("Welcome to the SILC Network %s@%s",
903                            username, sock->hostname));
904   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
905                           ("Your host is %s, running version %s",
906                            server->config->server_info->server_name,
907                            server_version));
908   if (server->server_type == SILC_ROUTER) {
909     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
910                             ("There are %d clients on %d servers in SILC "
911                              "Network", server->stat.clients,
912                              server->stat.servers + 1));
913     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
914                             ("There are %d clients on %d server in our cell",
915                              server->stat.cell_clients,
916                              server->stat.cell_servers + 1));
917     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
918                             ("I have %d clients, %d channels, %d servers and "
919                              "%d routers",
920                              server->stat.my_clients, 
921                              server->stat.my_channels,
922                              server->stat.my_servers,
923                              server->stat.my_routers));
924     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
925                             ("%d server operators and %d router operators "
926                              "online",
927                              server->stat.my_server_ops,
928                              server->stat.my_router_ops));
929   } else {
930     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
931                             ("I have %d clients and %d channels formed",
932                              server->stat.my_clients,
933                              server->stat.my_channels));
934     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
935                             ("%d operators online",
936                              server->stat.my_server_ops));
937   }
938   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
939                           ("Your connection is secured with %s cipher, "
940                            "key length %d bits",
941                            idata->send_key->cipher->name,
942                            idata->send_key->cipher->key_len));
943   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
944                           ("Your current nickname is %s",
945                            client->nickname));
946
947   /* Send motd */
948   silc_server_send_motd(server, sock);
949
950   return client;
951 }
952
953 /* Create new server. This processes received New Server packet and
954    saves the received Server ID. The server is our locally connected
955    server thus we save all the information and save it to local list. 
956    This funtion can be used by both normal server and router server.
957    If normal server uses this it means that its router has connected
958    to the server. If router uses this it means that one of the cell's
959    servers is connected to the router. */
960
961 SilcServerEntry silc_server_new_server(SilcServer server,
962                                        SilcSocketConnection sock,
963                                        SilcPacketContext *packet)
964 {
965   SilcBuffer buffer = packet->buffer;
966   SilcServerEntry new_server;
967   SilcIDCacheEntry cache;
968   SilcServerID *server_id;
969   SilcIDListData idata;
970   unsigned char *server_name, *id_string;
971   unsigned short id_len;
972   int ret;
973
974   SILC_LOG_DEBUG(("Creating new server"));
975
976   if (sock->type != SILC_SOCKET_TYPE_SERVER &&
977       sock->type != SILC_SOCKET_TYPE_ROUTER)
978     return NULL;
979
980   /* Take server entry */
981   new_server = (SilcServerEntry)sock->user_data;
982   idata = (SilcIDListData)new_server;
983
984   /* Fetch the old server cache entry so that we can update it. */
985   if (!silc_idcache_find_by_context(server->local_list->servers,
986                                     sock->user_data, &cache)) {
987     SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
988     return NULL;
989   }
990
991   /* Parse the incoming packet */
992   ret = silc_buffer_unformat(buffer,
993                              SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
994                              SILC_STR_UI16_STRING_ALLOC(&server_name),
995                              SILC_STR_END);
996   if (ret == -1) {
997     if (id_string)
998       silc_free(id_string);
999     if (server_name)
1000       silc_free(server_name);
1001     return NULL;
1002   }
1003
1004   if (id_len > buffer->len) {
1005     silc_free(id_string);
1006     silc_free(server_name);
1007     return NULL;
1008   }
1009
1010   /* Get Server ID */
1011   server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1012   if (!server_id) {
1013     silc_free(id_string);
1014     silc_free(server_name);
1015     return NULL;
1016   }
1017   silc_free(id_string);
1018
1019   /* Update client entry */
1020   idata->registered = TRUE;
1021   new_server->server_name = server_name;
1022   new_server->id = server_id;
1023
1024   /* Update the cache entry */
1025   cache->id = (void *)server_id;
1026   cache->type = SILC_ID_SERVER;
1027   cache->data = server_name;
1028   silc_idcache_sort_by_data(server->local_list->servers);
1029
1030   /* Distribute the information about new server in the SILC network
1031      to our router. If we are normal server we won't send anything
1032      since this connection must be our router connection. */
1033   if (server->server_type == SILC_ROUTER && !server->standalone &&
1034       server->router->connection != sock)
1035     silc_server_send_new_id(server, server->router->connection,
1036                             TRUE, new_server->id, SILC_ID_SERVER, 
1037                             SILC_ID_SERVER_LEN);
1038
1039   if (server->server_type == SILC_ROUTER)
1040     server->stat.cell_servers++;
1041
1042   return new_server;
1043 }
1044
1045 /* Processes incoming New ID packet. New ID Payload is used to distribute
1046    information about newly registered clients and servers. */
1047
1048 static void silc_server_new_id_real(SilcServer server, 
1049                                     SilcSocketConnection sock,
1050                                     SilcPacketContext *packet,
1051                                     int broadcast)
1052 {
1053   SilcBuffer buffer = packet->buffer;
1054   SilcIDList id_list;
1055   SilcServerEntry router;
1056   SilcSocketConnection router_sock;
1057   SilcIDPayload idp;
1058   SilcIdType id_type;
1059   unsigned char *hash = NULL;
1060   void *id;
1061
1062   SILC_LOG_DEBUG(("Processing new ID"));
1063
1064   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1065       server->server_type == SILC_SERVER ||
1066       packet->src_id_type != SILC_ID_SERVER)
1067     return;
1068
1069   idp = silc_id_payload_parse(buffer);
1070   if (!idp)
1071     return;
1072
1073   id_type = silc_id_payload_get_type(idp);
1074
1075   /* Normal server cannot have other normal server connections */
1076   if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1077     goto out;
1078
1079   id = silc_id_payload_get_id(idp);
1080   if (!id)
1081     goto out;
1082
1083   /* If the sender of this packet is server and we are router we need to
1084      broadcast this packet to other routers in the network. */
1085   if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1086       sock->type == SILC_SOCKET_TYPE_SERVER &&
1087       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1088     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1089     silc_server_packet_send(server, server->router->connection,
1090                             packet->type, 
1091                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1092                             buffer->data, buffer->len, FALSE);
1093   }
1094
1095   if (sock->type == SILC_SOCKET_TYPE_SERVER)
1096     id_list = server->local_list;
1097   else
1098     id_list = server->global_list;
1099
1100   router_sock = sock;
1101   router = sock->user_data;
1102
1103   switch(id_type) {
1104   case SILC_ID_CLIENT:
1105     {
1106       SilcClientEntry entry;
1107
1108       SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1109                       silc_id_render(id, SILC_ID_CLIENT),
1110                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1111                       "Server" : "Router", sock->hostname));
1112     
1113       /* As a router we keep information of all global information in our
1114          global list. Cell wide information however is kept in the local
1115          list. The client is put to global list and we will take the hash
1116          value of the Client ID and save it to the ID Cache system for fast
1117          searching in the future. */
1118       hash = silc_calloc(sizeof(((SilcClientID *)id)->hash), 
1119                          sizeof(unsigned char));
1120       memcpy(hash, ((SilcClientID *)id)->hash, 
1121              sizeof(((SilcClientID *)id)->hash));
1122       entry = silc_idlist_add_client(id_list, hash, NULL, NULL, id, 
1123                                      router, NULL);
1124       entry->nickname = NULL;
1125
1126       if (sock->type == SILC_SOCKET_TYPE_SERVER)
1127         server->stat.cell_clients++;
1128       server->stat.clients++;
1129
1130 #if 0
1131       /* XXX Adding two ID's with same IP number replaces the old entry thus
1132          gives wrong route. Thus, now disabled until figured out a better way
1133          to do this or when removed the whole thing. This could be removed
1134          because entry->router->connection gives always the most optimal route
1135          for the ID anyway (unless new routes (faster perhaps) are established
1136          after receiving this ID, this we don't know however). */
1137       /* Add route cache for this ID */
1138       silc_server_route_add(silc_server_route_hash(
1139                             ((SilcClientID *)id)->ip.s_addr,
1140                             server->id->port), ((SilcClientID *)id)->ip.s_addr,
1141                             router);
1142 #endif
1143     }
1144     break;
1145
1146   case SILC_ID_SERVER:
1147     SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1148                     silc_id_render(id, SILC_ID_SERVER),
1149                     sock->type == SILC_SOCKET_TYPE_SERVER ?
1150                     "Server" : "Router", sock->hostname));
1151     
1152     /* As a router we keep information of all global information in our global
1153        list. Cell wide information however is kept in the local list. */
1154     silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1155
1156     if (sock->type == SILC_SOCKET_TYPE_SERVER)
1157       server->stat.cell_servers++;
1158     server->stat.servers++;
1159
1160 #if 0
1161     /* Add route cache for this ID */
1162     silc_server_route_add(silc_server_route_hash(
1163                           ((SilcServerID *)id)->ip.s_addr,
1164                           ((SilcServerID *)id)->port), 
1165                           ((SilcServerID *)id)->ip.s_addr,
1166                           router);
1167 #endif
1168     break;
1169
1170   case SILC_ID_CHANNEL:
1171     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1172     break;
1173
1174   default:
1175     break;
1176   }
1177
1178  out:
1179   silc_id_payload_free(idp);
1180 }
1181
1182
1183 /* Processes incoming New ID packet. New ID Payload is used to distribute
1184    information about newly registered clients and servers. */
1185
1186 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1187                         SilcPacketContext *packet)
1188 {
1189   silc_server_new_id_real(server, sock, packet, TRUE);
1190 }
1191
1192 /* Receoved New Id List packet, list of New ID payloads inside one
1193    packet. Process the New ID payloads one by one. */
1194
1195 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1196                              SilcPacketContext *packet)
1197 {
1198   SilcPacketContext *new_id;
1199   SilcBuffer idp;
1200   unsigned short id_len;
1201
1202   SILC_LOG_DEBUG(("Processing New ID List"));
1203
1204   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1205       packet->src_id_type != SILC_ID_SERVER)
1206     return;
1207
1208   /* If the sender of this packet is server and we are router we need to
1209      broadcast this packet to other routers in the network. Broadcast
1210      this list packet instead of multiple New ID packets. */
1211   if (!server->standalone && server->server_type == SILC_ROUTER &&
1212       sock->type == SILC_SOCKET_TYPE_SERVER &&
1213       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1214     SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1215     silc_server_packet_send(server, server->router->connection,
1216                             packet->type, 
1217                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1218                             packet->buffer->data, packet->buffer->len, FALSE);
1219   }
1220
1221   /* Make copy of the original packet context, except for the actual
1222      data buffer, which we will here now fetch from the original buffer. */
1223   new_id = silc_packet_context_alloc();
1224   new_id->type = SILC_PACKET_NEW_ID;
1225   new_id->flags = packet->flags;
1226   new_id->src_id = packet->src_id;
1227   new_id->src_id_len = packet->src_id_len;
1228   new_id->src_id_type = packet->src_id_type;
1229   new_id->dst_id = packet->dst_id;
1230   new_id->dst_id_len = packet->dst_id_len;
1231   new_id->dst_id_type = packet->dst_id_type;
1232
1233   idp = silc_buffer_alloc(256);
1234   new_id->buffer = idp;
1235
1236   while (packet->buffer->len) {
1237     SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1238     if ((id_len > packet->buffer->len) ||
1239         (id_len > idp->truelen))
1240       break;
1241
1242     silc_buffer_pull_tail(idp, 4 + id_len);
1243     silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1244
1245     /* Process the New ID */
1246     silc_server_new_id_real(server, sock, new_id, FALSE);
1247
1248     silc_buffer_push_tail(idp, 4 + id_len);
1249     silc_buffer_pull(packet->buffer, 4 + id_len);
1250   }
1251
1252   silc_buffer_free(idp);
1253   silc_free(new_id);
1254 }
1255
1256 /* Received New Channel packet. Information about new channels in the 
1257    network are distributed using this packet. Save the information about
1258    the new channel. This usually comes from router but also normal server
1259    can send this to notify channels it has when it connects to us. */
1260
1261 void silc_server_new_channel(SilcServer server,
1262                              SilcSocketConnection sock,
1263                              SilcPacketContext *packet)
1264 {
1265   unsigned char *id;
1266   SilcChannelID *channel_id;
1267   unsigned short channel_id_len;
1268   char *channel_name;
1269   int ret;
1270
1271   SILC_LOG_DEBUG(("Processing New Channel"));
1272
1273   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1274       packet->src_id_type != SILC_ID_SERVER ||
1275       server->server_type == SILC_SERVER)
1276     return;
1277
1278   /* Parse payload */
1279   ret = silc_buffer_unformat(packet->buffer, 
1280                              SILC_STR_UI16_STRING_ALLOC(&channel_name),
1281                              SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
1282                              SILC_STR_END);
1283   if (ret == -1) {
1284     if (channel_name)
1285       silc_free(channel_name);
1286     if (id)
1287       silc_free(id);
1288     return;
1289   }
1290     
1291   /* Decode the channel ID */
1292   channel_id = silc_id_str2id(id, channel_id_len, SILC_ID_CHANNEL);
1293   if (!channel_id)
1294     return;
1295
1296   if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1297     /* Add the server to global list as it is coming from router. It 
1298        cannot be our own channel as it is coming from router. */
1299
1300     SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1301                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1302                     sock->hostname));
1303     
1304     silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id, 
1305                             server->router->connection, NULL);
1306
1307     server->stat.channels++;
1308   } else {
1309     /* The channel is coming from our server, thus it is in our cell
1310        we will add it to our local list. */
1311     SilcChannelEntry channel;
1312     SilcBuffer chk;
1313
1314     SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1315                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1316                     sock->hostname));
1317     
1318     /* Check that we don't already have this channel */
1319     channel = silc_idlist_find_channel_by_name(server->local_list, 
1320                                                channel_name, NULL);
1321     if (!channel)
1322       channel = silc_idlist_find_channel_by_name(server->global_list, 
1323                                                  channel_name, NULL);
1324
1325     /* If the channel does not exist, then create it. We create the channel
1326        with the channel ID provided by the server. This creates a new
1327        key to the channel as well that we will send to the server. */
1328     if (!channel) {
1329       channel = silc_server_create_new_channel_with_id(server, NULL,
1330                                                        channel_name,
1331                                                        channel_id, FALSE);
1332       if (!channel)
1333         return;
1334
1335       /* Send the new channel key to the server */
1336       chk = silc_channel_key_payload_encode(channel_id_len, id,
1337                                             strlen(channel->channel_key->
1338                                                    cipher->name),
1339                                             channel->channel_key->cipher->name,
1340                                             channel->key_len / 8, 
1341                                             channel->key);
1342       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1343                               chk->data, chk->len, FALSE);
1344       silc_buffer_free(chk);
1345
1346     } else {
1347       /* The channel exist by that name, check whether the ID's match.
1348          If they don't then we'll force the server to use the ID we have.
1349          We also create a new key for the channel. */
1350
1351       if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1352         /* They don't match, send CHANNEL_CHANGE notify to the server to
1353            force the ID change. */
1354         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1355         silc_server_send_notify_channel_change(server, sock, FALSE, 
1356                                                channel_id,
1357                                                channel->id, 
1358                                                SILC_ID_CHANNEL_LEN);
1359       }
1360
1361       /* Create new key for the channel and send it to the server and
1362          everybody else possibly on the channel. */
1363
1364       silc_server_create_channel_key(server, channel, 0);
1365
1366       /* Send to the channel */
1367       silc_server_send_channel_key(server, sock, channel, FALSE);
1368
1369       /* Send to the server */
1370       chk = silc_channel_key_payload_encode(channel_id_len, id,
1371                                             strlen(channel->channel_key->
1372                                                    cipher->name),
1373                                             channel->channel_key->cipher->name,
1374                                             channel->key_len / 8, 
1375                                             channel->key);
1376       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1377                               chk->data, chk->len, FALSE);
1378       silc_buffer_free(chk);
1379
1380       /* Since the channel is coming from server and we also know about it
1381          then send the JOIN notify to the server so that it see's our
1382          users on the channel "joining" the channel. */
1383       /* XXX TODO **/
1384     }
1385   }
1386
1387   silc_free(id);
1388 }
1389
1390 /* Received New Channel List packet, list of New Channel List payloads inside
1391    one packet. Process the New Channel payloads one by one. */
1392
1393 void silc_server_new_channel_list(SilcServer server,
1394                                   SilcSocketConnection sock,
1395                                   SilcPacketContext *packet)
1396 {
1397   SilcPacketContext *new;
1398   SilcBuffer buffer;
1399   unsigned short len1, len2;
1400
1401   SILC_LOG_DEBUG(("Processing New Channel List"));
1402
1403   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1404       packet->src_id_type != SILC_ID_SERVER ||
1405       server->server_type == SILC_SERVER)
1406     return;
1407
1408   /* If the sender of this packet is server and we are router we need to
1409      broadcast this packet to other routers in the network. Broadcast
1410      this list packet instead of multiple New Channel packets. */
1411   if (!server->standalone && server->server_type == SILC_ROUTER &&
1412       sock->type == SILC_SOCKET_TYPE_SERVER &&
1413       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1414     SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1415     silc_server_packet_send(server, server->router->connection,
1416                             packet->type, 
1417                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1418                             packet->buffer->data, packet->buffer->len, FALSE);
1419   }
1420
1421   /* Make copy of the original packet context, except for the actual
1422      data buffer, which we will here now fetch from the original buffer. */
1423   new = silc_packet_context_alloc();
1424   new->type = SILC_PACKET_NEW_CHANNEL;
1425   new->flags = packet->flags;
1426   new->src_id = packet->src_id;
1427   new->src_id_len = packet->src_id_len;
1428   new->src_id_type = packet->src_id_type;
1429   new->dst_id = packet->dst_id;
1430   new->dst_id_len = packet->dst_id_len;
1431   new->dst_id_type = packet->dst_id_type;
1432
1433   buffer = silc_buffer_alloc(512);
1434   new->buffer = buffer;
1435
1436   while (packet->buffer->len) {
1437     SILC_GET16_MSB(len1, packet->buffer->data);
1438     if ((len1 > packet->buffer->len) ||
1439         (len1 > buffer->truelen))
1440       break;
1441
1442     SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1443     if ((len2 > packet->buffer->len) ||
1444         (len2 > buffer->truelen))
1445       break;
1446
1447     silc_buffer_pull_tail(buffer, 4 + len1 + len2);
1448     silc_buffer_put(buffer, packet->buffer->data, 4 + len1 + len2);
1449
1450     /* Process the New Channel */
1451     silc_server_new_channel(server, sock, new);
1452
1453     silc_buffer_push_tail(buffer, 4 + len1 + len2);
1454     silc_buffer_pull(packet->buffer, 4 + len1 + len2);
1455   }
1456
1457   silc_buffer_free(buffer);
1458   silc_free(new);
1459 }