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