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, 0, 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, 
1309                                      sizeof(((SilcClientID *)id)->hash),
1310                                      NULL, NULL, id, router, NULL);
1311       entry->nickname = NULL;
1312       entry->data.registered = TRUE;
1313
1314       if (sock->type == SILC_SOCKET_TYPE_SERVER)
1315         server->stat.cell_clients++;
1316       server->stat.clients++;
1317
1318 #if 0
1319       /* XXX Adding two ID's with same IP number replaces the old entry thus
1320          gives wrong route. Thus, now disabled until figured out a better way
1321          to do this or when removed the whole thing. This could be removed
1322          because entry->router->connection gives always the most optimal route
1323          for the ID anyway (unless new routes (faster perhaps) are established
1324          after receiving this ID, this we don't know however). */
1325       /* Add route cache for this ID */
1326       silc_server_route_add(silc_server_route_hash(
1327                             ((SilcClientID *)id)->ip.s_addr,
1328                             server->id->port), ((SilcClientID *)id)->ip.s_addr,
1329                             router);
1330 #endif
1331     }
1332     break;
1333
1334   case SILC_ID_SERVER:
1335     SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1336                     silc_id_render(id, SILC_ID_SERVER),
1337                     sock->type == SILC_SOCKET_TYPE_SERVER ?
1338                     "Server" : "Router", sock->hostname));
1339     
1340     /* As a router we keep information of all global information in our global
1341        list. Cell wide information however is kept in the local list. */
1342     silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1343
1344     if (sock->type == SILC_SOCKET_TYPE_SERVER)
1345       server->stat.cell_servers++;
1346     server->stat.servers++;
1347
1348 #if 0
1349     /* Add route cache for this ID */
1350     silc_server_route_add(silc_server_route_hash(
1351                           ((SilcServerID *)id)->ip.s_addr,
1352                           ((SilcServerID *)id)->port), 
1353                           ((SilcServerID *)id)->ip.s_addr,
1354                           router);
1355 #endif
1356     break;
1357
1358   case SILC_ID_CHANNEL:
1359     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1360     break;
1361
1362   default:
1363     break;
1364   }
1365
1366  out:
1367   silc_id_payload_free(idp);
1368 }
1369
1370
1371 /* Processes incoming New ID packet. New ID Payload is used to distribute
1372    information about newly registered clients and servers. */
1373
1374 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1375                         SilcPacketContext *packet)
1376 {
1377   silc_server_new_id_real(server, sock, packet, TRUE);
1378 }
1379
1380 /* Receoved New Id List packet, list of New ID payloads inside one
1381    packet. Process the New ID payloads one by one. */
1382
1383 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1384                              SilcPacketContext *packet)
1385 {
1386   SilcPacketContext *new_id;
1387   SilcBuffer idp;
1388   unsigned short id_len;
1389
1390   SILC_LOG_DEBUG(("Processing New ID List"));
1391
1392   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1393       packet->src_id_type != SILC_ID_SERVER)
1394     return;
1395
1396   /* If the sender of this packet is server and we are router we need to
1397      broadcast this packet to other routers in the network. Broadcast
1398      this list packet instead of multiple New ID packets. */
1399   if (!server->standalone && server->server_type == SILC_ROUTER &&
1400       sock->type == SILC_SOCKET_TYPE_SERVER &&
1401       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1402     SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1403     silc_server_packet_send(server, server->router->connection,
1404                             packet->type, 
1405                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1406                             packet->buffer->data, packet->buffer->len, FALSE);
1407   }
1408
1409   /* Make copy of the original packet context, except for the actual
1410      data buffer, which we will here now fetch from the original buffer. */
1411   new_id = silc_packet_context_alloc();
1412   new_id->type = SILC_PACKET_NEW_ID;
1413   new_id->flags = packet->flags;
1414   new_id->src_id = packet->src_id;
1415   new_id->src_id_len = packet->src_id_len;
1416   new_id->src_id_type = packet->src_id_type;
1417   new_id->dst_id = packet->dst_id;
1418   new_id->dst_id_len = packet->dst_id_len;
1419   new_id->dst_id_type = packet->dst_id_type;
1420
1421   idp = silc_buffer_alloc(256);
1422   new_id->buffer = idp;
1423
1424   while (packet->buffer->len) {
1425     SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1426     if ((id_len > packet->buffer->len) ||
1427         (id_len > idp->truelen))
1428       break;
1429
1430     silc_buffer_pull_tail(idp, 4 + id_len);
1431     silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1432
1433     /* Process the New ID */
1434     silc_server_new_id_real(server, sock, new_id, FALSE);
1435
1436     silc_buffer_push_tail(idp, 4 + id_len);
1437     silc_buffer_pull(packet->buffer, 4 + id_len);
1438   }
1439
1440   silc_buffer_free(idp);
1441   silc_free(new_id);
1442 }
1443
1444 /* Received New Channel packet. Information about new channels in the 
1445    network are distributed using this packet. Save the information about
1446    the new channel. This usually comes from router but also normal server
1447    can send this to notify channels it has when it connects to us. */
1448
1449 void silc_server_new_channel(SilcServer server,
1450                              SilcSocketConnection sock,
1451                              SilcPacketContext *packet)
1452 {
1453   SilcChannelPayload payload;
1454   SilcChannelID *channel_id;
1455   char *channel_name;
1456   unsigned int name_len;
1457   unsigned char *id;
1458   unsigned int id_len;
1459
1460   SILC_LOG_DEBUG(("Processing New Channel"));
1461
1462   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1463       packet->src_id_type != SILC_ID_SERVER ||
1464       server->server_type == SILC_SERVER)
1465     return;
1466
1467   /* Parse the channel payload */
1468   payload = silc_channel_payload_parse(packet->buffer);
1469   if (!payload)
1470     return;
1471     
1472   /* Get the channel ID */
1473   channel_id = silc_channel_get_id_parse(payload);
1474   if (!channel_id) {
1475     silc_channel_payload_free(payload);
1476     return;
1477   }
1478
1479   channel_name = silc_channel_get_name(payload, &name_len);
1480   if (name_len > 256)
1481     channel_name[255] = '\0';
1482
1483   id = silc_channel_get_id(payload, &id_len);
1484
1485   if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1486     /* Add the server to global list as it is coming from router. It 
1487        cannot be our own channel as it is coming from router. */
1488
1489     SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1490                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1491                     sock->hostname));
1492     
1493     silc_idlist_add_channel(server->global_list, strdup(channel_name), 
1494                             0, channel_id, server->router->connection, 
1495                             NULL, NULL);
1496
1497     server->stat.channels++;
1498   } else {
1499     /* The channel is coming from our server, thus it is in our cell
1500        we will add it to our local list. */
1501     SilcChannelEntry channel;
1502     SilcBuffer chk;
1503
1504     SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1505                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1506                     sock->hostname));
1507     
1508     /* Check that we don't already have this channel */
1509     channel = silc_idlist_find_channel_by_name(server->local_list, 
1510                                                channel_name, NULL);
1511     if (!channel)
1512       channel = silc_idlist_find_channel_by_name(server->global_list, 
1513                                                  channel_name, NULL);
1514
1515     /* If the channel does not exist, then create it. We create the channel
1516        with the channel ID provided by the server. This creates a new
1517        key to the channel as well that we will send to the server. */
1518     if (!channel) {
1519       channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1520                                                        channel_name,
1521                                                        channel_id, FALSE);
1522       if (!channel) {
1523         silc_channel_payload_free(payload);
1524         silc_free(channel_id);
1525         return;
1526       }
1527
1528       /* Send the new channel key to the server */
1529       chk = silc_channel_key_payload_encode(id_len, id,
1530                                             strlen(channel->channel_key->
1531                                                    cipher->name),
1532                                             channel->channel_key->cipher->name,
1533                                             channel->key_len / 8, 
1534                                             channel->key);
1535       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1536                               chk->data, chk->len, FALSE);
1537       silc_buffer_free(chk);
1538
1539     } else {
1540       /* The channel exist by that name, check whether the ID's match.
1541          If they don't then we'll force the server to use the ID we have.
1542          We also create a new key for the channel. */
1543
1544       if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1545         /* They don't match, send CHANNEL_CHANGE notify to the server to
1546            force the ID change. */
1547         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1548         silc_server_send_notify_channel_change(server, sock, FALSE, 
1549                                                channel_id,
1550                                                channel->id, 
1551                                                SILC_ID_CHANNEL_LEN);
1552       }
1553
1554       /* Create new key for the channel and send it to the server and
1555          everybody else possibly on the channel. */
1556
1557       silc_server_create_channel_key(server, channel, 0);
1558
1559       /* Send to the channel */
1560       silc_server_send_channel_key(server, sock, channel, FALSE);
1561
1562       /* Send to the server */
1563       chk = silc_channel_key_payload_encode(id_len, id,
1564                                             strlen(channel->channel_key->
1565                                                    cipher->name),
1566                                             channel->channel_key->cipher->name,
1567                                             channel->key_len / 8, 
1568                                             channel->key);
1569       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1570                               chk->data, chk->len, FALSE);
1571       silc_buffer_free(chk);
1572       silc_free(channel_id);
1573
1574       /* Since the channel is coming from server and we also know about it
1575          then send the JOIN notify to the server so that it see's our
1576          users on the channel "joining" the channel. */
1577       /* XXX TODO **/
1578     }
1579   }
1580 }
1581
1582 /* Received New Channel List packet, list of New Channel List payloads inside
1583    one packet. Process the New Channel payloads one by one. */
1584
1585 void silc_server_new_channel_list(SilcServer server,
1586                                   SilcSocketConnection sock,
1587                                   SilcPacketContext *packet)
1588 {
1589   SilcPacketContext *new;
1590   SilcBuffer buffer;
1591   unsigned short len1, len2;
1592
1593   SILC_LOG_DEBUG(("Processing New Channel List"));
1594
1595   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1596       packet->src_id_type != SILC_ID_SERVER ||
1597       server->server_type == SILC_SERVER)
1598     return;
1599
1600   /* If the sender of this packet is server and we are router we need to
1601      broadcast this packet to other routers in the network. Broadcast
1602      this list packet instead of multiple New Channel packets. */
1603   if (!server->standalone && server->server_type == SILC_ROUTER &&
1604       sock->type == SILC_SOCKET_TYPE_SERVER &&
1605       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1606     SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1607     silc_server_packet_send(server, server->router->connection,
1608                             packet->type, 
1609                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1610                             packet->buffer->data, packet->buffer->len, FALSE);
1611   }
1612
1613   /* Make copy of the original packet context, except for the actual
1614      data buffer, which we will here now fetch from the original buffer. */
1615   new = silc_packet_context_alloc();
1616   new->type = SILC_PACKET_NEW_CHANNEL;
1617   new->flags = packet->flags;
1618   new->src_id = packet->src_id;
1619   new->src_id_len = packet->src_id_len;
1620   new->src_id_type = packet->src_id_type;
1621   new->dst_id = packet->dst_id;
1622   new->dst_id_len = packet->dst_id_len;
1623   new->dst_id_type = packet->dst_id_type;
1624
1625   buffer = silc_buffer_alloc(512);
1626   new->buffer = buffer;
1627
1628   while (packet->buffer->len) {
1629     SILC_GET16_MSB(len1, packet->buffer->data);
1630     if ((len1 > packet->buffer->len) ||
1631         (len1 > buffer->truelen))
1632       break;
1633
1634     SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1635     if ((len2 > packet->buffer->len) ||
1636         (len2 > buffer->truelen))
1637       break;
1638
1639     silc_buffer_pull_tail(buffer, 8 + len1 + len2);
1640     silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
1641
1642     /* Process the New Channel */
1643     silc_server_new_channel(server, sock, new);
1644
1645     silc_buffer_push_tail(buffer, 8 + len1 + len2);
1646     silc_buffer_pull(packet->buffer, 8 + len1 + len2);
1647   }
1648
1649   silc_buffer_free(buffer);
1650   silc_free(new);
1651 }
1652
1653 /* Received key agreement packet. This packet is never for us. It is to
1654    the client in the packet's destination ID. Sending of this sort of packet
1655    equals sending private message, ie. it is sent point to point from
1656    one client to another. */
1657
1658 void silc_server_key_agreement(SilcServer server,
1659                                SilcSocketConnection sock,
1660                                SilcPacketContext *packet)
1661 {
1662   SilcSocketConnection dst_sock;
1663   SilcIDListData idata;
1664
1665   SILC_LOG_DEBUG(("Start"));
1666
1667   if (packet->src_id_type != SILC_ID_CLIENT ||
1668       packet->dst_id_type != SILC_ID_CLIENT)
1669     return;
1670
1671   if (!packet->dst_id)
1672     return;
1673
1674   /* Get the route to the client */
1675   dst_sock = silc_server_get_client_route(server, packet->dst_id,
1676                                           packet->dst_id_len, &idata);
1677   if (!dst_sock)
1678     return;
1679
1680   /* Relay the packet */
1681   silc_server_relay_packet(server, dst_sock, idata->send_key,
1682                            idata->hmac, packet, FALSE);
1683 }