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