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