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   /* Update client entry */
1051   idata->registered = TRUE;
1052   client->nickname = strdup(username);
1053   client->username = username;
1054   client->userinfo = realname ? realname : strdup(" ");
1055   client->id = client_id;
1056
1057   /* Update the cache entry */
1058   cache->id = (void *)client_id;
1059   cache->type = SILC_ID_CLIENT;
1060   cache->data = username;
1061   silc_idcache_sort_by_data(server->local_list->clients);
1062
1063   /* Notify our router about new client on the SILC network */
1064   if (!server->standalone)
1065     silc_server_send_new_id(server, (SilcSocketConnection) 
1066                             server->router->connection, 
1067                             server->server_type == SILC_ROUTER ? TRUE : FALSE,
1068                             client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
1069   
1070   /* Send the new client ID to the client. */
1071   id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1072   reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
1073   silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1074   silc_buffer_format(reply,
1075                      SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1076                      SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
1077                      SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
1078                      SILC_STR_END);
1079   silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0, 
1080                           reply->data, reply->len, FALSE);
1081   silc_free(id_string);
1082   silc_buffer_free(reply);
1083
1084   /* Send some nice info to the client */
1085   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1086                           ("Welcome to the SILC Network %s@%s",
1087                            username, sock->hostname));
1088   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1089                           ("Your host is %s, running version %s",
1090                            server->config->server_info->server_name,
1091                            server_version));
1092   if (server->server_type == SILC_ROUTER) {
1093     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1094                             ("There are %d clients on %d servers in SILC "
1095                              "Network", server->stat.clients,
1096                              server->stat.servers + 1));
1097     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1098                             ("There are %d clients on %d server in our cell",
1099                              server->stat.cell_clients,
1100                              server->stat.cell_servers + 1));
1101     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1102                             ("I have %d clients, %d channels, %d servers and "
1103                              "%d routers",
1104                              server->stat.my_clients, 
1105                              server->stat.my_channels,
1106                              server->stat.my_servers,
1107                              server->stat.my_routers));
1108     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1109                             ("%d server operators and %d router operators "
1110                              "online",
1111                              server->stat.my_server_ops,
1112                              server->stat.my_router_ops));
1113   } else {
1114     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1115                             ("I have %d clients and %d channels formed",
1116                              server->stat.my_clients,
1117                              server->stat.my_channels));
1118     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1119                             ("%d operators online",
1120                              server->stat.my_server_ops));
1121   }
1122   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1123                           ("Your connection is secured with %s cipher, "
1124                            "key length %d bits",
1125                            idata->send_key->cipher->name,
1126                            idata->send_key->cipher->key_len));
1127   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1128                           ("Your current nickname is %s",
1129                            client->nickname));
1130
1131   /* Send motd */
1132   silc_server_send_motd(server, sock);
1133
1134   return client;
1135 }
1136
1137 /* Create new server. This processes received New Server packet and
1138    saves the received Server ID. The server is our locally connected
1139    server thus we save all the information and save it to local list. 
1140    This funtion can be used by both normal server and router server.
1141    If normal server uses this it means that its router has connected
1142    to the server. If router uses this it means that one of the cell's
1143    servers is connected to the router. */
1144
1145 SilcServerEntry silc_server_new_server(SilcServer server,
1146                                        SilcSocketConnection sock,
1147                                        SilcPacketContext *packet)
1148 {
1149   SilcBuffer buffer = packet->buffer;
1150   SilcServerEntry new_server;
1151   SilcIDCacheEntry cache;
1152   SilcServerID *server_id;
1153   SilcIDListData idata;
1154   unsigned char *server_name, *id_string;
1155   unsigned short id_len;
1156   int ret;
1157
1158   SILC_LOG_DEBUG(("Creating new server"));
1159
1160   if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1161       sock->type != SILC_SOCKET_TYPE_ROUTER)
1162     return NULL;
1163
1164   /* Take server entry */
1165   new_server = (SilcServerEntry)sock->user_data;
1166   idata = (SilcIDListData)new_server;
1167
1168   /* Fetch the old server cache entry so that we can update it. */
1169   if (!silc_idcache_find_by_context(server->local_list->servers,
1170                                     sock->user_data, &cache)) {
1171     SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
1172     return NULL;
1173   }
1174
1175   /* Parse the incoming packet */
1176   ret = silc_buffer_unformat(buffer,
1177                              SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1178                              SILC_STR_UI16_STRING_ALLOC(&server_name),
1179                              SILC_STR_END);
1180   if (ret == -1) {
1181     if (id_string)
1182       silc_free(id_string);
1183     if (server_name)
1184       silc_free(server_name);
1185     return NULL;
1186   }
1187
1188   if (id_len > buffer->len) {
1189     silc_free(id_string);
1190     silc_free(server_name);
1191     return NULL;
1192   }
1193
1194   /* Get Server ID */
1195   server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1196   if (!server_id) {
1197     silc_free(id_string);
1198     silc_free(server_name);
1199     return NULL;
1200   }
1201   silc_free(id_string);
1202
1203   /* Update client entry */
1204   idata->registered = TRUE;
1205   new_server->server_name = server_name;
1206   new_server->id = server_id;
1207
1208   /* Update the cache entry */
1209   cache->id = (void *)server_id;
1210   cache->type = SILC_ID_SERVER;
1211   cache->data = server_name;
1212   silc_idcache_sort_by_data(server->local_list->servers);
1213
1214   /* Distribute the information about new server in the SILC network
1215      to our router. If we are normal server we won't send anything
1216      since this connection must be our router connection. */
1217   if (server->server_type == SILC_ROUTER && !server->standalone &&
1218       server->router->connection != sock)
1219     silc_server_send_new_id(server, server->router->connection,
1220                             TRUE, new_server->id, SILC_ID_SERVER, 
1221                             SILC_ID_SERVER_LEN);
1222
1223   if (server->server_type == SILC_ROUTER)
1224     server->stat.cell_servers++;
1225
1226   return new_server;
1227 }
1228
1229 /* Processes incoming New ID packet. New ID Payload is used to distribute
1230    information about newly registered clients and servers. */
1231
1232 static void silc_server_new_id_real(SilcServer server, 
1233                                     SilcSocketConnection sock,
1234                                     SilcPacketContext *packet,
1235                                     int broadcast)
1236 {
1237   SilcBuffer buffer = packet->buffer;
1238   SilcIDList id_list;
1239   SilcServerEntry router;
1240   SilcSocketConnection router_sock;
1241   SilcIDPayload idp;
1242   SilcIdType id_type;
1243   unsigned char *hash = NULL;
1244   void *id;
1245
1246   SILC_LOG_DEBUG(("Processing new ID"));
1247
1248   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1249       server->server_type == SILC_SERVER ||
1250       packet->src_id_type != SILC_ID_SERVER)
1251     return;
1252
1253   idp = silc_id_payload_parse(buffer);
1254   if (!idp)
1255     return;
1256
1257   id_type = silc_id_payload_get_type(idp);
1258
1259   /* Normal server cannot have other normal server connections */
1260   if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1261     goto out;
1262
1263   id = silc_id_payload_get_id(idp);
1264   if (!id)
1265     goto out;
1266
1267   /* If the sender of this packet is server and we are router we need to
1268      broadcast this packet to other routers in the network. */
1269   if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1270       sock->type == SILC_SOCKET_TYPE_SERVER &&
1271       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1272     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1273     silc_server_packet_send(server, server->router->connection,
1274                             packet->type, 
1275                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1276                             buffer->data, buffer->len, FALSE);
1277   }
1278
1279   if (sock->type == SILC_SOCKET_TYPE_SERVER)
1280     id_list = server->local_list;
1281   else
1282     id_list = server->global_list;
1283
1284   router_sock = sock;
1285   router = sock->user_data;
1286
1287   switch(id_type) {
1288   case SILC_ID_CLIENT:
1289     {
1290       SilcClientEntry entry;
1291
1292       SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1293                       silc_id_render(id, SILC_ID_CLIENT),
1294                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1295                       "Server" : "Router", sock->hostname));
1296     
1297       /* As a router we keep information of all global information in our
1298          global list. Cell wide information however is kept in the local
1299          list. The client is put to global list and we will take the hash
1300          value of the Client ID and save it to the ID Cache system for fast
1301          searching in the future. */
1302       hash = silc_calloc(sizeof(((SilcClientID *)id)->hash), 
1303                          sizeof(unsigned char));
1304       memcpy(hash, ((SilcClientID *)id)->hash, 
1305              sizeof(((SilcClientID *)id)->hash));
1306       entry = silc_idlist_add_client(id_list, hash, NULL, NULL, id, 
1307                                      router, NULL);
1308       entry->nickname = NULL;
1309
1310       if (sock->type == SILC_SOCKET_TYPE_SERVER)
1311         server->stat.cell_clients++;
1312       server->stat.clients++;
1313
1314 #if 0
1315       /* XXX Adding two ID's with same IP number replaces the old entry thus
1316          gives wrong route. Thus, now disabled until figured out a better way
1317          to do this or when removed the whole thing. This could be removed
1318          because entry->router->connection gives always the most optimal route
1319          for the ID anyway (unless new routes (faster perhaps) are established
1320          after receiving this ID, this we don't know however). */
1321       /* Add route cache for this ID */
1322       silc_server_route_add(silc_server_route_hash(
1323                             ((SilcClientID *)id)->ip.s_addr,
1324                             server->id->port), ((SilcClientID *)id)->ip.s_addr,
1325                             router);
1326 #endif
1327     }
1328     break;
1329
1330   case SILC_ID_SERVER:
1331     SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1332                     silc_id_render(id, SILC_ID_SERVER),
1333                     sock->type == SILC_SOCKET_TYPE_SERVER ?
1334                     "Server" : "Router", sock->hostname));
1335     
1336     /* As a router we keep information of all global information in our global
1337        list. Cell wide information however is kept in the local list. */
1338     silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1339
1340     if (sock->type == SILC_SOCKET_TYPE_SERVER)
1341       server->stat.cell_servers++;
1342     server->stat.servers++;
1343
1344 #if 0
1345     /* Add route cache for this ID */
1346     silc_server_route_add(silc_server_route_hash(
1347                           ((SilcServerID *)id)->ip.s_addr,
1348                           ((SilcServerID *)id)->port), 
1349                           ((SilcServerID *)id)->ip.s_addr,
1350                           router);
1351 #endif
1352     break;
1353
1354   case SILC_ID_CHANNEL:
1355     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1356     break;
1357
1358   default:
1359     break;
1360   }
1361
1362  out:
1363   silc_id_payload_free(idp);
1364 }
1365
1366
1367 /* Processes incoming New ID packet. New ID Payload is used to distribute
1368    information about newly registered clients and servers. */
1369
1370 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1371                         SilcPacketContext *packet)
1372 {
1373   silc_server_new_id_real(server, sock, packet, TRUE);
1374 }
1375
1376 /* Receoved New Id List packet, list of New ID payloads inside one
1377    packet. Process the New ID payloads one by one. */
1378
1379 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1380                              SilcPacketContext *packet)
1381 {
1382   SilcPacketContext *new_id;
1383   SilcBuffer idp;
1384   unsigned short id_len;
1385
1386   SILC_LOG_DEBUG(("Processing New ID List"));
1387
1388   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1389       packet->src_id_type != SILC_ID_SERVER)
1390     return;
1391
1392   /* If the sender of this packet is server and we are router we need to
1393      broadcast this packet to other routers in the network. Broadcast
1394      this list packet instead of multiple New ID packets. */
1395   if (!server->standalone && server->server_type == SILC_ROUTER &&
1396       sock->type == SILC_SOCKET_TYPE_SERVER &&
1397       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1398     SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1399     silc_server_packet_send(server, server->router->connection,
1400                             packet->type, 
1401                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1402                             packet->buffer->data, packet->buffer->len, FALSE);
1403   }
1404
1405   /* Make copy of the original packet context, except for the actual
1406      data buffer, which we will here now fetch from the original buffer. */
1407   new_id = silc_packet_context_alloc();
1408   new_id->type = SILC_PACKET_NEW_ID;
1409   new_id->flags = packet->flags;
1410   new_id->src_id = packet->src_id;
1411   new_id->src_id_len = packet->src_id_len;
1412   new_id->src_id_type = packet->src_id_type;
1413   new_id->dst_id = packet->dst_id;
1414   new_id->dst_id_len = packet->dst_id_len;
1415   new_id->dst_id_type = packet->dst_id_type;
1416
1417   idp = silc_buffer_alloc(256);
1418   new_id->buffer = idp;
1419
1420   while (packet->buffer->len) {
1421     SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1422     if ((id_len > packet->buffer->len) ||
1423         (id_len > idp->truelen))
1424       break;
1425
1426     silc_buffer_pull_tail(idp, 4 + id_len);
1427     silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1428
1429     /* Process the New ID */
1430     silc_server_new_id_real(server, sock, new_id, FALSE);
1431
1432     silc_buffer_push_tail(idp, 4 + id_len);
1433     silc_buffer_pull(packet->buffer, 4 + id_len);
1434   }
1435
1436   silc_buffer_free(idp);
1437   silc_free(new_id);
1438 }
1439
1440 /* Received New Channel packet. Information about new channels in the 
1441    network are distributed using this packet. Save the information about
1442    the new channel. This usually comes from router but also normal server
1443    can send this to notify channels it has when it connects to us. */
1444
1445 void silc_server_new_channel(SilcServer server,
1446                              SilcSocketConnection sock,
1447                              SilcPacketContext *packet)
1448 {
1449   unsigned char *id;
1450   SilcChannelID *channel_id;
1451   unsigned short channel_id_len;
1452   char *channel_name;
1453   int ret;
1454
1455   SILC_LOG_DEBUG(("Processing New Channel"));
1456
1457   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1458       packet->src_id_type != SILC_ID_SERVER ||
1459       server->server_type == SILC_SERVER)
1460     return;
1461
1462   /* Parse payload */
1463   ret = silc_buffer_unformat(packet->buffer, 
1464                              SILC_STR_UI16_STRING_ALLOC(&channel_name),
1465                              SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
1466                              SILC_STR_END);
1467   if (ret == -1) {
1468     if (channel_name)
1469       silc_free(channel_name);
1470     if (id)
1471       silc_free(id);
1472     return;
1473   }
1474     
1475   /* Decode the channel ID */
1476   channel_id = silc_id_str2id(id, channel_id_len, SILC_ID_CHANNEL);
1477   if (!channel_id)
1478     return;
1479
1480   if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1481     /* Add the server to global list as it is coming from router. It 
1482        cannot be our own channel as it is coming from router. */
1483
1484     SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1485                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1486                     sock->hostname));
1487     
1488     silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id, 
1489                             server->router->connection, NULL, NULL);
1490
1491     server->stat.channels++;
1492   } else {
1493     /* The channel is coming from our server, thus it is in our cell
1494        we will add it to our local list. */
1495     SilcChannelEntry channel;
1496     SilcBuffer chk;
1497
1498     SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1499                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1500                     sock->hostname));
1501     
1502     /* Check that we don't already have this channel */
1503     channel = silc_idlist_find_channel_by_name(server->local_list, 
1504                                                channel_name, NULL);
1505     if (!channel)
1506       channel = silc_idlist_find_channel_by_name(server->global_list, 
1507                                                  channel_name, NULL);
1508
1509     /* If the channel does not exist, then create it. We create the channel
1510        with the channel ID provided by the server. This creates a new
1511        key to the channel as well that we will send to the server. */
1512     if (!channel) {
1513       channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1514                                                        channel_name,
1515                                                        channel_id, FALSE);
1516       if (!channel)
1517         return;
1518
1519       /* Send the new channel key to the server */
1520       chk = silc_channel_key_payload_encode(channel_id_len, id,
1521                                             strlen(channel->channel_key->
1522                                                    cipher->name),
1523                                             channel->channel_key->cipher->name,
1524                                             channel->key_len / 8, 
1525                                             channel->key);
1526       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1527                               chk->data, chk->len, FALSE);
1528       silc_buffer_free(chk);
1529
1530     } else {
1531       /* The channel exist by that name, check whether the ID's match.
1532          If they don't then we'll force the server to use the ID we have.
1533          We also create a new key for the channel. */
1534
1535       if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1536         /* They don't match, send CHANNEL_CHANGE notify to the server to
1537            force the ID change. */
1538         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1539         silc_server_send_notify_channel_change(server, sock, FALSE, 
1540                                                channel_id,
1541                                                channel->id, 
1542                                                SILC_ID_CHANNEL_LEN);
1543       }
1544
1545       /* Create new key for the channel and send it to the server and
1546          everybody else possibly on the channel. */
1547
1548       silc_server_create_channel_key(server, channel, 0);
1549
1550       /* Send to the channel */
1551       silc_server_send_channel_key(server, sock, channel, FALSE);
1552
1553       /* Send to the server */
1554       chk = silc_channel_key_payload_encode(channel_id_len, id,
1555                                             strlen(channel->channel_key->
1556                                                    cipher->name),
1557                                             channel->channel_key->cipher->name,
1558                                             channel->key_len / 8, 
1559                                             channel->key);
1560       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1561                               chk->data, chk->len, FALSE);
1562       silc_buffer_free(chk);
1563
1564       /* Since the channel is coming from server and we also know about it
1565          then send the JOIN notify to the server so that it see's our
1566          users on the channel "joining" the channel. */
1567       /* XXX TODO **/
1568     }
1569   }
1570
1571   silc_free(id);
1572 }
1573
1574 /* Received New Channel List packet, list of New Channel List payloads inside
1575    one packet. Process the New Channel payloads one by one. */
1576
1577 void silc_server_new_channel_list(SilcServer server,
1578                                   SilcSocketConnection sock,
1579                                   SilcPacketContext *packet)
1580 {
1581   SilcPacketContext *new;
1582   SilcBuffer buffer;
1583   unsigned short len1, len2;
1584
1585   SILC_LOG_DEBUG(("Processing New Channel List"));
1586
1587   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1588       packet->src_id_type != SILC_ID_SERVER ||
1589       server->server_type == SILC_SERVER)
1590     return;
1591
1592   /* If the sender of this packet is server and we are router we need to
1593      broadcast this packet to other routers in the network. Broadcast
1594      this list packet instead of multiple New Channel packets. */
1595   if (!server->standalone && server->server_type == SILC_ROUTER &&
1596       sock->type == SILC_SOCKET_TYPE_SERVER &&
1597       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1598     SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1599     silc_server_packet_send(server, server->router->connection,
1600                             packet->type, 
1601                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1602                             packet->buffer->data, packet->buffer->len, FALSE);
1603   }
1604
1605   /* Make copy of the original packet context, except for the actual
1606      data buffer, which we will here now fetch from the original buffer. */
1607   new = silc_packet_context_alloc();
1608   new->type = SILC_PACKET_NEW_CHANNEL;
1609   new->flags = packet->flags;
1610   new->src_id = packet->src_id;
1611   new->src_id_len = packet->src_id_len;
1612   new->src_id_type = packet->src_id_type;
1613   new->dst_id = packet->dst_id;
1614   new->dst_id_len = packet->dst_id_len;
1615   new->dst_id_type = packet->dst_id_type;
1616
1617   buffer = silc_buffer_alloc(512);
1618   new->buffer = buffer;
1619
1620   while (packet->buffer->len) {
1621     SILC_GET16_MSB(len1, packet->buffer->data);
1622     if ((len1 > packet->buffer->len) ||
1623         (len1 > buffer->truelen))
1624       break;
1625
1626     SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1627     if ((len2 > packet->buffer->len) ||
1628         (len2 > buffer->truelen))
1629       break;
1630
1631     silc_buffer_pull_tail(buffer, 4 + len1 + len2);
1632     silc_buffer_put(buffer, packet->buffer->data, 4 + len1 + len2);
1633
1634     /* Process the New Channel */
1635     silc_server_new_channel(server, sock, new);
1636
1637     silc_buffer_push_tail(buffer, 4 + len1 + len2);
1638     silc_buffer_pull(packet->buffer, 4 + len1 + len2);
1639   }
1640
1641   silc_buffer_free(buffer);
1642   silc_free(new);
1643 }
1644
1645 /* Received key agreement packet. This packet is never for us. It is to
1646    the client in the packet's destination ID. Sending of this sort of packet
1647    equals sending private message, ie. it is sent point to point from
1648    one client to another. */
1649
1650 void silc_server_key_agreement(SilcServer server,
1651                                SilcSocketConnection sock,
1652                                SilcPacketContext *packet)
1653 {
1654   SilcClientID *id;
1655   SilcServerEntry router;
1656   SilcSocketConnection dst_sock;
1657   SilcClientEntry client;
1658   SilcIDListData idata;
1659
1660   SILC_LOG_DEBUG(("Start"));
1661
1662   if (packet->src_id_type != SILC_ID_CLIENT ||
1663       packet->dst_id_type != SILC_ID_CLIENT)
1664     return;
1665
1666   if (!packet->dst_id)
1667     return;
1668
1669   /* Decode destination Client ID */
1670   id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1671   if (!id) {
1672     SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
1673     return;
1674   }
1675
1676   /* If the destination belongs to our server we don't have to route
1677      the message anywhere but to send it to the local destination. */
1678   client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
1679   if (client) {
1680     /* It exists, now deliver the message to the destination */
1681     dst_sock = (SilcSocketConnection)client->connection;
1682
1683     /* If we are router and the client has router then the client is in
1684        our cell but not directly connected to us. */
1685     if (server->server_type == SILC_ROUTER && client->router) {
1686       /* We are of course in this case the client's router thus the real
1687          "router" of the client is the server who owns the client. Thus
1688          we will send the packet to that server. */
1689       router = (SilcServerEntry)client->router;
1690       idata = (SilcIDListData)router;
1691       silc_server_send_key_agreement(server, router->connection,
1692                                      idata->send_key,
1693                                      idata->hmac,
1694                                      packet);
1695       return;
1696     }
1697
1698     /* Seems that client really is directly connected to us */
1699     idata = (SilcIDListData)client;
1700     silc_server_send_key_agreement(server, dst_sock, 
1701                                    idata->send_key,
1702                                    idata->hmac, packet);
1703     return;
1704   }
1705
1706   /* Destination belongs to someone not in this server. If we are normal
1707      server our action is to send the packet to our router. */
1708   if (server->server_type == SILC_SERVER && !server->standalone) {
1709     router = server->router;
1710
1711     /* Send to primary route */
1712     if (router) {
1713       dst_sock = (SilcSocketConnection)router->connection;
1714       idata = (SilcIDListData)router;
1715       silc_server_send_key_agreement(server, dst_sock, 
1716                                      idata->send_key,
1717                                      idata->hmac, packet);
1718     }
1719     return;
1720   }
1721
1722   /* We are router and we will perform route lookup for the destination 
1723      and send the packet to fastest route. */
1724   if (server->server_type == SILC_ROUTER && !server->standalone) {
1725     /* Check first that the ID is valid */
1726     client = silc_idlist_find_client_by_id(server->global_list, id, NULL);
1727     if (client) {
1728       dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
1729       router = (SilcServerEntry)dst_sock->user_data;
1730       idata = (SilcIDListData)router;
1731
1732       /* Get fastest route and send packet. */
1733       if (router)
1734         silc_server_send_key_agreement(server, dst_sock, 
1735                                        idata->send_key,
1736                                        idata->hmac, packet);
1737       return;
1738     }
1739   }
1740 }