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