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